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