FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dwt.c
Go to the documentation of this file.
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 "dwt.h"
27 #include "libavcodec/x86/dwt.h"
28 
29 int ff_slice_buffer_init(slice_buffer *buf, int line_count,
30  int max_allocated_lines, int line_width,
31  IDWTELEM *base_buffer)
32 {
33  int i;
34 
35  buf->base_buffer = base_buffer;
36  buf->line_count = line_count;
37  buf->line_width = line_width;
38  buf->data_count = max_allocated_lines;
39  buf->line = av_mallocz(sizeof(IDWTELEM *) * line_count);
40  if (!buf->line)
41  return AVERROR(ENOMEM);
42  buf->data_stack = av_malloc(sizeof(IDWTELEM *) * max_allocated_lines);
43  if (!buf->data_stack) {
44  av_freep(&buf->line);
45  return AVERROR(ENOMEM);
46  }
47 
48  for (i = 0; i < max_allocated_lines; i++) {
49  buf->data_stack[i] = av_malloc(sizeof(IDWTELEM) * line_width);
50  if (!buf->data_stack[i]) {
51  for (i--; i >=0; i--)
52  av_freep(&buf->data_stack[i]);
53  av_freep(&buf->data_stack);
54  av_freep(&buf->line);
55  return AVERROR(ENOMEM);
56  }
57  }
58 
59  buf->data_stack_top = max_allocated_lines - 1;
60  return 0;
61 }
62 
64 {
66 
67  av_assert0(buf->data_stack_top >= 0);
68 // av_assert1(!buf->line[line]);
69  if (buf->line[line])
70  return buf->line[line];
71 
72  buffer = buf->data_stack[buf->data_stack_top];
73  buf->data_stack_top--;
74  buf->line[line] = buffer;
75 
76  return buffer;
77 }
78 
80 {
82 
83  av_assert1(line >= 0 && line < buf->line_count);
84  av_assert1(buf->line[line]);
85 
86  buffer = buf->line[line];
87  buf->data_stack_top++;
88  buf->data_stack[buf->data_stack_top] = buffer;
89  buf->line[line] = NULL;
90 }
91 
93 {
94  int i;
95  for (i = 0; i < buf->line_count; i++)
96  if (buf->line[i])
98 }
99 
101 {
102  int i;
104 
105  for (i = buf->data_count - 1; i >= 0; i--)
106  av_freep(&buf->data_stack[i]);
107  av_freep(&buf->data_stack);
108  av_freep(&buf->line);
109 }
110 
111 static inline int mirror(int v, int m)
112 {
113  while ((unsigned)v > (unsigned)m) {
114  v = -v;
115  if (v < 0)
116  v += 2 * m;
117  }
118  return v;
119 }
120 
121 static av_always_inline void lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
122  int dst_step, int src_step, int ref_step,
123  int width, int mul, int add, int shift,
124  int highpass, int inverse)
125 {
126  const int mirror_left = !highpass;
127  const int mirror_right = (width & 1) ^ highpass;
128  const int w = (width >> 1) - 1 + (highpass & width);
129  int i;
130 
131 #define LIFT(src, ref, inv) ((src) + ((inv) ? -(ref) : +(ref)))
132  if (mirror_left) {
133  dst[0] = LIFT(src[0], ((mul * 2 * ref[0] + add) >> shift), inverse);
134  dst += dst_step;
135  src += src_step;
136  }
137 
138  for (i = 0; i < w; i++)
139  dst[i * dst_step] = LIFT(src[i * src_step],
140  ((mul * (ref[i * ref_step] +
141  ref[(i + 1) * ref_step]) +
142  add) >> shift),
143  inverse);
144 
145  if (mirror_right)
146  dst[w * dst_step] = LIFT(src[w * src_step],
147  ((mul * 2 * ref[w * ref_step] + add) >> shift),
148  inverse);
149 }
150 
151 static av_always_inline void liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
152  int dst_step, int src_step, int ref_step,
153  int width, int mul, int add, int shift,
154  int highpass, int inverse)
155 {
156  const int mirror_left = !highpass;
157  const int mirror_right = (width & 1) ^ highpass;
158  const int w = (width >> 1) - 1 + (highpass & width);
159  int i;
160 
161  av_assert1(shift == 4);
162 #define LIFTS(src, ref, inv) \
163  ((inv) ? (src) + (((ref) + 4 * (src)) >> shift) \
164  : -((-16 * (src) + (ref) + add / \
165  4 + 1 + (5 << 25)) / (5 * 4) - (1 << 23)))
166  if (mirror_left) {
167  dst[0] = LIFTS(src[0], mul * 2 * ref[0] + add, inverse);
168  dst += dst_step;
169  src += src_step;
170  }
171 
172  for (i = 0; i < w; i++)
173  dst[i * dst_step] = LIFTS(src[i * src_step],
174  mul * (ref[i * ref_step] +
175  ref[(i + 1) * ref_step]) + add,
176  inverse);
177 
178  if (mirror_right)
179  dst[w * dst_step] = LIFTS(src[w * src_step],
180  mul * 2 * ref[w * ref_step] + add,
181  inverse);
182 }
183 
185 {
186  const int width2 = width >> 1;
187  int x;
188  const int w2 = (width + 1) >> 1;
189 
190  for (x = 0; x < width2; x++) {
191  temp[x] = b[2 * x];
192  temp[x + w2] = b[2 * x + 1];
193  }
194  if (width & 1)
195  temp[x] = b[2 * x];
196  lift(b + w2, temp + w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 0);
197  lift(b, temp, b + w2, 1, 1, 1, width, 1, 2, 2, 0, 0);
198 }
199 
200 static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
201  int width)
202 {
203  int i;
204 
205  for (i = 0; i < width; i++)
206  b1[i] -= (b0[i] + b2[i]) >> 1;
207 }
208 
209 static void vertical_decompose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
210  int width)
211 {
212  int i;
213 
214  for (i = 0; i < width; i++)
215  b1[i] += (b0[i] + b2[i] + 2) >> 2;
216 }
217 
219  int width, int height, int stride)
220 {
221  int y;
222  DWTELEM *b0 = buffer + mirror(-2 - 1, height - 1) * stride;
223  DWTELEM *b1 = buffer + mirror(-2, height - 1) * stride;
224 
225  for (y = -2; y < height; y += 2) {
226  DWTELEM *b2 = buffer + mirror(y + 1, height - 1) * stride;
227  DWTELEM *b3 = buffer + mirror(y + 2, height - 1) * stride;
228 
229  if (y + 1 < (unsigned)height)
230  horizontal_decompose53i(b2, temp, width);
231  if (y + 2 < (unsigned)height)
232  horizontal_decompose53i(b3, temp, width);
233 
234  if (y + 1 < (unsigned)height)
235  vertical_decompose53iH0(b1, b2, b3, width);
236  if (y + 0 < (unsigned)height)
237  vertical_decompose53iL0(b0, b1, b2, width);
238 
239  b0 = b2;
240  b1 = b3;
241  }
242 }
243 
245 {
246  const int w2 = (width + 1) >> 1;
247 
248  lift(temp + w2, b + 1, b, 1, 2, 2, width, W_AM, W_AO, W_AS, 1, 1);
249  liftS(temp, b, temp + w2, 1, 2, 1, width, W_BM, W_BO, W_BS, 0, 0);
250  lift(b + w2, temp + w2, temp, 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 0);
251  lift(b, temp, b + w2, 1, 1, 1, width, W_DM, W_DO, W_DS, 0, 0);
252 }
253 
254 static void vertical_decompose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
255  int width)
256 {
257  int i;
258 
259  for (i = 0; i < width; i++)
260  b1[i] -= (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
261 }
262 
263 static void vertical_decompose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
264  int width)
265 {
266  int i;
267 
268  for (i = 0; i < width; i++)
269  b1[i] += (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS;
270 }
271 
272 static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
273  int width)
274 {
275  int i;
276 
277  for (i = 0; i < width; i++)
278  b1[i] = (16 * 4 * b1[i] - 4 * (b0[i] + b2[i]) + W_BO * 5 + (5 << 27)) /
279  (5 * 16) - (1 << 23);
280 }
281 
282 static void vertical_decompose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
283  int width)
284 {
285  int i;
286 
287  for (i = 0; i < width; i++)
288  b1[i] += (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS;
289 }
290 
292  int width, int height, int stride)
293 {
294  int y;
295  DWTELEM *b0 = buffer + mirror(-4 - 1, height - 1) * stride;
296  DWTELEM *b1 = buffer + mirror(-4, height - 1) * stride;
297  DWTELEM *b2 = buffer + mirror(-4 + 1, height - 1) * stride;
298  DWTELEM *b3 = buffer + mirror(-4 + 2, height - 1) * stride;
299 
300  for (y = -4; y < height; y += 2) {
301  DWTELEM *b4 = buffer + mirror(y + 3, height - 1) * stride;
302  DWTELEM *b5 = buffer + mirror(y + 4, height - 1) * stride;
303 
304  if (y + 3 < (unsigned)height)
305  horizontal_decompose97i(b4, temp, width);
306  if (y + 4 < (unsigned)height)
307  horizontal_decompose97i(b5, temp, width);
308 
309  if (y + 3 < (unsigned)height)
310  vertical_decompose97iH0(b3, b4, b5, width);
311  if (y + 2 < (unsigned)height)
312  vertical_decompose97iL0(b2, b3, b4, width);
313  if (y + 1 < (unsigned)height)
314  vertical_decompose97iH1(b1, b2, b3, width);
315  if (y + 0 < (unsigned)height)
316  vertical_decompose97iL1(b0, b1, b2, width);
317 
318  b0 = b2;
319  b1 = b3;
320  b2 = b4;
321  b3 = b5;
322  }
323 }
324 
326  int stride, int type, int decomposition_count)
327 {
328  int level;
329 
330  for (level = 0; level < decomposition_count; level++) {
331  switch (type) {
332  case DWT_97:
333  spatial_decompose97i(buffer, temp,
334  width >> level, height >> level,
335  stride << level);
336  break;
337  case DWT_53:
338  spatial_decompose53i(buffer, temp,
339  width >> level, height >> level,
340  stride << level);
341  break;
342  }
343  }
344 }
345 
347 {
348  const int width2 = width >> 1;
349  const int w2 = (width + 1) >> 1;
350  int x;
351 
352  for (x = 0; x < width2; x++) {
353  temp[2 * x] = b[x];
354  temp[2 * x + 1] = b[x + w2];
355  }
356  if (width & 1)
357  temp[2 * x] = b[x];
358 
359  b[0] = temp[0] - ((temp[1] + 1) >> 1);
360  for (x = 2; x < width - 1; x += 2) {
361  b[x] = temp[x] - ((temp[x - 1] + temp[x + 1] + 2) >> 2);
362  b[x - 1] = temp[x - 1] + ((b[x - 2] + b[x] + 1) >> 1);
363  }
364  if (width & 1) {
365  b[x] = temp[x] - ((temp[x - 1] + 1) >> 1);
366  b[x - 1] = temp[x - 1] + ((b[x - 2] + b[x] + 1) >> 1);
367  } else
368  b[x - 1] = temp[x - 1] + b[x - 2];
369 }
370 
372  int width)
373 {
374  int i;
375 
376  for (i = 0; i < width; i++)
377  b1[i] += (b0[i] + b2[i]) >> 1;
378 }
379 
381  int width)
382 {
383  int i;
384 
385  for (i = 0; i < width; i++)
386  b1[i] -= (b0[i] + b2[i] + 2) >> 2;
387 }
388 
390  int height, int stride_line)
391 {
392  cs->b0 = slice_buffer_get_line(sb,
393  mirror(-1 - 1, height - 1) * stride_line);
394  cs->b1 = slice_buffer_get_line(sb, mirror(-1, height - 1) * stride_line);
395  cs->y = -1;
396 }
397 
399  int height, int stride)
400 {
401  cs->b0 = buffer + mirror(-1 - 1, height - 1) * stride;
402  cs->b1 = buffer + mirror(-1, height - 1) * stride;
403  cs->y = -1;
404 }
405 
407  IDWTELEM *temp,
408  int width, int height,
409  int stride_line)
410 {
411  int y = cs->y;
412 
413  IDWTELEM *b0 = cs->b0;
414  IDWTELEM *b1 = cs->b1;
416  mirror(y + 1, height - 1) *
417  stride_line);
419  mirror(y + 2, height - 1) *
420  stride_line);
421 
422  if (y + 1 < (unsigned)height && y < (unsigned)height) {
423  int x;
424 
425  for (x = 0; x < width; x++) {
426  b2[x] -= (b1[x] + b3[x] + 2) >> 2;
427  b1[x] += (b0[x] + b2[x]) >> 1;
428  }
429  } else {
430  if (y + 1 < (unsigned)height)
431  vertical_compose53iL0(b1, b2, b3, width);
432  if (y + 0 < (unsigned)height)
433  vertical_compose53iH0(b0, b1, b2, width);
434  }
435 
436  if (y - 1 < (unsigned)height)
437  horizontal_compose53i(b0, temp, width);
438  if (y + 0 < (unsigned)height)
439  horizontal_compose53i(b1, temp, width);
440 
441  cs->b0 = b2;
442  cs->b1 = b3;
443  cs->y += 2;
444 }
445 
447  IDWTELEM *temp, int width, int height,
448  int stride)
449 {
450  int y = cs->y;
451  IDWTELEM *b0 = cs->b0;
452  IDWTELEM *b1 = cs->b1;
453  IDWTELEM *b2 = buffer + mirror(y + 1, height - 1) * stride;
454  IDWTELEM *b3 = buffer + mirror(y + 2, height - 1) * stride;
455 
456  if (y + 1 < (unsigned)height)
457  vertical_compose53iL0(b1, b2, b3, width);
458  if (y + 0 < (unsigned)height)
459  vertical_compose53iH0(b0, b1, b2, width);
460 
461  if (y - 1 < (unsigned)height)
462  horizontal_compose53i(b0, temp, width);
463  if (y + 0 < (unsigned)height)
464  horizontal_compose53i(b1, temp, width);
465 
466  cs->b0 = b2;
467  cs->b1 = b3;
468  cs->y += 2;
469 }
470 
472 {
473  const int w2 = (width + 1) >> 1;
474  int x;
475 
476  temp[0] = b[0] - ((3 * b[w2] + 2) >> 2);
477  for (x = 1; x < (width >> 1); x++) {
478  temp[2 * x] = b[x] - ((3 * (b[x + w2 - 1] + b[x + w2]) + 4) >> 3);
479  temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x];
480  }
481  if (width & 1) {
482  temp[2 * x] = b[x] - ((3 * b[x + w2 - 1] + 2) >> 2);
483  temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x];
484  } else
485  temp[2 * x - 1] = b[x + w2 - 1] - 2 * temp[2 * x - 2];
486 
487  b[0] = temp[0] + ((2 * temp[0] + temp[1] + 4) >> 3);
488  for (x = 2; x < width - 1; x += 2) {
489  b[x] = temp[x] + ((4 * temp[x] + temp[x - 1] + temp[x + 1] + 8) >> 4);
490  b[x - 1] = temp[x - 1] + ((3 * (b[x - 2] + b[x])) >> 1);
491  }
492  if (width & 1) {
493  b[x] = temp[x] + ((2 * temp[x] + temp[x - 1] + 4) >> 3);
494  b[x - 1] = temp[x - 1] + ((3 * (b[x - 2] + b[x])) >> 1);
495  } else
496  b[x - 1] = temp[x - 1] + 3 * b[x - 2];
497 }
498 
500  int width)
501 {
502  int i;
503 
504  for (i = 0; i < width; i++)
505  b1[i] += (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
506 }
507 
509  int width)
510 {
511  int i;
512 
513  for (i = 0; i < width; i++)
514  b1[i] -= (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS;
515 }
516 
518  int width)
519 {
520  int i;
521 
522  for (i = 0; i < width; i++)
523  b1[i] += (W_BM * (b0[i] + b2[i]) + 4 * b1[i] + W_BO) >> W_BS;
524 }
525 
527  int width)
528 {
529  int i;
530 
531  for (i = 0; i < width; i++)
532  b1[i] -= (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS;
533 }
534 
536  IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
537  int width)
538 {
539  int i;
540 
541  for (i = 0; i < width; i++) {
542  b4[i] -= (W_DM * (b3[i] + b5[i]) + W_DO) >> W_DS;
543  b3[i] -= (W_CM * (b2[i] + b4[i]) + W_CO) >> W_CS;
544  b2[i] += (W_BM * (b1[i] + b3[i]) + 4 * b2[i] + W_BO) >> W_BS;
545  b1[i] += (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
546  }
547 }
548 
550  int height, int stride_line)
551 {
552  cs->b0 = slice_buffer_get_line(sb, mirror(-3 - 1, height - 1) * stride_line);
553  cs->b1 = slice_buffer_get_line(sb, mirror(-3, height - 1) * stride_line);
554  cs->b2 = slice_buffer_get_line(sb, mirror(-3 + 1, height - 1) * stride_line);
555  cs->b3 = slice_buffer_get_line(sb, mirror(-3 + 2, height - 1) * stride_line);
556  cs->y = -3;
557 }
558 
560  int stride)
561 {
562  cs->b0 = buffer + mirror(-3 - 1, height - 1) * stride;
563  cs->b1 = buffer + mirror(-3, height - 1) * stride;
564  cs->b2 = buffer + mirror(-3 + 1, height - 1) * stride;
565  cs->b3 = buffer + mirror(-3 + 2, height - 1) * stride;
566  cs->y = -3;
567 }
568 
570  slice_buffer * sb, IDWTELEM *temp,
571  int width, int height,
572  int stride_line)
573 {
574  int y = cs->y;
575 
576  IDWTELEM *b0 = cs->b0;
577  IDWTELEM *b1 = cs->b1;
578  IDWTELEM *b2 = cs->b2;
579  IDWTELEM *b3 = cs->b3;
581  mirror(y + 3, height - 1) *
582  stride_line);
584  mirror(y + 4, height - 1) *
585  stride_line);
586 
587  if (y > 0 && y + 4 < height) {
588  dsp->vertical_compose97i(b0, b1, b2, b3, b4, b5, width);
589  } else {
590  if (y + 3 < (unsigned)height)
591  vertical_compose97iL1(b3, b4, b5, width);
592  if (y + 2 < (unsigned)height)
593  vertical_compose97iH1(b2, b3, b4, width);
594  if (y + 1 < (unsigned)height)
595  vertical_compose97iL0(b1, b2, b3, width);
596  if (y + 0 < (unsigned)height)
597  vertical_compose97iH0(b0, b1, b2, width);
598  }
599 
600  if (y - 1 < (unsigned)height)
601  dsp->horizontal_compose97i(b0, temp, width);
602  if (y + 0 < (unsigned)height)
603  dsp->horizontal_compose97i(b1, temp, width);
604 
605  cs->b0 = b2;
606  cs->b1 = b3;
607  cs->b2 = b4;
608  cs->b3 = b5;
609  cs->y += 2;
610 }
611 
613  IDWTELEM *temp, int width, int height,
614  int stride)
615 {
616  int y = cs->y;
617  IDWTELEM *b0 = cs->b0;
618  IDWTELEM *b1 = cs->b1;
619  IDWTELEM *b2 = cs->b2;
620  IDWTELEM *b3 = cs->b3;
621  IDWTELEM *b4 = buffer + mirror(y + 3, height - 1) * stride;
622  IDWTELEM *b5 = buffer + mirror(y + 4, height - 1) * stride;
623 
624  if (y + 3 < (unsigned)height)
625  vertical_compose97iL1(b3, b4, b5, width);
626  if (y + 2 < (unsigned)height)
627  vertical_compose97iH1(b2, b3, b4, width);
628  if (y + 1 < (unsigned)height)
629  vertical_compose97iL0(b1, b2, b3, width);
630  if (y + 0 < (unsigned)height)
631  vertical_compose97iH0(b0, b1, b2, width);
632 
633  if (y - 1 < (unsigned)height)
634  ff_snow_horizontal_compose97i(b0, temp, width);
635  if (y + 0 < (unsigned)height)
636  ff_snow_horizontal_compose97i(b1, temp, width);
637 
638  cs->b0 = b2;
639  cs->b1 = b3;
640  cs->b2 = b4;
641  cs->b3 = b5;
642  cs->y += 2;
643 }
644 
646  int height, int stride_line, int type,
647  int decomposition_count)
648 {
649  int level;
650  for (level = decomposition_count - 1; level >= 0; level--) {
651  switch (type) {
652  case DWT_97:
653  spatial_compose97i_buffered_init(cs + level, sb, height >> level,
654  stride_line << level);
655  break;
656  case DWT_53:
657  spatial_compose53i_buffered_init(cs + level, sb, height >> level,
658  stride_line << level);
659  break;
660  }
661  }
662 }
663 
665  slice_buffer *slice_buf, IDWTELEM *temp,
666  int width, int height, int stride_line,
667  int type, int decomposition_count, int y)
668 {
669  const int support = type == 1 ? 3 : 5;
670  int level;
671  if (type == 2)
672  return;
673 
674  for (level = decomposition_count - 1; level >= 0; level--)
675  while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
676  switch (type) {
677  case DWT_97:
678  spatial_compose97i_dy_buffered(dsp, cs + level, slice_buf, temp,
679  width >> level,
680  height >> level,
681  stride_line << level);
682  break;
683  case DWT_53:
684  spatial_compose53i_dy_buffered(cs + level, slice_buf, temp,
685  width >> level,
686  height >> level,
687  stride_line << level);
688  break;
689  }
690  }
691 }
692 
694  int height, int stride, int type,
695  int decomposition_count)
696 {
697  int level;
698  for (level = decomposition_count - 1; level >= 0; level--) {
699  switch (type) {
700  case DWT_97:
701  spatial_compose97i_init(cs + level, buffer, height >> level,
702  stride << level);
703  break;
704  case DWT_53:
705  spatial_compose53i_init(cs + level, buffer, height >> level,
706  stride << level);
707  break;
708  }
709  }
710 }
711 
713  IDWTELEM *temp, int width, int height,
714  int stride, int type,
715  int decomposition_count, int y)
716 {
717  const int support = type == 1 ? 3 : 5;
718  int level;
719  if (type == 2)
720  return;
721 
722  for (level = decomposition_count - 1; level >= 0; level--)
723  while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
724  switch (type) {
725  case DWT_97:
726  spatial_compose97i_dy(cs + level, buffer, temp, width >> level,
727  height >> level, stride << level);
728  break;
729  case DWT_53:
730  spatial_compose53i_dy(cs + level, buffer, temp, width >> level,
731  height >> level, stride << level);
732  break;
733  }
734  }
735 }
736 
738  int stride, int type, int decomposition_count)
739 {
741  int y;
742  ff_spatial_idwt_init(cs, buffer, width, height, stride, type,
743  decomposition_count);
744  for (y = 0; y < height; y += 4)
745  ff_spatial_idwt_slice(cs, buffer, temp, width, height, stride, type,
746  decomposition_count, y);
747 }
748 
749 static inline int w_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size,
750  int w, int h, int type)
751 {
752  int s, i, j;
753  const int dec_count = w == 8 ? 3 : 4;
754  int tmp[32 * 32], tmp2[32];
755  int level, ori;
756  static const int scale[2][2][4][4] = {
757  {
758  { // 9/7 8x8 dec=3
759  { 268, 239, 239, 213 },
760  { 0, 224, 224, 152 },
761  { 0, 135, 135, 110 },
762  },
763  { // 9/7 16x16 or 32x32 dec=4
764  { 344, 310, 310, 280 },
765  { 0, 320, 320, 228 },
766  { 0, 175, 175, 136 },
767  { 0, 129, 129, 102 },
768  }
769  },
770  {
771  { // 5/3 8x8 dec=3
772  { 275, 245, 245, 218 },
773  { 0, 230, 230, 156 },
774  { 0, 138, 138, 113 },
775  },
776  { // 5/3 16x16 or 32x32 dec=4
777  { 352, 317, 317, 286 },
778  { 0, 328, 328, 233 },
779  { 0, 180, 180, 140 },
780  { 0, 132, 132, 105 },
781  }
782  }
783  };
784 
785  for (i = 0; i < h; i++) {
786  for (j = 0; j < w; j += 4) {
787  tmp[32 * i + j + 0] = (pix1[j + 0] - pix2[j + 0]) << 4;
788  tmp[32 * i + j + 1] = (pix1[j + 1] - pix2[j + 1]) << 4;
789  tmp[32 * i + j + 2] = (pix1[j + 2] - pix2[j + 2]) << 4;
790  tmp[32 * i + j + 3] = (pix1[j + 3] - pix2[j + 3]) << 4;
791  }
792  pix1 += line_size;
793  pix2 += line_size;
794  }
795 
796  ff_spatial_dwt(tmp, tmp2, w, h, 32, type, dec_count);
797 
798  s = 0;
799  av_assert1(w == h);
800  for (level = 0; level < dec_count; level++)
801  for (ori = level ? 1 : 0; ori < 4; ori++) {
802  int size = w >> (dec_count - level);
803  int sx = (ori & 1) ? size : 0;
804  int stride = 32 << (dec_count - level);
805  int sy = (ori & 2) ? stride >> 1 : 0;
806 
807  for (i = 0; i < size; i++)
808  for (j = 0; j < size; j++) {
809  int v = tmp[sx + sy + i * stride + j] *
810  scale[type][dec_count - 3][level][ori];
811  s += FFABS(v);
812  }
813  }
814  av_assert1(s >= 0);
815  return s >> 9;
816 }
817 
818 static int w53_8_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
819 {
820  return w_c(v, pix1, pix2, line_size, 8, h, 1);
821 }
822 
823 static int w97_8_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
824 {
825  return w_c(v, pix1, pix2, line_size, 8, h, 0);
826 }
827 
828 static int w53_16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
829 {
830  return w_c(v, pix1, pix2, line_size, 16, h, 1);
831 }
832 
833 static int w97_16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
834 {
835  return w_c(v, pix1, pix2, line_size, 16, h, 0);
836 }
837 
838 int ff_w53_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
839 {
840  return w_c(v, pix1, pix2, line_size, 32, h, 1);
841 }
842 
843 int ff_w97_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
844 {
845  return w_c(v, pix1, pix2, line_size, 32, h, 0);
846 }
847 
849 {
850  c->w53[0] = w53_16_c;
851  c->w53[1] = w53_8_c;
852  c->w97[0] = w97_16_c;
853  c->w97[1] = w97_8_c;
854 }
855 
857 {
861 
862  if (HAVE_MMX)
863  ff_dwt_init_x86(c);
864 }
865 
866 
867 static av_always_inline
868 void interleave(IDWTELEM *dst, IDWTELEM *src0, IDWTELEM *src1, int w2, int add, int shift)
869 {
870  int i;
871  for (i = 0; i < w2; i++) {
872  dst[2*i ] = (src0[i] + add) >> shift;
873  dst[2*i+1] = (src1[i] + add) >> shift;
874  }
875 }
876 
878 {
879  const int w2 = w >> 1;
880  int x;
881 
882  temp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
883  for (x = 1; x < w2; x++) {
884  temp[x ] = COMPOSE_53iL0 (b[x+w2-1], b[x ], b[x+w2]);
885  temp[x+w2-1] = COMPOSE_DIRAC53iH0(temp[x-1], b[x+w2-1], temp[x]);
886  }
887  temp[w-1] = COMPOSE_DIRAC53iH0(temp[w2-1], b[w-1], temp[w2-1]);
888 
889  interleave(b, temp, temp+w2, w2, 1, 1);
890 }
891 
892 static void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int w)
893 {
894  const int w2 = w >> 1;
895  int x;
896 
897  tmp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
898  for (x = 1; x < w2; x++)
899  tmp[x] = COMPOSE_53iL0(b[x+w2-1], b[x], b[x+w2]);
900 
901  // extend the edges
902  tmp[-1] = tmp[0];
903  tmp[w2+1] = tmp[w2] = tmp[w2-1];
904 
905  for (x = 0; x < w2; x++) {
906  b[2*x ] = (tmp[x] + 1)>>1;
907  b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
908  }
909 }
910 
911 static void horizontal_compose_dd137i(IDWTELEM *b, IDWTELEM *tmp, int w)
912 {
913  const int w2 = w >> 1;
914  int x;
915 
916  tmp[0] = COMPOSE_DD137iL0(b[w2], b[w2], b[0], b[w2 ], b[w2+1]);
917  tmp[1] = COMPOSE_DD137iL0(b[w2], b[w2], b[1], b[w2+1], b[w2+2]);
918  for (x = 2; x < w2-1; x++)
919  tmp[x] = COMPOSE_DD137iL0(b[x+w2-2], b[x+w2-1], b[x], b[x+w2], b[x+w2+1]);
920  tmp[w2-1] = COMPOSE_DD137iL0(b[w-3], b[w-2], b[w2-1], b[w-1], b[w-1]);
921 
922  // extend the edges
923  tmp[-1] = tmp[0];
924  tmp[w2+1] = tmp[w2] = tmp[w2-1];
925 
926  for (x = 0; x < w2; x++) {
927  b[2*x ] = (tmp[x] + 1)>>1;
928  b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
929  }
930 }
931 
932 static av_always_inline
934 {
935  const int w2 = w >> 1;
936  int x;
937 
938  for (x = 0; x < w2; x++) {
939  temp[x ] = COMPOSE_HAARiL0(b[x ], b[x+w2]);
940  temp[x+w2] = COMPOSE_HAARiH0(b[x+w2], temp[x]);
941  }
942 
943  interleave(b, temp, temp+w2, w2, shift, shift);
944 }
945 
947 {
948  horizontal_compose_haari(b, temp, w, 0);
949 }
950 
952 {
953  horizontal_compose_haari(b, temp, w, 1);
954 }
955 
957 {
958  const int w2 = w >> 1;
959  int i, x;
960  IDWTELEM v[8];
961 
962  for (x = 0; x < w2; x++) {
963  for (i = 0; i < 8; i++)
964  v[i] = b[av_clip(x-3+i, 0, w2-1)];
965  tmp[x] = COMPOSE_FIDELITYiH0(v[0], v[1], v[2], v[3], b[x+w2], v[4], v[5], v[6], v[7]);
966  }
967 
968  for (x = 0; x < w2; x++) {
969  for (i = 0; i < 8; i++)
970  v[i] = tmp[av_clip(x-4+i, 0, w2-1)];
971  tmp[x+w2] = COMPOSE_FIDELITYiL0(v[0], v[1], v[2], v[3], b[x], v[4], v[5], v[6], v[7]);
972  }
973 
974  interleave(b, tmp+w2, tmp, w2, 0, 0);
975 }
976 
978 {
979  const int w2 = w >> 1;
980  int x, b0, b1, b2;
981 
982  temp[0] = COMPOSE_DAUB97iL1(b[w2], b[0], b[w2]);
983  for (x = 1; x < w2; x++) {
984  temp[x ] = COMPOSE_DAUB97iL1(b[x+w2-1], b[x ], b[x+w2]);
985  temp[x+w2-1] = COMPOSE_DAUB97iH1(temp[x-1], b[x+w2-1], temp[x]);
986  }
987  temp[w-1] = COMPOSE_DAUB97iH1(temp[w2-1], b[w-1], temp[w2-1]);
988 
989  // second stage combined with interleave and shift
990  b0 = b2 = COMPOSE_DAUB97iL0(temp[w2], temp[0], temp[w2]);
991  b[0] = (b0 + 1) >> 1;
992  for (x = 1; x < w2; x++) {
993  b2 = COMPOSE_DAUB97iL0(temp[x+w2-1], temp[x ], temp[x+w2]);
994  b1 = COMPOSE_DAUB97iH0( b0, temp[x+w2-1], b2 );
995  b[2*x-1] = (b1 + 1) >> 1;
996  b[2*x ] = (b2 + 1) >> 1;
997  b0 = b2;
998  }
999  b[w-1] = (COMPOSE_DAUB97iH0(b2, temp[w-1], b2) + 1) >> 1;
1000 }
1001 
1003 {
1004  int i;
1005 
1006  for(i=0; i<width; i++){
1007  b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]);
1008  }
1009 }
1010 
1012  IDWTELEM *b3, IDWTELEM *b4, int width)
1013 {
1014  int i;
1015 
1016  for(i=0; i<width; i++){
1017  b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]);
1018  }
1019 }
1020 
1022  IDWTELEM *b3, IDWTELEM *b4, int width)
1023 {
1024  int i;
1025 
1026  for(i=0; i<width; i++){
1027  b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]);
1028  }
1029 }
1030 
1031 static void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width)
1032 {
1033  int i;
1034 
1035  for (i = 0; i < width; i++) {
1036  b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]);
1037  b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]);
1038  }
1039 }
1040 
1042 {
1043  int i;
1044 
1045  for(i=0; i<width; i++){
1046  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]);
1047  }
1048 }
1049 
1051 {
1052  int i;
1053 
1054  for(i=0; i<width; i++){
1055  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]);
1056  }
1057 }
1058 
1060 {
1061  int i;
1062 
1063  for(i=0; i<width; i++){
1064  b1[i] = COMPOSE_DAUB97iH0(b0[i], b1[i], b2[i]);
1065  }
1066 }
1067 
1069 {
1070  int i;
1071 
1072  for(i=0; i<width; i++){
1073  b1[i] = COMPOSE_DAUB97iH1(b0[i], b1[i], b2[i]);
1074  }
1075 }
1076 
1078 {
1079  int i;
1080 
1081  for(i=0; i<width; i++){
1082  b1[i] = COMPOSE_DAUB97iL0(b0[i], b1[i], b2[i]);
1083  }
1084 }
1085 
1087 {
1088  int i;
1089 
1090  for(i=0; i<width; i++){
1091  b1[i] = COMPOSE_DAUB97iL1(b0[i], b1[i], b2[i]);
1092  }
1093 }
1094 
1095 
1096 static void spatial_compose_dd97i_dy(DWTContext *d, int level, int width, int height, int stride)
1097 {
1098  vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
1099  vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
1100  DWTCompose *cs = d->cs + level;
1101 
1102  int i, y = cs->y;
1103  IDWTELEM *b[8];
1104  for (i = 0; i < 6; i++)
1105  b[i] = cs->b[i];
1106  b[6] = d->buffer + av_clip(y+5, 0, height-2)*stride;
1107  b[7] = d->buffer + av_clip(y+6, 1, height-1)*stride;
1108 
1109  if(y+5<(unsigned)height) vertical_compose_l0( b[5], b[6], b[7], width);
1110  if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
1111 
1112  if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
1113  if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
1114 
1115  for (i = 0; i < 6; i++)
1116  cs->b[i] = b[i+2];
1117  cs->y += 2;
1118 }
1119 
1120 static void spatial_compose_dirac53i_dy(DWTContext *d, int level, int width, int height, int stride)
1121 {
1122  vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
1123  vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
1124  DWTCompose *cs = d->cs + level;
1125 
1126  int y= cs->y;
1127  IDWTELEM *b[4] = { cs->b[0], cs->b[1] };
1128  b[2] = d->buffer + mirror(y+1, height-1)*stride;
1129  b[3] = d->buffer + mirror(y+2, height-1)*stride;
1130 
1131  if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
1132  if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
1133 
1134  if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
1135  if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
1136 
1137  cs->b[0] = b[2];
1138  cs->b[1] = b[3];
1139  cs->y += 2;
1140 }
1141 
1142 
1143 static void spatial_compose_dd137i_dy(DWTContext *d, int level, int width, int height, int stride)
1144 {
1145  vertical_compose_5tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
1146  vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
1147  DWTCompose *cs = d->cs + level;
1148 
1149  int i, y = cs->y;
1150  IDWTELEM *b[10];
1151  for (i = 0; i < 8; i++)
1152  b[i] = cs->b[i];
1153  b[8] = d->buffer + av_clip(y+7, 0, height-2)*stride;
1154  b[9] = d->buffer + av_clip(y+8, 1, height-1)*stride;
1155 
1156  if(y+5<(unsigned)height) vertical_compose_l0(b[3], b[5], b[6], b[7], b[9], width);
1157  if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
1158 
1159  if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
1160  if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
1161 
1162  for (i = 0; i < 8; i++)
1163  cs->b[i] = b[i+2];
1164  cs->y += 2;
1165 }
1166 
1167 // haar makes the assumption that height is even (always true for dirac)
1168 static void spatial_compose_haari_dy(DWTContext *d, int level, int width, int height, int stride)
1169 {
1170  vertical_compose_2tap vertical_compose = (void*)d->vertical_compose;
1171  int y = d->cs[level].y;
1172  IDWTELEM *b0 = d->buffer + (y-1)*stride;
1173  IDWTELEM *b1 = d->buffer + (y )*stride;
1174 
1175  vertical_compose(b0, b1, width);
1176  d->horizontal_compose(b0, d->temp, width);
1177  d->horizontal_compose(b1, d->temp, width);
1178 
1179  d->cs[level].y += 2;
1180 }
1181 
1182 // Don't do sliced idwt for fidelity; the 9 tap filter makes it a bit annoying
1183 // Fortunately, this filter isn't used in practice.
1184 static void spatial_compose_fidelity(DWTContext *d, int level, int width, int height, int stride)
1185 {
1186  vertical_compose_9tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
1187  vertical_compose_9tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
1188  int i, y;
1189  IDWTELEM *b[8];
1190 
1191  for (y = 1; y < height; y += 2) {
1192  for (i = 0; i < 8; i++)
1193  b[i] = d->buffer + av_clip((y-7 + 2*i), 0, height-2)*stride;
1194  vertical_compose_h0(d->buffer + y*stride, b, width);
1195  }
1196 
1197  for (y = 0; y < height; y += 2) {
1198  for (i = 0; i < 8; i++)
1199  b[i] = d->buffer + av_clip((y-7 + 2*i), 1, height-1)*stride;
1200  vertical_compose_l0(d->buffer + y*stride, b, width);
1201  }
1202 
1203  for (y = 0; y < height; y++)
1204  d->horizontal_compose(d->buffer + y*stride, d->temp, width);
1205 
1206  d->cs[level].y = height+1;
1207 }
1208 
1209 static void spatial_compose_daub97i_dy(DWTContext *d, int level, int width, int height, int stride)
1210 {
1211  vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
1212  vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
1213  vertical_compose_3tap vertical_compose_l1 = (void*)d->vertical_compose_l1;
1214  vertical_compose_3tap vertical_compose_h1 = (void*)d->vertical_compose_h1;
1215  DWTCompose *cs = d->cs + level;
1216 
1217  int i, y = cs->y;
1218  IDWTELEM *b[6];
1219  for (i = 0; i < 4; i++)
1220  b[i] = cs->b[i];
1221  b[4] = d->buffer + mirror(y+3, height-1)*stride;
1222  b[5] = d->buffer + mirror(y+4, height-1)*stride;
1223 
1224  if(y+3<(unsigned)height) vertical_compose_l1(b[3], b[4], b[5], width);
1225  if(y+2<(unsigned)height) vertical_compose_h1(b[2], b[3], b[4], width);
1226  if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
1227  if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
1228 
1229  if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
1230  if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
1231 
1232  for (i = 0; i < 4; i++)
1233  cs->b[i] = b[i+2];
1234  cs->y += 2;
1235 }
1236 
1237 
1239 {
1240  cs->b[0] = buffer + mirror(-3-1, height-1)*stride;
1241  cs->b[1] = buffer + mirror(-3 , height-1)*stride;
1242  cs->b[2] = buffer + mirror(-3+1, height-1)*stride;
1243  cs->b[3] = buffer + mirror(-3+2, height-1)*stride;
1244  cs->y = -3;
1245 }
1246 
1248 {
1249  cs->b[0] = buffer + mirror(-1-1, height-1)*stride;
1250  cs->b[1] = buffer + mirror(-1 , height-1)*stride;
1251  cs->y = -1;
1252 }
1253 
1255 {
1256  cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
1257  cs->b[1] = buffer + av_clip(-5 , 1, height-1)*stride;
1258  cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
1259  cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
1260  cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
1261  cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
1262  cs->y = -5;
1263 }
1264 
1266 {
1267  cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
1268  cs->b[1] = buffer + av_clip(-5 , 1, height-1)*stride;
1269  cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
1270  cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
1271  cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
1272  cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
1273  cs->b[6] = buffer + av_clip(-5+5, 0, height-2)*stride;
1274  cs->b[7] = buffer + av_clip(-5+6, 1, height-1)*stride;
1275  cs->y = -5;
1276 }
1277 
1279  int stride, enum dwt_type type, int decomposition_count,
1280  IDWTELEM *temp)
1281 {
1282  int level;
1283 
1284  d->buffer = buffer;
1285  d->width = width;
1286  d->height = height;
1287  d->stride = stride;
1288  d->decomposition_count = decomposition_count;
1289  d->temp = temp + 8;
1290 
1291  for(level=decomposition_count-1; level>=0; level--){
1292  int hl = height >> level;
1293  int stride_l = stride << level;
1294 
1295  switch(type){
1296  case DWT_DIRAC_DD9_7:
1297  spatial_compose_dd97i_init(d->cs+level, buffer, hl, stride_l);
1298  break;
1299  case DWT_DIRAC_LEGALL5_3:
1300  spatial_compose53i_init2(d->cs+level, buffer, hl, stride_l);
1301  break;
1302  case DWT_DIRAC_DD13_7:
1303  spatial_compose_dd137i_init(d->cs+level, buffer, hl, stride_l);
1304  break;
1305  case DWT_DIRAC_HAAR0:
1306  case DWT_DIRAC_HAAR1:
1307  d->cs[level].y = 1;
1308  break;
1309  case DWT_DIRAC_DAUB9_7:
1310  spatial_compose97i_init2(d->cs+level, buffer, hl, stride_l);
1311  break;
1312  default:
1313  d->cs[level].y = 0;
1314  break;
1315  }
1316  }
1317 
1318  switch (type) {
1319  case DWT_DIRAC_DD9_7:
1324  d->support = 7;
1325  break;
1326  case DWT_DIRAC_LEGALL5_3:
1331  d->support = 3;
1332  break;
1333  case DWT_DIRAC_DD13_7:
1338  d->support = 7;
1339  break;
1340  case DWT_DIRAC_HAAR0:
1341  case DWT_DIRAC_HAAR1:
1344  if (type == DWT_DIRAC_HAAR0)
1346  else
1348  d->support = 1;
1349  break;
1350  case DWT_DIRAC_FIDELITY:
1355  break;
1356  case DWT_DIRAC_DAUB9_7:
1363  d->support = 5;
1364  break;
1365  default:
1366  av_log(NULL, AV_LOG_ERROR, "Unknown wavelet type %d\n", type);
1367  return -1;
1368  }
1369 
1370  if (HAVE_MMX) ff_spatial_idwt_init_mmx(d, type);
1371 
1372  return 0;
1373 }
1374 
1376 {
1377  int level, support = d->support;
1378 
1379  for (level = d->decomposition_count-1; level >= 0; level--) {
1380  int wl = d->width >> level;
1381  int hl = d->height >> level;
1382  int stride_l = d->stride << level;
1383 
1384  while (d->cs[level].y <= FFMIN((y>>level)+support, hl))
1385  d->spatial_compose(d, level, wl, hl, stride_l);
1386  }
1387 }
1388 
1390  enum dwt_type type, int decomposition_count, IDWTELEM *temp)
1391 {
1392  DWTContext d;
1393  int y;
1394 
1395  if (ff_spatial_idwt_init2(&d, buffer, width, height, stride, type, decomposition_count, temp))
1396  return -1;
1397 
1398  for (y = 0; y < d.height; y += 4)
1399  ff_spatial_idwt_slice2(&d, y);
1400 
1401  return 0;
1402 }