Merge commit '801c39e1e3058fc4ba822bfb5d8612d777111e32'
[ffmpeg.git] / libavcodec / dirac_dwt.c
1 /*
2  * Copyright (C) 2004-2010 Michael Niedermayer <michaelni@gmx.at>
3  * Copyright (C) 2008 David Conrad
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "libavutil/attributes.h"
23 #include "libavutil/avassert.h"
24 #include "libavutil/common.h"
25 #include "dsputil.h"
26 #include "dirac_dwt.h"
27 #include "libavcodec/x86/dirac_dwt.h"
28
29
30 static inline int mirror(int v, int m)
31 {
32     while ((unsigned)v > (unsigned)m) {
33         v = -v;
34         if (v < 0)
35             v += 2 * m;
36     }
37     return v;
38 }
39
40 static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
41                                   int width)
42 {
43     int i;
44
45     for (i = 0; i < width; i++)
46         b1[i] -= (b0[i] + b2[i] + 2) >> 2;
47 }
48
49
50 static av_always_inline
51 void interleave(IDWTELEM *dst, IDWTELEM *src0, IDWTELEM *src1, int w2, int add, int shift)
52 {
53     int i;
54     for (i = 0; i < w2; i++) {
55         dst[2*i  ] = (src0[i] + add) >> shift;
56         dst[2*i+1] = (src1[i] + add) >> shift;
57     }
58 }
59
60 static void horizontal_compose_dirac53i(IDWTELEM *b, IDWTELEM *temp, int w)
61 {
62     const int w2 = w >> 1;
63     int x;
64
65     temp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
66     for (x = 1; x < w2; x++) {
67         temp[x     ] = COMPOSE_53iL0     (b[x+w2-1], b[x     ], b[x+w2]);
68         temp[x+w2-1] = COMPOSE_DIRAC53iH0(temp[x-1], b[x+w2-1], temp[x]);
69     }
70     temp[w-1] = COMPOSE_DIRAC53iH0(temp[w2-1], b[w-1], temp[w2-1]);
71
72     interleave(b, temp, temp+w2, w2, 1, 1);
73 }
74
75 static void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int w)
76 {
77     const int w2 = w >> 1;
78     int x;
79
80     tmp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
81     for (x = 1; x < w2; x++)
82         tmp[x] = COMPOSE_53iL0(b[x+w2-1], b[x], b[x+w2]);
83
84     // extend the edges
85     tmp[-1]   = tmp[0];
86     tmp[w2+1] = tmp[w2] = tmp[w2-1];
87
88     for (x = 0; x < w2; x++) {
89         b[2*x  ] = (tmp[x] + 1)>>1;
90         b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
91     }
92 }
93
94 static void horizontal_compose_dd137i(IDWTELEM *b, IDWTELEM *tmp, int w)
95 {
96     const int w2 = w >> 1;
97     int x;
98
99     tmp[0] = COMPOSE_DD137iL0(b[w2], b[w2], b[0], b[w2  ], b[w2+1]);
100     tmp[1] = COMPOSE_DD137iL0(b[w2], b[w2], b[1], b[w2+1], b[w2+2]);
101     for (x = 2; x < w2-1; x++)
102         tmp[x] = COMPOSE_DD137iL0(b[x+w2-2], b[x+w2-1], b[x], b[x+w2], b[x+w2+1]);
103     tmp[w2-1] = COMPOSE_DD137iL0(b[w-3], b[w-2], b[w2-1], b[w-1], b[w-1]);
104
105     // extend the edges
106     tmp[-1]   = tmp[0];
107     tmp[w2+1] = tmp[w2] = tmp[w2-1];
108
109     for (x = 0; x < w2; x++) {
110         b[2*x  ] = (tmp[x] + 1)>>1;
111         b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
112     }
113 }
114
115 static av_always_inline
116 void horizontal_compose_haari(IDWTELEM *b, IDWTELEM *temp, int w, int shift)
117 {
118     const int w2 = w >> 1;
119     int x;
120
121     for (x = 0; x < w2; x++) {
122         temp[x   ] = COMPOSE_HAARiL0(b[x   ], b[x+w2]);
123         temp[x+w2] = COMPOSE_HAARiH0(b[x+w2], temp[x]);
124     }
125
126     interleave(b, temp, temp+w2, w2, shift, shift);
127 }
128
129 static void horizontal_compose_haar0i(IDWTELEM *b, IDWTELEM *temp, int w)
130 {
131     horizontal_compose_haari(b, temp, w, 0);
132 }
133
134 static void horizontal_compose_haar1i(IDWTELEM *b, IDWTELEM *temp, int w)
135 {
136     horizontal_compose_haari(b, temp, w, 1);
137 }
138
139 static void horizontal_compose_fidelityi(IDWTELEM *b, IDWTELEM *tmp, int w)
140 {
141     const int w2 = w >> 1;
142     int i, x;
143     IDWTELEM v[8];
144
145     for (x = 0; x < w2; x++) {
146         for (i = 0; i < 8; i++)
147             v[i] = b[av_clip(x-3+i, 0, w2-1)];
148         tmp[x] = COMPOSE_FIDELITYiH0(v[0], v[1], v[2], v[3], b[x+w2], v[4], v[5], v[6], v[7]);
149     }
150
151     for (x = 0; x < w2; x++) {
152         for (i = 0; i < 8; i++)
153             v[i] = tmp[av_clip(x-4+i, 0, w2-1)];
154         tmp[x+w2] = COMPOSE_FIDELITYiL0(v[0], v[1], v[2], v[3], b[x], v[4], v[5], v[6], v[7]);
155     }
156
157     interleave(b, tmp+w2, tmp, w2, 0, 0);
158 }
159
160 static void horizontal_compose_daub97i(IDWTELEM *b, IDWTELEM *temp, int w)
161 {
162     const int w2 = w >> 1;
163     int x, b0, b1, b2;
164
165     temp[0] = COMPOSE_DAUB97iL1(b[w2], b[0], b[w2]);
166     for (x = 1; x < w2; x++) {
167         temp[x     ] = COMPOSE_DAUB97iL1(b[x+w2-1], b[x     ], b[x+w2]);
168         temp[x+w2-1] = COMPOSE_DAUB97iH1(temp[x-1], b[x+w2-1], temp[x]);
169     }
170     temp[w-1] = COMPOSE_DAUB97iH1(temp[w2-1], b[w-1], temp[w2-1]);
171
172     // second stage combined with interleave and shift
173     b0 = b2 = COMPOSE_DAUB97iL0(temp[w2], temp[0], temp[w2]);
174     b[0] = (b0 + 1) >> 1;
175     for (x = 1; x < w2; x++) {
176         b2 = COMPOSE_DAUB97iL0(temp[x+w2-1], temp[x     ], temp[x+w2]);
177         b1 = COMPOSE_DAUB97iH0(          b0, temp[x+w2-1], b2        );
178         b[2*x-1] = (b1 + 1) >> 1;
179         b[2*x  ] = (b2 + 1) >> 1;
180         b0 = b2;
181     }
182     b[w-1] = (COMPOSE_DAUB97iH0(b2, temp[w-1], b2) + 1) >> 1;
183 }
184
185 static void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
186 {
187     int i;
188
189     for(i=0; i<width; i++){
190         b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]);
191     }
192 }
193
194 static void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
195                                   IDWTELEM *b3, IDWTELEM *b4, int width)
196 {
197     int i;
198
199     for(i=0; i<width; i++){
200         b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]);
201     }
202 }
203
204 static void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
205                                       IDWTELEM *b3, IDWTELEM *b4, int width)
206 {
207     int i;
208
209     for(i=0; i<width; i++){
210         b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]);
211     }
212 }
213
214 static void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width)
215 {
216     int i;
217
218     for (i = 0; i < width; i++) {
219         b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]);
220         b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]);
221     }
222 }
223
224 static void vertical_compose_fidelityiH0(IDWTELEM *dst, IDWTELEM *b[8], int width)
225 {
226     int i;
227
228     for(i=0; i<width; i++){
229         dst[i] = COMPOSE_FIDELITYiH0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
230     }
231 }
232
233 static void vertical_compose_fidelityiL0(IDWTELEM *dst, IDWTELEM *b[8], int width)
234 {
235     int i;
236
237     for(i=0; i<width; i++){
238         dst[i] = COMPOSE_FIDELITYiL0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
239     }
240 }
241
242 static void vertical_compose_daub97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
243 {
244     int i;
245
246     for(i=0; i<width; i++){
247         b1[i] = COMPOSE_DAUB97iH0(b0[i], b1[i], b2[i]);
248     }
249 }
250
251 static void vertical_compose_daub97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
252 {
253     int i;
254
255     for(i=0; i<width; i++){
256         b1[i] = COMPOSE_DAUB97iH1(b0[i], b1[i], b2[i]);
257     }
258 }
259
260 static void vertical_compose_daub97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
261 {
262     int i;
263
264     for(i=0; i<width; i++){
265         b1[i] = COMPOSE_DAUB97iL0(b0[i], b1[i], b2[i]);
266     }
267 }
268
269 static void vertical_compose_daub97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
270 {
271     int i;
272
273     for(i=0; i<width; i++){
274         b1[i] = COMPOSE_DAUB97iL1(b0[i], b1[i], b2[i]);
275     }
276 }
277
278
279 static void spatial_compose_dd97i_dy(DWTContext *d, int level, int width, int height, int stride)
280 {
281     vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
282     vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
283     DWTCompose *cs = d->cs + level;
284
285     int i, y = cs->y;
286     IDWTELEM *b[8];
287     for (i = 0; i < 6; i++)
288         b[i] = cs->b[i];
289     b[6] = d->buffer + av_clip(y+5, 0, height-2)*stride;
290     b[7] = d->buffer + av_clip(y+6, 1, height-1)*stride;
291
292         if(y+5<(unsigned)height) vertical_compose_l0(      b[5], b[6], b[7],       width);
293         if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
294
295         if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
296         if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
297
298     for (i = 0; i < 6; i++)
299         cs->b[i] = b[i+2];
300     cs->y += 2;
301 }
302
303 static void spatial_compose_dirac53i_dy(DWTContext *d, int level, int width, int height, int stride)
304 {
305     vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
306     vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
307     DWTCompose *cs = d->cs + level;
308
309     int y= cs->y;
310     IDWTELEM *b[4] = { cs->b[0], cs->b[1] };
311     b[2] = d->buffer + mirror(y+1, height-1)*stride;
312     b[3] = d->buffer + mirror(y+2, height-1)*stride;
313
314         if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
315         if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
316
317         if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
318         if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
319
320     cs->b[0] = b[2];
321     cs->b[1] = b[3];
322     cs->y += 2;
323 }
324
325
326 static void spatial_compose_dd137i_dy(DWTContext *d, int level, int width, int height, int stride)
327 {
328     vertical_compose_5tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
329     vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
330     DWTCompose *cs = d->cs + level;
331
332     int i, y = cs->y;
333     IDWTELEM *b[10];
334     for (i = 0; i < 8; i++)
335         b[i] = cs->b[i];
336     b[8] = d->buffer + av_clip(y+7, 0, height-2)*stride;
337     b[9] = d->buffer + av_clip(y+8, 1, height-1)*stride;
338
339         if(y+5<(unsigned)height) vertical_compose_l0(b[3], b[5], b[6], b[7], b[9], width);
340         if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
341
342         if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
343         if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
344
345     for (i = 0; i < 8; i++)
346         cs->b[i] = b[i+2];
347     cs->y += 2;
348 }
349
350 // haar makes the assumption that height is even (always true for dirac)
351 static void spatial_compose_haari_dy(DWTContext *d, int level, int width, int height, int stride)
352 {
353     vertical_compose_2tap vertical_compose = (void*)d->vertical_compose;
354     int y = d->cs[level].y;
355     IDWTELEM *b0 = d->buffer + (y-1)*stride;
356     IDWTELEM *b1 = d->buffer + (y  )*stride;
357
358     vertical_compose(b0, b1, width);
359     d->horizontal_compose(b0, d->temp, width);
360     d->horizontal_compose(b1, d->temp, width);
361
362     d->cs[level].y += 2;
363 }
364
365 // Don't do sliced idwt for fidelity; the 9 tap filter makes it a bit annoying
366 // Fortunately, this filter isn't used in practice.
367 static void spatial_compose_fidelity(DWTContext *d, int level, int width, int height, int stride)
368 {
369     vertical_compose_9tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
370     vertical_compose_9tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
371     int i, y;
372     IDWTELEM *b[8];
373
374     for (y = 1; y < height; y += 2) {
375         for (i = 0; i < 8; i++)
376             b[i] = d->buffer + av_clip((y-7 + 2*i), 0, height-2)*stride;
377         vertical_compose_h0(d->buffer + y*stride, b, width);
378     }
379
380     for (y = 0; y < height; y += 2) {
381         for (i = 0; i < 8; i++)
382             b[i] = d->buffer + av_clip((y-7 + 2*i), 1, height-1)*stride;
383         vertical_compose_l0(d->buffer + y*stride, b, width);
384     }
385
386     for (y = 0; y < height; y++)
387         d->horizontal_compose(d->buffer + y*stride, d->temp, width);
388
389     d->cs[level].y = height+1;
390 }
391
392 static void spatial_compose_daub97i_dy(DWTContext *d, int level, int width, int height, int stride)
393 {
394     vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
395     vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
396     vertical_compose_3tap vertical_compose_l1 = (void*)d->vertical_compose_l1;
397     vertical_compose_3tap vertical_compose_h1 = (void*)d->vertical_compose_h1;
398     DWTCompose *cs = d->cs + level;
399
400     int i, y = cs->y;
401     IDWTELEM *b[6];
402     for (i = 0; i < 4; i++)
403         b[i] = cs->b[i];
404     b[4] = d->buffer + mirror(y+3, height-1)*stride;
405     b[5] = d->buffer + mirror(y+4, height-1)*stride;
406
407         if(y+3<(unsigned)height) vertical_compose_l1(b[3], b[4], b[5], width);
408         if(y+2<(unsigned)height) vertical_compose_h1(b[2], b[3], b[4], width);
409         if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
410         if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
411
412         if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
413         if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
414
415     for (i = 0; i < 4; i++)
416         cs->b[i] = b[i+2];
417     cs->y += 2;
418 }
419
420
421 static void spatial_compose97i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
422 {
423     cs->b[0] = buffer + mirror(-3-1, height-1)*stride;
424     cs->b[1] = buffer + mirror(-3  , height-1)*stride;
425     cs->b[2] = buffer + mirror(-3+1, height-1)*stride;
426     cs->b[3] = buffer + mirror(-3+2, height-1)*stride;
427     cs->y = -3;
428 }
429
430 static void spatial_compose53i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
431 {
432     cs->b[0] = buffer + mirror(-1-1, height-1)*stride;
433     cs->b[1] = buffer + mirror(-1  , height-1)*stride;
434     cs->y = -1;
435 }
436
437 static void spatial_compose_dd97i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
438 {
439     cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
440     cs->b[1] = buffer + av_clip(-5  , 1, height-1)*stride;
441     cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
442     cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
443     cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
444     cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
445     cs->y = -5;
446 }
447
448 static void spatial_compose_dd137i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
449 {
450     cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
451     cs->b[1] = buffer + av_clip(-5  , 1, height-1)*stride;
452     cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
453     cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
454     cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
455     cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
456     cs->b[6] = buffer + av_clip(-5+5, 0, height-2)*stride;
457     cs->b[7] = buffer + av_clip(-5+6, 1, height-1)*stride;
458     cs->y = -5;
459 }
460
461 int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height,
462                           int stride, enum dwt_type type, int decomposition_count,
463                           IDWTELEM *temp)
464 {
465     int level;
466
467     d->buffer = buffer;
468     d->width = width;
469     d->height = height;
470     d->stride = stride;
471     d->decomposition_count = decomposition_count;
472     d->temp = temp + 8;
473
474     for(level=decomposition_count-1; level>=0; level--){
475         int hl = height >> level;
476         int stride_l = stride << level;
477
478         switch(type){
479         case DWT_DIRAC_DD9_7:
480             spatial_compose_dd97i_init(d->cs+level, buffer, hl, stride_l);
481             break;
482         case DWT_DIRAC_LEGALL5_3:
483             spatial_compose53i_init2(d->cs+level, buffer, hl, stride_l);
484             break;
485         case DWT_DIRAC_DD13_7:
486             spatial_compose_dd137i_init(d->cs+level, buffer, hl, stride_l);
487             break;
488         case DWT_DIRAC_HAAR0:
489         case DWT_DIRAC_HAAR1:
490             d->cs[level].y = 1;
491             break;
492         case DWT_DIRAC_DAUB9_7:
493             spatial_compose97i_init2(d->cs+level, buffer, hl, stride_l);
494             break;
495         default:
496             d->cs[level].y = 0;
497             break;
498         }
499     }
500
501     switch (type) {
502     case DWT_DIRAC_DD9_7:
503         d->spatial_compose = spatial_compose_dd97i_dy;
504         d->vertical_compose_l0 = (void*)vertical_compose53iL0;
505         d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0;
506         d->horizontal_compose = horizontal_compose_dd97i;
507         d->support = 7;
508         break;
509     case DWT_DIRAC_LEGALL5_3:
510         d->spatial_compose = spatial_compose_dirac53i_dy;
511         d->vertical_compose_l0 = (void*)vertical_compose53iL0;
512         d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0;
513         d->horizontal_compose = horizontal_compose_dirac53i;
514         d->support = 3;
515         break;
516     case DWT_DIRAC_DD13_7:
517         d->spatial_compose = spatial_compose_dd137i_dy;
518         d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0;
519         d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0;
520         d->horizontal_compose = horizontal_compose_dd137i;
521         d->support = 7;
522         break;
523     case DWT_DIRAC_HAAR0:
524     case DWT_DIRAC_HAAR1:
525         d->spatial_compose = spatial_compose_haari_dy;
526         d->vertical_compose = (void*)vertical_compose_haar;
527         if (type == DWT_DIRAC_HAAR0)
528             d->horizontal_compose = horizontal_compose_haar0i;
529         else
530             d->horizontal_compose = horizontal_compose_haar1i;
531         d->support = 1;
532         break;
533     case DWT_DIRAC_FIDELITY:
534         d->spatial_compose = spatial_compose_fidelity;
535         d->vertical_compose_l0 = (void*)vertical_compose_fidelityiL0;
536         d->vertical_compose_h0 = (void*)vertical_compose_fidelityiH0;
537         d->horizontal_compose = horizontal_compose_fidelityi;
538         d->support = 0; // not really used
539         break;
540     case DWT_DIRAC_DAUB9_7:
541         d->spatial_compose = spatial_compose_daub97i_dy;
542         d->vertical_compose_l0 = (void*)vertical_compose_daub97iL0;
543         d->vertical_compose_h0 = (void*)vertical_compose_daub97iH0;
544         d->vertical_compose_l1 = (void*)vertical_compose_daub97iL1;
545         d->vertical_compose_h1 = (void*)vertical_compose_daub97iH1;
546         d->horizontal_compose = horizontal_compose_daub97i;
547         d->support = 5;
548         break;
549     default:
550         av_log(NULL, AV_LOG_ERROR, "Unknown wavelet type %d\n", type);
551         return -1;
552     }
553
554     if (HAVE_MMX) ff_spatial_idwt_init_mmx(d, type);
555
556     return 0;
557 }
558
559 void ff_spatial_idwt_slice2(DWTContext *d, int y)
560 {
561     int level, support = d->support;
562
563     for (level = d->decomposition_count-1; level >= 0; level--) {
564         int wl = d->width  >> level;
565         int hl = d->height >> level;
566         int stride_l = d->stride << level;
567
568         while (d->cs[level].y <= FFMIN((y>>level)+support, hl))
569             d->spatial_compose(d, level, wl, hl, stride_l);
570     }
571 }
572