Git init
[profile/ivi/liboil.git] / liboil / dct / fdct8x8theora.c
1 /*
2  * LIBOIL - Library of Optimized Inner Loops
3  * Copyright (c) 2003,2004 David A. Schleef <ds@schleef.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
19  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /********************************************************************
29  *                                                                  *
30  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
31  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
32  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
33  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
34  *                                                                  *
35  * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2003                *
36  * by the Xiph.Org Foundation http://www.xiph.org/                  *
37  *                                                                  *
38  ********************************************************************
39
40   function:
41   last mod: $Id: fdct8x8theora.c,v 1.3 2005-12-16 17:30:40 ds Exp $
42
43  ********************************************************************/
44
45 #ifdef HAVE_CONFIG_H
46 #include "config.h"
47 #endif
48
49 #include <liboil/liboilfunction.h>
50 #include <liboil/liboilfuncs.h>
51 #include <liboil/dct/dct.h>
52 #include <math.h>
53
54 static int32_t xC1S7 = 64277;
55 static int32_t xC2S6 = 60547;
56 static int32_t xC3S5 = 54491;
57 static int32_t xC4S4 = 46341;
58 static int32_t xC5S3 = 36410;
59 static int32_t xC6S2 = 25080;
60 static int32_t xC7S1 = 12785;
61
62 #define SIGNBITDUPPED(X) ((signed )(((X) & 0x80000000)) >> 31)
63 #define DOROUND(X) ( (SIGNBITDUPPED(X) & (0xffff)) + (X) )
64
65 /**
66  * oil_fdct8x8theora:
67  * @s_8x8:
68  * @d_8x8:
69  *
70  * Calculates the FDCT transformation of @s_8x8 according to the Theora
71  * specification and places the result in @d_8x8.
72  *
73  * Note that the source and destination arrays are reversed compared
74  * to normal Liboil order.
75  */
76 OIL_DEFINE_CLASS(fdct8x8theora, "int16_t *s_8x8, int16_t *d_8x8");
77
78 static void
79 fdct8x8theora_ref(const int16_t *src, int16_t *dest)
80 {
81   int loop;
82
83   int32_t  is07, is12, is34, is56;
84   int32_t  is0734, is1256;
85   int32_t  id07, id12, id34, id56;
86
87   int32_t  irot_input_x, irot_input_y;
88   int32_t  icommon_product1;   /* Re-used product  (c4s4 * (s12 - s56)). */
89   int32_t  icommon_product2;   /* Re-used product  (c4s4 * (d12 + d56)). */
90
91   int32_t  temp1, temp2;         /* intermediate variable for computation */
92
93   int32_t  InterData[64];
94   int32_t *ip = InterData;
95   int16_t * op = dest;
96   for (loop = 0; loop < 8; loop++){
97     /* Pre calculate some common sums and differences. */
98     is07 = src[0] + src[7];
99     is12 = src[1] + src[2];
100     is34 = src[3] + src[4];
101     is56 = src[5] + src[6];
102
103     id07 = src[0] - src[7];
104     id12 = src[1] - src[2];
105     id34 = src[3] - src[4];
106     id56 = src[5] - src[6];
107
108     is0734 = is07 + is34;
109     is1256 = is12 + is56;
110
111     /* Pre-Calculate some common product terms. */
112     icommon_product1 = xC4S4*(is12 - is56);
113     icommon_product1 = DOROUND(icommon_product1);
114     icommon_product1>>=16;
115
116     icommon_product2 = xC4S4*(id12 + id56);
117     icommon_product2 = DOROUND(icommon_product2);
118     icommon_product2>>=16;
119
120
121     ip[0] = (xC4S4*(is0734 + is1256));
122     ip[0] = DOROUND(ip[0]);
123     ip[0] >>= 16;
124
125     ip[4] = (xC4S4*(is0734 - is1256));
126     ip[4] = DOROUND(ip[4]);
127     ip[4] >>= 16;
128
129     /* Define inputs to rotation for outputs 2 and 6 */
130     irot_input_x = id12 - id56;
131     irot_input_y = is07 - is34;
132
133     /* Apply rotation for outputs 2 and 6.  */
134     temp1=xC6S2*irot_input_x;
135     temp1=DOROUND(temp1);
136     temp1>>=16;
137     temp2=xC2S6*irot_input_y;
138     temp2=DOROUND(temp2);
139     temp2>>=16;
140     ip[2] = temp1 + temp2;
141
142     temp1=xC6S2*irot_input_y;
143     temp1=DOROUND(temp1);
144     temp1>>=16;
145     temp2=xC2S6*irot_input_x ;
146     temp2=DOROUND(temp2);
147     temp2>>=16;
148     ip[6] = temp1 -temp2 ;
149
150     /* Define inputs to rotation for outputs 1 and 7  */
151     irot_input_x = icommon_product1 + id07;
152     irot_input_y = -( id34 + icommon_product2 );
153
154     /* Apply rotation for outputs 1 and 7.  */
155
156     temp1=xC1S7*irot_input_x;
157     temp1=DOROUND(temp1);
158     temp1>>=16;
159     temp2=xC7S1*irot_input_y;
160     temp2=DOROUND(temp2);
161     temp2>>=16;
162     ip[1] = temp1 - temp2;
163
164     temp1=xC7S1*irot_input_x;
165     temp1=DOROUND(temp1);
166     temp1>>=16;
167     temp2=xC1S7*irot_input_y ;
168     temp2=DOROUND(temp2);
169     temp2>>=16;
170     ip[7] = temp1 + temp2 ;
171
172     /* Define inputs to rotation for outputs 3 and 5 */
173     irot_input_x = id07 - icommon_product1;
174     irot_input_y = id34 - icommon_product2;
175
176     /* Apply rotation for outputs 3 and 5. */
177     temp1=xC3S5*irot_input_x;
178     temp1=DOROUND(temp1);
179     temp1>>=16;
180     temp2=xC5S3*irot_input_y ;
181     temp2=DOROUND(temp2);
182     temp2>>=16;
183     ip[3] = temp1 - temp2 ;
184
185     temp1=xC5S3*irot_input_x;
186     temp1=DOROUND(temp1);
187     temp1>>=16;
188     temp2=xC3S5*irot_input_y;
189     temp2=DOROUND(temp2);
190     temp2>>=16;
191     ip[5] = temp1 + temp2;
192
193     /* Increment data pointer for next row. */
194     src += 8 ;
195     ip += 8; /* advance pointer to next row */
196
197   }
198
199
200   /* Performed DCT on rows, now transform the columns */
201   ip = InterData;
202   for (loop = 0; loop < 8; loop++){
203     /* Pre calculate some common sums and differences.  */
204     is07 = ip[0 * 8] + ip[7 * 8];
205     is12 = ip[1 * 8] + ip[2 * 8];
206     is34 = ip[3 * 8] + ip[4 * 8];
207     is56 = ip[5 * 8] + ip[6 * 8];
208
209     id07 = ip[0 * 8] - ip[7 * 8];
210     id12 = ip[1 * 8] - ip[2 * 8];
211     id34 = ip[3 * 8] - ip[4 * 8];
212     id56 = ip[5 * 8] - ip[6 * 8];
213
214     is0734 = is07 + is34;
215     is1256 = is12 + is56;
216
217     /* Pre-Calculate some common product terms. */
218     icommon_product1 = xC4S4*(is12 - is56) ;
219     icommon_product2 = xC4S4*(id12 + id56) ;
220     icommon_product1 = DOROUND(icommon_product1);
221     icommon_product2 = DOROUND(icommon_product2);
222     icommon_product1>>=16;
223     icommon_product2>>=16;
224
225
226     temp1 = xC4S4*(is0734 + is1256) ;
227     temp2 = xC4S4*(is0734 - is1256) ;
228     temp1 = DOROUND(temp1);
229     temp2 = DOROUND(temp2);
230     temp1>>=16;
231     temp2>>=16;
232     op[0*8] = (int16_t) temp1;
233     op[4*8] = (int16_t) temp2;
234
235     /* Define inputs to rotation for outputs 2 and 6 */
236     irot_input_x = id12 - id56;
237     irot_input_y = is07 - is34;
238
239     /* Apply rotation for outputs 2 and 6.  */
240     temp1=xC6S2*irot_input_x;
241     temp1=DOROUND(temp1);
242     temp1>>=16;
243     temp2=xC2S6*irot_input_y;
244     temp2=DOROUND(temp2);
245     temp2>>=16;
246     op[2*8] = (int16_t) (temp1 + temp2);
247
248     temp1=xC6S2*irot_input_y;
249     temp1=DOROUND(temp1);
250     temp1>>=16;
251     temp2=xC2S6*irot_input_x ;
252     temp2=DOROUND(temp2);
253     temp2>>=16;
254     op[6*8] = (int16_t) (temp1 -temp2) ;
255
256     /* Define inputs to rotation for outputs 1 and 7 */
257     irot_input_x = icommon_product1 + id07;
258     irot_input_y = -( id34 + icommon_product2 );
259
260     /* Apply rotation for outputs 1 and 7. */
261     temp1=xC1S7*irot_input_x;
262     temp1=DOROUND(temp1);
263     temp1>>=16;
264     temp2=xC7S1*irot_input_y;
265     temp2=DOROUND(temp2);
266     temp2>>=16;
267     op[1*8] = (int16_t) (temp1 - temp2);
268
269     temp1=xC7S1*irot_input_x;
270     temp1=DOROUND(temp1);
271     temp1>>=16;
272     temp2=xC1S7*irot_input_y ;
273     temp2=DOROUND(temp2);
274     temp2>>=16;
275     op[7*8] = (int16_t) (temp1 + temp2);
276
277     /* Define inputs to rotation for outputs 3 and 5 */
278     irot_input_x = id07 - icommon_product1;
279     irot_input_y = id34 - icommon_product2;
280
281     /* Apply rotation for outputs 3 and 5. */
282     temp1=xC3S5*irot_input_x;
283     temp1=DOROUND(temp1);
284     temp1>>=16;
285     temp2=xC5S3*irot_input_y ;
286     temp2=DOROUND(temp2);
287     temp2>>=16;
288     op[3*8] = (int16_t) (temp1 - temp2) ;
289
290     temp1=xC5S3*irot_input_x;
291     temp1=DOROUND(temp1);
292     temp1>>=16;
293     temp2=xC3S5*irot_input_y;
294     temp2=DOROUND(temp2);
295     temp2>>=16;
296     op[5*8] = (int16_t) (temp1 + temp2);
297
298     /* Increment data pointer for next column.  */
299     ip ++;
300     op ++;
301   }
302 }
303
304 OIL_DEFINE_IMPL_REF (fdct8x8theora_ref, fdct8x8theora);
305