Git init
[profile/ivi/liboil.git] / liboil / ref / wavelet.c
1
2 #include <liboil/liboilfunction.h>
3 #include <liboil/liboiltest.h>
4 #include <liboil/liboilrandom.h>
5
6
7 static void
8 wavelet_test (OilTest *test)
9 {
10   int16_t *data = (int16_t *)oil_test_get_source_data (test, OIL_ARG_SRC1);
11   int i;
12
13   for(i=0;i<test->n;i++){
14     data[i] = oil_rand_u8();
15   }
16 }
17
18 static void
19 rshift_test (OilTest *test)
20 {
21   int16_t *data;
22   int i;
23
24   data = (int16_t *)oil_test_get_source_data (test, OIL_ARG_SRC1);
25   for(i=0;i<test->n;i++){
26     data[i] = oil_rand_s16()>>1;
27   }
28
29   data = (int16_t *)oil_test_get_source_data (test, OIL_ARG_SRC2);
30   data[0] = (1<<3);
31   data[1] = 4;
32 }
33
34 static void
35 lshift_test (OilTest *test)
36 {
37   int16_t *data;
38
39   data = (int16_t *)oil_test_get_source_data (test, OIL_ARG_SRC2);
40   data[0] = 12;
41 }
42  
43 static void
44 combine2_test (OilTest *test)
45 {
46   int16_t *data;
47
48   data = (int16_t *)oil_test_get_source_data (test, OIL_ARG_SRC3);
49   data[0] = 1;
50   data[1] = 1;
51   data[2] = 1;
52   data[3] = 1;
53 }
54
55 static void
56 combine4_test (OilTest *test)
57 {
58   int16_t *data;
59
60   data = (int16_t *)oil_test_get_source_data (test, OIL_ARG_SRC5);
61   data[0] = 4;
62   data[1] = 4;
63   data[2] = 4;
64   data[3] = 4;
65   data[4] = 8;
66   data[5] = 4;
67 }
68
69 static void
70 add2_test (OilTest *test)
71 {
72   int16_t *data;
73   int i;
74
75   data = (int16_t *)oil_test_get_source_data (test, OIL_ARG_SRC1);
76   for(i=0;i<test->n;i++){
77     data[i] = oil_rand_s16()>>4;
78   }
79
80   data = (int16_t *)oil_test_get_source_data (test, OIL_ARG_SRC2);
81   for(i=0;i<test->n;i++){
82     data[i] = oil_rand_s16()>>4;
83   }
84
85   data = (int16_t *)oil_test_get_source_data (test, OIL_ARG_SRC3);
86   for(i=0;i<test->n;i++){
87     data[i] = oil_rand_s16()>>4;
88   }
89
90   data = (int16_t *)oil_test_get_source_data (test, OIL_ARG_SRC4);
91   data[0] = 1;
92   data[1] = 1;
93 }
94  
95 OIL_DEFINE_CLASS_FULL (deinterleave,
96     "int16_t *d_2xn, int16_t *s_2xn, int n", wavelet_test);
97 OIL_DEFINE_CLASS (deinterleave2_s16,
98     "int16_t *d1_n, int16_t *d2_n, int16_t *s_2xn, int n");
99 OIL_DEFINE_CLASS_FULL (interleave,
100     "int16_t *d_2xn, int16_t *s_2xn, int n", wavelet_test);
101 OIL_DEFINE_CLASS (interleave2_s16,
102     "int16_t *d_2xn, int16_t *s1_n, int16_t *s2_n, int n");
103 OIL_DEFINE_CLASS_FULL (synth_daub97,
104     "int16_t *d_2xn, int16_t *s_2xn, int n", wavelet_test);
105 OIL_DEFINE_CLASS_FULL (split_daub97,
106     "int16_t *d_2xn, int16_t *s_2xn, int n", wavelet_test);
107 OIL_DEFINE_CLASS_FULL (split_approx97,
108     "int16_t *d_2xn, int16_t *s_2xn, int n", wavelet_test);
109 OIL_DEFINE_CLASS_FULL (synth_approx97,
110     "int16_t *d_2xn, int16_t *s_2xn, int n", wavelet_test);
111 OIL_DEFINE_CLASS_FULL (split_53,
112     "int16_t *d_2xn, int16_t *s_2xn, int n", wavelet_test);
113 OIL_DEFINE_CLASS_FULL (synth_53,
114     "int16_t *d_2xn, int16_t *s_2xn, int n", wavelet_test);
115 OIL_DEFINE_CLASS_FULL (split_135,
116     "int16_t *d_2xn, int16_t *s_2xn, int n", wavelet_test);
117 OIL_DEFINE_CLASS_FULL (synth_135,
118     "int16_t *d_2xn, int16_t *s_2xn, int n", wavelet_test);
119 OIL_DEFINE_CLASS_FULL (add_const_rshift_s16,
120     "int16_t *d1, int16_t *s1, int16_t *s2_2, int n", rshift_test);
121 OIL_DEFINE_CLASS_FULL (lshift_s16,
122     "int16_t *d1, int16_t *s1, int16_t *s2_1, int n", lshift_test);
123 OIL_DEFINE_CLASS (multiply_and_add_s16,
124     "int16_t *d, int16_t *src1, int16_t *src2, int16_t *src3, int n");
125 OIL_DEFINE_CLASS (multiply_and_add_s16_u8,
126     "int16_t *d, int16_t *src1, int16_t *src2, uint8_t *src3, int n");
127 OIL_DEFINE_CLASS (multiply_and_acc_6xn_s16_u8, "int16_t *i1_6xn, int is1, "
128     "int16_t *s1_6xn, int ss1, uint8_t *s2_6xn, int ss2, int n");
129 OIL_DEFINE_CLASS (multiply_and_acc_8xn_s16_u8, "int16_t *i1_8xn, int is1, "
130     "int16_t *s1_8xn, int ss1, uint8_t *s2_8xn, int ss2, int n");
131 OIL_DEFINE_CLASS (multiply_and_acc_12xn_s16_u8, "int16_t *i1_12xn, int is1, "
132     "int16_t *s1_12xn, int ss1, uint8_t *s2_12xn, int ss2, int n");
133 OIL_DEFINE_CLASS (multiply_and_acc_16xn_s16_u8, "int16_t *i1_16xn, int is1, "
134     "int16_t *s1_16xn, int ss1, uint8_t *s2_16xn, int ss2, int n");
135 OIL_DEFINE_CLASS (multiply_and_acc_24xn_s16_u8, "int16_t *i1_24xn, int is1, "
136     "int16_t *s1_24xn, int ss1, uint8_t *s2_24xn, int ss2, int n");
137 OIL_DEFINE_CLASS_FULL (combine2_8xn_u8, "uint8_t *d_8xn, int ds1, "
138     "uint8_t *s1_8xn, int ss1, uint8_t *s2_8xn, int ss2, int16_t *s3_4, int n", combine2_test);
139 OIL_DEFINE_CLASS_FULL (combine2_12xn_u8, "uint8_t *d_12xn, int ds1, "
140     "uint8_t *s1_12xn, int ss1, uint8_t *s2_12xn, int ss2, int16_t *s3_4, int n", combine2_test);
141 OIL_DEFINE_CLASS_FULL (combine2_16xn_u8, "uint8_t *d_16xn, int ds1, "
142     "uint8_t *s1_16xn, int ss1, uint8_t *s2_16xn, int ss2, int16_t *s3_4, int n", combine2_test);
143 OIL_DEFINE_CLASS_FULL (combine4_8xn_u8, "uint8_t *d_8xn, int ds1, "
144     "uint8_t *s1_8xn, int ss1, uint8_t *s2_8xn, int ss2, uint8_t *s3_8xn, "
145     "int ss3, uint8_t *s4_8xn, int ss4, int16_t *s5_6, int n", combine4_test);
146 OIL_DEFINE_CLASS_FULL (combine4_12xn_u8, "uint8_t *d_12xn, int ds1, "
147     "uint8_t *s1_12xn, int ss1, uint8_t *s2_12xn, int ss2, uint8_t *s3_12xn, "
148     "int ss3, uint8_t *s4_12xn, int ss4, int16_t *s5_6, int n", combine4_test);
149 OIL_DEFINE_CLASS_FULL (combine4_16xn_u8, "uint8_t *d_16xn, int ds1, "
150     "uint8_t *s1_16xn, int ss1, uint8_t *s2_16xn, int ss2, uint8_t *s3_16xn, "
151     "int ss3, uint8_t *s4_16xn, int ss4, int16_t *s5_6, int n", combine4_test);
152 OIL_DEFINE_CLASS_FULL (combine4_32xn_u8, "uint8_t *d_32xn, int ds1, "
153     "uint8_t *s1_16xn, int ss1, uint8_t *s2_32xn, int ss2, uint8_t *s3_32xn, "
154     "int ss3, uint8_t *s4_32xn, int ss4, int16_t *s5_6, int n", combine4_test);
155 OIL_DEFINE_CLASS_FULL (add2_rshift_add_s16, "int16_t *d, int16_t *s1, "
156     "int16_t *s2, int16_t *s3, int16_t *s4_2, int n", add2_test);
157 OIL_DEFINE_CLASS_FULL (add2_rshift_sub_s16, "int16_t *d, int16_t *s1, "
158     "int16_t *s2, int16_t *s3, int16_t *s4_2, int n", add2_test);
159 OIL_DEFINE_CLASS (avg2_8xn_u8, "uint8_t *d_8xn, int ds1, "
160     "uint8_t *s1_8xn, int ss1, uint8_t *s2_8xn, int ss2, int n");
161 OIL_DEFINE_CLASS (avg2_12xn_u8, "uint8_t *d_12xn, int ds1, "
162     "uint8_t *s1_12xn, int ss1, uint8_t *s2_12xn, int ss2, int n");
163 OIL_DEFINE_CLASS (avg2_16xn_u8, "uint8_t *d_16xn, int ds1, "
164     "uint8_t *s1_16xn, int ss1, uint8_t *s2_16xn, int ss2, int n");
165 OIL_DEFINE_CLASS (avg2_32xn_u8, "uint8_t *d_32xn, int ds1, "
166     "uint8_t *s1_32xn, int ss1, uint8_t *s2_32xn, int ss2, int n");
167
168 void
169 deinterleave_ref (int16_t *d_2xn, int16_t *s_2xn, int n)
170 {
171   int i;
172
173   for(i=0;i<n;i++) {
174     d_2xn[i] = s_2xn[2*i];
175     d_2xn[n + i] = s_2xn[2*i + 1];
176   }
177 }
178 OIL_DEFINE_IMPL_REF (deinterleave_ref, deinterleave);
179
180 void
181 deinterleave2_s16_ref (int16_t *d1_n, int16_t *d2_n, int16_t *s_2xn, int n)
182 {
183   int i;
184
185   for(i=0;i<n;i++) {
186     d1_n[i] = s_2xn[2*i];
187     d2_n[i] = s_2xn[2*i + 1];
188   }
189 }
190 OIL_DEFINE_IMPL_REF (deinterleave2_s16_ref, deinterleave2_s16);
191
192 void
193 interleave_ref (int16_t *d_2xn, int16_t *s_2xn, int n)
194 {
195   int i;
196
197   for(i=0;i<n;i++) {
198     d_2xn[2*i] = s_2xn[i];
199     d_2xn[2*i + 1] = s_2xn[n + i];
200   }
201 }
202 OIL_DEFINE_IMPL_REF (interleave_ref, interleave);
203
204 void
205 interleave2_s16_ref (int16_t *d_2xn, int16_t *s1_n, int16_t *s2_n, int n)
206 {
207   int i;
208
209   for(i=0;i<n;i++) {
210     d_2xn[2*i] = s1_n[i];
211     d_2xn[2*i + 1] = s2_n[i];
212   }
213 }
214 OIL_DEFINE_IMPL_REF (interleave2_s16_ref, interleave2_s16);
215
216 void
217 synth_daub97_ref (int16_t *d_2xn, int16_t *s_2xn, int n)
218 {
219   int i;
220
221   if (n==0) return;
222   /* predict */
223   d_2xn[0] = s_2xn[0] - ((1817 * s_2xn[1]) >> 11);
224   for(i=2;i<n*2;i+=2){
225     d_2xn[i] = s_2xn[i] - ((1817 * (s_2xn[i-1] + s_2xn[i+1])) >> 12);
226   }
227   for(i=1;i<n*2-2;i+=2){
228     d_2xn[i] = s_2xn[i] - ((3616 * (d_2xn[i-1] + d_2xn[i+1])) >> 12);
229   }
230   d_2xn[n*2-1] = s_2xn[n*2-1] - ((3616 * d_2xn[n*2-2]) >> 11);
231
232   /* update */
233   d_2xn[0] += (217 * d_2xn[1]) >> 11;
234   for(i=2;i<n*2;i+=2){
235     d_2xn[i] += (217 * (d_2xn[i-1] + d_2xn[i+1])) >> 12;
236   }
237   for(i=1;i<n*2-2;i+=2){
238     d_2xn[i] += (6497 * (d_2xn[i-1] + d_2xn[i+1])) >> 12;
239   }
240   d_2xn[n*2-1] += (6497 * d_2xn[n*2-2]) >> 11;
241 }
242 OIL_DEFINE_IMPL_REF (synth_daub97_ref, synth_daub97);
243
244 void
245 split_daub97_ref (int16_t *d_2xn, int16_t *s_2xn, int n)
246 {
247   int i;
248
249   if (n==0) return;
250   /* predict */
251   for(i=1;i<n*2-2;i+=2){
252     d_2xn[i] = s_2xn[i] - ((6497 * (s_2xn[i-1] + s_2xn[i+1])) >> 12);
253   }
254   d_2xn[n*2-1] = s_2xn[n*2-1] - ((6497 * s_2xn[n*2-2]) >> 11);
255   d_2xn[0] = s_2xn[0] - ((217 * d_2xn[1]) >> 11);
256   for(i=2;i<n*2;i+=2){
257     d_2xn[i] = s_2xn[i] - ((217 * (d_2xn[i-1] + d_2xn[i+1])) >> 12);
258   }
259
260   /* update */
261   for(i=1;i<n*2-2;i+=2){
262     d_2xn[i] += (3616 * (d_2xn[i-1] + d_2xn[i+1])) >> 12;
263   }
264   d_2xn[n*2-1] += (3616 * d_2xn[n*2-2]) >> 11;
265   d_2xn[0] += (1817 * d_2xn[1]) >> 11;
266   for(i=2;i<n*2;i+=2){
267     d_2xn[i] += (1817 * (d_2xn[i-1] + d_2xn[i+1])) >> 12;
268   }
269 }
270 OIL_DEFINE_IMPL_REF (split_daub97_ref, split_daub97);
271
272
273 void
274 split_approx97_ref (int16_t *d_2xn, int16_t *s_2xn, int n)
275 {
276   int i;
277
278   if (n==0) return;
279   if (n==1) {
280     d_2xn[1] = s_2xn[1] - s_2xn[0];
281     d_2xn[0] = s_2xn[0] + (d_2xn[1] >> 1);
282   } else if (n==2) {
283     /* predict */
284     d_2xn[1] = s_2xn[1] - ((9*(s_2xn[0] + s_2xn[2]) - (s_2xn[2] + s_2xn[2])) >> 4);
285     d_2xn[3] = s_2xn[3] - ((9*s_2xn[2] - s_2xn[0]) >> 3);
286
287     /* update */
288     d_2xn[0] = s_2xn[0] + (d_2xn[1] >> 1);
289     d_2xn[2] = s_2xn[2] + ((d_2xn[1] + d_2xn[3]) >> 2);
290   } else {
291     /* predict */
292     d_2xn[1] = s_2xn[1] - ((9*(s_2xn[0] + s_2xn[2]) - (s_2xn[2] + s_2xn[4])) >> 4);
293     for(i=3;i<n*2-4;i+=2){
294       d_2xn[i] = s_2xn[i] - ((9*(s_2xn[i-1] + s_2xn[i+1]) - (s_2xn[i-3] + s_2xn[i+3])) >> 4);
295     }
296     d_2xn[n*2-3] = s_2xn[n*2-3] - ((9*(s_2xn[n*2-4] + s_2xn[n*2-2]) - (s_2xn[n*2-6] + s_2xn[n*2-2])) >> 4);
297     d_2xn[n*2-1] = s_2xn[n*2-1] - ((9*s_2xn[n*2-2] - s_2xn[n*2-4]) >> 3);
298
299     /* update */
300     d_2xn[0] = s_2xn[0] + (d_2xn[1] >> 1);
301     for(i=2;i<n*2;i+=2){
302       d_2xn[i] = s_2xn[i] + ((d_2xn[i-1] + d_2xn[i+1]) >> 2);
303     }
304   }
305
306 }
307 OIL_DEFINE_IMPL_REF (split_approx97_ref, split_approx97);
308
309 void
310 synth_approx97_ref (int16_t *d_2xn, int16_t *s_2xn, int n)
311 {
312   int i;
313
314   if (n==0) return;
315   if (n==1) {
316     d_2xn[0] = s_2xn[0] - (s_2xn[1] >> 1);
317     d_2xn[1] = s_2xn[1] + d_2xn[0];
318   } else if (n==2) {
319     /* predict */
320     d_2xn[0] = s_2xn[0] - (s_2xn[1] >> 1);
321     d_2xn[2] = s_2xn[2] - ((s_2xn[1] + s_2xn[3]) >> 2);
322
323     /* update */
324     d_2xn[1] = s_2xn[1] + ((9*(d_2xn[0] + d_2xn[2]) - (d_2xn[2] + d_2xn[2])) >> 4);
325     d_2xn[3] = s_2xn[3] + ((9*d_2xn[2] - d_2xn[0]) >> 3);
326   } else {
327     /* predict */
328     d_2xn[0] = s_2xn[0] - (s_2xn[1] >> 1);
329     for(i=2;i<n*2;i+=2){
330       d_2xn[i] = s_2xn[i] - ((s_2xn[i-1] + s_2xn[i+1]) >> 2);
331     }
332
333     /* update */
334     d_2xn[1] = s_2xn[1] + ((9*(d_2xn[0] + d_2xn[2]) - (d_2xn[2] + d_2xn[4])) >> 4);
335     for(i=3;i<n*2-4;i+=2){
336       d_2xn[i] = s_2xn[i] + ((9*(d_2xn[i-1] + d_2xn[i+1]) - (d_2xn[i-3] + d_2xn[i+3])) >> 4);
337     }
338     d_2xn[n*2-3] = s_2xn[n*2-3] + ((9*(d_2xn[n*2-4] + d_2xn[n*2-2]) - (d_2xn[n*2-6] + d_2xn[n*2-2])) >> 4);
339     d_2xn[n*2-1] = s_2xn[n*2-1] + ((9*d_2xn[n*2-2] - d_2xn[n*2-4]) >> 3);
340   }
341 }
342 OIL_DEFINE_IMPL_REF (synth_approx97_ref, synth_approx97);
343
344 void
345 split_53_ref (int16_t *d_2xn, int16_t *s_2xn, int n)
346 {
347   int i;
348
349   if (n==0) return;
350   if (n == 1) {
351     d_2xn[1] = s_2xn[1] - s_2xn[0];
352     d_2xn[0] = s_2xn[0] + (d_2xn[1] >> 1);
353   } else {
354     d_2xn[1] = s_2xn[1] - ((s_2xn[0] + s_2xn[2]) >> 1);
355     d_2xn[0] = s_2xn[0] + (d_2xn[1] >> 1);
356     for(i=2;i<n*2-2;i+=2){
357       d_2xn[i+1] = s_2xn[i+1] - ((s_2xn[i] + s_2xn[i+2]) >> 1);
358       d_2xn[i] = s_2xn[i] + ((d_2xn[i-1] + d_2xn[i+1]) >> 2);
359     }
360     d_2xn[n*2-1] = s_2xn[n*2-1] - s_2xn[n*2-2];
361     d_2xn[n*2-2] = s_2xn[n*2-2] + ((d_2xn[n*2-3] + d_2xn[n*2-1]) >> 2);
362   }
363 }
364 OIL_DEFINE_IMPL_REF (split_53_ref, split_53);
365
366 void
367 synth_53_ref (int16_t *d_2xn, int16_t *s_2xn, int n)
368 {
369   int i;
370
371   if (n==0) return;
372   if (n == 1) {
373     d_2xn[0] = s_2xn[0] - (s_2xn[1] >> 1);
374     d_2xn[1] = s_2xn[1] + d_2xn[0];
375   } else {
376     d_2xn[0] = s_2xn[0] - (s_2xn[1] >> 1);
377     for(i=2;i<n*2-2;i+=2){
378       d_2xn[i] = s_2xn[i] - ((s_2xn[i-1] + s_2xn[i+1]) >> 2);
379       d_2xn[i-1] = s_2xn[i-1] + ((d_2xn[i] + d_2xn[i-2]) >> 1);
380     }
381     d_2xn[n*2-2] = s_2xn[n*2-2] - ((s_2xn[n*2-3] + s_2xn[n*2-1]) >> 2);
382     d_2xn[n*2-3] = s_2xn[n*2-3] + ((d_2xn[n*2-2] + d_2xn[n*2-4]) >> 1);
383     d_2xn[n*2-1] = s_2xn[n*2-1] + d_2xn[n*2-2];
384   }
385 }
386 OIL_DEFINE_IMPL_REF (synth_53_ref, synth_53);
387
388
389 void
390 split_135_ref (int16_t *d_2xn, int16_t *s_2xn, int n)
391 {
392   int i;
393
394   if (n==0) return;
395   if (n==1) {
396     d_2xn[1] = s_2xn[1] - (s_2xn[0]);
397     d_2xn[0] = s_2xn[0] + (d_2xn[1]>>1);
398   } else if (n==2) {
399     /* predict */
400     d_2xn[1] = s_2xn[1] - ((9*(s_2xn[0] + s_2xn[2]) - (s_2xn[2] + s_2xn[2])) >> 4);
401     d_2xn[3] = s_2xn[3] - ((9*s_2xn[2] - s_2xn[0]) >> 3);
402
403     /* update */
404     d_2xn[0] = s_2xn[0] + ((9*d_2xn[1] - d_2xn[3]) >> 4);
405     d_2xn[2] = s_2xn[2] + ((9*(d_2xn[1] + d_2xn[3]) - (d_2xn[1] + d_2xn[1])) >> 5);
406   } else {
407     /* predict */
408     d_2xn[1] = s_2xn[1] - ((9*(s_2xn[0] + s_2xn[2]) - (s_2xn[2] + s_2xn[4])) >> 4);
409     for(i=3;i<n*2-4;i+=2){
410       d_2xn[i] = s_2xn[i] - ((9*(s_2xn[i-1] + s_2xn[i+1]) - (s_2xn[i-3] + s_2xn[i+3])) >> 4);
411     }
412     d_2xn[n*2-3] = s_2xn[n*2-3] - ((9*(s_2xn[n*2-4] + s_2xn[n*2-2]) - (s_2xn[n*2-6] + s_2xn[n*2-2])) >> 4);
413     d_2xn[n*2-1] = s_2xn[n*2-1] - ((9*s_2xn[n*2-2] - s_2xn[n*2-4]) >> 3);
414
415     /* update */
416     d_2xn[0] = s_2xn[0] + ((9*d_2xn[1] - d_2xn[3]) >> 4);
417     d_2xn[2] = s_2xn[2] + ((9*(d_2xn[1] + d_2xn[3]) - (d_2xn[1] + d_2xn[5])) >> 5);
418     for(i=4;i<n*2-2;i+=2){
419       d_2xn[i] = s_2xn[i] + ((9*(d_2xn[i-1] + d_2xn[i+1]) - (d_2xn[i-3] + d_2xn[i+3])) >> 5);
420     }
421     d_2xn[n*2-2] = s_2xn[n*2-2] + ((9*(d_2xn[n*2-3] + d_2xn[n*2-1]) - (d_2xn[n*2-5] + d_2xn[n*2-1])) >> 5);
422   }
423
424 }
425 OIL_DEFINE_IMPL_REF (split_135_ref, split_135);
426
427 void
428 synth_135_ref (int16_t *d_2xn, int16_t *s_2xn, int n)
429 {
430   int i;
431
432   if (n==0) return;
433   if (n==1) {
434     d_2xn[0] = s_2xn[0] - (s_2xn[1]>>1);
435     d_2xn[1] = s_2xn[1] + (d_2xn[0]);
436   } else if (n==2) {
437     /* predict */
438     d_2xn[0] = s_2xn[0] - ((9*s_2xn[1] - s_2xn[3]) >> 4);
439     d_2xn[2] = s_2xn[2] - ((9*(s_2xn[1] + s_2xn[3]) - (s_2xn[1] + s_2xn[1])) >> 5);
440
441     /* update */
442     d_2xn[1] = s_2xn[1] + ((9*(d_2xn[0] + d_2xn[2]) - (d_2xn[2] + d_2xn[2])) >> 4);
443     d_2xn[3] = s_2xn[3] + ((9*d_2xn[2] - d_2xn[0]) >> 3);
444   } else {
445     /* predict */
446     d_2xn[0] = s_2xn[0] - ((9*s_2xn[1] - s_2xn[3]) >> 4);
447     d_2xn[2] = s_2xn[2] - ((9*(s_2xn[1] + s_2xn[3]) - (s_2xn[1] + s_2xn[5])) >> 5);
448     for(i=4;i<n*2-2;i+=2){
449       d_2xn[i] = s_2xn[i] - ((9*(s_2xn[i-1] + s_2xn[i+1]) - (s_2xn[i-3] + s_2xn[i+3])) >> 5);
450     }
451     d_2xn[n*2-2] = s_2xn[n*2-2] - ((9*(s_2xn[n*2-3] + s_2xn[n*2-1]) - (s_2xn[n*2-5] + s_2xn[n*2-1])) >> 5);
452
453     /* update */
454     d_2xn[1] = s_2xn[1] + ((9*(d_2xn[0] + d_2xn[2]) - (d_2xn[2] + d_2xn[4])) >> 4);
455     for(i=3;i<n*2-4;i+=2){
456       d_2xn[i] = s_2xn[i] + ((9*(d_2xn[i-1] + d_2xn[i+1]) - (d_2xn[i-3] + d_2xn[i+3])) >> 4);
457     }
458     d_2xn[n*2-3] = s_2xn[n*2-3] + ((9*(d_2xn[n*2-4] + d_2xn[n*2-2]) - (d_2xn[n*2-6] + d_2xn[n*2-2])) >> 4);
459     d_2xn[n*2-1] = s_2xn[n*2-1] + ((9*d_2xn[n*2-2] - d_2xn[n*2-4]) >> 3);
460   }
461 }
462 OIL_DEFINE_IMPL_REF (synth_135_ref, synth_135);
463
464
465
466
467 static void
468 lift_test (OilTest *test)
469 {
470   int16_t *data;
471   int i;
472
473   data = (int16_t *)oil_test_get_source_data (test, OIL_ARG_SRC1);
474   for(i=0;i<test->n;i++){
475     data[i] = oil_rand_u8();
476   }
477   data = (int16_t *)oil_test_get_source_data (test, OIL_ARG_SRC2);
478   for(i=0;i<test->n;i++){
479     data[i] = oil_rand_u8();
480   }
481   data = (int16_t *)oil_test_get_source_data (test, OIL_ARG_SRC3);
482   for(i=0;i<test->n;i++){
483     data[i] = oil_rand_u8();
484   }
485 }
486
487 OIL_DEFINE_CLASS_FULL (lift_add_shift1,
488     "int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int n", lift_test);
489 OIL_DEFINE_CLASS_FULL (lift_sub_shift1,
490     "int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int n", lift_test);
491 OIL_DEFINE_CLASS_FULL (lift_add_shift2,
492     "int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int n", lift_test);
493 OIL_DEFINE_CLASS_FULL (lift_sub_shift2,
494     "int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int n", lift_test);
495 OIL_DEFINE_CLASS_FULL (lift_add_mult_shift12,
496     "int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int16_t *s4_1, int n", lift_test);
497 OIL_DEFINE_CLASS_FULL (lift_sub_mult_shift12,
498     "int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int16_t *s4_1, int n", lift_test);
499 OIL_DEFINE_CLASS_FULL (lift_add_135,
500     "int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int16_t *s4, int16_t *s5, int n", lift_test);
501 OIL_DEFINE_CLASS_FULL (lift_sub_135,
502     "int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int16_t *s4, int16_t *s5, int n", lift_test);
503
504
505 void
506 lift_add_shift1_ref (int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int n)
507 {
508   int i;
509   for(i=0;i<n;i++) {
510     d[i] = s1[i] + ((s2[i] + s3[i])>>1);
511   }
512 }
513 OIL_DEFINE_IMPL_REF (lift_add_shift1_ref, lift_add_shift1);
514
515 void
516 lift_sub_shift1_ref (int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int n)
517 {
518   int i;
519   for(i=0;i<n;i++) {
520     d[i] = s1[i] - ((s2[i] + s3[i])>>1);
521   }
522 }
523 OIL_DEFINE_IMPL_REF (lift_sub_shift1_ref, lift_sub_shift1);
524
525 void
526 lift_add_shift2_ref (int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int n)
527 {
528   int i;
529   for(i=0;i<n;i++) {
530     d[i] = s1[i] + ((s2[i] + s3[i])>>2);
531   }
532 }
533 OIL_DEFINE_IMPL_REF (lift_add_shift2_ref, lift_add_shift2);
534
535 void
536 lift_sub_shift2_ref (int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int n)
537 {
538   int i;
539   for(i=0;i<n;i++) {
540     d[i] = s1[i] - ((s2[i] + s3[i])>>2);
541   }
542 }
543 OIL_DEFINE_IMPL_REF (lift_sub_shift2_ref, lift_sub_shift2);
544
545 void
546 lift_add_mult_shift12_ref (int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int16_t *s4, int n)
547 {
548   int i;
549   for(i=0;i<n;i++) {
550     d[i] = s1[i] + ((s4[0]*(s2[i] + s3[i]))>>12);
551   }
552 }
553 OIL_DEFINE_IMPL_REF (lift_add_mult_shift12_ref, lift_add_mult_shift12);
554
555 void
556 lift_sub_mult_shift12_ref (int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3, int16_t *s4, int n)
557 {
558   int i;
559   for(i=0;i<n;i++) {
560     d[i] = s1[i] - ((s4[0]*(s2[i] + s3[i]))>>12);
561   }
562 }
563 OIL_DEFINE_IMPL_REF (lift_sub_mult_shift12_ref, lift_sub_mult_shift12);
564
565 void
566 lift_add_135_ref (int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3,
567     int16_t *s4, int16_t *s5, int n)
568 {
569   int i;
570   for(i=0;i<n;i++) {
571     d[i] = s1[i] + ((9*(s3[i-1] + s4[i+1]) - (s2[i-3] + s5[i+3])) >> 4);
572   }
573 }
574 OIL_DEFINE_IMPL_REF (lift_add_135_ref, lift_add_135);
575
576 void
577 lift_sub_135_ref (int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3,
578     int16_t *s4, int16_t *s5, int n)
579 {
580   int i;
581   for(i=0;i<n;i++) {
582     d[i] = s1[i] - ((9*(s3[i-1] + s4[i+1]) - (s2[i-3] + s5[i+3])) >> 4);
583   }
584 }
585 OIL_DEFINE_IMPL_REF (lift_sub_135_ref, lift_sub_135);
586
587
588 void
589 add_const_rshift_s16_ref(int16_t *d1, int16_t *s1, int16_t *s3_2, int n)
590 {
591   int i;
592   for(i=0;i<n;i++){
593     d1[i] = (s1[i] + s3_2[0])>>s3_2[1];
594   }
595 }
596 OIL_DEFINE_IMPL_REF (add_const_rshift_s16_ref, add_const_rshift_s16);
597
598 void
599 lshift_s16_ref(int16_t *d1, int16_t *s1, int16_t *s3_1, int n)
600 {
601   int i;
602   for(i=0;i<n;i++){
603     d1[i] = s1[i]<<s3_1[0];
604   }
605 }
606 OIL_DEFINE_IMPL_REF (lshift_s16_ref, lshift_s16);
607
608 void
609 multiply_and_add_s16_ref (int16_t *d, int16_t *src1, int16_t *src2, int16_t *src3, int n)
610 {
611   int i;
612   for(i=0;i<n;i++){
613     d[i] = src1[i] + src2[i]*src3[i];
614   }
615 }
616 OIL_DEFINE_IMPL_REF (multiply_and_add_s16_ref, multiply_and_add_s16);
617
618 void
619 multiply_and_add_s16_u8_ref (int16_t *d, int16_t *src1, int16_t *src2,
620     uint8_t *src3, int n)
621 {
622   int i;
623   for(i=0;i<n;i++){
624     d[i] = src1[i] + src2[i]*src3[i];
625   }
626 }
627 OIL_DEFINE_IMPL_REF (multiply_and_add_s16_u8_ref, multiply_and_add_s16_u8);
628
629 void
630 multiply_and_acc_6xn_s16_u8_ref (int16_t *i1, int is1, int16_t *s1,
631     int ss1, uint8_t *s2, int ss2, int n)
632 {
633   int i, j;
634   for(j=0;j<n;j++){
635     for(i=0;i<6;i++){
636       i1[i] += s1[i]*s2[i];
637     }
638     i1 = OIL_OFFSET(i1,is1);
639     s1 = OIL_OFFSET(s1,ss1);
640     s2 = OIL_OFFSET(s2,ss2);
641   }
642 }
643 OIL_DEFINE_IMPL_REF (multiply_and_acc_6xn_s16_u8_ref,
644     multiply_and_acc_6xn_s16_u8);
645
646 void
647 multiply_and_acc_8xn_s16_u8_ref (int16_t *i1, int is1, int16_t *s1,
648     int ss1, uint8_t *s2, int ss2, int n)
649 {
650   int i, j;
651   for(j=0;j<n;j++){
652     for(i=0;i<8;i++){
653       i1[i] += s1[i]*s2[i];
654     }
655     i1 = OIL_OFFSET(i1,is1);
656     s1 = OIL_OFFSET(s1,ss1);
657     s2 = OIL_OFFSET(s2,ss2);
658   }
659 }
660 OIL_DEFINE_IMPL_REF (multiply_and_acc_8xn_s16_u8_ref,
661     multiply_and_acc_8xn_s16_u8);
662
663 void
664 multiply_and_acc_12xn_s16_u8_ref (int16_t *i1, int is1, int16_t *s1,
665     int ss1, uint8_t *s2, int ss2, int n)
666 {
667   int i, j;
668   for(j=0;j<n;j++){
669     for(i=0;i<12;i++){
670       i1[i] += s1[i]*s2[i];
671     }
672     i1 = OIL_OFFSET(i1,is1);
673     s1 = OIL_OFFSET(s1,ss1);
674     s2 = OIL_OFFSET(s2,ss2);
675   }
676 }
677 OIL_DEFINE_IMPL_REF (multiply_and_acc_12xn_s16_u8_ref,
678     multiply_and_acc_12xn_s16_u8);
679
680 void
681 multiply_and_acc_16xn_s16_u8_ref (int16_t *i1, int is1, int16_t *s1,
682     int ss1, uint8_t *s2, int ss2, int n)
683 {
684   int i, j;
685   for(j=0;j<n;j++){
686     for(i=0;i<16;i++){
687       i1[i] += s1[i]*s2[i];
688     }
689     i1 = OIL_OFFSET(i1,is1);
690     s1 = OIL_OFFSET(s1,ss1);
691     s2 = OIL_OFFSET(s2,ss2);
692   }
693 }
694 OIL_DEFINE_IMPL_REF (multiply_and_acc_16xn_s16_u8_ref,
695     multiply_and_acc_16xn_s16_u8);
696
697 void
698 multiply_and_acc_24xn_s16_u8_ref (int16_t *i1, int is1, int16_t *s1,
699     int ss1, uint8_t *s2, int ss2, int n)
700 {
701   int i, j;
702   for(j=0;j<n;j++){
703     for(i=0;i<24;i++){
704       i1[i] += s1[i]*s2[i];
705     }
706     i1 = OIL_OFFSET(i1,is1);
707     s1 = OIL_OFFSET(s1,ss1);
708     s2 = OIL_OFFSET(s2,ss2);
709   }
710 }
711 OIL_DEFINE_IMPL_REF (multiply_and_acc_24xn_s16_u8_ref,
712     multiply_and_acc_24xn_s16_u8);
713
714 void
715 combine4_8xn_u8_ref (uint8_t *d, int ds1,
716     uint8_t *s1, int ss1,
717     uint8_t *s2, int ss2,
718     uint8_t *s3, int ss3,
719     uint8_t *s4, int ss4,
720     int16_t *s5_6, int n)
721 {
722   int i;
723   int j;
724   for(j=0;j<n;j++){
725     for(i=0;i<8;i++){
726       int x = 0;
727       x += s5_6[0] * s1[i];
728       x += s5_6[1] * s2[i];
729       x += s5_6[2] * s3[i];
730       x += s5_6[3] * s4[i];
731       d[i] = (x + s5_6[4]) >> s5_6[5];
732     }
733     s1 += ss1;
734     s2 += ss2;
735     s3 += ss3;
736     s4 += ss4;
737     d += ds1;
738   }
739 }
740 OIL_DEFINE_IMPL_REF (combine4_8xn_u8_ref, combine4_8xn_u8);
741
742 void
743 combine4_12xn_u8_ref (uint8_t *d, int ds1,
744     uint8_t *s1, int ss1,
745     uint8_t *s2, int ss2,
746     uint8_t *s3, int ss3,
747     uint8_t *s4, int ss4,
748     int16_t *s5_6, int n)
749 {
750   int i;
751   int j;
752   for(j=0;j<n;j++){
753     for(i=0;i<12;i++){
754       int x = 0;
755       x += s5_6[0] * s1[i];
756       x += s5_6[1] * s2[i];
757       x += s5_6[2] * s3[i];
758       x += s5_6[3] * s4[i];
759       d[i] = (x + s5_6[4]) >> s5_6[5];
760     }
761     s1 += ss1;
762     s2 += ss2;
763     s3 += ss3;
764     s4 += ss4;
765     d += ds1;
766   }
767 }
768 OIL_DEFINE_IMPL_REF (combine4_12xn_u8_ref, combine4_12xn_u8);
769
770 void
771 combine4_16xn_u8_ref (uint8_t *d, int ds1,
772     uint8_t *s1, int ss1,
773     uint8_t *s2, int ss2,
774     uint8_t *s3, int ss3,
775     uint8_t *s4, int ss4,
776     int16_t *s5_6, int n)
777 {
778   int i;
779   int j;
780   for(j=0;j<n;j++){
781     for(i=0;i<16;i++){
782       int x = 0;
783       x += s5_6[0] * s1[i];
784       x += s5_6[1] * s2[i];
785       x += s5_6[2] * s3[i];
786       x += s5_6[3] * s4[i];
787       d[i] = (x + s5_6[4]) >> s5_6[5];
788     }
789     s1 += ss1;
790     s2 += ss2;
791     s3 += ss3;
792     s4 += ss4;
793     d += ds1;
794   }
795 }
796 OIL_DEFINE_IMPL_REF (combine4_16xn_u8_ref, combine4_16xn_u8);
797
798 void
799 combine4_32xn_u8_ref (uint8_t *d, int ds1,
800     uint8_t *s1, int ss1,
801     uint8_t *s2, int ss2,
802     uint8_t *s3, int ss3,
803     uint8_t *s4, int ss4,
804     int16_t *s5_6, int n)
805 {
806   int i;
807   int j;
808   for(j=0;j<n;j++){
809     for(i=0;i<32;i++){
810       int x = 0;
811       x += s5_6[0] * s1[i];
812       x += s5_6[1] * s2[i];
813       x += s5_6[2] * s3[i];
814       x += s5_6[3] * s4[i];
815       d[i] = (x + s5_6[4]) >> s5_6[5];
816     }
817     s1 += ss1;
818     s2 += ss2;
819     s3 += ss3;
820     s4 += ss4;
821     d += ds1;
822   }
823 }
824 OIL_DEFINE_IMPL_REF (combine4_32xn_u8_ref, combine4_32xn_u8);
825
826 void
827 combine2_8xn_u8_ref (uint8_t *d, int ds1,
828     uint8_t *s1, int ss1,
829     uint8_t *s2, int ss2,
830     int16_t *s3_4, int n)
831 {
832   int i;
833   int j;
834   for(j=0;j<n;j++){
835     for(i=0;i<8;i++){
836       int x = 0;
837       x += s3_4[0] * s1[i];
838       x += s3_4[1] * s2[i];
839       d[i] = (x + s3_4[2]) >> s3_4[3];
840     }
841     s1 += ss1;
842     s2 += ss2;
843     d += ds1;
844   }
845 }
846 OIL_DEFINE_IMPL_REF (combine2_8xn_u8_ref, combine2_8xn_u8);
847
848 void
849 combine2_12xn_u8_ref (uint8_t *d, int ds1,
850     uint8_t *s1, int ss1,
851     uint8_t *s2, int ss2,
852     int16_t *s3_4, int n)
853 {
854   int i;
855   int j;
856   for(j=0;j<n;j++){
857     for(i=0;i<12;i++){
858       int x = 0;
859       x += s3_4[0] * s1[i];
860       x += s3_4[1] * s2[i];
861       d[i] = (x + s3_4[2]) >> s3_4[3];
862     }
863     s1 += ss1;
864     s2 += ss2;
865     d += ds1;
866   }
867 }
868 OIL_DEFINE_IMPL_REF (combine2_12xn_u8_ref, combine2_12xn_u8);
869
870 void
871 combine2_16xn_u8_ref (uint8_t *d, int ds1,
872     uint8_t *s1, int ss1,
873     uint8_t *s2, int ss2,
874     int16_t *s3_4, int n)
875 {
876   int i;
877   int j;
878   for(j=0;j<n;j++){
879     for(i=0;i<16;i++){
880       int x = 0;
881       x += s3_4[0] * s1[i];
882       x += s3_4[1] * s2[i];
883       d[i] = (x + s3_4[2]) >> s3_4[3];
884     }
885     s1 += ss1;
886     s2 += ss2;
887     d += ds1;
888   }
889 }
890 OIL_DEFINE_IMPL_REF (combine2_16xn_u8_ref, combine2_16xn_u8);
891
892 void
893 add2_rshift_add_s16_ref (int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3,
894     int16_t *s4_2, int n)
895 {
896   int i;
897   for(i=0;i<n;i++) {
898     d[i] = s1[i] + ((s2[i] + s3[i] + s4_2[0])>>s4_2[1]);
899   }
900 }
901 OIL_DEFINE_IMPL_REF (add2_rshift_add_s16_ref, add2_rshift_add_s16);
902
903 void
904 add2_rshift_sub_s16_ref (int16_t *d, int16_t *s1, int16_t *s2, int16_t *s3,
905     int16_t *s4_2, int n)
906 {
907   int i;
908   for(i=0;i<n;i++) {
909     d[i] = s1[i] - ((s2[i] + s3[i] + s4_2[0])>>s4_2[1]);
910   }
911 }
912 OIL_DEFINE_IMPL_REF (add2_rshift_sub_s16_ref, add2_rshift_sub_s16);
913
914 void
915 avg2_8xn_u8_ref (uint8_t *d, int ds1, uint8_t *s1, int ss1,
916     uint8_t *s2, int ss2, int n)
917 {
918   int i;
919   int j;
920   for(j=0;j<n;j++){
921     for(i=0;i<8;i++){
922       d[i] = (s1[i] + s2[i] + 1)>>1;
923     }
924     s1 += ss1;
925     s2 += ss2;
926     d += ds1;
927   }
928 }
929 OIL_DEFINE_IMPL_REF (avg2_8xn_u8_ref, avg2_8xn_u8);
930
931 void
932 avg2_12xn_u8_ref (uint8_t *d, int ds1, uint8_t *s1, int ss1,
933     uint8_t *s2, int ss2, int n)
934 {
935   int i;
936   int j;
937   for(j=0;j<n;j++){
938     for(i=0;i<12;i++){
939       d[i] = (s1[i] + s2[i] + 1)>>1;
940     }
941     s1 += ss1;
942     s2 += ss2;
943     d += ds1;
944   }
945 }
946 OIL_DEFINE_IMPL_REF (avg2_12xn_u8_ref, avg2_12xn_u8);
947
948 void
949 avg2_16xn_u8_ref (uint8_t *d, int ds1, uint8_t *s1, int ss1,
950     uint8_t *s2, int ss2, int n)
951 {
952   int i;
953   int j;
954   for(j=0;j<n;j++){
955     for(i=0;i<16;i++){
956       d[i] = (s1[i] + s2[i] + 1)>>1;
957     }
958     s1 += ss1;
959     s2 += ss2;
960     d += ds1;
961   }
962 }
963 OIL_DEFINE_IMPL_REF (avg2_16xn_u8_ref, avg2_16xn_u8);
964
965 void
966 avg2_32xn_u8_ref (uint8_t *d, int ds1, uint8_t *s1, int ss1,
967     uint8_t *s2, int ss2, int n)
968 {
969   int i;
970   int j;
971   for(j=0;j<n;j++){
972     for(i=0;i<32;i++){
973       d[i] = (s1[i] + s2[i] + 1)>>1;
974     }
975     s1 += ss1;
976     s2 += ss2;
977     d += ds1;
978   }
979 }
980 OIL_DEFINE_IMPL_REF (avg2_32xn_u8_ref, avg2_32xn_u8);