dwt.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2010 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of Libav.
5  *
6  * Libav is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * Libav is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/attributes.h"
22 #include "libavutil/common.h"
23 #include "dsputil.h"
24 #include "dwt.h"
25 
26 int ff_slice_buffer_init(slice_buffer *buf, int line_count,
27  int max_allocated_lines, int line_width,
28  IDWTELEM *base_buffer)
29 {
30  int i;
31 
32  buf->base_buffer = base_buffer;
33  buf->line_count = line_count;
34  buf->line_width = line_width;
35  buf->data_count = max_allocated_lines;
36  buf->line = av_mallocz(sizeof(IDWTELEM *) * line_count);
37  if (!buf->line)
38  return AVERROR(ENOMEM);
39  buf->data_stack = av_malloc(sizeof(IDWTELEM *) * max_allocated_lines);
40  if (!buf->data_stack) {
41  av_free(buf->line);
42  return AVERROR(ENOMEM);
43  }
44 
45  for (i = 0; i < max_allocated_lines; i++) {
46  buf->data_stack[i] = av_malloc(sizeof(IDWTELEM) * line_width);
47  if (!buf->data_stack[i]) {
48  for (i--; i >=0; i--)
49  av_free(buf->data_stack[i]);
50  av_free(buf->data_stack);
51  av_free(buf->line);
52  return AVERROR(ENOMEM);
53  }
54  }
55 
56  buf->data_stack_top = max_allocated_lines - 1;
57  return 0;
58 }
59 
61 {
63 
64  assert(buf->data_stack_top >= 0);
65 // assert(!buf->line[line]);
66  if (buf->line[line])
67  return buf->line[line];
68 
69  buffer = buf->data_stack[buf->data_stack_top];
70  buf->data_stack_top--;
71  buf->line[line] = buffer;
72 
73  return buffer;
74 }
75 
77 {
79 
80  assert(line >= 0 && line < buf->line_count);
81  assert(buf->line[line]);
82 
83  buffer = buf->line[line];
84  buf->data_stack_top++;
85  buf->data_stack[buf->data_stack_top] = buffer;
86  buf->line[line] = NULL;
87 }
88 
90 {
91  int i;
92  for (i = 0; i < buf->line_count; i++)
93  if (buf->line[i])
95 }
96 
98 {
99  int i;
101 
102  for (i = buf->data_count - 1; i >= 0; i--)
103  av_freep(&buf->data_stack[i]);
104  av_freep(&buf->data_stack);
105  av_freep(&buf->line);
106 }
107 
108 static inline int mirror(int v, int m)
109 {
110  while ((unsigned)v > (unsigned)m) {
111  v = -v;
112  if (v < 0)
113  v += 2 * m;
114  }
115  return v;
116 }
117 
118 static av_always_inline void lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
119  int dst_step, int src_step, int ref_step,
120  int width, int mul, int add, int shift,
121  int highpass, int inverse)
122 {
123  const int mirror_left = !highpass;
124  const int mirror_right = (width & 1) ^ highpass;
125  const int w = (width >> 1) - 1 + (highpass & width);
126  int i;
127 
128 #define LIFT(src, ref, inv) ((src) + ((inv) ? -(ref) : +(ref)))
129  if (mirror_left) {
130  dst[0] = LIFT(src[0], ((mul * 2 * ref[0] + add) >> shift), inverse);
131  dst += dst_step;
132  src += src_step;
133  }
134 
135  for (i = 0; i < w; i++)
136  dst[i * dst_step] = LIFT(src[i * src_step],
137  ((mul * (ref[i * ref_step] +
138  ref[(i + 1) * ref_step]) +
139  add) >> shift),
140  inverse);
141 
142  if (mirror_right)
143  dst[w * dst_step] = LIFT(src[w * src_step],
144  ((mul * 2 * ref[w * ref_step] + add) >> shift),
145  inverse);
146 }
147 
148 static av_always_inline void liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
149  int dst_step, int src_step, int ref_step,
150  int width, int mul, int add, int shift,
151  int highpass, int inverse)
152 {
153  const int mirror_left = !highpass;
154  const int mirror_right = (width & 1) ^ highpass;
155  const int w = (width >> 1) - 1 + (highpass & width);
156  int i;
157 
158  assert(shift == 4);
159 #define LIFTS(src, ref, inv) \
160  ((inv) ? (src) + (((ref) + 4 * (src)) >> shift) \
161  : -((-16 * (src) + (ref) + add / \
162  4 + 1 + (5 << 25)) / (5 * 4) - (1 << 23)))
163  if (mirror_left) {
164  dst[0] = LIFTS(src[0], mul * 2 * ref[0] + add, inverse);
165  dst += dst_step;
166  src += src_step;
167  }
168 
169  for (i = 0; i < w; i++)
170  dst[i * dst_step] = LIFTS(src[i * src_step],
171  mul * (ref[i * ref_step] +
172  ref[(i + 1) * ref_step]) + add,
173  inverse);
174 
175  if (mirror_right)
176  dst[w * dst_step] = LIFTS(src[w * src_step],
177  mul * 2 * ref[w * ref_step] + add,
178  inverse);
179 }
180 
181 static void horizontal_decompose53i(DWTELEM *b, DWTELEM *temp, int width)
182 {
183  const int width2 = width >> 1;
184  int x;
185  const int w2 = (width + 1) >> 1;
186 
187  for (x = 0; x < width2; x++) {
188  temp[x] = b[2 * x];
189  temp[x + w2] = b[2 * x + 1];
190  }
191  if (width & 1)
192  temp[x] = b[2 * x];
193  lift(b + w2, temp + w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 0);
194  lift(b, temp, b + w2, 1, 1, 1, width, 1, 2, 2, 0, 0);
195 }
196 
197 static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
198  int width)
199 {
200  int i;
201 
202  for (i = 0; i < width; i++)
203  b1[i] -= (b0[i] + b2[i]) >> 1;
204 }
205 
206 static void vertical_decompose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
207  int width)
208 {
209  int i;
210 
211  for (i = 0; i < width; i++)
212  b1[i] += (b0[i] + b2[i] + 2) >> 2;
213 }
214 
216  int width, int height, int stride)
217 {
218  int y;
219  DWTELEM *b0 = buffer + mirror(-2 - 1, height - 1) * stride;
220  DWTELEM *b1 = buffer + mirror(-2, height - 1) * stride;
221 
222  for (y = -2; y < height; y += 2) {
223  DWTELEM *b2 = buffer + mirror(y + 1, height - 1) * stride;
224  DWTELEM *b3 = buffer + mirror(y + 2, height - 1) * stride;
225 
226  if (y + 1 < (unsigned)height)
227  horizontal_decompose53i(b2, temp, width);
228  if (y + 2 < (unsigned)height)
229  horizontal_decompose53i(b3, temp, width);
230 
231  if (y + 1 < (unsigned)height)
232  vertical_decompose53iH0(b1, b2, b3, width);
233  if (y + 0 < (unsigned)height)
234  vertical_decompose53iL0(b0, b1, b2, width);
235 
236  b0 = b2;
237  b1 = b3;
238  }
239 }
240 
241 static void horizontal_decompose97i(DWTELEM *b, DWTELEM *temp, int width)
242 {
243  const int w2 = (width + 1) >> 1;
244 
245  lift(temp + w2, b + 1, b, 1, 2, 2, width, W_AM, W_AO, W_AS, 1, 1);
246  liftS(temp, b, temp + w2, 1, 2, 1, width, W_BM, W_BO, W_BS, 0, 0);
247  lift(b + w2, temp + w2, temp, 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 0);
248  lift(b, temp, b + w2, 1, 1, 1, width, W_DM, W_DO, W_DS, 0, 0);
249 }
250 
251 static void vertical_decompose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
252  int width)
253 {
254  int i;
255 
256  for (i = 0; i < width; i++)
257  b1[i] -= (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
258 }
259 
260 static void vertical_decompose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
261  int width)
262 {
263  int i;
264 
265  for (i = 0; i < width; i++)
266  b1[i] += (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS;
267 }
268 
269 static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
270  int width)
271 {
272  int i;
273 
274  for (i = 0; i < width; i++)
275  b1[i] = (16 * 4 * b1[i] - 4 * (b0[i] + b2[i]) + W_BO * 5 + (5 << 27)) /
276  (5 * 16) - (1 << 23);
277 }
278 
279 static void vertical_decompose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
280  int width)
281 {
282  int i;
283 
284  for (i = 0; i < width; i++)
285  b1[i] += (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS;
286 }
287 
289  int width, int height, int stride)
290 {
291  int y;
292  DWTELEM *b0 = buffer + mirror(-4 - 1, height - 1) * stride;
293  DWTELEM *b1 = buffer + mirror(-4, height - 1) * stride;
294  DWTELEM *b2 = buffer + mirror(-4 + 1, height - 1) * stride;
295  DWTELEM *b3 = buffer + mirror(-4 + 2, height - 1) * stride;
296 
297  for (y = -4; y < height; y += 2) {
298  DWTELEM *b4 = buffer + mirror(y + 3, height - 1) * stride;
299  DWTELEM *b5 = buffer + mirror(y + 4, height - 1) * stride;
300 
301  if (y + 3 < (unsigned)height)
302  horizontal_decompose97i(b4, temp, width);
303  if (y + 4 < (unsigned)height)
304  horizontal_decompose97i(b5, temp, width);
305 
306  if (y + 3 < (unsigned)height)
307  vertical_decompose97iH0(b3, b4, b5, width);
308  if (y + 2 < (unsigned)height)
309  vertical_decompose97iL0(b2, b3, b4, width);
310  if (y + 1 < (unsigned)height)
311  vertical_decompose97iH1(b1, b2, b3, width);
312  if (y + 0 < (unsigned)height)
313  vertical_decompose97iL1(b0, b1, b2, width);
314 
315  b0 = b2;
316  b1 = b3;
317  b2 = b4;
318  b3 = b5;
319  }
320 }
321 
323  int stride, int type, int decomposition_count)
324 {
325  int level;
326 
327  for (level = 0; level < decomposition_count; level++) {
328  switch (type) {
329  case DWT_97:
330  spatial_decompose97i(buffer, temp,
331  width >> level, height >> level,
332  stride << level);
333  break;
334  case DWT_53:
335  spatial_decompose53i(buffer, temp,
336  width >> level, height >> level,
337  stride << level);
338  break;
339  }
340  }
341 }
342 
343 static void horizontal_compose53i(IDWTELEM *b, IDWTELEM *temp, int width)
344 {
345  const int width2 = width >> 1;
346  const int w2 = (width + 1) >> 1;
347  int x;
348 
349  for (x = 0; x < width2; x++) {
350  temp[2 * x] = b[x];
351  temp[2 * x + 1] = b[x + w2];
352  }
353  if (width & 1)
354  temp[2 * x] = b[x];
355 
356  b[0] = temp[0] - ((temp[1] + 1) >> 1);
357  for (x = 2; x < width - 1; x += 2) {
358  b[x] = temp[x] - ((temp[x - 1] + temp[x + 1] + 2) >> 2);
359  b[x - 1] = temp[x - 1] + ((b[x - 2] + b[x] + 1) >> 1);
360  }
361  if (width & 1) {
362  b[x] = temp[x] - ((temp[x - 1] + 1) >> 1);
363  b[x - 1] = temp[x - 1] + ((b[x - 2] + b[x] + 1) >> 1);
364  } else
365  b[x - 1] = temp[x - 1] + b[x - 2];
366 }
367 
369  int width)
370 {
371  int i;
372 
373  for (i = 0; i < width; i++)
374  b1[i] += (b0[i] + b2[i]) >> 1;
375 }
376 
378  int width)
379 {
380  int i;
381 
382  for (i = 0; i < width; i++)
383  b1[i] -= (b0[i] + b2[i] + 2) >> 2;
384 }
385 
387  int height, int stride_line)
388 {
389  cs->b0 = slice_buffer_get_line(sb,
390  mirror(-1 - 1, height - 1) * stride_line);
391  cs->b1 = slice_buffer_get_line(sb, mirror(-1, height - 1) * stride_line);
392  cs->y = -1;
393 }
394 
396  int height, int stride)
397 {
398  cs->b0 = buffer + mirror(-1 - 1, height - 1) * stride;
399  cs->b1 = buffer + mirror(-1, height - 1) * stride;
400  cs->y = -1;
401 }
402 
404  IDWTELEM *temp,
405  int width, int height,
406  int stride_line)
407 {
408  int y = cs->y;
409 
410  IDWTELEM *b0 = cs->b0;
411  IDWTELEM *b1 = cs->b1;
413  mirror(y + 1, height - 1) *
414  stride_line);
416  mirror(y + 2, height - 1) *
417  stride_line);
418 
419  if (y + 1 < (unsigned)height && y < (unsigned)height) {
420  int x;
421 
422  for (x = 0; x < width; x++) {
423  b2[x] -= (b1[x] + b3[x] + 2) >> 2;
424  b1[x] += (b0[x] + b2[x]) >> 1;
425  }
426  } else {
427  if (y + 1 < (unsigned)height)
428  vertical_compose53iL0(b1, b2, b3, width);
429  if (y + 0 < (unsigned)height)
430  vertical_compose53iH0(b0, b1, b2, width);
431  }
432 
433  if (y - 1 < (unsigned)height)
434  horizontal_compose53i(b0, temp, width);
435  if (y + 0 < (unsigned)height)
436  horizontal_compose53i(b1, temp, width);
437 
438  cs->b0 = b2;
439  cs->b1 = b3;
440  cs->y += 2;
441 }
442 
444  IDWTELEM *temp, int width, int height,
445  int stride)
446 {
447  int y = cs->y;
448  IDWTELEM *b0 = cs->b0;
449  IDWTELEM *b1 = cs->b1;
450  IDWTELEM *b2 = buffer + mirror(y + 1, height - 1) * stride;
451  IDWTELEM *b3 = buffer + mirror(y + 2, height - 1) * stride;
452 
453  if (y + 1 < (unsigned)height)
454  vertical_compose53iL0(b1, b2, b3, width);
455  if (y + 0 < (unsigned)height)
456  vertical_compose53iH0(b0, b1, b2, width);
457 
458  if (y - 1 < (unsigned)height)
459  horizontal_compose53i(b0, temp, width);
460  if (y + 0 < (unsigned)height)
461  horizontal_compose53i(b1, temp, width);
462 
463  cs->b0 = b2;
464  cs->b1 = b3;
465  cs->y += 2;
466 }
467 
469 {
470  const int w2 = (width + 1) >> 1;
471  int x;
472 
473  temp[0] = b[0] - ((3 * b[w2] + 2) >> 2);
474  for (x = 1; x < (width >> 1); x++) {
475  temp[2 * x] = b[x] - ((3 * (b[x + w2 - 1] + b[x + w2]) + 4) >> 3);
476  temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x];
477  }
478  if (width & 1) {
479  temp[2 * x] = b[x] - ((3 * b[x + w2 - 1] + 2) >> 2);
480  temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x];
481  } else
482  temp[2 * x - 1] = b[x + w2 - 1] - 2 * temp[2 * x - 2];
483 
484  b[0] = temp[0] + ((2 * temp[0] + temp[1] + 4) >> 3);
485  for (x = 2; x < width - 1; x += 2) {
486  b[x] = temp[x] + ((4 * temp[x] + temp[x - 1] + temp[x + 1] + 8) >> 4);
487  b[x - 1] = temp[x - 1] + ((3 * (b[x - 2] + b[x])) >> 1);
488  }
489  if (width & 1) {
490  b[x] = temp[x] + ((2 * temp[x] + temp[x - 1] + 4) >> 3);
491  b[x - 1] = temp[x - 1] + ((3 * (b[x - 2] + b[x])) >> 1);
492  } else
493  b[x - 1] = temp[x - 1] + 3 * b[x - 2];
494 }
495 
497  int width)
498 {
499  int i;
500 
501  for (i = 0; i < width; i++)
502  b1[i] += (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
503 }
504 
506  int width)
507 {
508  int i;
509 
510  for (i = 0; i < width; i++)
511  b1[i] -= (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS;
512 }
513 
515  int width)
516 {
517  int i;
518 
519  for (i = 0; i < width; i++)
520  b1[i] += (W_BM * (b0[i] + b2[i]) + 4 * b1[i] + W_BO) >> W_BS;
521 }
522 
524  int width)
525 {
526  int i;
527 
528  for (i = 0; i < width; i++)
529  b1[i] -= (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS;
530 }
531 
533  IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
534  int width)
535 {
536  int i;
537 
538  for (i = 0; i < width; i++) {
539  b4[i] -= (W_DM * (b3[i] + b5[i]) + W_DO) >> W_DS;
540  b3[i] -= (W_CM * (b2[i] + b4[i]) + W_CO) >> W_CS;
541  b2[i] += (W_BM * (b1[i] + b3[i]) + 4 * b2[i] + W_BO) >> W_BS;
542  b1[i] += (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
543  }
544 }
545 
547  int height, int stride_line)
548 {
549  cs->b0 = slice_buffer_get_line(sb, mirror(-3 - 1, height - 1) * stride_line);
550  cs->b1 = slice_buffer_get_line(sb, mirror(-3, height - 1) * stride_line);
551  cs->b2 = slice_buffer_get_line(sb, mirror(-3 + 1, height - 1) * stride_line);
552  cs->b3 = slice_buffer_get_line(sb, mirror(-3 + 2, height - 1) * stride_line);
553  cs->y = -3;
554 }
555 
557  int stride)
558 {
559  cs->b0 = buffer + mirror(-3 - 1, height - 1) * stride;
560  cs->b1 = buffer + mirror(-3, height - 1) * stride;
561  cs->b2 = buffer + mirror(-3 + 1, height - 1) * stride;
562  cs->b3 = buffer + mirror(-3 + 2, height - 1) * stride;
563  cs->y = -3;
564 }
565 
567  slice_buffer * sb, IDWTELEM *temp,
568  int width, int height,
569  int stride_line)
570 {
571  int y = cs->y;
572 
573  IDWTELEM *b0 = cs->b0;
574  IDWTELEM *b1 = cs->b1;
575  IDWTELEM *b2 = cs->b2;
576  IDWTELEM *b3 = cs->b3;
578  mirror(y + 3, height - 1) *
579  stride_line);
581  mirror(y + 4, height - 1) *
582  stride_line);
583 
584  if (y > 0 && y + 4 < height) {
585  dsp->vertical_compose97i(b0, b1, b2, b3, b4, b5, width);
586  } else {
587  if (y + 3 < (unsigned)height)
588  vertical_compose97iL1(b3, b4, b5, width);
589  if (y + 2 < (unsigned)height)
590  vertical_compose97iH1(b2, b3, b4, width);
591  if (y + 1 < (unsigned)height)
592  vertical_compose97iL0(b1, b2, b3, width);
593  if (y + 0 < (unsigned)height)
594  vertical_compose97iH0(b0, b1, b2, width);
595  }
596 
597  if (y - 1 < (unsigned)height)
598  dsp->horizontal_compose97i(b0, temp, width);
599  if (y + 0 < (unsigned)height)
600  dsp->horizontal_compose97i(b1, temp, width);
601 
602  cs->b0 = b2;
603  cs->b1 = b3;
604  cs->b2 = b4;
605  cs->b3 = b5;
606  cs->y += 2;
607 }
608 
610  IDWTELEM *temp, int width, int height,
611  int stride)
612 {
613  int y = cs->y;
614  IDWTELEM *b0 = cs->b0;
615  IDWTELEM *b1 = cs->b1;
616  IDWTELEM *b2 = cs->b2;
617  IDWTELEM *b3 = cs->b3;
618  IDWTELEM *b4 = buffer + mirror(y + 3, height - 1) * stride;
619  IDWTELEM *b5 = buffer + mirror(y + 4, height - 1) * stride;
620 
621  if (y + 3 < (unsigned)height)
622  vertical_compose97iL1(b3, b4, b5, width);
623  if (y + 2 < (unsigned)height)
624  vertical_compose97iH1(b2, b3, b4, width);
625  if (y + 1 < (unsigned)height)
626  vertical_compose97iL0(b1, b2, b3, width);
627  if (y + 0 < (unsigned)height)
628  vertical_compose97iH0(b0, b1, b2, width);
629 
630  if (y - 1 < (unsigned)height)
631  ff_snow_horizontal_compose97i(b0, temp, width);
632  if (y + 0 < (unsigned)height)
633  ff_snow_horizontal_compose97i(b1, temp, width);
634 
635  cs->b0 = b2;
636  cs->b1 = b3;
637  cs->b2 = b4;
638  cs->b3 = b5;
639  cs->y += 2;
640 }
641 
643  int height, int stride_line, int type,
644  int decomposition_count)
645 {
646  int level;
647  for (level = decomposition_count - 1; level >= 0; level--) {
648  switch (type) {
649  case DWT_97:
650  spatial_compose97i_buffered_init(cs + level, sb, height >> level,
651  stride_line << level);
652  break;
653  case DWT_53:
654  spatial_compose53i_buffered_init(cs + level, sb, height >> level,
655  stride_line << level);
656  break;
657  }
658  }
659 }
660 
662  slice_buffer *slice_buf, IDWTELEM *temp,
663  int width, int height, int stride_line,
664  int type, int decomposition_count, int y)
665 {
666  const int support = type == 1 ? 3 : 5;
667  int level;
668  if (type == 2)
669  return;
670 
671  for (level = decomposition_count - 1; level >= 0; level--)
672  while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
673  switch (type) {
674  case DWT_97:
675  spatial_compose97i_dy_buffered(dsp, cs + level, slice_buf, temp,
676  width >> level,
677  height >> level,
678  stride_line << level);
679  break;
680  case DWT_53:
681  spatial_compose53i_dy_buffered(cs + level, slice_buf, temp,
682  width >> level,
683  height >> level,
684  stride_line << level);
685  break;
686  }
687  }
688 }
689 
691  int height, int stride, int type,
692  int decomposition_count)
693 {
694  int level;
695  for (level = decomposition_count - 1; level >= 0; level--) {
696  switch (type) {
697  case DWT_97:
698  spatial_compose97i_init(cs + level, buffer, height >> level,
699  stride << level);
700  break;
701  case DWT_53:
702  spatial_compose53i_init(cs + level, buffer, height >> level,
703  stride << level);
704  break;
705  }
706  }
707 }
708 
710  IDWTELEM *temp, int width, int height,
711  int stride, int type,
712  int decomposition_count, int y)
713 {
714  const int support = type == 1 ? 3 : 5;
715  int level;
716  if (type == 2)
717  return;
718 
719  for (level = decomposition_count - 1; level >= 0; level--)
720  while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
721  switch (type) {
722  case DWT_97:
723  spatial_compose97i_dy(cs + level, buffer, temp, width >> level,
724  height >> level, stride << level);
725  break;
726  case DWT_53:
727  spatial_compose53i_dy(cs + level, buffer, temp, width >> level,
728  height >> level, stride << level);
729  break;
730  }
731  }
732 }
733 
735  int stride, int type, int decomposition_count)
736 {
738  int y;
739  ff_spatial_idwt_init(cs, buffer, width, height, stride, type,
740  decomposition_count);
741  for (y = 0; y < height; y += 4)
742  ff_spatial_idwt_slice(cs, buffer, temp, width, height, stride, type,
743  decomposition_count, y);
744 }
745 
746 static inline int w_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size,
747  int w, int h, int type)
748 {
749  int s, i, j;
750  const int dec_count = w == 8 ? 3 : 4;
751  int tmp[32 * 32], tmp2[32];
752  int level, ori;
753  static const int scale[2][2][4][4] = {
754  {
755  { // 9/7 8x8 dec=3
756  { 268, 239, 239, 213 },
757  { 0, 224, 224, 152 },
758  { 0, 135, 135, 110 },
759  },
760  { // 9/7 16x16 or 32x32 dec=4
761  { 344, 310, 310, 280 },
762  { 0, 320, 320, 228 },
763  { 0, 175, 175, 136 },
764  { 0, 129, 129, 102 },
765  }
766  },
767  {
768  { // 5/3 8x8 dec=3
769  { 275, 245, 245, 218 },
770  { 0, 230, 230, 156 },
771  { 0, 138, 138, 113 },
772  },
773  { // 5/3 16x16 or 32x32 dec=4
774  { 352, 317, 317, 286 },
775  { 0, 328, 328, 233 },
776  { 0, 180, 180, 140 },
777  { 0, 132, 132, 105 },
778  }
779  }
780  };
781 
782  for (i = 0; i < h; i++) {
783  for (j = 0; j < w; j += 4) {
784  tmp[32 * i + j + 0] = (pix1[j + 0] - pix2[j + 0]) << 4;
785  tmp[32 * i + j + 1] = (pix1[j + 1] - pix2[j + 1]) << 4;
786  tmp[32 * i + j + 2] = (pix1[j + 2] - pix2[j + 2]) << 4;
787  tmp[32 * i + j + 3] = (pix1[j + 3] - pix2[j + 3]) << 4;
788  }
789  pix1 += line_size;
790  pix2 += line_size;
791  }
792 
793  ff_spatial_dwt(tmp, tmp2, w, h, 32, type, dec_count);
794 
795  s = 0;
796  assert(w == h);
797  for (level = 0; level < dec_count; level++)
798  for (ori = level ? 1 : 0; ori < 4; ori++) {
799  int size = w >> (dec_count - level);
800  int sx = (ori & 1) ? size : 0;
801  int stride = 32 << (dec_count - level);
802  int sy = (ori & 2) ? stride >> 1 : 0;
803 
804  for (i = 0; i < size; i++)
805  for (j = 0; j < size; j++) {
806  int v = tmp[sx + sy + i * stride + j] *
807  scale[type][dec_count - 3][level][ori];
808  s += FFABS(v);
809  }
810  }
811  assert(s >= 0);
812  return s >> 9;
813 }
814 
815 static int w53_8_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
816 {
817  return w_c(v, pix1, pix2, line_size, 8, h, 1);
818 }
819 
820 static int w97_8_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
821 {
822  return w_c(v, pix1, pix2, line_size, 8, h, 0);
823 }
824 
825 static int w53_16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
826 {
827  return w_c(v, pix1, pix2, line_size, 16, h, 1);
828 }
829 
830 static int w97_16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
831 {
832  return w_c(v, pix1, pix2, line_size, 16, h, 0);
833 }
834 
835 int ff_w53_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
836 {
837  return w_c(v, pix1, pix2, line_size, 32, h, 1);
838 }
839 
840 int ff_w97_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
841 {
842  return w_c(v, pix1, pix2, line_size, 32, h, 0);
843 }
844 
846 {
847  c->w53[0] = w53_16_c;
848  c->w53[1] = w53_8_c;
849  c->w97[0] = w97_16_c;
850  c->w97[1] = w97_8_c;
851 }
852 
854 {
858 
859  if (HAVE_MMX)
860  ff_dwt_init_x86(c);
861 }
#define slice_buffer_get_line(slice_buf, line_num)
Definition: dwt.h:83
#define LIFTS(src, ref, inv)
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:61
void ff_slice_buffer_release(slice_buffer *buf, int line)
Definition: dwt.c:76
int size
#define DWT_53
Definition: dwt.h:63
static void spatial_compose97i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
Definition: dwt.c:556
int data_stack_top
Definition: dwt.h:42
static void vertical_decompose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width)
Definition: dwt.c:279
int ff_slice_buffer_init(slice_buffer *buf, int line_count, int max_allocated_lines, int line_width, IDWTELEM *base_buffer)
Definition: dwt.c:26
void ff_dwt_init_x86(DWTContext *c)
Definition: snowdsp.c:878
static void spatial_compose97i_dy_buffered(DWTContext *dsp, DWTCompose *cs, slice_buffer *sb, IDWTELEM *temp, int width, int height, int stride_line)
Definition: dwt.c:566
static void spatial_compose53i_buffered_init(DWTCompose *cs, slice_buffer *sb, int height, int stride_line)
Definition: dwt.c:386
static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
Definition: dwt.c:377
int ff_w53_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
Definition: dwt.c:835
int ff_w97_32_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
Definition: dwt.c:840
int data_count
Definition: dwt.h:45
int stride
Definition: mace.c:144
static void vertical_compose97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
Definition: dwt.c:514
IDWTELEM ** line
For use by idwt and predict_slices.
Definition: dwt.h:40
void ff_dwt_init(DWTContext *c)
Definition: dwt.c:853
static int w53_8_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
Definition: dwt.c:815
#define HAVE_MMX
Definition: config.h:46
Macro definitions for various function/variable attributes.
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:151
#define W_CO
Definition: dwt.h:76
short IDWTELEM
Definition: dwt.h:27
static void horizontal_decompose97i(DWTELEM *b, DWTELEM *temp, int width)
Definition: dwt.c:241
static void spatial_decompose53i(DWTELEM *buffer, DWTELEM *temp, int width, int height, int stride)
Definition: dwt.c:215
uint8_t
#define W_AO
Definition: dwt.h:67
#define b
Definition: input.c:52
int line_width
Definition: dwt.h:44
IDWTELEM ** data_stack
Used for internal purposes.
Definition: dwt.h:41
#define MAX_DECOMPOSITIONS
Definition: dwt.h:60
static void ff_spatial_idwt_init(DWTCompose *cs, IDWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count)
Definition: dwt.c:690
static void spatial_decompose97i(DWTELEM *buffer, DWTELEM *temp, int width, int height, int stride)
Definition: dwt.c:288
static void ff_spatial_idwt_slice(DWTCompose *cs, IDWTELEM *buffer, IDWTELEM *temp, int width, int height, int stride, int type, int decomposition_count, int y)
Definition: dwt.c:709
static void horizontal_compose53i(IDWTELEM *b, IDWTELEM *temp, int width)
Definition: dwt.c:343
me_cmp_func w53[6]
Definition: dsputil.h:234
static int mirror(int v, int m)
Definition: dwt.c:108
Used to minimize the amount of memory used in order to optimize cache performance.
Definition: dwt.h:39
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:139
static int w_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int w, int h, int type)
Definition: dwt.c:746
int y
Definition: dwt.h:34
IDWTELEM * b0
Definition: dwt.h:30
Definition: graph2dot.c:48
static void vertical_compose97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
Definition: dwt.c:505
static void spatial_compose53i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
Definition: dwt.c:395
void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width)
Definition: dwt.c:532
void(* horizontal_compose97i)(IDWTELEM *b, IDWTELEM *temp, int width)
Definition: dwt.h:53
void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride, uint8_t **block, int b_w, int b_h, int src_x, int src_y, int src_stride, slice_buffer *sb, int add, uint8_t *dst8)
Definition: snow.c:39
#define W_CM
Definition: dwt.h:75
#define W_CS
Definition: dwt.h:77
IDWTELEM * b3
Definition: dwt.h:33
void(* inner_add_yblock)(const uint8_t *obmc, const int obmc_stride, uint8_t **block, int b_w, int b_h, int src_x, int src_y, int src_stride, slice_buffer *sb, int add, uint8_t *dst8)
Definition: dwt.h:54
#define W_DO
Definition: dwt.h:80
static void horizontal_decompose53i(DWTELEM *b, DWTELEM *temp, int width)
Definition: dwt.c:181
static void spatial_compose97i_buffered_init(DWTCompose *cs, slice_buffer *sb, int height, int stride_line)
Definition: dwt.c:546
void ff_slice_buffer_flush(slice_buffer *buf)
Definition: dwt.c:89
void ff_dsputil_init_dwt(DSPContext *c)
Definition: dwt.c:845
static char buffer[20]
Definition: seek-test.c:31
Definition: dwt.h:49
#define W_BM
Definition: dwt.h:71
#define W_AS
Definition: dwt.h:68
IDWTELEM * ff_slice_buffer_load_line(slice_buffer *buf, int line)
Definition: dwt.c:60
NULL
Definition: eval.c:52
static int width
Definition: utils.c:156
static void vertical_decompose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width)
Definition: dwt.c:260
static int w97_16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
Definition: dwt.c:830
void ff_slice_buffer_destroy(slice_buffer *buf)
Definition: dwt.c:97
#define W_BO
Definition: dwt.h:72
#define W_DS
Definition: dwt.h:81
void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer *sb, int width, int height, int stride_line, int type, int decomposition_count)
Definition: dwt.c:642
static void vertical_compose97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
Definition: dwt.c:523
static void vertical_compose53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
Definition: dwt.c:368
void ff_snow_horizontal_compose97i(IDWTELEM *b, IDWTELEM *temp, int width)
Definition: dwt.c:468
void(* vertical_compose97i)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width)
Definition: dwt.h:50
int DWTELEM
Definition: dwt.h:26
me_cmp_func w97[6]
Definition: dsputil.h:235
static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width)
Definition: dwt.c:269
static const uint16_t scale[4]
uint8_t level
Definition: svq3.c:133
IDWTELEM * b1
Definition: dwt.h:31
static void spatial_compose53i_dy_buffered(DWTCompose *cs, slice_buffer *sb, IDWTELEM *temp, int width, int height, int stride_line)
Definition: dwt.c:403
int height
Definition: gxfenc.c:72
#define W_DM
Definition: dwt.h:79
IDWTELEM * b2
Definition: dwt.h:32
common internal and external API header
static int w53_16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
Definition: dwt.c:825
static void spatial_compose53i_dy(DWTCompose *cs, IDWTELEM *buffer, IDWTELEM *temp, int width, int height, int stride)
Definition: dwt.c:443
void ff_spatial_dwt(DWTELEM *buffer, DWTELEM *temp, int width, int height, int stride, int type, int decomposition_count)
Definition: dwt.c:322
#define DWT_97
Definition: dwt.h:62
#define LIFT(src, ref, inv)
DSP utils.
void ff_spatial_idwt_buffered_slice(DWTContext *dsp, DWTCompose *cs, slice_buffer *slice_buf, IDWTELEM *temp, int width, int height, int stride_line, int type, int decomposition_count, int y)
Definition: dwt.c:661
static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width)
Definition: dwt.c:197
static void spatial_compose97i_dy(DWTCompose *cs, IDWTELEM *buffer, IDWTELEM *temp, int width, int height, int stride)
Definition: dwt.c:609
Definition: dwt.h:29
static av_always_inline void lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int dst_step, int src_step, int ref_step, int width, int mul, int add, int shift, int highpass, int inverse)
Definition: dwt.c:118
static int w97_8_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
Definition: dwt.c:820
int line_count
Definition: dwt.h:43
#define W_AM
Definition: dwt.h:66
IDWTELEM * base_buffer
Buffer that this structure is caching.
Definition: dwt.h:46
static av_always_inline void liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int dst_step, int src_step, int ref_step, int width, int mul, int add, int shift, int highpass, int inverse)
Definition: dwt.c:148
static void vertical_decompose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width)
Definition: dwt.c:206
static void vertical_decompose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2, int width)
Definition: dwt.c:251
static uint32_t inverse(uint32_t v)
find multiplicative inverse modulo 2 ^ 32
Definition: asfcrypt.c:35
#define W_BS
Definition: dwt.h:73
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:158
static void vertical_compose97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
Definition: dwt.c:496
DSPContext.
Definition: dsputil.h:194
void ff_spatial_idwt(IDWTELEM *buffer, IDWTELEM *temp, int width, int height, int stride, int type, int decomposition_count)
Definition: dwt.c:734