FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/lagarith.c
Date: 2024-05-26 22:00:00
Exec Total Coverage
Lines: 282 387 72.9%
Functions: 13 14 92.9%
Branches: 137 210 65.2%

Line Branch Exec Source
1 /*
2 * Lagarith lossless decoder
3 * Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com>
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 /**
23 * @file
24 * Lagarith lossless decoder
25 * @author Nathan Caldwell
26 */
27
28 #include <inttypes.h>
29
30 #include "libavutil/thread.h"
31
32 #include "avcodec.h"
33 #include "codec_internal.h"
34 #include "get_bits.h"
35 #include "mathops.h"
36 #include "lagarithrac.h"
37 #include "lossless_videodsp.h"
38 #include "thread.h"
39
40 #define VLC_BITS 7
41
42 enum LagarithFrameType {
43 FRAME_RAW = 1, /**< uncompressed */
44 FRAME_U_RGB24 = 2, /**< unaligned RGB24 */
45 FRAME_ARITH_YUY2 = 3, /**< arithmetic coded YUY2 */
46 FRAME_ARITH_RGB24 = 4, /**< arithmetic coded RGB24 */
47 FRAME_SOLID_GRAY = 5, /**< solid grayscale color frame */
48 FRAME_SOLID_COLOR = 6, /**< solid non-grayscale color frame */
49 FRAME_OLD_ARITH_RGB = 7, /**< obsolete arithmetic coded RGB (no longer encoded by upstream since version 1.1.0) */
50 FRAME_ARITH_RGBA = 8, /**< arithmetic coded RGBA */
51 FRAME_SOLID_RGBA = 9, /**< solid RGBA color frame */
52 FRAME_ARITH_YV12 = 10, /**< arithmetic coded YV12 */
53 FRAME_REDUCED_RES = 11, /**< reduced resolution YV12 frame */
54 };
55
56 typedef struct LagarithContext {
57 AVCodecContext *avctx;
58 LLVidDSPContext llviddsp;
59 int zeros; /**< number of consecutive zero bytes encountered */
60 int zeros_rem; /**< number of zero bytes remaining to output */
61 } LagarithContext;
62
63 static VLCElem lag_tab[1 << VLC_BITS];
64
65 static const uint8_t lag_bits[] = {
66 7, 7, 2, 7, 3, 4, 5, 6, 7, 7, 7, 7, 7, 6, 7, 4, 5, 7, 7, 7, 7,
67 5, 6, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7,
68 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
69 };
70
71 static const uint8_t lag_codes[] = {
72 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x05,
73 0x08, 0x09, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B, 0x10, 0x11, 0x12, 0x13,
74 0x13, 0x13, 0x14, 0x15, 0x20, 0x21, 0x22, 0x23, 0x23, 0x24, 0x25,
75 0x28, 0x29, 0x2A, 0x2B, 0x2B, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
76 0x48, 0x49, 0x4A, 0x4B, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55,
77 };
78
79 static const uint8_t lag_symbols[] = {
80 20, 12, 0, 12, 1, 2, 4, 7, 7, 28, 4, 25, 17,
81 10, 17, 3, 6, 2, 23, 15, 15, 5, 9, 10, 31, 1, 22,
82 14, 14, 8, 9, 30, 6, 27, 19, 11, 19, 0, 21, 13, 13,
83 8, 29, 5, 26, 18, 18, 3, 24, 16, 16, 11, 32,
84 };
85
86 9 static av_cold void lag_init_static_data(void)
87 {
88 9 VLC_INIT_STATIC_SPARSE_TABLE(lag_tab, VLC_BITS, FF_ARRAY_ELEMS(lag_bits),
89 lag_bits, 1, 1, lag_codes, 1, 1, lag_symbols, 1, 1, 0);
90 9 }
91
92 /**
93 * Compute the 52-bit mantissa of 1/(double)denom.
94 * This crazy format uses floats in an entropy coder and we have to match x86
95 * rounding exactly, thus ordinary floats aren't portable enough.
96 * @param denom denominator
97 * @return 52-bit mantissa
98 * @see softfloat_mul
99 */
100 124 static uint64_t softfloat_reciprocal(uint32_t denom)
101 {
102 124 int shift = av_log2(denom - 1) + 1;
103 124 uint64_t ret = (1ULL << 52) / denom;
104 124 uint64_t err = (1ULL << 52) - ret * denom;
105 124 ret <<= shift;
106 124 err <<= shift;
107 124 err += denom / 2;
108 124 return ret + err / denom;
109 }
110
111 /**
112 * (uint32_t)(x*f), where f has the given mantissa, and exponent 0
113 * Used in combination with softfloat_reciprocal computes x/(double)denom.
114 * @param x 32-bit integer factor
115 * @param mantissa mantissa of f with exponent 0
116 * @return 32-bit integer value (x*f)
117 * @see softfloat_reciprocal
118 */
119 31744 static uint32_t softfloat_mul(uint32_t x, uint64_t mantissa)
120 {
121 31744 uint64_t l = x * (mantissa & 0xffffffff);
122 31744 uint64_t h = x * (mantissa >> 32);
123 31744 h += l >> 32;
124 31744 l &= 0xffffffff;
125 31744 l += 1LL << av_log2(h >> 21);
126 31744 h += l >> 32;
127 31744 return h >> 20;
128 }
129
130 462516 static uint8_t lag_calc_zero_run(int8_t x)
131 {
132 462516 return (x * 2) ^ (x >> 7);
133 }
134
135 21140 static int lag_decode_prob(GetBitContext *gb, uint32_t *value)
136 {
137 unsigned val, bits;
138
139 21140 bits = get_vlc2(gb, lag_tab, VLC_BITS, 1);
140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21140 times.
21140 if (bits > 31) {
141 *value = 0;
142 return AVERROR_INVALIDDATA;
143
2/2
✓ Branch 0 taken 3841 times.
✓ Branch 1 taken 17299 times.
21140 } else if (bits == 0) {
144 3841 *value = 0;
145 3841 return 0;
146 }
147
148 17299 val = get_bits_long(gb, bits);
149 17299 val |= 1U << bits;
150
151 17299 *value = val - 1;
152
153 17299 return 0;
154 }
155
156 126 static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb)
157 {
158 int i, j, scale_factor;
159 unsigned prob, cumulative_target;
160 126 unsigned cumul_prob = 0;
161 126 unsigned scaled_cumul_prob = 0;
162 126 int nnz = 0;
163
164 126 rac->prob[0] = 0;
165 126 rac->prob[257] = UINT_MAX;
166 /* Read probabilities from bitstream */
167
2/2
✓ Branch 0 taken 18484 times.
✓ Branch 1 taken 126 times.
18610 for (i = 1; i < 257; i++) {
168
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 18484 times.
18484 if (lag_decode_prob(gb, &rac->prob[i]) < 0) {
169 av_log(rac->logctx, AV_LOG_ERROR, "Invalid probability encountered.\n");
170 return AVERROR_INVALIDDATA;
171 }
172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18484 times.
18484 if ((uint64_t)cumul_prob + rac->prob[i] > UINT_MAX) {
173 av_log(rac->logctx, AV_LOG_ERROR, "Integer overflow encountered in cumulative probability calculation.\n");
174 return AVERROR_INVALIDDATA;
175 }
176 18484 cumul_prob += rac->prob[i];
177
2/2
✓ Branch 0 taken 2656 times.
✓ Branch 1 taken 15828 times.
18484 if (!rac->prob[i]) {
178
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2656 times.
2656 if (lag_decode_prob(gb, &prob)) {
179 av_log(rac->logctx, AV_LOG_ERROR, "Invalid probability run encountered.\n");
180 return AVERROR_INVALIDDATA;
181 }
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2656 times.
2656 if (prob > 256 - i)
183 prob = 256 - i;
184
2/2
✓ Branch 0 taken 13772 times.
✓ Branch 1 taken 2656 times.
16428 for (j = 0; j < prob; j++)
185 13772 rac->prob[++i] = 0;
186 }else {
187 15828 nnz++;
188 }
189 }
190
191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (!cumul_prob) {
192 av_log(rac->logctx, AV_LOG_ERROR, "All probabilities are 0!\n");
193 return AVERROR_INVALIDDATA;
194 }
195
196
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
126 if (nnz == 1 && (show_bits_long(gb, 32) & 0xFFFFFF)) {
197 return AVERROR_INVALIDDATA;
198 }
199
200 /* Scale probabilities so cumulative probability is an even power of 2. */
201 126 scale_factor = av_log2(cumul_prob);
202
203
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 2 times.
126 if (cumul_prob & (cumul_prob - 1)) {
204 124 uint64_t mul = softfloat_reciprocal(cumul_prob);
205
2/2
✓ Branch 0 taken 15872 times.
✓ Branch 1 taken 124 times.
15996 for (i = 1; i <= 128; i++) {
206 15872 rac->prob[i] = softfloat_mul(rac->prob[i], mul);
207 15872 scaled_cumul_prob += rac->prob[i];
208 }
209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 124 times.
124 if (scaled_cumul_prob <= 0) {
210 av_log(rac->logctx, AV_LOG_ERROR, "Scaled probabilities invalid\n");
211 return AVERROR_INVALIDDATA;
212 }
213
2/2
✓ Branch 0 taken 15872 times.
✓ Branch 1 taken 124 times.
15996 for (; i < 257; i++) {
214 15872 rac->prob[i] = softfloat_mul(rac->prob[i], mul);
215 15872 scaled_cumul_prob += rac->prob[i];
216 }
217
218 124 scale_factor++;
219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 124 times.
124 if (scale_factor >= 32U)
220 return AVERROR_INVALIDDATA;
221 124 cumulative_target = 1U << scale_factor;
222
223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 124 times.
124 if (scaled_cumul_prob > cumulative_target) {
224 av_log(rac->logctx, AV_LOG_ERROR,
225 "Scaled probabilities are larger than target!\n");
226 return AVERROR_INVALIDDATA;
227 }
228
229 124 scaled_cumul_prob = cumulative_target - scaled_cumul_prob;
230
231
2/2
✓ Branch 0 taken 12751 times.
✓ Branch 1 taken 124 times.
12875 for (i = 1; scaled_cumul_prob; i = (i & 0x7f) + 1) {
232
2/2
✓ Branch 0 taken 7341 times.
✓ Branch 1 taken 5410 times.
12751 if (rac->prob[i]) {
233 7341 rac->prob[i]++;
234 7341 scaled_cumul_prob--;
235 }
236 /* Comment from reference source:
237 * if (b & 0x80 == 0) { // order of operations is 'wrong'; it has been left this way
238 * // since the compression change is negligible and fixing it
239 * // breaks backwards compatibility
240 * b =- (signed int)b;
241 * b &= 0xFF;
242 * } else {
243 * b++;
244 * b &= 0x7f;
245 * }
246 */
247 }
248 }
249
250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (scale_factor > 23)
251 return AVERROR_INVALIDDATA;
252
253 126 rac->scale = scale_factor;
254
255 /* Fill probability array with cumulative probability for each symbol. */
256
2/2
✓ Branch 0 taken 32256 times.
✓ Branch 1 taken 126 times.
32382 for (i = 1; i < 257; i++)
257 32256 rac->prob[i] += rac->prob[i - 1];
258
259 126 return 0;
260 }
261
262 49320 static void add_lag_median_prediction(uint8_t *dst, uint8_t *src1,
263 uint8_t *diff, int w, int *left,
264 int *left_top)
265 {
266 /* This is almost identical to add_hfyu_median_pred in huffyuvdsp.h.
267 * However the &0xFF on the gradient predictor yields incorrect output
268 * for lagarith.
269 */
270 int i;
271 uint8_t l, lt;
272
273 49320 l = *left;
274 49320 lt = *left_top;
275
276
2/2
✓ Branch 0 taken 33377504 times.
✓ Branch 1 taken 49320 times.
33426824 for (i = 0; i < w; i++) {
277 33377504 l = mid_pred(l, src1[i], l + src1[i] - lt) + diff[i];
278 33377504 lt = src1[i];
279 33377504 dst[i] = l;
280 }
281
282 49320 *left = l;
283 49320 *left_top = lt;
284 49320 }
285
286 49440 static void lag_pred_line(LagarithContext *l, uint8_t *buf,
287 int width, int stride, int line)
288 {
289 int L, TL;
290
291
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 49320 times.
49440 if (!line) {
292 /* Left prediction only for first line */
293 120 L = l->llviddsp.add_left_pred(buf, buf, width, 0);
294 } else {
295 /* Left pixel is actually prev_row[width] */
296 49320 L = buf[width - stride - 1];
297
298
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 49200 times.
49320 if (line == 1) {
299 /* Second line, left predict first pixel, the rest of the line is median predicted
300 * NOTE: In the case of RGB this pixel is top predicted */
301
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 111 times.
120 TL = l->avctx->pix_fmt == AV_PIX_FMT_YUV420P ? buf[-stride] : L;
302 } else {
303 /* Top left is 2 rows back, last pixel */
304 49200 TL = buf[width - (2 * stride) - 1];
305 }
306
307 49320 add_lag_median_prediction(buf, buf - stride, buf,
308 width, &L, &TL);
309 }
310 49440 }
311
312 4608 static void lag_pred_line_yuy2(LagarithContext *l, uint8_t *buf,
313 int width, int stride, int line,
314 int is_luma)
315 {
316 int L, TL;
317
318
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4602 times.
4608 if (!line) {
319 6 L= buf[0];
320
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (is_luma)
321 2 buf[0] = 0;
322 6 l->llviddsp.add_left_pred(buf, buf, width, 0);
323
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (is_luma)
324 2 buf[0] = L;
325 6 return;
326 }
327
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4596 times.
4602 if (line == 1) {
328
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 const int HEAD = is_luma ? 4 : 2;
329 int i;
330
331 6 L = buf[width - stride - 1];
332 6 TL = buf[HEAD - stride - 1];
333
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6 times.
22 for (i = 0; i < HEAD; i++) {
334 16 L += buf[i];
335 16 buf[i] = L;
336 }
337
2/2
✓ Branch 0 taken 4080 times.
✓ Branch 1 taken 6 times.
4086 for (; i < width; i++) {
338 4080 L = mid_pred(L & 0xFF, buf[i - stride], (L + buf[i - stride] - TL) & 0xFF) + buf[i];
339 4080 TL = buf[i - stride];
340 4080 buf[i] = L;
341 }
342 } else {
343 4596 TL = buf[width - (2 * stride) - 1];
344 4596 L = buf[width - stride - 1];
345 4596 l->llviddsp.add_median_pred(buf, buf - stride, buf, width, &L, &TL);
346 }
347 }
348
349 54048 static int lag_decode_line(LagarithContext *l, lag_rac *rac,
350 uint8_t *dst, int width, int stride,
351 int esc_count)
352 {
353 54048 int i = 0;
354 54048 int ret = 0;
355
356
2/2
✓ Branch 0 taken 52392 times.
✓ Branch 1 taken 1656 times.
54048 if (!esc_count)
357 1656 esc_count = -1;
358
359 /* Output any zeros remaining from the previous run */
360 54048 handle_zeros:
361
2/2
✓ Branch 0 taken 376521 times.
✓ Branch 1 taken 140043 times.
516564 if (l->zeros_rem) {
362 376521 int count = FFMIN(l->zeros_rem, width - i);
363 376521 memset(dst + i, 0, count);
364 376521 i += count;
365 376521 l->zeros_rem -= count;
366 }
367
368
2/2
✓ Branch 0 taken 4147575 times.
✓ Branch 1 taken 54048 times.
4201623 while (i < width) {
369 4147575 dst[i] = lag_get_rac(rac);
370 4147575 ret++;
371
372
2/2
✓ Branch 0 taken 2802454 times.
✓ Branch 1 taken 1345121 times.
4147575 if (dst[i])
373 2802454 l->zeros = 0;
374 else
375 1345121 l->zeros++;
376
377 4147575 i++;
378
2/2
✓ Branch 0 taken 462516 times.
✓ Branch 1 taken 3685059 times.
4147575 if (l->zeros == esc_count) {
379 462516 int index = lag_get_rac(rac);
380 462516 ret++;
381
382 462516 l->zeros = 0;
383
384 462516 l->zeros_rem = lag_calc_zero_run(index);
385 462516 goto handle_zeros;
386 }
387 }
388 54048 return ret;
389 }
390
391 static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst,
392 const uint8_t *src, const uint8_t *src_end,
393 int width, int esc_count)
394 {
395 int i = 0;
396 int count;
397 uint8_t zero_run = 0;
398 const uint8_t *src_start = src;
399 uint8_t mask1 = -(esc_count < 2);
400 uint8_t mask2 = -(esc_count < 3);
401 uint8_t *end = dst + (width - 2);
402
403 avpriv_request_sample(l->avctx, "zero_run_line");
404
405 memset(dst, 0, width);
406
407 output_zeros:
408 if (l->zeros_rem) {
409 count = FFMIN(l->zeros_rem, width - i);
410 if (end - dst < count) {
411 av_log(l->avctx, AV_LOG_ERROR, "Too many zeros remaining.\n");
412 return AVERROR_INVALIDDATA;
413 }
414
415 memset(dst, 0, count);
416 l->zeros_rem -= count;
417 dst += count;
418 }
419
420 while (dst < end) {
421 i = 0;
422 while (!zero_run && dst + i < end) {
423 i++;
424 if (i+2 >= src_end - src)
425 return AVERROR_INVALIDDATA;
426 zero_run =
427 !(src[i] | (src[i + 1] & mask1) | (src[i + 2] & mask2));
428 }
429 if (zero_run) {
430 zero_run = 0;
431 i += esc_count;
432 if (i > end - dst ||
433 i >= src_end - src)
434 return AVERROR_INVALIDDATA;
435 memcpy(dst, src, i);
436 dst += i;
437 l->zeros_rem = lag_calc_zero_run(src[i]);
438
439 src += i + 1;
440 goto output_zeros;
441 } else {
442 memcpy(dst, src, i);
443 src += i;
444 dst += i;
445 }
446 }
447 return src - src_start;
448 }
449
450
451
452 134 static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst,
453 int width, int height, int stride,
454 const uint8_t *src, int src_size)
455 {
456 134 int i = 0;
457 134 int read = 0;
458 uint32_t length;
459 134 uint32_t offset = 1;
460 int esc_count;
461 GetBitContext gb;
462 lag_rac rac;
463 134 const uint8_t *src_end = src + src_size;
464 int ret;
465
466 134 rac.logctx = l->avctx;
467 134 l->zeros = 0;
468
469
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 134 times.
134 if(src_size < 2)
470 return AVERROR_INVALIDDATA;
471
472 134 esc_count = src[0];
473
2/2
✓ Branch 0 taken 126 times.
✓ Branch 1 taken 8 times.
134 if (esc_count < 4) {
474 126 length = width * height;
475
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if(src_size < 5)
476 return AVERROR_INVALIDDATA;
477
3/4
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 123 times.
✗ Branch 3 not taken.
126 if (esc_count && AV_RL32(src + 1) < length) {
478 123 length = AV_RL32(src + 1);
479 123 offset += 4;
480 }
481
482
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 126 times.
126 if ((ret = init_get_bits8(&gb, src + offset, src_size - offset)) < 0)
483 return ret;
484
485
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 126 times.
126 if ((ret = lag_read_prob_header(&rac, &gb)) < 0)
486 return ret;
487
488 126 ff_lag_rac_init(&rac, &gb, length - stride);
489
2/2
✓ Branch 0 taken 54048 times.
✓ Branch 1 taken 126 times.
54174 for (i = 0; i < height; i++) {
490
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54048 times.
54048 if (rac.overread > MAX_OVERREAD)
491 return AVERROR_INVALIDDATA;
492 54048 read += lag_decode_line(l, &rac, dst + (i * stride), width,
493 stride, esc_count);
494 }
495
496
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 126 times.
126 if (read > length)
497 av_log(l->avctx, AV_LOG_WARNING,
498 "Output more bytes than length (%d of %"PRIu32")\n", read,
499 length);
500
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 } else if (esc_count < 8) {
501 esc_count -= 4;
502 src ++;
503 src_size --;
504 if (esc_count > 0) {
505 /* Zero run coding only, no range coding. */
506 for (i = 0; i < height; i++) {
507 int res = lag_decode_zero_run_line(l, dst + (i * stride), src,
508 src_end, width, esc_count);
509 if (res < 0)
510 return res;
511 src += res;
512 }
513 } else {
514 if (src_size < width * height)
515 return AVERROR_INVALIDDATA; // buffer not big enough
516 /* Plane is stored uncompressed */
517 for (i = 0; i < height; i++) {
518 memcpy(dst + (i * stride), src, width);
519 src += width;
520 }
521 }
522
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 } else if (esc_count == 0xff) {
523 /* Plane is a solid run of given value */
524
2/2
✓ Branch 0 taken 2880 times.
✓ Branch 1 taken 8 times.
2888 for (i = 0; i < height; i++)
525 2880 memset(dst + i * stride, src[1], width);
526 /* Do not apply prediction.
527 Note: memset to 0 above, setting first value to src[1]
528 and applying prediction gives the same result. */
529 8 return 0;
530 } else {
531 av_log(l->avctx, AV_LOG_ERROR,
532 "Invalid zero run escape code! (%#x)\n", esc_count);
533 return AVERROR_INVALIDDATA;
534 }
535
536
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 6 times.
126 if (l->avctx->pix_fmt != AV_PIX_FMT_YUV422P) {
537
2/2
✓ Branch 0 taken 49440 times.
✓ Branch 1 taken 120 times.
49560 for (i = 0; i < height; i++) {
538 49440 lag_pred_line(l, dst, width, stride, i);
539 49440 dst += stride;
540 }
541 } else {
542
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 6 times.
4614 for (i = 0; i < height; i++) {
543 4608 lag_pred_line_yuy2(l, dst, width, stride, i,
544 4608 width == l->avctx->width);
545 4608 dst += stride;
546 }
547 }
548
549 126 return 0;
550 }
551
552 /**
553 * Decode a frame.
554 * @param avctx codec context
555 * @param data output AVFrame
556 * @param data_size size of output data or 0 if no picture is returned
557 * @param avpkt input packet
558 * @return number of consumed bytes on success or negative if decode fails
559 */
560 78 static int lag_decode_frame(AVCodecContext *avctx, AVFrame *p,
561 int *got_frame, AVPacket *avpkt)
562 {
563 78 const uint8_t *buf = avpkt->data;
564 78 unsigned int buf_size = avpkt->size;
565 78 LagarithContext *l = avctx->priv_data;
566 uint8_t frametype;
567 78 uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
568 uint32_t offs[4];
569 uint8_t *srcs[4];
570 78 int i, j, planes = 3;
571 78 int ret = 0;
572
573 78 frametype = buf[0];
574
575 78 offset_gu = AV_RL32(buf + 1);
576 78 offset_bv = AV_RL32(buf + 5);
577
578
7/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
78 switch (frametype) {
579 6 case FRAME_SOLID_RGBA:
580 6 avctx->pix_fmt = AV_PIX_FMT_GBRAP;
581 14 case FRAME_SOLID_GRAY:
582
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
14 if (frametype == FRAME_SOLID_GRAY)
583
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (avctx->bits_per_coded_sample == 24) {
584 8 avctx->pix_fmt = AV_PIX_FMT_GBRP;
585 } else {
586 avctx->pix_fmt = AV_PIX_FMT_GBRAP;
587 planes = 4;
588 }
589
590
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
14 if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
591 return ret;
592
593
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8 times.
14 if (frametype == FRAME_SOLID_RGBA) {
594
2/2
✓ Branch 0 taken 2880 times.
✓ Branch 1 taken 6 times.
2886 for (i = 0; i < avctx->height; i++) {
595 2880 memset(p->data[0] + i * p->linesize[0], buf[2], avctx->width);
596 2880 memset(p->data[1] + i * p->linesize[1], buf[1], avctx->width);
597 2880 memset(p->data[2] + i * p->linesize[2], buf[3], avctx->width);
598 2880 memset(p->data[3] + i * p->linesize[3], buf[4], avctx->width);
599 }
600 } else {
601
2/2
✓ Branch 0 taken 2880 times.
✓ Branch 1 taken 8 times.
2888 for (i = 0; i < avctx->height; i++) {
602
2/2
✓ Branch 0 taken 8640 times.
✓ Branch 1 taken 2880 times.
11520 for (j = 0; j < planes; j++)
603 8640 memset(p->data[j] + i * p->linesize[j], buf[1], avctx->width);
604 }
605 }
606 14 break;
607 26 case FRAME_SOLID_COLOR:
608
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (avctx->bits_per_coded_sample == 24) {
609 26 avctx->pix_fmt = AV_PIX_FMT_GBRP;
610 } else {
611 avctx->pix_fmt = AV_PIX_FMT_GBRAP;
612 }
613
614
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
26 if ((ret = ff_thread_get_buffer(avctx, p,0)) < 0)
615 return ret;
616
617
2/2
✓ Branch 0 taken 6240 times.
✓ Branch 1 taken 26 times.
6266 for (i = 0; i < avctx->height; i++) {
618 6240 memset(p->data[0] + i * p->linesize[0], buf[2], avctx->width);
619 6240 memset(p->data[1] + i * p->linesize[1], buf[1], avctx->width);
620 6240 memset(p->data[2] + i * p->linesize[2], buf[3], avctx->width);
621
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6240 times.
6240 if (avctx->pix_fmt == AV_PIX_FMT_GBRAP)
622 memset(p->data[3] + i * p->linesize[3], 0xFFu, avctx->width);
623 }
624 26 break;
625 20 case FRAME_ARITH_RGBA:
626 20 avctx->pix_fmt = AV_PIX_FMT_GBRAP;
627 20 planes = 4;
628 20 offset_ry += 4;
629 20 offs[3] = AV_RL32(buf + 9);
630 33 case FRAME_ARITH_RGB24:
631 case FRAME_U_RGB24:
632
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20 times.
33 if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24)
633 13 avctx->pix_fmt = AV_PIX_FMT_GBRP;
634
635
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
33 if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
636 return ret;
637
638 33 offs[0] = offset_bv;
639 33 offs[1] = offset_gu;
640 33 offs[2] = offset_ry;
641
642
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 33 times.
152 for (i = 0; i < planes; i++)
643 119 srcs[i] = p->data[i] + (avctx->height - 1) * p->linesize[i];
644
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 33 times.
152 for (i = 0; i < planes; i++)
645
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 119 times.
119 if (buf_size <= offs[i]) {
646 av_log(avctx, AV_LOG_ERROR,
647 "Invalid frame offsets\n");
648 return AVERROR_INVALIDDATA;
649 }
650
651
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 33 times.
152 for (i = 0; i < planes; i++) {
652 119 ret = lag_decode_arith_plane(l, srcs[i],
653 avctx->width, avctx->height,
654 119 -p->linesize[i], buf + offs[i],
655 119 buf_size - offs[i]);
656
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 119 times.
119 if (ret < 0)
657 return ret;
658 }
659
2/2
✓ Branch 0 taken 13760 times.
✓ Branch 1 taken 33 times.
13793 for (i = 0; i < avctx->height; i++) {
660 13760 l->llviddsp.add_bytes(p->data[0] + i * p->linesize[0], p->data[1] + i * p->linesize[1], avctx->width);
661 13760 l->llviddsp.add_bytes(p->data[2] + i * p->linesize[2], p->data[1] + i * p->linesize[1], avctx->width);
662 }
663 33 FFSWAP(uint8_t*, p->data[0], p->data[1]);
664 33 FFSWAP(int, p->linesize[0], p->linesize[1]);
665 33 FFSWAP(uint8_t*, p->data[2], p->data[1]);
666 33 FFSWAP(int, p->linesize[2], p->linesize[1]);
667 33 break;
668 2 case FRAME_ARITH_YUY2:
669 2 avctx->pix_fmt = AV_PIX_FMT_YUV422P;
670
671
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
672 return ret;
673
674
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 if (offset_ry >= buf_size ||
675
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 offset_gu >= buf_size ||
676 offset_bv >= buf_size) {
677 av_log(avctx, AV_LOG_ERROR,
678 "Invalid frame offsets\n");
679 return AVERROR_INVALIDDATA;
680 }
681
682 2 ret = lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
683 p->linesize[0], buf + offset_ry,
684 2 buf_size - offset_ry);
685
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret < 0)
686 return ret;
687 2 ret = lag_decode_arith_plane(l, p->data[1], (avctx->width + 1) / 2,
688 avctx->height, p->linesize[1],
689 2 buf + offset_gu, buf_size - offset_gu);
690
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret < 0)
691 return ret;
692 2 ret = lag_decode_arith_plane(l, p->data[2], (avctx->width + 1) / 2,
693 avctx->height, p->linesize[2],
694 2 buf + offset_bv, buf_size - offset_bv);
695 2 break;
696 3 case FRAME_ARITH_YV12:
697 3 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
698
699
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
700 return ret;
701
702
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 if (offset_ry >= buf_size ||
703
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 offset_gu >= buf_size ||
704 offset_bv >= buf_size) {
705 av_log(avctx, AV_LOG_ERROR,
706 "Invalid frame offsets\n");
707 return AVERROR_INVALIDDATA;
708 }
709
710 3 ret = lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
711 p->linesize[0], buf + offset_ry,
712 3 buf_size - offset_ry);
713
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0)
714 return ret;
715 3 ret = lag_decode_arith_plane(l, p->data[2], (avctx->width + 1) / 2,
716 3 (avctx->height + 1) / 2, p->linesize[2],
717 3 buf + offset_gu, buf_size - offset_gu);
718
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (ret < 0)
719 return ret;
720 3 ret = lag_decode_arith_plane(l, p->data[1], (avctx->width + 1) / 2,
721 3 (avctx->height + 1) / 2, p->linesize[1],
722 3 buf + offset_bv, buf_size - offset_bv);
723 3 break;
724 default:
725 av_log(avctx, AV_LOG_ERROR,
726 "Unsupported Lagarith frame type: %#"PRIx8"\n", frametype);
727 return AVERROR_PATCHWELCOME;
728 }
729
730
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 78 times.
78 if (ret < 0)
731 return ret;
732
733 78 *got_frame = 1;
734
735 78 return buf_size;
736 }
737
738 18 static av_cold int lag_decode_init(AVCodecContext *avctx)
739 {
740 static AVOnce init_static_once = AV_ONCE_INIT;
741 18 LagarithContext *l = avctx->priv_data;
742 18 l->avctx = avctx;
743
744 18 ff_llviddsp_init(&l->llviddsp);
745 18 ff_thread_once(&init_static_once, lag_init_static_data);
746
747 18 return 0;
748 }
749
750 const FFCodec ff_lagarith_decoder = {
751 .p.name = "lagarith",
752 CODEC_LONG_NAME("Lagarith lossless"),
753 .p.type = AVMEDIA_TYPE_VIDEO,
754 .p.id = AV_CODEC_ID_LAGARITH,
755 .priv_data_size = sizeof(LagarithContext),
756 .init = lag_decode_init,
757 FF_CODEC_DECODE_CB(lag_decode_frame),
758 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
759 };
760