FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/snow_dwt.c
Date: 2026-10-13 05:06:32
Exec Total Coverage
Lines: 436 455 95.8%
Functions: 45 49 91.8%
Branches: 221 245 90.2%

Line Branch Exec Source
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 "libavutil/mem.h"
26 #include "me_cmp.h"
27 #include "snow_dwt.h"
28
29 495 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 495 buf->base_buffer = base_buffer;
36 495 buf->line_count = line_count;
37 495 buf->line_width = line_width;
38 495 buf->data_count = max_allocated_lines;
39 495 buf->line = av_calloc(line_count, sizeof(*buf->line));
40
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 495 times.
495 if (!buf->line)
41 ✗ return AVERROR(ENOMEM);
42 495 buf->data_stack = av_malloc_array(max_allocated_lines, sizeof(IDWTELEM *));
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 495 times.
495 if (!buf->data_stack) {
44 ✗ av_freep(&buf->line);
45 ✗ return AVERROR(ENOMEM);
46 }
47
48
2/2
✓ Branch 0 taken 34408 times.
✓ Branch 1 taken 495 times.
34903 for (i = 0; i < max_allocated_lines; i++) {
49 34408 buf->data_stack[i] = av_malloc_array(line_width, sizeof(IDWTELEM));
50
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34408 times.
34408 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 495 buf->data_stack_top = max_allocated_lines - 1;
60 495 return 0;
61 }
62
63 138772 IDWTELEM *ff_slice_buffer_load_line(slice_buffer *buf, int line)
64 {
65 IDWTELEM *buffer;
66
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 138772 times.
138772 av_assert0(buf->data_stack_top >= 0);
68 // av_assert1(!buf->line[line]);
69
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 138772 times.
138772 if (buf->line[line])
70 ✗ return buf->line[line];
71
72 138772 buffer = buf->data_stack[buf->data_stack_top];
73 138772 buf->data_stack_top--;
74 138772 buf->line[line] = buffer;
75
76 138772 return buffer;
77 }
78
79 138772 void ff_slice_buffer_release(slice_buffer *buf, int line)
80 {
81 IDWTELEM *buffer;
82
83 av_assert1(line >= 0 && line < buf->line_count);
84 av_assert1(buf->line[line]);
85
86 138772 buffer = buf->line[line];
87 138772 buf->data_stack_top++;
88 138772 buf->data_stack[buf->data_stack_top] = buffer;
89 138772 buf->line[line] = NULL;
90 138772 }
91
92 2002 void ff_slice_buffer_flush(slice_buffer *buf)
93 {
94 int i;
95
96
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 1980 times.
2002 if (!buf->line)
97 22 return;
98
99
2/2
✓ Branch 0 taken 275584 times.
✓ Branch 1 taken 1980 times.
277564 for (i = 0; i < buf->line_count; i++)
100
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 274604 times.
275584 if (buf->line[i])
101 980 ff_slice_buffer_release(buf, i);
102 }
103
104 517 void ff_slice_buffer_destroy(slice_buffer *buf)
105 {
106 int i;
107 517 ff_slice_buffer_flush(buf);
108
109
2/2
✓ Branch 0 taken 495 times.
✓ Branch 1 taken 22 times.
517 if (buf->data_stack)
110
2/2
✓ Branch 0 taken 34408 times.
✓ Branch 1 taken 495 times.
34903 for (i = buf->data_count - 1; i >= 0; i--)
111 34408 av_freep(&buf->data_stack[i]);
112 517 av_freep(&buf->data_stack);
113 517 av_freep(&buf->line);
114 517 }
115
116 71100719 static av_always_inline void lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
117 int dst_step, int src_step, int ref_step,
118 int width, int mul, int add, int shift,
119 int highpass, int inverse)
120 {
121 71100719 const int mirror_left = !highpass;
122 71100719 const int mirror_right = (width & 1) ^ highpass;
123 71100719 const int w = (width >> 1) - 1 + (highpass & width);
124 int i;
125
126 #define LIFT(src, ref, inv) ((src) + ((inv) ? -(ref) : +(ref)))
127
2/2
✓ Branch 0 taken 23759364 times.
✓ Branch 1 taken 47341355 times.
71100719 if (mirror_left) {
128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23759364 times.
23759364 dst[0] = LIFT(src[0], ((mul * 2 * ref[0] + add) >> shift), inverse);
129 23759364 dst += dst_step;
130 23759364 src += src_step;
131 }
132
133
2/2
✓ Branch 0 taken 681168125 times.
✓ Branch 1 taken 71100719 times.
752268844 for (i = 0; i < w; i++)
134
2/2
✓ Branch 0 taken 216730771 times.
✓ Branch 1 taken 464437354 times.
681168125 dst[i * dst_step] = LIFT(src[i * src_step],
135 ((mul * (ref[i * ref_step] +
136 ref[(i + 1) * ref_step]) +
137 add) >> shift),
138 inverse);
139
140
2/2
✓ Branch 0 taken 47340760 times.
✓ Branch 1 taken 23759959 times.
71100719 if (mirror_right)
141
2/2
✓ Branch 0 taken 23581396 times.
✓ Branch 1 taken 23759364 times.
47340760 dst[w * dst_step] = LIFT(src[w * src_step],
142 ((mul * 2 * ref[w * ref_step] + add) >> shift),
143 inverse);
144 71100719 }
145
146 23581991 static av_always_inline void liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
147 int dst_step, int src_step, int ref_step,
148 int width, int mul, int add, int shift,
149 int highpass, int inverse)
150 {
151 23581991 const int mirror_left = !highpass;
152 23581991 const int mirror_right = (width & 1) ^ highpass;
153 23581991 const int w = (width >> 1) - 1 + (highpass & width);
154 int i;
155
156 av_assert1(shift == 4);
157 #define LIFTS(src, ref, inv) \
158 ((inv) ? (src) + (((ref) + 4 * (src)) >> shift) \
159 : -((-16 * (src) + (ref) + add / \
160 4 + 1 + (5 << 25)) / (5 * 4) - (1 << 23)))
161
1/2
✓ Branch 0 taken 23581991 times.
✗ Branch 1 not taken.
23581991 if (mirror_left) {
162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23581991 times.
23581991 dst[0] = LIFTS(src[0], mul * 2 * ref[0] + add, inverse);
163 23581991 dst += dst_step;
164 23581991 src += src_step;
165 }
166
167
2/2
✓ Branch 0 taken 216730176 times.
✓ Branch 1 taken 23581991 times.
240312167 for (i = 0; i < w; i++)
168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216730176 times.
216730176 dst[i * dst_step] = LIFTS(src[i * src_step],
169 mul * (ref[i * ref_step] +
170 ref[(i + 1) * ref_step]) + add,
171 inverse);
172
173
2/2
✓ Branch 0 taken 595 times.
✓ Branch 1 taken 23581396 times.
23581991 if (mirror_right)
174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 595 times.
595 dst[w * dst_step] = LIFTS(src[w * src_step],
175 mul * 2 * ref[w * ref_step] + add,
176 inverse);
177 23581991 }
178
179 177373 static void horizontal_decompose53i(DWTELEM *b, DWTELEM *temp, int width)
180 {
181 177373 const int width2 = width >> 1;
182 int x;
183 177373 const int w2 = (width + 1) >> 1;
184
185
2/2
✓ Branch 0 taken 15663929 times.
✓ Branch 1 taken 177373 times.
15841302 for (x = 0; x < width2; x++) {
186 15663929 temp[x] = b[2 * x];
187 15663929 temp[x + w2] = b[2 * x + 1];
188 }
189
2/2
✓ Branch 0 taken 3295 times.
✓ Branch 1 taken 174078 times.
177373 if (width & 1)
190 3295 temp[x] = b[2 * x];
191 177373 lift(b + w2, temp + w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 0);
192 177373 lift(b, temp, b + w2, 1, 1, 1, width, 1, 2, 2, 0, 0);
193 177373 }
194
195 88511 static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
196 int width)
197 {
198 int i;
199
200
2/2
✓ Branch 0 taken 15663646 times.
✓ Branch 1 taken 88511 times.
15752157 for (i = 0; i < width; i++)
201 15663646 b1[i] -= (b0[i] + b2[i]) >> 1;
202 88511 }
203
204 88862 static void vertical_decompose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
205 int width)
206 {
207 int i;
208
209
2/2
✓ Branch 0 taken 15667507 times.
✓ Branch 1 taken 88862 times.
15756369 for (i = 0; i < width; i++)
210 15667507 b1[i] += (b0[i] + b2[i] + 2) >> 2;
211 88862 }
212
213 2511 static void spatial_decompose53i(DWTELEM *buffer, DWTELEM *temp,
214 int width, int height, int stride)
215 {
216 int y;
217 2511 DWTELEM *b0 = buffer + avpriv_mirror(-2 - 1, height - 1) * stride;
218 2511 DWTELEM *b1 = buffer + avpriv_mirror(-2, height - 1) * stride;
219
220
2/2
✓ Branch 0 taken 91373 times.
✓ Branch 1 taken 2511 times.
93884 for (y = -2; y < height; y += 2) {
221 91373 DWTELEM *b2 = buffer + avpriv_mirror(y + 1, height - 1) * stride;
222 91373 DWTELEM *b3 = buffer + avpriv_mirror(y + 2, height - 1) * stride;
223
224
2/2
✓ Branch 0 taken 88511 times.
✓ Branch 1 taken 2862 times.
91373 if (y + 1 < (unsigned)height)
225 88511 horizontal_decompose53i(b2, temp, width);
226
2/2
✓ Branch 0 taken 88862 times.
✓ Branch 1 taken 2511 times.
91373 if (y + 2 < (unsigned)height)
227 88862 horizontal_decompose53i(b3, temp, width);
228
229
2/2
✓ Branch 0 taken 88511 times.
✓ Branch 1 taken 2862 times.
91373 if (y + 1 < (unsigned)height)
230 88511 vertical_decompose53iH0(b1, b2, b3, width);
231
2/2
✓ Branch 0 taken 88862 times.
✓ Branch 1 taken 2511 times.
91373 if (y + 0 < (unsigned)height)
232 88862 vertical_decompose53iL0(b0, b1, b2, width);
233
234 91373 b0 = b2;
235 91373 b1 = b3;
236 }
237 2511 }
238
239 23581991 static void horizontal_decompose97i(DWTELEM *b, DWTELEM *temp, int width)
240 {
241 23581991 const int w2 = (width + 1) >> 1;
242
243 23581991 lift(temp + w2, b + 1, b, 1, 2, 2, width, W_AM, W_AO, W_AS, 1, 1);
244 23581991 liftS(temp, b, temp + w2, 1, 2, 1, width, W_BM, W_BO, W_BS, 0, 0);
245 23581991 lift(b + w2, temp + w2, temp, 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 0);
246 23581991 lift(b, temp, b + w2, 1, 1, 1, width, W_DM, W_DO, W_DS, 0, 0);
247 23581991 }
248
249 11790970 static void vertical_decompose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
250 int width)
251 {
252 int i;
253
254
2/2
✓ Branch 0 taken 240312184 times.
✓ Branch 1 taken 11790970 times.
252103154 for (i = 0; i < width; i++)
255 240312184 b1[i] -= (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
256 11790970 }
257
258 11790970 static void vertical_decompose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
259 int width)
260 {
261 int i;
262
263
2/2
✓ Branch 0 taken 240312184 times.
✓ Branch 1 taken 11790970 times.
252103154 for (i = 0; i < width; i++)
264 240312184 b1[i] += (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS;
265 11790970 }
266
267 11791021 static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
268 int width)
269 {
270 int i;
271
272
2/2
✓ Branch 0 taken 240312745 times.
✓ Branch 1 taken 11791021 times.
252103766 for (i = 0; i < width; i++)
273 240312745 b1[i] = (16 * 4 * b1[i] - 4 * (b0[i] + b2[i]) + W_BO * 5 + (5 << 27)) /
274 240312745 (5 * 16) - (1 << 23);
275 11791021 }
276
277 11791021 static void vertical_decompose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
278 int width)
279 {
280 int i;
281
282
2/2
✓ Branch 0 taken 240312745 times.
✓ Branch 1 taken 11791021 times.
252103766 for (i = 0; i < width; i++)
283 240312745 b1[i] += (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS;
284 11791021 }
285
286 1911960 static void spatial_decompose97i(DWTELEM *buffer, DWTELEM *temp,
287 int width, int height, int stride)
288 {
289 int y;
290 1911960 DWTELEM *b0 = buffer + avpriv_mirror(-4 - 1, height - 1) * stride;
291 1911960 DWTELEM *b1 = buffer + avpriv_mirror(-4, height - 1) * stride;
292 1911960 DWTELEM *b2 = buffer + avpriv_mirror(-4 + 1, height - 1) * stride;
293 1911960 DWTELEM *b3 = buffer + avpriv_mirror(-4 + 2, height - 1) * stride;
294
295
2/2
✓ Branch 0 taken 15614941 times.
✓ Branch 1 taken 1911960 times.
17526901 for (y = -4; y < height; y += 2) {
296 15614941 DWTELEM *b4 = buffer + avpriv_mirror(y + 3, height - 1) * stride;
297 15614941 DWTELEM *b5 = buffer + avpriv_mirror(y + 4, height - 1) * stride;
298
299
2/2
✓ Branch 0 taken 11790970 times.
✓ Branch 1 taken 3823971 times.
15614941 if (y + 3 < (unsigned)height)
300 11790970 horizontal_decompose97i(b4, temp, width);
301
2/2
✓ Branch 0 taken 11791021 times.
✓ Branch 1 taken 3823920 times.
15614941 if (y + 4 < (unsigned)height)
302 11791021 horizontal_decompose97i(b5, temp, width);
303
304
2/2
✓ Branch 0 taken 11790970 times.
✓ Branch 1 taken 3823971 times.
15614941 if (y + 3 < (unsigned)height)
305 11790970 vertical_decompose97iH0(b3, b4, b5, width);
306
2/2
✓ Branch 0 taken 11791021 times.
✓ Branch 1 taken 3823920 times.
15614941 if (y + 2 < (unsigned)height)
307 11791021 vertical_decompose97iL0(b2, b3, b4, width);
308
2/2
✓ Branch 0 taken 11790970 times.
✓ Branch 1 taken 3823971 times.
15614941 if (y + 1 < (unsigned)height)
309 11790970 vertical_decompose97iH1(b1, b2, b3, width);
310
2/2
✓ Branch 0 taken 11791021 times.
✓ Branch 1 taken 3823920 times.
15614941 if (y + 0 < (unsigned)height)
311 11791021 vertical_decompose97iL1(b0, b1, b2, width);
312
313 15614941 b0 = b2;
314 15614941 b1 = b3;
315 15614941 b2 = b4;
316 15614941 b3 = b5;
317 }
318 1911960 }
319
320 478254 void ff_spatial_dwt(DWTELEM *buffer, DWTELEM *temp, int width, int height,
321 int stride, int type, int decomposition_count)
322 {
323 int level;
324
325
2/2
✓ Branch 0 taken 1914471 times.
✓ Branch 1 taken 478254 times.
2392725 for (level = 0; level < decomposition_count; level++) {
326
2/3
✓ Branch 0 taken 1911960 times.
✓ Branch 1 taken 2511 times.
✗ Branch 2 not taken.
1914471 switch (type) {
327 1911960 case DWT_97:
328 1911960 spatial_decompose97i(buffer, temp,
329 width >> level, height >> level,
330 stride << level);
331 1911960 break;
332 2511 case DWT_53:
333 2511 spatial_decompose53i(buffer, temp,
334 width >> level, height >> level,
335 stride << level);
336 2511 break;
337 }
338 }
339 478254 }
340
341 421186 static void horizontal_compose53i(IDWTELEM *b, IDWTELEM *temp, int width)
342 {
343 421186 const int width2 = width >> 1;
344 421186 const int w2 = (width + 1) >> 1;
345 int x;
346
347
2/2
✓ Branch 0 taken 36954866 times.
✓ Branch 1 taken 421186 times.
37376052 for (x = 0; x < width2; x++) {
348 36954866 temp[2 * x] = b[x];
349 36954866 temp[2 * x + 1] = b[x + w2];
350 }
351
2/2
✓ Branch 0 taken 8086 times.
✓ Branch 1 taken 413100 times.
421186 if (width & 1)
352 8086 temp[2 * x] = b[x];
353
354 421186 b[0] = temp[0] - ((temp[1] + 1) >> 1);
355
2/2
✓ Branch 0 taken 36533680 times.
✓ Branch 1 taken 421186 times.
36954866 for (x = 2; x < width - 1; x += 2) {
356 36533680 b[x] = temp[x] - ((temp[x - 1] + temp[x + 1] + 2) >> 2);
357 36533680 b[x - 1] = temp[x - 1] + ((b[x - 2] + b[x] + 1) >> 1);
358 }
359
2/2
✓ Branch 0 taken 8086 times.
✓ Branch 1 taken 413100 times.
421186 if (width & 1) {
360 8086 b[x] = temp[x] - ((temp[x - 1] + 1) >> 1);
361 8086 b[x - 1] = temp[x - 1] + ((b[x - 2] + b[x] + 1) >> 1);
362 } else
363 413100 b[x - 1] = temp[x - 1] + b[x - 2];
364 421186 }
365
366 121885 static void vertical_compose53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
367 int width)
368 {
369 int i;
370
371
2/2
✓ Branch 0 taken 21146866 times.
✓ Branch 1 taken 121885 times.
21268751 for (i = 0; i < width; i++)
372 21146866 b1[i] += (b0[i] + b2[i]) >> 1;
373 121885 }
374
375 122739 static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
376 int width)
377 {
378 int i;
379
380
2/2
✓ Branch 0 taken 21156260 times.
✓ Branch 1 taken 122739 times.
21278999 for (i = 0; i < width; i++)
381 21156260 b1[i] -= (b0[i] + b2[i] + 2) >> 2;
382 122739 }
383
384 2565 static void spatial_compose53i_buffered_init(DWTCompose *cs, slice_buffer *sb,
385 int height, int stride_line)
386 {
387
2/2
✓ Branch 0 taken 2052 times.
✓ Branch 1 taken 513 times.
2565 cs->b0 = slice_buffer_get_line(sb,
388 avpriv_mirror(-1 - 1, height - 1) * stride_line);
389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2565 times.
2565 cs->b1 = slice_buffer_get_line(sb, avpriv_mirror(-1, height - 1) * stride_line);
390 2565 cs->y = -1;
391 2565 }
392
393 3471 static void spatial_compose53i_init(DWTCompose *cs, IDWTELEM *buffer,
394 int height, int stride)
395 {
396 3471 cs->b0 = buffer + avpriv_mirror(-1 - 1, height - 1) * stride;
397 3471 cs->b1 = buffer + avpriv_mirror(-1, height - 1) * stride;
398 3471 cs->y = -1;
399 3471 }
400
401 93411 static void spatial_compose53i_dy_buffered(DWTCompose *cs, slice_buffer *sb,
402 IDWTELEM *temp,
403 int width, int height,
404 int stride_line)
405 {
406 93411 int y = cs->y;
407
408 93411 IDWTELEM *b0 = cs->b0;
409 93411 IDWTELEM *b1 = cs->b1;
410
1/2
✓ Branch 0 taken 93411 times.
✗ Branch 1 not taken.
93411 IDWTELEM *b2 = slice_buffer_get_line(sb,
411 avpriv_mirror(y + 1, height - 1) *
412 stride_line);
413
2/2
✓ Branch 0 taken 93052 times.
✓ Branch 1 taken 359 times.
93411 IDWTELEM *b3 = slice_buffer_get_line(sb,
414 avpriv_mirror(y + 2, height - 1) *
415 stride_line);
416
417
4/4
✓ Branch 0 taken 90846 times.
✓ Branch 1 taken 2565 times.
✓ Branch 2 taken 88281 times.
✓ Branch 3 taken 2565 times.
181692 if (y + 1 < (unsigned)height && y < (unsigned)height) {
418 int x;
419
420
2/2
✓ Branch 0 taken 15807346 times.
✓ Branch 1 taken 88281 times.
15895627 for (x = 0; x < width; x++) {
421 15807346 b2[x] -= (b1[x] + b3[x] + 2) >> 2;
422 15807346 b1[x] += (b0[x] + b2[x]) >> 1;
423 }
424 } else {
425
2/2
✓ Branch 0 taken 2565 times.
✓ Branch 1 taken 2565 times.
5130 if (y + 1 < (unsigned)height)
426 2565 vertical_compose53iL0(b1, b2, b3, width);
427
2/2
✓ Branch 0 taken 2206 times.
✓ Branch 1 taken 2924 times.
5130 if (y + 0 < (unsigned)height)
428 2206 vertical_compose53iH0(b0, b1, b2, width);
429 }
430
431
2/2
✓ Branch 0 taken 90846 times.
✓ Branch 1 taken 2565 times.
93411 if (y - 1 < (unsigned)height)
432 90846 horizontal_compose53i(b0, temp, width);
433
2/2
✓ Branch 0 taken 90487 times.
✓ Branch 1 taken 2924 times.
93411 if (y + 0 < (unsigned)height)
434 90487 horizontal_compose53i(b1, temp, width);
435
436 93411 cs->b0 = b2;
437 93411 cs->b1 = b3;
438 93411 cs->y += 2;
439 93411 }
440
441 123645 static void spatial_compose53i_dy(DWTCompose *cs, IDWTELEM *buffer,
442 IDWTELEM *temp, int width, int height,
443 int stride)
444 {
445 123645 int y = cs->y;
446 123645 IDWTELEM *b0 = cs->b0;
447 123645 IDWTELEM *b1 = cs->b1;
448 123645 IDWTELEM *b2 = buffer + avpriv_mirror(y + 1, height - 1) * stride;
449 123645 IDWTELEM *b3 = buffer + avpriv_mirror(y + 2, height - 1) * stride;
450
451
2/2
✓ Branch 0 taken 120174 times.
✓ Branch 1 taken 3471 times.
123645 if (y + 1 < (unsigned)height)
452 120174 vertical_compose53iL0(b1, b2, b3, width);
453
2/2
✓ Branch 0 taken 119679 times.
✓ Branch 1 taken 3966 times.
123645 if (y + 0 < (unsigned)height)
454 119679 vertical_compose53iH0(b0, b1, b2, width);
455
456
2/2
✓ Branch 0 taken 120174 times.
✓ Branch 1 taken 3471 times.
123645 if (y - 1 < (unsigned)height)
457 120174 horizontal_compose53i(b0, temp, width);
458
2/2
✓ Branch 0 taken 119679 times.
✓ Branch 1 taken 3966 times.
123645 if (y + 0 < (unsigned)height)
459 119679 horizontal_compose53i(b1, temp, width);
460
461 123645 cs->b0 = b2;
462 123645 cs->b1 = b3;
463 123645 cs->y += 2;
464 123645 }
465
466 269917 static void snow_horizontal_compose97i(IDWTELEM *b, IDWTELEM *temp, int width)
467 {
468 269917 const int w2 = (width + 1) >> 1;
469 int x;
470
471 269917 temp[0] = b[0] - ((3 * b[w2] + 2) >> 2);
472
2/2
✓ Branch 0 taken 20043092 times.
✓ Branch 1 taken 269917 times.
20313009 for (x = 1; x < (width >> 1); x++) {
473 20043092 temp[2 * x] = b[x] - ((3 * (b[x + w2 - 1] + b[x + w2]) + 4) >> 3);
474 20043092 temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x];
475 }
476
2/2
✓ Branch 0 taken 5283 times.
✓ Branch 1 taken 264634 times.
269917 if (width & 1) {
477 5283 temp[2 * x] = b[x] - ((3 * b[x + w2 - 1] + 2) >> 2);
478 5283 temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x];
479 } else
480 264634 temp[2 * x - 1] = b[x + w2 - 1] - 2 * temp[2 * x - 2];
481
482 269917 b[0] = temp[0] + ((2 * temp[0] + temp[1] + 4) >> 3);
483
2/2
✓ Branch 0 taken 20043092 times.
✓ Branch 1 taken 269917 times.
20313009 for (x = 2; x < width - 1; x += 2) {
484 20043092 b[x] = temp[x] + ((4 * temp[x] + temp[x - 1] + temp[x + 1] + 8) >> 4);
485 20043092 b[x - 1] = temp[x - 1] + ((3 * (b[x - 2] + b[x])) >> 1);
486 }
487
2/2
✓ Branch 0 taken 5283 times.
✓ Branch 1 taken 264634 times.
269917 if (width & 1) {
488 5283 b[x] = temp[x] + ((2 * temp[x] + temp[x - 1] + 4) >> 3);
489 5283 b[x - 1] = temp[x - 1] + ((3 * (b[x - 2] + b[x])) >> 1);
490 } else
491 264634 b[x - 1] = temp[x - 1] + 3 * b[x - 2];
492 269917 }
493
494 106071 static void vertical_compose97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
495 int width)
496 {
497 int i;
498
499
2/2
✓ Branch 0 taken 18136044 times.
✓ Branch 1 taken 106071 times.
18242115 for (i = 0; i < width; i++)
500 18136044 b1[i] += (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
501 106071 }
502
503 106071 static void vertical_compose97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
504 int width)
505 {
506 int i;
507
508
2/2
✓ Branch 0 taken 18136044 times.
✓ Branch 1 taken 106071 times.
18242115 for (i = 0; i < width; i++)
509 18136044 b1[i] -= (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS;
510 106071 }
511
512 106221 static void vertical_compose97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
513 int width)
514 {
515 int i;
516
517
2/2
✓ Branch 0 taken 18137694 times.
✓ Branch 1 taken 106221 times.
18243915 for (i = 0; i < width; i++)
518 18137694 b1[i] += (W_BM * (b0[i] + b2[i]) + 4 * b1[i] + W_BO) >> W_BS;
519 106221 }
520
521 106221 static void vertical_compose97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
522 int width)
523 {
524 int i;
525
526
2/2
✓ Branch 0 taken 18137694 times.
✓ Branch 1 taken 106221 times.
18243915 for (i = 0; i < width; i++)
527 18137694 b1[i] -= (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS;
528 106221 }
529
530 29376 static void snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
531 IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5,
532 int width)
533 {
534 int i;
535
536
2/2
✓ Branch 0 taken 2203200 times.
✓ Branch 1 taken 29376 times.
2232576 for (i = 0; i < width; i++) {
537 2203200 b4[i] -= (W_DM * (b3[i] + b5[i]) + W_DO) >> W_DS;
538 2203200 b3[i] -= (W_CM * (b2[i] + b4[i]) + W_CO) >> W_CS;
539 2203200 b2[i] += (W_BM * (b1[i] + b3[i]) + 4 * b2[i] + W_BO) >> W_BS;
540 2203200 b1[i] += (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
541 }
542 29376 }
543
544 4860 static void spatial_compose97i_buffered_init(DWTCompose *cs, slice_buffer *sb,
545 int height, int stride_line)
546 {
547
2/2
✓ Branch 0 taken 3888 times.
✓ Branch 1 taken 972 times.
4860 cs->b0 = slice_buffer_get_line(sb, avpriv_mirror(-3 - 1, height - 1) * stride_line);
548
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4860 times.
4860 cs->b1 = slice_buffer_get_line(sb, avpriv_mirror(-3, height - 1) * stride_line);
549
2/2
✓ Branch 0 taken 4843 times.
✓ Branch 1 taken 17 times.
4860 cs->b2 = slice_buffer_get_line(sb, avpriv_mirror(-3 + 1, height - 1) * stride_line);
550
2/2
✓ Branch 0 taken 614 times.
✓ Branch 1 taken 4246 times.
4860 cs->b3 = slice_buffer_get_line(sb, avpriv_mirror(-3 + 2, height - 1) * stride_line);
551 4860 cs->y = -3;
552 4860 }
553
554 7005 static void spatial_compose97i_init(DWTCompose *cs, IDWTELEM *buffer, int height,
555 int stride)
556 {
557 7005 cs->b0 = buffer + avpriv_mirror(-3 - 1, height - 1) * stride;
558 7005 cs->b1 = buffer + avpriv_mirror(-3, height - 1) * stride;
559 7005 cs->b2 = buffer + avpriv_mirror(-3 + 1, height - 1) * stride;
560 7005 cs->b3 = buffer + avpriv_mirror(-3 + 2, height - 1) * stride;
561 7005 cs->y = -3;
562 7005 }
563
564 52548 static void spatial_compose97i_dy_buffered(SnowDWTContext *dsp, DWTCompose *cs,
565 slice_buffer * sb, IDWTELEM *temp,
566 int width, int height,
567 int stride_line)
568 {
569 52548 int y = cs->y;
570
571 52548 IDWTELEM *b0 = cs->b0;
572 52548 IDWTELEM *b1 = cs->b1;
573 52548 IDWTELEM *b2 = cs->b2;
574 52548 IDWTELEM *b3 = cs->b3;
575
1/2
✓ Branch 0 taken 52548 times.
✗ Branch 1 not taken.
52548 IDWTELEM *b4 = slice_buffer_get_line(sb,
576 avpriv_mirror(y + 3, height - 1) *
577 stride_line);
578
2/2
✓ Branch 0 taken 51927 times.
✓ Branch 1 taken 621 times.
52548 IDWTELEM *b5 = slice_buffer_get_line(sb,
579 avpriv_mirror(y + 4, height - 1) *
580 stride_line);
581
582
4/4
✓ Branch 0 taken 42828 times.
✓ Branch 1 taken 9720 times.
✓ Branch 2 taken 33671 times.
✓ Branch 3 taken 9157 times.
52548 if (y > 0 && y + 4 < height) {
583 33671 dsp->vertical_compose97i(b0, b1, b2, b3, b4, b5, width);
584 } else {
585
2/2
✓ Branch 0 taken 9157 times.
✓ Branch 1 taken 9720 times.
18877 if (y + 3 < (unsigned)height)
586 9157 vertical_compose97iL1(b3, b4, b5, width);
587
2/2
✓ Branch 0 taken 9106 times.
✓ Branch 1 taken 9771 times.
18877 if (y + 2 < (unsigned)height)
588 9106 vertical_compose97iH1(b2, b3, b4, width);
589
2/2
✓ Branch 0 taken 9157 times.
✓ Branch 1 taken 9720 times.
18877 if (y + 1 < (unsigned)height)
590 9157 vertical_compose97iL0(b1, b2, b3, width);
591
2/2
✓ Branch 0 taken 9106 times.
✓ Branch 1 taken 9771 times.
18877 if (y + 0 < (unsigned)height)
592 9106 vertical_compose97iH0(b0, b1, b2, width);
593 }
594
595
2/2
✓ Branch 0 taken 42828 times.
✓ Branch 1 taken 9720 times.
52548 if (y - 1 < (unsigned)height)
596 42828 dsp->horizontal_compose97i(b0, temp, width);
597
2/2
✓ Branch 0 taken 42777 times.
✓ Branch 1 taken 9771 times.
52548 if (y + 0 < (unsigned)height)
598 42777 dsp->horizontal_compose97i(b1, temp, width);
599
600 52548 cs->b0 = b2;
601 52548 cs->b1 = b3;
602 52548 cs->b2 = b4;
603 52548 cs->b3 = b5;
604 52548 cs->y += 2;
605 52548 }
606
607 111074 static void spatial_compose97i_dy(DWTCompose *cs, IDWTELEM *buffer,
608 IDWTELEM *temp, int width, int height,
609 int stride)
610 {
611 111074 int y = cs->y;
612 111074 IDWTELEM *b0 = cs->b0;
613 111074 IDWTELEM *b1 = cs->b1;
614 111074 IDWTELEM *b2 = cs->b2;
615 111074 IDWTELEM *b3 = cs->b3;
616 111074 IDWTELEM *b4 = buffer + avpriv_mirror(y + 3, height - 1) * stride;
617 111074 IDWTELEM *b5 = buffer + avpriv_mirror(y + 4, height - 1) * stride;
618
619
2/2
✓ Branch 0 taken 97064 times.
✓ Branch 1 taken 14010 times.
111074 if (y + 3 < (unsigned)height)
620 97064 vertical_compose97iL1(b3, b4, b5, width);
621
2/2
✓ Branch 0 taken 96965 times.
✓ Branch 1 taken 14109 times.
111074 if (y + 2 < (unsigned)height)
622 96965 vertical_compose97iH1(b2, b3, b4, width);
623
2/2
✓ Branch 0 taken 97064 times.
✓ Branch 1 taken 14010 times.
111074 if (y + 1 < (unsigned)height)
624 97064 vertical_compose97iL0(b1, b2, b3, width);
625
2/2
✓ Branch 0 taken 96965 times.
✓ Branch 1 taken 14109 times.
111074 if (y + 0 < (unsigned)height)
626 96965 vertical_compose97iH0(b0, b1, b2, width);
627
628
2/2
✓ Branch 0 taken 97064 times.
✓ Branch 1 taken 14010 times.
111074 if (y - 1 < (unsigned)height)
629 97064 snow_horizontal_compose97i(b0, temp, width);
630
2/2
✓ Branch 0 taken 96965 times.
✓ Branch 1 taken 14109 times.
111074 if (y + 0 < (unsigned)height)
631 96965 snow_horizontal_compose97i(b1, temp, width);
632
633 111074 cs->b0 = b2;
634 111074 cs->b1 = b3;
635 111074 cs->b2 = b4;
636 111074 cs->b3 = b5;
637 111074 cs->y += 2;
638 111074 }
639
640 1485 void ff_spatial_idwt_buffered_init(DWTCompose *cs, slice_buffer *sb, int width,
641 int height, int stride_line, int type,
642 int decomposition_count)
643 {
644 int level;
645
2/2
✓ Branch 0 taken 7425 times.
✓ Branch 1 taken 1485 times.
8910 for (level = decomposition_count - 1; level >= 0; level--) {
646
2/3
✓ Branch 0 taken 4860 times.
✓ Branch 1 taken 2565 times.
✗ Branch 2 not taken.
7425 switch (type) {
647 4860 case DWT_97:
648 4860 spatial_compose97i_buffered_init(cs + level, sb, height >> level,
649 stride_line << level);
650 4860 break;
651 2565 case DWT_53:
652 2565 spatial_compose53i_buffered_init(cs + level, sb, height >> level,
653 stride_line << level);
654 2565 break;
655 }
656 }
657 1485 }
658
659 36457 void ff_spatial_idwt_buffered_slice(SnowDWTContext *dsp, DWTCompose *cs,
660 slice_buffer *slice_buf, IDWTELEM *temp,
661 int width, int height, int stride_line,
662 int type, int decomposition_count, int y)
663 {
664
2/2
✓ Branch 0 taken 23957 times.
✓ Branch 1 taken 12500 times.
36457 const int support = type == 1 ? 3 : 5;
665 int level;
666
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36457 times.
36457 if (type == 2)
667 ✗ return;
668
669
2/2
✓ Branch 0 taken 182285 times.
✓ Branch 1 taken 36457 times.
218742 for (level = decomposition_count - 1; level >= 0; level--)
670
2/2
✓ Branch 0 taken 145959 times.
✓ Branch 1 taken 182285 times.
510529 while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
671
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 52548 times.
✓ Branch 2 taken 93411 times.
145959 switch (type) {
672 52548 case DWT_97:
673 52548 spatial_compose97i_dy_buffered(dsp, cs + level, slice_buf, temp,
674 width >> level,
675 height >> level,
676 stride_line << level);
677 52548 break;
678 93411 case DWT_53:
679 93411 spatial_compose53i_dy_buffered(cs + level, slice_buf, temp,
680 width >> level,
681 height >> level,
682 stride_line << level);
683 93411 break;
684 }
685 }
686 }
687
688 2121 static void spatial_idwt_init(DWTCompose *cs, IDWTELEM *buffer, int width,
689 int height, int stride, int type,
690 int decomposition_count)
691 {
692 int level;
693
2/2
✓ Branch 0 taken 10476 times.
✓ Branch 1 taken 2121 times.
12597 for (level = decomposition_count - 1; level >= 0; level--) {
694
2/3
✓ Branch 0 taken 7005 times.
✓ Branch 1 taken 3471 times.
✗ Branch 2 not taken.
10476 switch (type) {
695 7005 case DWT_97:
696 7005 spatial_compose97i_init(cs + level, buffer, height >> level,
697 stride << level);
698 7005 break;
699 3471 case DWT_53:
700 3471 spatial_compose53i_init(cs + level, buffer, height >> level,
701 stride << level);
702 3471 break;
703 }
704 }
705 2121 }
706
707 56100 static void spatial_idwt_slice(DWTCompose *cs, IDWTELEM *buffer,
708 IDWTELEM *temp, int width, int height,
709 int stride, int type,
710 int decomposition_count, int y)
711 {
712
2/2
✓ Branch 0 taken 30952 times.
✓ Branch 1 taken 25148 times.
56100 const int support = type == 1 ? 3 : 5;
713 int level;
714
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56100 times.
56100 if (type == 2)
715 ✗ return;
716
717
2/2
✓ Branch 0 taken 278796 times.
✓ Branch 1 taken 56100 times.
334896 for (level = decomposition_count - 1; level >= 0; level--)
718
2/2
✓ Branch 0 taken 234719 times.
✓ Branch 1 taken 278796 times.
792311 while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
719
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 111074 times.
✓ Branch 2 taken 123645 times.
234719 switch (type) {
720 111074 case DWT_97:
721 111074 spatial_compose97i_dy(cs + level, buffer, temp, width >> level,
722 height >> level, stride << level);
723 111074 break;
724 123645 case DWT_53:
725 123645 spatial_compose53i_dy(cs + level, buffer, temp, width >> level,
726 height >> level, stride << level);
727 123645 break;
728 }
729 }
730 }
731
732 2121 void ff_spatial_idwt(IDWTELEM *buffer, IDWTELEM *temp, int width, int height,
733 int stride, int type, int decomposition_count)
734 {
735 DWTCompose cs[MAX_DECOMPOSITIONS];
736 int y;
737 2121 spatial_idwt_init(cs, buffer, width, height, stride, type,
738 decomposition_count);
739
2/2
✓ Branch 0 taken 56100 times.
✓ Branch 1 taken 2121 times.
58221 for (y = 0; y < height; y += 4)
740 56100 spatial_idwt_slice(cs, buffer, temp, width, height, stride, type,
741 decomposition_count, y);
742 2121 }
743
744 476799 static inline int w_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size,
745 int w, int h, int type)
746 {
747 int s, i, j;
748
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 476799 times.
476799 const int dec_count = w == 8 ? 3 : 4;
749 int tmp[32 * 32], tmp2[32];
750 int level, ori;
751 static const int scale[2][2][4][4] = {
752 {
753 { // 9/7 8x8 dec=3
754 { 268, 239, 239, 213 },
755 { 0, 224, 224, 152 },
756 { 0, 135, 135, 110 },
757 },
758 { // 9/7 16x16 or 32x32 dec=4
759 { 344, 310, 310, 280 },
760 { 0, 320, 320, 228 },
761 { 0, 175, 175, 136 },
762 { 0, 129, 129, 102 },
763 }
764 },
765 {
766 { // 5/3 8x8 dec=3
767 { 275, 245, 245, 218 },
768 { 0, 230, 230, 156 },
769 { 0, 138, 138, 113 },
770 },
771 { // 5/3 16x16 or 32x32 dec=4
772 { 352, 317, 317, 286 },
773 { 0, 328, 328, 233 },
774 { 0, 180, 180, 140 },
775 { 0, 132, 132, 105 },
776 }
777 }
778 };
779
780
2/2
✓ Branch 0 taken 12531824 times.
✓ Branch 1 taken 476799 times.
13008623 for (i = 0; i < h; i++) {
781
2/2
✓ Branch 0 taken 89351616 times.
✓ Branch 1 taken 12531824 times.
101883440 for (j = 0; j < w; j += 4) {
782 89351616 tmp[32 * i + j + 0] = (pix1[j + 0] - pix2[j + 0]) * (1 << 4);
783 89351616 tmp[32 * i + j + 1] = (pix1[j + 1] - pix2[j + 1]) * (1 << 4);
784 89351616 tmp[32 * i + j + 2] = (pix1[j + 2] - pix2[j + 2]) * (1 << 4);
785 89351616 tmp[32 * i + j + 3] = (pix1[j + 3] - pix2[j + 3]) * (1 << 4);
786 }
787 12531824 pix1 += line_size;
788 12531824 pix2 += line_size;
789 }
790
791 476799 ff_spatial_dwt(tmp, tmp2, w, h, 32, type, dec_count);
792
793 476799 s = 0;
794 av_assert1(w == h);
795
2/2
✓ Branch 0 taken 1907196 times.
✓ Branch 1 taken 476799 times.
2383995 for (level = 0; level < dec_count; level++)
796
2/2
✓ Branch 0 taken 6198387 times.
✓ Branch 1 taken 1907196 times.
8105583 for (ori = level ? 1 : 0; ori < 4; ori++) {
797 6198387 int size = w >> (dec_count - level);
798
2/2
✓ Branch 0 taken 3814392 times.
✓ Branch 1 taken 2383995 times.
6198387 int sx = (ori & 1) ? size : 0;
799 6198387 int stride = 32 << (dec_count - level);
800
2/2
✓ Branch 0 taken 3814392 times.
✓ Branch 1 taken 2383995 times.
6198387 int sy = (ori & 2) ? stride >> 1 : 0;
801
802
2/2
✓ Branch 0 taken 36028994 times.
✓ Branch 1 taken 6198387 times.
42227381 for (i = 0; i < size; i++)
803
2/2
✓ Branch 0 taken 357406464 times.
✓ Branch 1 taken 36028994 times.
393435458 for (j = 0; j < size; j++) {
804 357406464 int v = tmp[sx + sy + i * stride + j] *
805 357406464 scale[type][dec_count - 3][level][ori];
806 357406464 s += FFABS(v);
807 }
808 }
809 av_assert1(s >= 0);
810 476799 return s >> 9;
811 }
812
813 ✗ static int w53_8_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
814 {
815 ✗ return w_c(v, pix1, pix2, line_size, 8, h, 1);
816 }
817
818 ✗ static int w97_8_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
819 {
820 ✗ return w_c(v, pix1, pix2, line_size, 8, h, 0);
821 }
822
823 ✗ static int w53_16_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
824 {
825 ✗ return w_c(v, pix1, pix2, line_size, 16, h, 1);
826 }
827
828 170359 static int w97_16_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
829 {
830 170359 return w_c(v, pix1, pix2, line_size, 16, h, 0);
831 }
832
833 ✗ int ff_w53_32_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
834 {
835 ✗ return w_c(v, pix1, pix2, line_size, 32, h, 1);
836 }
837
838 306440 int ff_w97_32_c(MPVEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int h)
839 {
840 306440 return w_c(v, pix1, pix2, line_size, 32, h, 0);
841 }
842
843 1658 av_cold void ff_dsputil_init_dwt(MECmpContext *c)
844 {
845 1658 c->w53[0] = w53_16_c;
846 1658 c->w53[1] = w53_8_c;
847 1658 c->w97[0] = w97_16_c;
848 1658 c->w97[1] = w97_8_c;
849 1658 }
850
851 51 av_cold void ff_dwt_init(SnowDWTContext *c)
852 {
853 51 c->vertical_compose97i = snow_vertical_compose97i;
854 51 c->horizontal_compose97i = snow_horizontal_compose97i;
855 51 c->inner_add_yblock = ff_snow_inner_add_yblock_c;
856
857 #if ARCH_X86 && HAVE_MMX
858 51 ff_dwt_init_x86(c);
859 #endif
860 51 }
861