FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/snow_dwt.c
Date: 2024-04-19 17:50:32
Exec Total Coverage
Lines: 435 455 95.6%
Functions: 45 49 91.8%
Branches: 218 245 89.0%

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 461 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 461 buf->base_buffer = base_buffer;
36 461 buf->line_count = line_count;
37 461 buf->line_width = line_width;
38 461 buf->data_count = max_allocated_lines;
39 461 buf->line = av_calloc(line_count, sizeof(*buf->line));
40
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 461 times.
461 if (!buf->line)
41 return AVERROR(ENOMEM);
42 461 buf->data_stack = av_malloc_array(max_allocated_lines, sizeof(IDWTELEM *));
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 461 times.
461 if (!buf->data_stack) {
44 av_freep(&buf->line);
45 return AVERROR(ENOMEM);
46 }
47
48
2/2
✓ Branch 0 taken 31960 times.
✓ Branch 1 taken 461 times.
32421 for (i = 0; i < max_allocated_lines; i++) {
49 31960 buf->data_stack[i] = av_malloc_array(line_width, sizeof(IDWTELEM));
50
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31960 times.
31960 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 461 buf->data_stack_top = max_allocated_lines - 1;
60 461 return 0;
61 }
62
63 128848 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 128848 times.
128848 av_assert0(buf->data_stack_top >= 0);
68 // av_assert1(!buf->line[line]);
69
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128848 times.
128848 if (buf->line[line])
70 return buf->line[line];
71
72 128848 buffer = buf->data_stack[buf->data_stack_top];
73 128848 buf->data_stack_top--;
74 128848 buf->line[line] = buffer;
75
76 128848 return buffer;
77 }
78
79 128848 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 128848 buffer = buf->line[line];
87 128848 buf->data_stack_top++;
88 128848 buf->data_stack[buf->data_stack_top] = buffer;
89 128848 buf->line[line] = NULL;
90 128848 }
91
92 1864 void ff_slice_buffer_flush(slice_buffer *buf)
93 {
94 int i;
95
96
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1844 times.
1864 if (!buf->line)
97 20 return;
98
99
2/2
✓ Branch 0 taken 256000 times.
✓ Branch 1 taken 1844 times.
257844 for (i = 0; i < buf->line_count; i++)
100
2/2
✓ Branch 0 taken 848 times.
✓ Branch 1 taken 255152 times.
256000 if (buf->line[i])
101 848 ff_slice_buffer_release(buf, i);
102 }
103
104 481 void ff_slice_buffer_destroy(slice_buffer *buf)
105 {
106 int i;
107 481 ff_slice_buffer_flush(buf);
108
109
2/2
✓ Branch 0 taken 461 times.
✓ Branch 1 taken 20 times.
481 if (buf->data_stack)
110
2/2
✓ Branch 0 taken 31960 times.
✓ Branch 1 taken 461 times.
32421 for (i = buf->data_count - 1; i >= 0; i--)
111 31960 av_freep(&buf->data_stack[i]);
112 481 av_freep(&buf->data_stack);
113 481 av_freep(&buf->line);
114 481 }
115
116 71049510 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 71049510 const int mirror_left = !highpass;
122 71049510 const int mirror_right = (width & 1) ^ highpass;
123 71049510 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 23738970 times.
✓ Branch 1 taken 47310540 times.
71049510 if (mirror_left) {
128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23738970 times.
23738970 dst[0] = LIFT(src[0], ((mul * 2 * ref[0] + add) >> shift), inverse);
129 23738970 dst += dst_step;
130 23738970 src += src_step;
131 }
132
133
2/2
✓ Branch 0 taken 678719880 times.
✓ Branch 1 taken 71049510 times.
749769390 for (i = 0; i < w; i++)
134
2/2
✓ Branch 0 taken 216223860 times.
✓ Branch 1 taken 462496020 times.
678719880 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 47310540 times.
✓ Branch 1 taken 23738970 times.
71049510 if (mirror_right)
141
2/2
✓ Branch 0 taken 23571570 times.
✓ Branch 1 taken 23738970 times.
47310540 dst[w * dst_step] = LIFT(src[w * src_step],
142 ((mul * 2 * ref[w * ref_step] + add) >> shift),
143 inverse);
144 71049510 }
145
146 23571570 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 23571570 const int mirror_left = !highpass;
152 23571570 const int mirror_right = (width & 1) ^ highpass;
153 23571570 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 23571570 times.
✗ Branch 1 not taken.
23571570 if (mirror_left) {
162
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23571570 times.
23571570 dst[0] = LIFTS(src[0], mul * 2 * ref[0] + add, inverse);
163 23571570 dst += dst_step;
164 23571570 src += src_step;
165 }
166
167
2/2
✓ Branch 0 taken 216223860 times.
✓ Branch 1 taken 23571570 times.
239795430 for (i = 0; i < w; i++)
168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216223860 times.
216223860 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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23571570 times.
23571570 if (mirror_right)
174 dst[w * dst_step] = LIFTS(src[w * src_step],
175 mul * 2 * ref[w * ref_step] + add,
176 inverse);
177 23571570 }
178
179 167400 static void horizontal_decompose53i(DWTELEM *b, DWTELEM *temp, int width)
180 {
181 167400 const int width2 = width >> 1;
182 int x;
183 167400 const int w2 = (width + 1) >> 1;
184
185
2/2
✓ Branch 0 taken 15190200 times.
✓ Branch 1 taken 167400 times.
15357600 for (x = 0; x < width2; x++) {
186 15190200 temp[x] = b[2 * x];
187 15190200 temp[x + w2] = b[2 * x + 1];
188 }
189
2/2
✓ Branch 0 taken 2700 times.
✓ Branch 1 taken 164700 times.
167400 if (width & 1)
190 2700 temp[x] = b[2 * x];
191 167400 lift(b + w2, temp + w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 0);
192 167400 lift(b, temp, b + w2, 1, 1, 1, width, 1, 2, 2, 0, 0);
193 167400 }
194
195 83550 static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
196 int width)
197 {
198 int i;
199
200
2/2
✓ Branch 0 taken 15189900 times.
✓ Branch 1 taken 83550 times.
15273450 for (i = 0; i < width; i++)
201 15189900 b1[i] -= (b0[i] + b2[i]) >> 1;
202 83550 }
203
204 83850 static void vertical_decompose53iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
205 int width)
206 {
207 int i;
208
209
2/2
✓ Branch 0 taken 15193200 times.
✓ Branch 1 taken 83850 times.
15277050 for (i = 0; i < width; i++)
210 15193200 b1[i] += (b0[i] + b2[i] + 2) >> 2;
211 83850 }
212
213 2250 static void spatial_decompose53i(DWTELEM *buffer, DWTELEM *temp,
214 int width, int height, int stride)
215 {
216 int y;
217 2250 DWTELEM *b0 = buffer + avpriv_mirror(-2 - 1, height - 1) * stride;
218 2250 DWTELEM *b1 = buffer + avpriv_mirror(-2, height - 1) * stride;
219
220
2/2
✓ Branch 0 taken 86100 times.
✓ Branch 1 taken 2250 times.
88350 for (y = -2; y < height; y += 2) {
221 86100 DWTELEM *b2 = buffer + avpriv_mirror(y + 1, height - 1) * stride;
222 86100 DWTELEM *b3 = buffer + avpriv_mirror(y + 2, height - 1) * stride;
223
224
2/2
✓ Branch 0 taken 83550 times.
✓ Branch 1 taken 2550 times.
86100 if (y + 1 < (unsigned)height)
225 83550 horizontal_decompose53i(b2, temp, width);
226
2/2
✓ Branch 0 taken 83850 times.
✓ Branch 1 taken 2250 times.
86100 if (y + 2 < (unsigned)height)
227 83850 horizontal_decompose53i(b3, temp, width);
228
229
2/2
✓ Branch 0 taken 83550 times.
✓ Branch 1 taken 2550 times.
86100 if (y + 1 < (unsigned)height)
230 83550 vertical_decompose53iH0(b1, b2, b3, width);
231
2/2
✓ Branch 0 taken 83850 times.
✓ Branch 1 taken 2250 times.
86100 if (y + 0 < (unsigned)height)
232 83850 vertical_decompose53iL0(b0, b1, b2, width);
233
234 86100 b0 = b2;
235 86100 b1 = b3;
236 }
237 2250 }
238
239 23571570 static void horizontal_decompose97i(DWTELEM *b, DWTELEM *temp, int width)
240 {
241 23571570 const int w2 = (width + 1) >> 1;
242
243 23571570 lift(temp + w2, b + 1, b, 1, 2, 2, width, W_AM, W_AO, W_AS, 1, 1);
244 23571570 liftS(temp, b, temp + w2, 1, 2, 1, width, W_BM, W_BO, W_BS, 0, 0);
245 23571570 lift(b + w2, temp + w2, temp, 1, 1, 1, width, W_CM, W_CO, W_CS, 1, 0);
246 23571570 lift(b, temp, b + w2, 1, 1, 1, width, W_DM, W_DO, W_DS, 0, 0);
247 23571570 }
248
249 11785785 static void vertical_decompose97iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
250 int width)
251 {
252 int i;
253
254
2/2
✓ Branch 0 taken 239795430 times.
✓ Branch 1 taken 11785785 times.
251581215 for (i = 0; i < width; i++)
255 239795430 b1[i] -= (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
256 11785785 }
257
258 11785785 static void vertical_decompose97iH1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
259 int width)
260 {
261 int i;
262
263
2/2
✓ Branch 0 taken 239795430 times.
✓ Branch 1 taken 11785785 times.
251581215 for (i = 0; i < width; i++)
264 239795430 b1[i] += (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS;
265 11785785 }
266
267 11785785 static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
268 int width)
269 {
270 int i;
271
272
2/2
✓ Branch 0 taken 239795430 times.
✓ Branch 1 taken 11785785 times.
251581215 for (i = 0; i < width; i++)
273 239795430 b1[i] = (16 * 4 * b1[i] - 4 * (b0[i] + b2[i]) + W_BO * 5 + (5 << 27)) /
274 239795430 (5 * 16) - (1 << 23);
275 11785785 }
276
277 11785785 static void vertical_decompose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
278 int width)
279 {
280 int i;
281
282
2/2
✓ Branch 0 taken 239795430 times.
✓ Branch 1 taken 11785785 times.
251581215 for (i = 0; i < width; i++)
283 239795430 b1[i] += (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS;
284 11785785 }
285
286 1911696 static void spatial_decompose97i(DWTELEM *buffer, DWTELEM *temp,
287 int width, int height, int stride)
288 {
289 int y;
290 1911696 DWTELEM *b0 = buffer + avpriv_mirror(-4 - 1, height - 1) * stride;
291 1911696 DWTELEM *b1 = buffer + avpriv_mirror(-4, height - 1) * stride;
292 1911696 DWTELEM *b2 = buffer + avpriv_mirror(-4 + 1, height - 1) * stride;
293 1911696 DWTELEM *b3 = buffer + avpriv_mirror(-4 + 2, height - 1) * stride;
294
295
2/2
✓ Branch 0 taken 15609177 times.
✓ Branch 1 taken 1911696 times.
17520873 for (y = -4; y < height; y += 2) {
296 15609177 DWTELEM *b4 = buffer + avpriv_mirror(y + 3, height - 1) * stride;
297 15609177 DWTELEM *b5 = buffer + avpriv_mirror(y + 4, height - 1) * stride;
298
299
2/2
✓ Branch 0 taken 11785785 times.
✓ Branch 1 taken 3823392 times.
15609177 if (y + 3 < (unsigned)height)
300 11785785 horizontal_decompose97i(b4, temp, width);
301
2/2
✓ Branch 0 taken 11785785 times.
✓ Branch 1 taken 3823392 times.
15609177 if (y + 4 < (unsigned)height)
302 11785785 horizontal_decompose97i(b5, temp, width);
303
304
2/2
✓ Branch 0 taken 11785785 times.
✓ Branch 1 taken 3823392 times.
15609177 if (y + 3 < (unsigned)height)
305 11785785 vertical_decompose97iH0(b3, b4, b5, width);
306
2/2
✓ Branch 0 taken 11785785 times.
✓ Branch 1 taken 3823392 times.
15609177 if (y + 2 < (unsigned)height)
307 11785785 vertical_decompose97iL0(b2, b3, b4, width);
308
2/2
✓ Branch 0 taken 11785785 times.
✓ Branch 1 taken 3823392 times.
15609177 if (y + 1 < (unsigned)height)
309 11785785 vertical_decompose97iH1(b1, b2, b3, width);
310
2/2
✓ Branch 0 taken 11785785 times.
✓ Branch 1 taken 3823392 times.
15609177 if (y + 0 < (unsigned)height)
311 11785785 vertical_decompose97iL1(b0, b1, b2, width);
312
313 15609177 b0 = b2;
314 15609177 b1 = b3;
315 15609177 b2 = b4;
316 15609177 b3 = b5;
317 }
318 1911696 }
319
320 478149 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 1913946 times.
✓ Branch 1 taken 478149 times.
2392095 for (level = 0; level < decomposition_count; level++) {
326
2/3
✓ Branch 0 taken 1911696 times.
✓ Branch 1 taken 2250 times.
✗ Branch 2 not taken.
1913946 switch (type) {
327 1911696 case DWT_97:
328 1911696 spatial_decompose97i(buffer, temp,
329 width >> level, height >> level,
330 stride << level);
331 1911696 break;
332 2250 case DWT_53:
333 2250 spatial_decompose53i(buffer, temp,
334 width >> level, height >> level,
335 stride << level);
336 2250 break;
337 }
338 }
339 478149 }
340
341 392832 static void horizontal_compose53i(IDWTELEM *b, IDWTELEM *temp, int width)
342 {
343 392832 const int width2 = width >> 1;
344 392832 const int w2 = (width + 1) >> 1;
345 int x;
346
347
2/2
✓ Branch 0 taken 35646336 times.
✓ Branch 1 taken 392832 times.
36039168 for (x = 0; x < width2; x++) {
348 35646336 temp[2 * x] = b[x];
349 35646336 temp[2 * x + 1] = b[x + w2];
350 }
351
2/2
✓ Branch 0 taken 6336 times.
✓ Branch 1 taken 386496 times.
392832 if (width & 1)
352 6336 temp[2 * x] = b[x];
353
354 392832 b[0] = temp[0] - ((temp[1] + 1) >> 1);
355
2/2
✓ Branch 0 taken 35253504 times.
✓ Branch 1 taken 392832 times.
35646336 for (x = 2; x < width - 1; x += 2) {
356 35253504 b[x] = temp[x] - ((temp[x - 1] + temp[x + 1] + 2) >> 2);
357 35253504 b[x - 1] = temp[x - 1] + ((b[x - 2] + b[x] + 1) >> 1);
358 }
359
2/2
✓ Branch 0 taken 6336 times.
✓ Branch 1 taken 386496 times.
392832 if (width & 1) {
360 6336 b[x] = temp[x] - ((temp[x - 1] + 1) >> 1);
361 6336 b[x - 1] = temp[x - 1] + ((b[x - 2] + b[x] + 1) >> 1);
362 } else
363 386496 b[x - 1] = temp[x - 1] + b[x - 2];
364 392832 }
365
366 112288 static void vertical_compose53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
367 int width)
368 {
369 int i;
370
371
2/2
✓ Branch 0 taken 20257336 times.
✓ Branch 1 taken 112288 times.
20369624 for (i = 0; i < width; i++)
372 20257336 b1[i] += (b0[i] + b2[i]) >> 1;
373 112288 }
374
375 112992 static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
376 int width)
377 {
378 int i;
379
380
2/2
✓ Branch 0 taken 20265080 times.
✓ Branch 1 taken 112992 times.
20378072 for (i = 0; i < width; i++)
381 20265080 b1[i] -= (b0[i] + b2[i] + 2) >> 2;
382 112992 }
383
384 2310 static void spatial_compose53i_buffered_init(DWTCompose *cs, slice_buffer *sb,
385 int height, int stride_line)
386 {
387
2/2
✓ Branch 0 taken 1848 times.
✓ Branch 1 taken 462 times.
2310 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 2310 times.
2310 cs->b1 = slice_buffer_get_line(sb, avpriv_mirror(-1, height - 1) * stride_line);
390 2310 cs->y = -1;
391 2310 }
392
393 2970 static void spatial_compose53i_init(DWTCompose *cs, IDWTELEM *buffer,
394 int height, int stride)
395 {
396 2970 cs->b0 = buffer + avpriv_mirror(-1 - 1, height - 1) * stride;
397 2970 cs->b1 = buffer + avpriv_mirror(-1, height - 1) * stride;
398 2970 cs->y = -1;
399 2970 }
400
401 88396 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 88396 int y = cs->y;
407
408 88396 IDWTELEM *b0 = cs->b0;
409 88396 IDWTELEM *b1 = cs->b1;
410
1/2
✓ Branch 0 taken 88396 times.
✗ Branch 1 not taken.
88396 IDWTELEM *b2 = slice_buffer_get_line(sb,
411 avpriv_mirror(y + 1, height - 1) *
412 stride_line);
413
2/2
✓ Branch 0 taken 88088 times.
✓ Branch 1 taken 308 times.
88396 IDWTELEM *b3 = slice_buffer_get_line(sb,
414 avpriv_mirror(y + 2, height - 1) *
415 stride_line);
416
417
4/4
✓ Branch 0 taken 86086 times.
✓ Branch 1 taken 2310 times.
✓ Branch 2 taken 83776 times.
✓ Branch 3 taken 2310 times.
172172 if (y + 1 < (unsigned)height && y < (unsigned)height) {
418 int x;
419
420
2/2
✓ Branch 0 taken 15388296 times.
✓ Branch 1 taken 83776 times.
15472072 for (x = 0; x < width; x++) {
421 15388296 b2[x] -= (b1[x] + b3[x] + 2) >> 2;
422 15388296 b1[x] += (b0[x] + b2[x]) >> 1;
423 }
424 } else {
425
2/2
✓ Branch 0 taken 2310 times.
✓ Branch 1 taken 2310 times.
4620 if (y + 1 < (unsigned)height)
426 2310 vertical_compose53iL0(b1, b2, b3, width);
427
2/2
✓ Branch 0 taken 2002 times.
✓ Branch 1 taken 2618 times.
4620 if (y + 0 < (unsigned)height)
428 2002 vertical_compose53iH0(b0, b1, b2, width);
429 }
430
431
2/2
✓ Branch 0 taken 86086 times.
✓ Branch 1 taken 2310 times.
88396 if (y - 1 < (unsigned)height)
432 86086 horizontal_compose53i(b0, temp, width);
433
2/2
✓ Branch 0 taken 85778 times.
✓ Branch 1 taken 2618 times.
88396 if (y + 0 < (unsigned)height)
434 85778 horizontal_compose53i(b1, temp, width);
435
436 88396 cs->b0 = b2;
437 88396 cs->b1 = b3;
438 88396 cs->y += 2;
439 88396 }
440
441 113652 static void spatial_compose53i_dy(DWTCompose *cs, IDWTELEM *buffer,
442 IDWTELEM *temp, int width, int height,
443 int stride)
444 {
445 113652 int y = cs->y;
446 113652 IDWTELEM *b0 = cs->b0;
447 113652 IDWTELEM *b1 = cs->b1;
448 113652 IDWTELEM *b2 = buffer + avpriv_mirror(y + 1, height - 1) * stride;
449 113652 IDWTELEM *b3 = buffer + avpriv_mirror(y + 2, height - 1) * stride;
450
451
2/2
✓ Branch 0 taken 110682 times.
✓ Branch 1 taken 2970 times.
113652 if (y + 1 < (unsigned)height)
452 110682 vertical_compose53iL0(b1, b2, b3, width);
453
2/2
✓ Branch 0 taken 110286 times.
✓ Branch 1 taken 3366 times.
113652 if (y + 0 < (unsigned)height)
454 110286 vertical_compose53iH0(b0, b1, b2, width);
455
456
2/2
✓ Branch 0 taken 110682 times.
✓ Branch 1 taken 2970 times.
113652 if (y - 1 < (unsigned)height)
457 110682 horizontal_compose53i(b0, temp, width);
458
2/2
✓ Branch 0 taken 110286 times.
✓ Branch 1 taken 3366 times.
113652 if (y + 0 < (unsigned)height)
459 110286 horizontal_compose53i(b1, temp, width);
460
461 113652 cs->b0 = b2;
462 113652 cs->b1 = b3;
463 113652 cs->y += 2;
464 113652 }
465
466 245520 static void snow_horizontal_compose97i(IDWTELEM *b, IDWTELEM *temp, int width)
467 {
468 245520 const int w2 = (width + 1) >> 1;
469 int x;
470
471 245520 temp[0] = b[0] - ((3 * b[w2] + 2) >> 2);
472
2/2
✓ Branch 0 taken 18755712 times.
✓ Branch 1 taken 245520 times.
19001232 for (x = 1; x < (width >> 1); x++) {
473 18755712 temp[2 * x] = b[x] - ((3 * (b[x + w2 - 1] + b[x + w2]) + 4) >> 3);
474 18755712 temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x];
475 }
476
2/2
✓ Branch 0 taken 3456 times.
✓ Branch 1 taken 242064 times.
245520 if (width & 1) {
477 3456 temp[2 * x] = b[x] - ((3 * b[x + w2 - 1] + 2) >> 2);
478 3456 temp[2 * x - 1] = b[x + w2 - 1] - temp[2 * x - 2] - temp[2 * x];
479 } else
480 242064 temp[2 * x - 1] = b[x + w2 - 1] - 2 * temp[2 * x - 2];
481
482 245520 b[0] = temp[0] + ((2 * temp[0] + temp[1] + 4) >> 3);
483
2/2
✓ Branch 0 taken 18755712 times.
✓ Branch 1 taken 245520 times.
19001232 for (x = 2; x < width - 1; x += 2) {
484 18755712 b[x] = temp[x] + ((4 * temp[x] + temp[x - 1] + temp[x + 1] + 8) >> 4);
485 18755712 b[x - 1] = temp[x - 1] + ((3 * (b[x - 2] + b[x])) >> 1);
486 }
487
2/2
✓ Branch 0 taken 3456 times.
✓ Branch 1 taken 242064 times.
245520 if (width & 1) {
488 3456 b[x] = temp[x] + ((2 * temp[x] + temp[x - 1] + 4) >> 3);
489 3456 b[x - 1] = temp[x - 1] + ((3 * (b[x - 2] + b[x])) >> 1);
490 } else
491 242064 b[x - 1] = temp[x - 1] + 3 * b[x - 2];
492 245520 }
493
494 93412 static void vertical_compose97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
495 int width)
496 {
497 int i;
498
499
2/2
✓ Branch 0 taken 16800744 times.
✓ Branch 1 taken 93412 times.
16894156 for (i = 0; i < width; i++)
500 16800744 b1[i] += (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
501 93412 }
502
503 93412 static void vertical_compose97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
504 int width)
505 {
506 int i;
507
508
2/2
✓ Branch 0 taken 16800744 times.
✓ Branch 1 taken 93412 times.
16894156 for (i = 0; i < width; i++)
509 16800744 b1[i] -= (W_CM * (b0[i] + b2[i]) + W_CO) >> W_CS;
510 93412 }
511
512 93412 static void vertical_compose97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
513 int width)
514 {
515 int i;
516
517
2/2
✓ Branch 0 taken 16800744 times.
✓ Branch 1 taken 93412 times.
16894156 for (i = 0; i < width; i++)
518 16800744 b1[i] += (W_BM * (b0[i] + b2[i]) + 4 * b1[i] + W_BO) >> W_BS;
519 93412 }
520
521 93412 static void vertical_compose97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
522 int width)
523 {
524 int i;
525
526
2/2
✓ Branch 0 taken 16800744 times.
✓ Branch 1 taken 93412 times.
16894156 for (i = 0; i < width; i++)
527 16800744 b1[i] -= (W_DM * (b0[i] + b2[i]) + W_DO) >> W_DS;
528 93412 }
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 4605 static void spatial_compose97i_buffered_init(DWTCompose *cs, slice_buffer *sb,
545 int height, int stride_line)
546 {
547
2/2
✓ Branch 0 taken 3684 times.
✓ Branch 1 taken 921 times.
4605 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 4605 times.
4605 cs->b1 = slice_buffer_get_line(sb, avpriv_mirror(-3, height - 1) * stride_line);
549
1/2
✓ Branch 0 taken 4605 times.
✗ Branch 1 not taken.
4605 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 3991 times.
4605 cs->b3 = slice_buffer_get_line(sb, avpriv_mirror(-3 + 2, height - 1) * stride_line);
551 4605 cs->y = -3;
552 4605 }
553
554 6420 static void spatial_compose97i_init(DWTCompose *cs, IDWTELEM *buffer, int height,
555 int stride)
556 {
557 6420 cs->b0 = buffer + avpriv_mirror(-3 - 1, height - 1) * stride;
558 6420 cs->b1 = buffer + avpriv_mirror(-3, height - 1) * stride;
559 6420 cs->b2 = buffer + avpriv_mirror(-3 + 1, height - 1) * stride;
560 6420 cs->b3 = buffer + avpriv_mirror(-3 + 2, height - 1) * stride;
561 6420 cs->y = -3;
562 6420 }
563
564 47278 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 47278 int y = cs->y;
570
571 47278 IDWTELEM *b0 = cs->b0;
572 47278 IDWTELEM *b1 = cs->b1;
573 47278 IDWTELEM *b2 = cs->b2;
574 47278 IDWTELEM *b3 = cs->b3;
575
1/2
✓ Branch 0 taken 47278 times.
✗ Branch 1 not taken.
47278 IDWTELEM *b4 = slice_buffer_get_line(sb,
576 avpriv_mirror(y + 3, height - 1) *
577 stride_line);
578
2/2
✓ Branch 0 taken 46738 times.
✓ Branch 1 taken 540 times.
47278 IDWTELEM *b5 = slice_buffer_get_line(sb,
579 avpriv_mirror(y + 4, height - 1) *
580 stride_line);
581
582
4/4
✓ Branch 0 taken 38068 times.
✓ Branch 1 taken 9210 times.
✓ Branch 2 taken 29472 times.
✓ Branch 3 taken 8596 times.
47278 if (y > 0 && y + 4 < height) {
583 29472 dsp->vertical_compose97i(b0, b1, b2, b3, b4, b5, width);
584 } else {
585
2/2
✓ Branch 0 taken 8596 times.
✓ Branch 1 taken 9210 times.
17806 if (y + 3 < (unsigned)height)
586 8596 vertical_compose97iL1(b3, b4, b5, width);
587
2/2
✓ Branch 0 taken 8596 times.
✓ Branch 1 taken 9210 times.
17806 if (y + 2 < (unsigned)height)
588 8596 vertical_compose97iH1(b2, b3, b4, width);
589
2/2
✓ Branch 0 taken 8596 times.
✓ Branch 1 taken 9210 times.
17806 if (y + 1 < (unsigned)height)
590 8596 vertical_compose97iL0(b1, b2, b3, width);
591
2/2
✓ Branch 0 taken 8596 times.
✓ Branch 1 taken 9210 times.
17806 if (y + 0 < (unsigned)height)
592 8596 vertical_compose97iH0(b0, b1, b2, width);
593 }
594
595
2/2
✓ Branch 0 taken 38068 times.
✓ Branch 1 taken 9210 times.
47278 if (y - 1 < (unsigned)height)
596 38068 dsp->horizontal_compose97i(b0, temp, width);
597
2/2
✓ Branch 0 taken 38068 times.
✓ Branch 1 taken 9210 times.
47278 if (y + 0 < (unsigned)height)
598 38068 dsp->horizontal_compose97i(b1, temp, width);
599
600 47278 cs->b0 = b2;
601 47278 cs->b1 = b3;
602 47278 cs->b2 = b4;
603 47278 cs->b3 = b5;
604 47278 cs->y += 2;
605 47278 }
606
607 97656 static void spatial_compose97i_dy(DWTCompose *cs, IDWTELEM *buffer,
608 IDWTELEM *temp, int width, int height,
609 int stride)
610 {
611 97656 int y = cs->y;
612 97656 IDWTELEM *b0 = cs->b0;
613 97656 IDWTELEM *b1 = cs->b1;
614 97656 IDWTELEM *b2 = cs->b2;
615 97656 IDWTELEM *b3 = cs->b3;
616 97656 IDWTELEM *b4 = buffer + avpriv_mirror(y + 3, height - 1) * stride;
617 97656 IDWTELEM *b5 = buffer + avpriv_mirror(y + 4, height - 1) * stride;
618
619
2/2
✓ Branch 0 taken 84816 times.
✓ Branch 1 taken 12840 times.
97656 if (y + 3 < (unsigned)height)
620 84816 vertical_compose97iL1(b3, b4, b5, width);
621
2/2
✓ Branch 0 taken 84816 times.
✓ Branch 1 taken 12840 times.
97656 if (y + 2 < (unsigned)height)
622 84816 vertical_compose97iH1(b2, b3, b4, width);
623
2/2
✓ Branch 0 taken 84816 times.
✓ Branch 1 taken 12840 times.
97656 if (y + 1 < (unsigned)height)
624 84816 vertical_compose97iL0(b1, b2, b3, width);
625
2/2
✓ Branch 0 taken 84816 times.
✓ Branch 1 taken 12840 times.
97656 if (y + 0 < (unsigned)height)
626 84816 vertical_compose97iH0(b0, b1, b2, width);
627
628
2/2
✓ Branch 0 taken 84816 times.
✓ Branch 1 taken 12840 times.
97656 if (y - 1 < (unsigned)height)
629 84816 snow_horizontal_compose97i(b0, temp, width);
630
2/2
✓ Branch 0 taken 84816 times.
✓ Branch 1 taken 12840 times.
97656 if (y + 0 < (unsigned)height)
631 84816 snow_horizontal_compose97i(b1, temp, width);
632
633 97656 cs->b0 = b2;
634 97656 cs->b1 = b3;
635 97656 cs->b2 = b4;
636 97656 cs->b3 = b5;
637 97656 cs->y += 2;
638 97656 }
639
640 1383 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 6915 times.
✓ Branch 1 taken 1383 times.
8298 for (level = decomposition_count - 1; level >= 0; level--) {
646
2/3
✓ Branch 0 taken 4605 times.
✓ Branch 1 taken 2310 times.
✗ Branch 2 not taken.
6915 switch (type) {
647 4605 case DWT_97:
648 4605 spatial_compose97i_buffered_init(cs + level, sb, height >> level,
649 stride_line << level);
650 4605 break;
651 2310 case DWT_53:
652 2310 spatial_compose53i_buffered_init(cs + level, sb, height >> level,
653 stride_line << level);
654 2310 break;
655 }
656 }
657 1383 }
658
659 33857 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 22657 times.
✓ Branch 1 taken 11200 times.
33857 const int support = type == 1 ? 3 : 5;
665 int level;
666
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33857 times.
33857 if (type == 2)
667 return;
668
669
2/2
✓ Branch 0 taken 169285 times.
✓ Branch 1 taken 33857 times.
203142 for (level = decomposition_count - 1; level >= 0; level--)
670
2/2
✓ Branch 0 taken 135674 times.
✓ Branch 1 taken 169285 times.
474244 while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
671
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 47278 times.
✓ Branch 2 taken 88396 times.
135674 switch (type) {
672 47278 case DWT_97:
673 47278 spatial_compose97i_dy_buffered(dsp, cs + level, slice_buf, temp,
674 width >> level,
675 height >> level,
676 stride_line << level);
677 47278 break;
678 88396 case DWT_53:
679 88396 spatial_compose53i_dy_buffered(cs + level, slice_buf, temp,
680 width >> level,
681 height >> level,
682 stride_line << level);
683 88396 break;
684 }
685 }
686 }
687
688 1878 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 9390 times.
✓ Branch 1 taken 1878 times.
11268 for (level = decomposition_count - 1; level >= 0; level--) {
694
2/3
✓ Branch 0 taken 6420 times.
✓ Branch 1 taken 2970 times.
✗ Branch 2 not taken.
9390 switch (type) {
695 6420 case DWT_97:
696 6420 spatial_compose97i_init(cs + level, buffer, height >> level,
697 stride << level);
698 6420 break;
699 2970 case DWT_53:
700 2970 spatial_compose53i_init(cs + level, buffer, height >> level,
701 stride << level);
702 2970 break;
703 }
704 }
705 1878 }
706
707 50400 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 28512 times.
✓ Branch 1 taken 21888 times.
50400 const int support = type == 1 ? 3 : 5;
713 int level;
714
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50400 times.
50400 if (type == 2)
715 return;
716
717
2/2
✓ Branch 0 taken 252000 times.
✓ Branch 1 taken 50400 times.
302400 for (level = decomposition_count - 1; level >= 0; level--)
718
2/2
✓ Branch 0 taken 211308 times.
✓ Branch 1 taken 252000 times.
715308 while (cs[level].y <= FFMIN((y >> level) + support, height >> level)) {
719
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 97656 times.
✓ Branch 2 taken 113652 times.
211308 switch (type) {
720 97656 case DWT_97:
721 97656 spatial_compose97i_dy(cs + level, buffer, temp, width >> level,
722 height >> level, stride << level);
723 97656 break;
724 113652 case DWT_53:
725 113652 spatial_compose53i_dy(cs + level, buffer, temp, width >> level,
726 height >> level, stride << level);
727 113652 break;
728 }
729 }
730 }
731
732 1878 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 1878 spatial_idwt_init(cs, buffer, width, height, stride, type,
738 decomposition_count);
739
2/2
✓ Branch 0 taken 50400 times.
✓ Branch 1 taken 1878 times.
52278 for (y = 0; y < height; y += 4)
740 50400 spatial_idwt_slice(cs, buffer, temp, width, height, stride, type,
741 decomposition_count, y);
742 1878 }
743
744 476799 static inline int w_c(struct MpegEncContext *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(struct MpegEncContext *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(struct MpegEncContext *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(struct MpegEncContext *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(struct MpegEncContext *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(struct MpegEncContext *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(struct MpegEncContext *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 1072 av_cold void ff_dsputil_init_dwt(MECmpContext *c)
844 {
845 1072 c->w53[0] = w53_16_c;
846 1072 c->w53[1] = w53_8_c;
847 1072 c->w97[0] = w97_16_c;
848 1072 c->w97[1] = w97_8_c;
849 1072 }
850
851 31 av_cold void ff_dwt_init(SnowDWTContext *c)
852 {
853 31 c->vertical_compose97i = snow_vertical_compose97i;
854 31 c->horizontal_compose97i = snow_horizontal_compose97i;
855 31 c->inner_add_yblock = ff_snow_inner_add_yblock;
856
857 #if ARCH_X86 && HAVE_MMX
858 31 ff_dwt_init_x86(c);
859 #endif
860 31 }
861
862
863