|
1 /* |
|
2 * LIBOIL - Library of Optimized Inner Loops |
|
3 * Copyright (c) 2001,2002,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 //Portions Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. |
|
28 |
|
29 #ifdef HAVE_CONFIG_H |
|
30 #include "config.h" |
|
31 #endif |
|
32 |
|
33 #include <liboil/liboil.h> |
|
34 #include "liboil/dct/dct.h" |
|
35 #include <math.h> |
|
36 #include <liboil/liboiltest.h> |
|
37 #include <liboil/liboilparameter.h> |
|
38 #include <liboil/liboilrandom.h> |
|
39 |
|
40 /** |
|
41 * SECTION:liboilfuncs-dct: |
|
42 * @title: Direct Cosine Transform |
|
43 * @short_description: DCT related functions |
|
44 */ |
|
45 |
|
46 #define BLOCK8x8_F64(ptr, stride, row, column) \ |
|
47 (*((double *)((unsigned char *)ptr + stride*row) + column)) |
|
48 |
|
49 #define BLOCK8x8_PTR_F64(ptr, stride, row, column) \ |
|
50 ((double *)((unsigned char *)ptr + stride*row) + column) |
|
51 |
|
52 #define BLOCK8x8_S16(ptr, stride, row, column) \ |
|
53 (*((int16_t *)((unsigned char *)ptr + stride*row) + column)) |
|
54 |
|
55 static void |
|
56 idct8x8_test (OilTest *test) |
|
57 { |
|
58 int16_t *data = oil_test_get_source_data (test, OIL_ARG_SRC1); |
|
59 int stride = oil_test_get_value (test, OIL_ARG_SSTR1); |
|
60 int i, j; |
|
61 |
|
62 for(j=0;j<8;j++){ |
|
63 for(i=0;i<8;i++){ |
|
64 OIL_GET(data, i*2 + j*stride, int16_t) = (oil_rand_s16() & 0xfff) - 2048; |
|
65 } |
|
66 } |
|
67 } |
|
68 |
|
69 /** |
|
70 * oil_idct8x8_f64: |
|
71 * @d_8x8: |
|
72 * @dstr: |
|
73 * @s_8x8: |
|
74 * @sstr: |
|
75 * |
|
76 * Performs a 2-D Inverse Discrete Cosine Transform on @s_8x8 and places |
|
77 * the result in @d_8x8. |
|
78 */ |
|
79 OIL_DEFINE_CLASS (idct8x8_f64, "double *d_8x8, int dstr, double *s_8x8, int sstr"); |
|
80 /** |
|
81 * oil_idct8x8lim10_f64: |
|
82 * @d_8x8: |
|
83 * @dstr: |
|
84 * @s_8x8: |
|
85 * @sstr: |
|
86 * |
|
87 * Performs a 2-D Inverse Discrete Cosine Transform on @s_8x8 and places |
|
88 * the result in @d_8x8. |
|
89 */ |
|
90 OIL_DEFINE_CLASS (idct8x8lim10_f64, "double *d_8x8, int dstr, double *s_8x8, int sstr"); |
|
91 /** |
|
92 * oil_idct8x8_s16: |
|
93 * @d_8x8: |
|
94 * @dstr: |
|
95 * @s_8x8: |
|
96 * @sstr: |
|
97 * |
|
98 * Performs a limited 2-D Inverse Discrete Cosine Transform on @s_8x8 |
|
99 * and places the result in @d_8x8. |
|
100 */ |
|
101 OIL_DEFINE_CLASS_FULL (idct8x8_s16, "int16_t *d_8x8, int dstr, int16_t *s_8x8, int sstr", idct8x8_test); |
|
102 /** |
|
103 * oil_idct8x8lim10_s16: |
|
104 * @d_8x8: |
|
105 * @dstr: |
|
106 * @s_8x8: |
|
107 * @sstr: |
|
108 * |
|
109 * Performs a limited 2-D Inverse Discrete Cosine Transform on @s_8x8 |
|
110 * and places the result in @d_8x8. The source 8x8 block must be non-zero |
|
111 * only in the 10 lowest-order components. |
|
112 */ |
|
113 OIL_DEFINE_CLASS (idct8x8lim10_s16, "int16_t *d_8x8, int dstr, int16_t *s_8x8, int sstr"); |
|
114 |
|
115 static void |
|
116 idct8x8_f64_ref (double *dest, int dstr, const double *src, int sstr) |
|
117 { |
|
118 static double idct_coeff[8][8]; |
|
119 static int idct_coeff_init = 0; |
|
120 int i,j,k,l; |
|
121 double tmp1,tmp2; |
|
122 |
|
123 if(!idct_coeff_init){ |
|
124 double scale; |
|
125 |
|
126 for(i=0;i<8;i++){ |
|
127 scale = (i==0) ? sqrt(0.125) : 0.5; |
|
128 for(j=0;j<8;j++){ |
|
129 idct_coeff[j][i] = scale * |
|
130 cos((M_PI/8)*i*(j+0.5)); |
|
131 } |
|
132 } |
|
133 idct_coeff_init = 1; |
|
134 } |
|
135 |
|
136 for(i=0;i<8;i++){ |
|
137 for(j=0;j<8;j++){ |
|
138 tmp1 = 0; |
|
139 for(k=0;k<8;k++){ |
|
140 tmp2 = 0; |
|
141 for(l=0;l<8;l++){ |
|
142 tmp2 += idct_coeff[j][l] * |
|
143 BLOCK8x8_F64(src,sstr,k,l); |
|
144 } |
|
145 tmp1 += idct_coeff[i][k] * tmp2; |
|
146 } |
|
147 BLOCK8x8_F64(dest,dstr,i,j) = tmp1; |
|
148 } |
|
149 } |
|
150 } |
|
151 OIL_DEFINE_IMPL_REF (idct8x8_f64_ref, idct8x8_f64); |
|
152 |
|
153 static void |
|
154 idct8x8lim10_f64_ref (double *dest, int dstr, const double *src, int sstr) |
|
155 { |
|
156 static double idct_coeff[8][8]; |
|
157 static int idct_coeff_init = 0; |
|
158 int i,j,k,l; |
|
159 double tmp1,tmp2; |
|
160 |
|
161 if(!idct_coeff_init){ |
|
162 double scale; |
|
163 |
|
164 for(i=0;i<8;i++){ |
|
165 scale = (i==0) ? sqrt(0.125) : 0.5; |
|
166 for(j=0;j<8;j++){ |
|
167 idct_coeff[j][i] = scale * |
|
168 cos((M_PI/8)*i*(j+0.5)); |
|
169 } |
|
170 } |
|
171 idct_coeff_init = 1; |
|
172 } |
|
173 |
|
174 for(i=0;i<8;i++){ |
|
175 for(j=0;j<8;j++){ |
|
176 tmp1 = 0; |
|
177 for(k=0;k<4;k++){ |
|
178 tmp2 = 0; |
|
179 for(l=0;l<4;l++){ |
|
180 tmp2 += idct_coeff[j][l] * |
|
181 BLOCK8x8_F64(src,sstr,k,l); |
|
182 } |
|
183 tmp1 += idct_coeff[i][k] * tmp2; |
|
184 } |
|
185 BLOCK8x8_F64(dest,dstr,i,j) = tmp1; |
|
186 } |
|
187 } |
|
188 } |
|
189 OIL_DEFINE_IMPL_REF (idct8x8lim10_f64_ref, idct8x8lim10_f64); |
|
190 |
|
191 #if defined(oil_idct8_f64) |
|
192 static void |
|
193 idct8x8_f64_c (double *dest, int dstr, const double *src, int sstr) |
|
194 { |
|
195 int i; |
|
196 double tmp[64]; |
|
197 int tmpstr = 8*sizeof(double); |
|
198 |
|
199 for(i=0;i<8;i++){ |
|
200 oil_idct8_f64( |
|
201 BLOCK8x8_PTR_F64(tmp,tmpstr,i,0), sizeof(double), |
|
202 BLOCK8x8_PTR_F64(src,sstr,i,0), sizeof(double)); |
|
203 } |
|
204 for(i=0;i<8;i++){ |
|
205 oil_idct8_f64( |
|
206 BLOCK8x8_PTR_F64(dest,dstr,0,i), dstr, |
|
207 BLOCK8x8_PTR_F64(tmp,tmpstr,0,i), tmpstr); |
|
208 } |
|
209 } |
|
210 |
|
211 OIL_DEFINE_IMPL_DEPENDS (idct8x8_f64_c, idct8x8_f64, idct8_f64); |
|
212 #endif |
|
213 |
|
214 #if defined(oil_conv8x8_f64_s16) && defined(oil_idct8x8_f64) && \ |
|
215 defined(oil_conv8x8_s16_f64) |
|
216 static void |
|
217 idct8x8_s16_ref (int16_t *dest, int dstr, const int16_t *src, int sstr) |
|
218 { |
|
219 double s[64], d[64]; |
|
220 |
|
221 oil_conv8x8_f64_s16 (s,8*sizeof(double),src,sstr); |
|
222 oil_idct8x8_f64 (d,8*sizeof(double),s,8*sizeof(double)); |
|
223 oil_conv8x8_s16_f64 (dest,dstr,d,8*sizeof(double)); |
|
224 } |
|
225 |
|
226 OIL_DEFINE_IMPL_REF (idct8x8_s16_ref, idct8x8_s16); |
|
227 #if 0 |
|
228 OIL_DEFINE_IMPL_DEPENDS (idct8x8_s16_ref, idct8x8_s16, |
|
229 conv8x8_f64_s16, idct8x8_f64, conv8x8_s16_f64); |
|
230 #endif |
|
231 #endif |
|
232 |
|
233 #if defined(oil_conv8x8_f64_s16) && defined(oil_idct8x8lim10_f64) && \ |
|
234 defined(oil_conv8x8_s16_f64) |
|
235 static void |
|
236 idct8x8lim10_s16_ref (int16_t *dest, int dstr, const int16_t *src, int sstr) |
|
237 { |
|
238 double s[64], d[64]; |
|
239 |
|
240 oil_conv8x8_f64_s16 (s,8*sizeof(double),src,sstr); |
|
241 oil_idct8x8lim10_f64 (d,8*sizeof(double),s,8*sizeof(double)); |
|
242 oil_conv8x8_s16_f64 (dest,dstr,d,8*sizeof(double)); |
|
243 } |
|
244 |
|
245 OIL_DEFINE_IMPL_REF (idct8x8lim10_s16_ref, idct8x8lim10_s16); |
|
246 #if 0 |
|
247 OIL_DEFINE_IMPL_DEPENDS (idct8x8_s16_ref, idct8x8_s16, |
|
248 conv8x8_f64_s16, idct8x8_f64, conv8x8_s16_f64); |
|
249 #endif |
|
250 #endif |
|
251 |
|
252 |
|
253 |
|
254 #ifdef __SYMBIAN32__ |
|
255 |
|
256 OilFunctionClass* __oil_function_class_idct8x8_f64() { |
|
257 return &_oil_function_class_idct8x8_f64; |
|
258 } |
|
259 #endif |
|
260 |
|
261 #ifdef __SYMBIAN32__ |
|
262 |
|
263 OilFunctionClass* __oil_function_class_idct8x8lim10_f64() { |
|
264 return &_oil_function_class_idct8x8lim10_f64; |
|
265 } |
|
266 #endif |
|
267 |
|
268 #ifdef __SYMBIAN32__ |
|
269 |
|
270 OilFunctionClass* __oil_function_class_idct8x8_s16() { |
|
271 return &_oil_function_class_idct8x8_s16; |
|
272 } |
|
273 #endif |
|
274 |
|
275 #ifdef __SYMBIAN32__ |
|
276 |
|
277 OilFunctionClass* __oil_function_class_idct8x8lim10_s16() { |
|
278 return &_oil_function_class_idct8x8lim10_s16; |
|
279 } |
|
280 #endif |
|
281 |
|
282 |
|
283 |
|
284 #ifdef __SYMBIAN32__ |
|
285 |
|
286 OilFunctionImpl* __oil_function_impl_idct8x8_f64_ref() { |
|
287 return &_oil_function_impl_idct8x8_f64_ref; |
|
288 } |
|
289 #endif |
|
290 |
|
291 #ifdef __SYMBIAN32__ |
|
292 |
|
293 OilFunctionImpl* __oil_function_impl_idct8x8lim10_f64_ref() { |
|
294 return &_oil_function_impl_idct8x8lim10_f64_ref; |
|
295 } |
|
296 #endif |
|
297 |
|
298 #ifdef __SYMBIAN32__ |
|
299 |
|
300 OilFunctionImpl* __oil_function_impl_idct8x8_s16_ref() { |
|
301 return &_oil_function_impl_idct8x8_s16_ref; |
|
302 } |
|
303 #endif |
|
304 |
|
305 #ifdef __SYMBIAN32__ |
|
306 |
|
307 OilFunctionImpl* __oil_function_impl_idct8x8lim10_s16_ref() { |
|
308 return &_oil_function_impl_idct8x8lim10_s16_ref; |
|
309 } |
|
310 #endif |
|
311 |
|
312 |
|
313 |
|
314 #ifdef __SYMBIAN32__ |
|
315 |
|
316 OilFunctionImpl* __oil_function_impl_idct8x8_f64_c() { |
|
317 return &_oil_function_impl_idct8x8_f64_c; |
|
318 } |
|
319 #endif |
|
320 |
|
321 |
|
322 |
|
323 |
|
324 #ifdef __SYMBIAN32__ |
|
325 |
|
326 EXPORT_C void** _oil_function_class_ptr_idct8x8_f64 () { |
|
327 oil_function_class_ptr_idct8x8_f64 = __oil_function_class_idct8x8_f64(); |
|
328 return &oil_function_class_ptr_idct8x8_f64->func; |
|
329 } |
|
330 #endif |
|
331 |
|
332 #ifdef __SYMBIAN32__ |
|
333 |
|
334 EXPORT_C void** _oil_function_class_ptr_idct8x8lim10_f64 () { |
|
335 oil_function_class_ptr_idct8x8lim10_f64 = __oil_function_class_idct8x8lim10_f64(); |
|
336 return &oil_function_class_ptr_idct8x8lim10_f64->func; |
|
337 } |
|
338 #endif |
|
339 |
|
340 #ifdef __SYMBIAN32__ |
|
341 |
|
342 EXPORT_C void** _oil_function_class_ptr_idct8x8_s16 () { |
|
343 oil_function_class_ptr_idct8x8_s16 = __oil_function_class_idct8x8_s16(); |
|
344 return &oil_function_class_ptr_idct8x8_s16->func; |
|
345 } |
|
346 #endif |
|
347 |
|
348 #ifdef __SYMBIAN32__ |
|
349 |
|
350 EXPORT_C void** _oil_function_class_ptr_idct8x8lim10_s16 () { |
|
351 oil_function_class_ptr_idct8x8lim10_s16 = __oil_function_class_idct8x8lim10_s16(); |
|
352 return &oil_function_class_ptr_idct8x8lim10_s16->func; |
|
353 } |
|
354 #endif |
|
355 |