FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/4xm.c
Date: 2025-06-01 09:29:47
Exec Total Coverage
Lines: 455 541 84.1%
Functions: 16 16 100.0%
Branches: 217 295 73.6%

Line Branch Exec Source
1 /*
2 * 4XM codec
3 * Copyright (c) 2003 Michael Niedermayer
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 * 4XM codec.
25 */
26
27 #include <inttypes.h>
28
29 #include "libavutil/avassert.h"
30 #include "libavutil/frame.h"
31 #include "libavutil/imgutils.h"
32 #include "libavutil/intreadwrite.h"
33 #include "libavutil/mem.h"
34 #include "libavutil/mem_internal.h"
35 #include "libavutil/thread.h"
36 #include "avcodec.h"
37 #include "blockdsp.h"
38 #include "bswapdsp.h"
39 #include "bytestream.h"
40 #include "codec_internal.h"
41 #include "decode.h"
42 #include "get_bits.h"
43
44
45 #define BLOCK_TYPE_VLC_BITS 5
46 #define ACDC_VLC_BITS 9
47
48 #define CFRAME_BUFFER_COUNT 100
49
50 static const uint8_t block_type_tab[2][4][8][2] = {
51 {
52 { // { 8, 4, 2 } x { 8, 4, 2}
53 { 0, 1 }, { 2, 2 }, { 6, 3 }, { 14, 4 }, { 30, 5 }, { 31, 5 }, { 0, 0 }
54 }, { // { 8, 4 } x 1
55 { 0, 1 }, { 0, 0 }, { 2, 2 }, { 6, 3 }, { 14, 4 }, { 15, 4 }, { 0, 0 }
56 }, { // 1 x { 8, 4 }
57 { 0, 1 }, { 2, 2 }, { 0, 0 }, { 6, 3 }, { 14, 4 }, { 15, 4 }, { 0, 0 }
58 }, { // 1 x 2, 2 x 1
59 { 0, 1 }, { 0, 0 }, { 0, 0 }, { 2, 2 }, { 6, 3 }, { 14, 4 }, { 15, 4 }
60 }
61 }, {
62 { // { 8, 4, 2 } x { 8, 4, 2}
63 { 1, 2 }, { 4, 3 }, { 5, 3 }, { 0, 2 }, { 6, 3 }, { 7, 3 }, { 0, 0 }
64 }, {// { 8, 4 } x 1
65 { 1, 2 }, { 0, 0 }, { 2, 2 }, { 0, 2 }, { 6, 3 }, { 7, 3 }, { 0, 0 }
66 }, {// 1 x { 8, 4 }
67 { 1, 2 }, { 2, 2 }, { 0, 0 }, { 0, 2 }, { 6, 3 }, { 7, 3 }, { 0, 0 }
68 }, {// 1 x 2, 2 x 1
69 { 1, 2 }, { 0, 0 }, { 0, 0 }, { 0, 2 }, { 2, 2 }, { 6, 3 }, { 7, 3 }
70 }
71 }
72 };
73
74 static const uint8_t size2index[4][4] = {
75 { -1, 3, 1, 1 },
76 { 3, 0, 0, 0 },
77 { 2, 0, 0, 0 },
78 { 2, 0, 0, 0 },
79 };
80
81 static const int8_t mv[256][2] = {
82 { 0, 0 }, { 0, -1 }, { -1, 0 }, { 1, 0 }, { 0, 1 }, { -1, -1 }, { 1, -1 }, { -1, 1 },
83 { 1, 1 }, { 0, -2 }, { -2, 0 }, { 2, 0 }, { 0, 2 }, { -1, -2 }, { 1, -2 }, { -2, -1 },
84 { 2, -1 }, { -2, 1 }, { 2, 1 }, { -1, 2 }, { 1, 2 }, { -2, -2 }, { 2, -2 }, { -2, 2 },
85 { 2, 2 }, { 0, -3 }, { -3, 0 }, { 3, 0 }, { 0, 3 }, { -1, -3 }, { 1, -3 }, { -3, -1 },
86 { 3, -1 }, { -3, 1 }, { 3, 1 }, { -1, 3 }, { 1, 3 }, { -2, -3 }, { 2, -3 }, { -3, -2 },
87 { 3, -2 }, { -3, 2 }, { 3, 2 }, { -2, 3 }, { 2, 3 }, { 0, -4 }, { -4, 0 }, { 4, 0 },
88 { 0, 4 }, { -1, -4 }, { 1, -4 }, { -4, -1 }, { 4, -1 }, { 4, 1 }, { -1, 4 }, { 1, 4 },
89 { -3, -3 }, { -3, 3 }, { 3, 3 }, { -2, -4 }, { -4, -2 }, { 4, -2 }, { -4, 2 }, { -2, 4 },
90 { 2, 4 }, { -3, -4 }, { 3, -4 }, { 4, -3 }, { -5, 0 }, { -4, 3 }, { -3, 4 }, { 3, 4 },
91 { -1, -5 }, { -5, -1 }, { -5, 1 }, { -1, 5 }, { -2, -5 }, { 2, -5 }, { 5, -2 }, { 5, 2 },
92 { -4, -4 }, { -4, 4 }, { -3, -5 }, { -5, -3 }, { -5, 3 }, { 3, 5 }, { -6, 0 }, { 0, 6 },
93 { -6, -1 }, { -6, 1 }, { 1, 6 }, { 2, -6 }, { -6, 2 }, { 2, 6 }, { -5, -4 }, { 5, 4 },
94 { 4, 5 }, { -6, -3 }, { 6, 3 }, { -7, 0 }, { -1, -7 }, { 5, -5 }, { -7, 1 }, { -1, 7 },
95 { 4, -6 }, { 6, 4 }, { -2, -7 }, { -7, 2 }, { -3, -7 }, { 7, -3 }, { 3, 7 }, { 6, -5 },
96 { 0, -8 }, { -1, -8 }, { -7, -4 }, { -8, 1 }, { 4, 7 }, { 2, -8 }, { -2, 8 }, { 6, 6 },
97 { -8, 3 }, { 5, -7 }, { -5, 7 }, { 8, -4 }, { 0, -9 }, { -9, -1 }, { 1, 9 }, { 7, -6 },
98 { -7, 6 }, { -5, -8 }, { -5, 8 }, { -9, 3 }, { 9, -4 }, { 7, -7 }, { 8, -6 }, { 6, 8 },
99 { 10, 1 }, { -10, 2 }, { 9, -5 }, { 10, -3 }, { -8, -7 }, { -10, -4 }, { 6, -9 }, { -11, 0 },
100 { 11, 1 }, { -11, -2 }, { -2, 11 }, { 7, -9 }, { -7, 9 }, { 10, 6 }, { -4, 11 }, { 8, -9 },
101 { 8, 9 }, { 5, 11 }, { 7, -10 }, { 12, -3 }, { 11, 6 }, { -9, -9 }, { 8, 10 }, { 5, 12 },
102 { -11, 7 }, { 13, 2 }, { 6, -12 }, { 10, 9 }, { -11, 8 }, { -7, 12 }, { 0, 14 }, { 14, -2 },
103 { -9, 11 }, { -6, 13 }, { -14, -4 }, { -5, -14 }, { 5, 14 }, { -15, -1 }, { -14, -6 }, { 3, -15 },
104 { 11, -11 }, { -7, 14 }, { -5, 15 }, { 8, -14 }, { 15, 6 }, { 3, 16 }, { 7, -15 }, { -16, 5 },
105 { 0, 17 }, { -16, -6 }, { -10, 14 }, { -16, 7 }, { 12, 13 }, { -16, 8 }, { -17, 6 }, { -18, 3 },
106 { -7, 17 }, { 15, 11 }, { 16, 10 }, { 2, -19 }, { 3, -19 }, { -11, -16 }, { -18, 8 }, { -19, -6 },
107 { 2, -20 }, { -17, -11 }, { -10, -18 }, { 8, 19 }, { -21, -1 }, { -20, 7 }, { -4, 21 }, { 21, 5 },
108 { 15, 16 }, { 2, -22 }, { -10, -20 }, { -22, 5 }, { 20, -11 }, { -7, -22 }, { -12, 20 }, { 23, -5 },
109 { 13, -20 }, { 24, -2 }, { -15, 19 }, { -11, 22 }, { 16, 19 }, { 23, -10 }, { -18, -18 }, { -9, -24 },
110 { 24, -10 }, { -3, 26 }, { -23, 13 }, { -18, -20 }, { 17, 21 }, { -4, 27 }, { 27, 6 }, { 1, -28 },
111 { -11, 26 }, { -17, -23 }, { 7, 28 }, { 11, -27 }, { 29, 5 }, { -23, -19 }, { -28, -11 }, { -21, 22 },
112 { -30, 7 }, { -17, 26 }, { -27, 16 }, { 13, 29 }, { 19, -26 }, { 10, -31 }, { -14, -30 }, { 20, -27 },
113 { -29, 18 }, { -16, -31 }, { -28, -22 }, { 21, -30 }, { -25, 28 }, { 26, -29 }, { 25, -32 }, { -32, -32 }
114 };
115
116 /* This is simply the scaled down elementwise product of the standard JPEG
117 * quantizer table and the AAN premul table. */
118 static const uint8_t dequant_table[64] = {
119 16, 15, 13, 19, 24, 31, 28, 17,
120 17, 23, 25, 31, 36, 63, 45, 21,
121 18, 24, 27, 37, 52, 59, 49, 20,
122 16, 28, 34, 40, 60, 80, 51, 20,
123 18, 31, 48, 66, 68, 86, 56, 21,
124 19, 38, 56, 59, 64, 64, 48, 20,
125 27, 48, 55, 55, 56, 51, 35, 15,
126 20, 35, 34, 32, 31, 22, 15, 8,
127 };
128
129 static VLCElem block_type_vlc[2][4][32];
130
131
132 typedef struct CFrameBuffer {
133 unsigned int allocated_size;
134 unsigned int size;
135 int id;
136 uint8_t *data;
137 } CFrameBuffer;
138
139 typedef struct FourXContext {
140 AVCodecContext *avctx;
141 BlockDSPContext bdsp;
142 BswapDSPContext bbdsp;
143 uint16_t *frame_buffer;
144 uint16_t *last_frame_buffer;
145 GetBitContext pre_gb; ///< ac/dc prefix
146 GetBitContext gb;
147 GetByteContext g;
148 GetByteContext g2;
149 int mv[256];
150 VLC pre_vlc;
151 int last_dc;
152 DECLARE_ALIGNED(32, int16_t, block)[6][64];
153 void *bitstream_buffer;
154 unsigned int bitstream_buffer_size;
155 int version;
156 CFrameBuffer cfrm[CFRAME_BUFFER_COUNT];
157 } FourXContext;
158
159
160 #define FIX_1_082392200 70936
161 #define FIX_1_414213562 92682
162 #define FIX_1_847759065 121095
163 #define FIX_2_613125930 171254
164
165 #define MULTIPLY(var, const) ((int)((var) * (unsigned)(const)) >> 16)
166
167 7200 static void idct(int16_t block[64])
168 {
169 int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
170 int tmp10, tmp11, tmp12, tmp13;
171 int z5, z10, z11, z12, z13;
172 int i;
173 int temp[64];
174
175
2/2
✓ Branch 0 taken 57600 times.
✓ Branch 1 taken 7200 times.
64800 for (i = 0; i < 8; i++) {
176 57600 tmp10 = block[8 * 0 + i] + block[8 * 4 + i];
177 57600 tmp11 = block[8 * 0 + i] - block[8 * 4 + i];
178
179 57600 tmp13 = block[8 * 2 + i] + block[8 * 6 + i];
180 57600 tmp12 = MULTIPLY(block[8 * 2 + i] - block[8 * 6 + i], FIX_1_414213562) - tmp13;
181
182 57600 tmp0 = tmp10 + tmp13;
183 57600 tmp3 = tmp10 - tmp13;
184 57600 tmp1 = tmp11 + tmp12;
185 57600 tmp2 = tmp11 - tmp12;
186
187 57600 z13 = block[8 * 5 + i] + block[8 * 3 + i];
188 57600 z10 = block[8 * 5 + i] - block[8 * 3 + i];
189 57600 z11 = block[8 * 1 + i] + block[8 * 7 + i];
190 57600 z12 = block[8 * 1 + i] - block[8 * 7 + i];
191
192 57600 tmp7 = z11 + z13;
193 57600 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
194
195 57600 z5 = MULTIPLY(z10 + z12, FIX_1_847759065);
196 57600 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
197 57600 tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5;
198
199 57600 tmp6 = tmp12 - tmp7;
200 57600 tmp5 = tmp11 - tmp6;
201 57600 tmp4 = tmp10 + tmp5;
202
203 57600 temp[8 * 0 + i] = tmp0 + tmp7;
204 57600 temp[8 * 7 + i] = tmp0 - tmp7;
205 57600 temp[8 * 1 + i] = tmp1 + tmp6;
206 57600 temp[8 * 6 + i] = tmp1 - tmp6;
207 57600 temp[8 * 2 + i] = tmp2 + tmp5;
208 57600 temp[8 * 5 + i] = tmp2 - tmp5;
209 57600 temp[8 * 4 + i] = tmp3 + tmp4;
210 57600 temp[8 * 3 + i] = tmp3 - tmp4;
211 }
212
213
2/2
✓ Branch 0 taken 57600 times.
✓ Branch 1 taken 7200 times.
64800 for (i = 0; i < 8 * 8; i += 8) {
214 57600 tmp10 = temp[0 + i] + temp[4 + i];
215 57600 tmp11 = temp[0 + i] - temp[4 + i];
216
217 57600 tmp13 = temp[2 + i] + temp[6 + i];
218 57600 tmp12 = MULTIPLY(temp[2 + i] - temp[6 + i], FIX_1_414213562) - tmp13;
219
220 57600 tmp0 = tmp10 + tmp13;
221 57600 tmp3 = tmp10 - tmp13;
222 57600 tmp1 = tmp11 + tmp12;
223 57600 tmp2 = tmp11 - tmp12;
224
225 57600 z13 = temp[5 + i] + temp[3 + i];
226 57600 z10 = temp[5 + i] - temp[3 + i];
227 57600 z11 = temp[1 + i] + temp[7 + i];
228 57600 z12 = temp[1 + i] - temp[7 + i];
229
230 57600 tmp7 = z11 + z13;
231 57600 tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
232
233 57600 z5 = MULTIPLY(z10 + z12, FIX_1_847759065);
234 57600 tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
235 57600 tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5;
236
237 57600 tmp6 = tmp12 - tmp7;
238 57600 tmp5 = tmp11 - tmp6;
239 57600 tmp4 = tmp10 + tmp5;
240
241 57600 block[0 + i] = (tmp0 + tmp7) >> 6;
242 57600 block[7 + i] = (tmp0 - tmp7) >> 6;
243 57600 block[1 + i] = (tmp1 + tmp6) >> 6;
244 57600 block[6 + i] = (tmp1 - tmp6) >> 6;
245 57600 block[2 + i] = (tmp2 + tmp5) >> 6;
246 57600 block[5 + i] = (tmp2 - tmp5) >> 6;
247 57600 block[4 + i] = (tmp3 + tmp4) >> 6;
248 57600 block[3 + i] = (tmp3 - tmp4) >> 6;
249 }
250 7200 }
251
252 3 static av_cold void init_vlcs(void)
253 {
254 int i, j;
255
256
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 for (i = 0; i < 2; i++) {
257
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
30 for (j = 0; j < 4; j++) {
258 24 ff_vlc_init_table_sparse(block_type_vlc[i][j], FF_ARRAY_ELEMS(block_type_vlc[i][j]),
259 BLOCK_TYPE_VLC_BITS, 7,
260 24 &block_type_tab[i][j][0][1], 2, 1,
261 24 &block_type_tab[i][j][0][0], 2, 1,
262 NULL, 0, 0, 0);
263 }
264 }
265 3 }
266
267 183 static void init_mv(FourXContext *f, int linesize)
268 {
269 int i;
270
271
2/2
✓ Branch 0 taken 46848 times.
✓ Branch 1 taken 183 times.
47031 for (i = 0; i < 256; i++) {
272
2/2
✓ Branch 0 taken 3584 times.
✓ Branch 1 taken 43264 times.
46848 if (f->version > 1)
273 3584 f->mv[i] = mv[i][0] + mv[i][1] * linesize / 2;
274 else
275 43264 f->mv[i] = (i & 15) - 8 + ((i >> 4) - 8) * linesize / 2;
276 }
277 183 }
278
279 #if HAVE_BIGENDIAN
280 #define LE_CENTRIC_MUL(dst, src, scale, dc) \
281 { \
282 unsigned tmpval = AV_RN32(src); \
283 tmpval = (tmpval << 16) | (tmpval >> 16); \
284 tmpval = tmpval * (scale) + (dc); \
285 tmpval = (tmpval << 16) | (tmpval >> 16); \
286 AV_WN32A(dst, tmpval); \
287 }
288 #else
289 #define LE_CENTRIC_MUL(dst, src, scale, dc) \
290 { \
291 unsigned tmpval = AV_RN32(src) * (scale) + (dc); \
292 AV_WN32A(dst, tmpval); \
293 }
294 #endif
295
296 257504 static inline void mcdc(uint16_t *dst, const uint16_t *src, int log2w,
297 int h, int stride, int scale, unsigned dc)
298 {
299 int i;
300 257504 dc *= 0x10001;
301
302
4/5
✓ Branch 0 taken 55650 times.
✓ Branch 1 taken 46051 times.
✓ Branch 2 taken 46050 times.
✓ Branch 3 taken 109753 times.
✗ Branch 4 not taken.
257504 switch (log2w) {
303 55650 case 0:
304
2/2
✓ Branch 0 taken 278382 times.
✓ Branch 1 taken 55650 times.
334032 for (i = 0; i < h; i++) {
305 278382 dst[0] = scale * src[0] + dc;
306
2/2
✓ Branch 0 taken 276226 times.
✓ Branch 1 taken 2156 times.
278382 if (scale)
307 276226 src += stride;
308 278382 dst += stride;
309 }
310 55650 break;
311 46051 case 1:
312
2/2
✓ Branch 0 taken 167495 times.
✓ Branch 1 taken 46051 times.
213546 for (i = 0; i < h; i++) {
313 167495 LE_CENTRIC_MUL(dst, src, scale, dc);
314
2/2
✓ Branch 0 taken 161189 times.
✓ Branch 1 taken 6306 times.
167495 if (scale)
315 161189 src += stride;
316 167495 dst += stride;
317 }
318 46051 break;
319 46050 case 2:
320
2/2
✓ Branch 0 taken 144220 times.
✓ Branch 1 taken 46050 times.
190270 for (i = 0; i < h; i++) {
321 144220 LE_CENTRIC_MUL(dst, src, scale, dc);
322 144220 LE_CENTRIC_MUL(dst + 2, src + 2, scale, dc);
323
2/2
✓ Branch 0 taken 136750 times.
✓ Branch 1 taken 7470 times.
144220 if (scale)
324 136750 src += stride;
325 144220 dst += stride;
326 }
327 46050 break;
328 109753 case 3:
329
2/2
✓ Branch 0 taken 694635 times.
✓ Branch 1 taken 109753 times.
804388 for (i = 0; i < h; i++) {
330 694635 LE_CENTRIC_MUL(dst, src, scale, dc);
331 694635 LE_CENTRIC_MUL(dst + 2, src + 2, scale, dc);
332 694635 LE_CENTRIC_MUL(dst + 4, src + 4, scale, dc);
333 694635 LE_CENTRIC_MUL(dst + 6, src + 6, scale, dc);
334
2/2
✓ Branch 0 taken 656084 times.
✓ Branch 1 taken 38551 times.
694635 if (scale)
335 656084 src += stride;
336 694635 dst += stride;
337 }
338 109753 break;
339 default:
340 av_unreachable("log2w starts at 3 and gets only decremented during "
341 "recursive calls to decode_p_block");
342 }
343 257504 }
344
345 458368 static int decode_p_block(FourXContext *f, uint16_t *dst, const uint16_t *src,
346 int log2w, int log2h, int stride)
347 {
348 458368 int index, h, code, ret, scale = 1;
349 uint16_t *start, *end;
350 458368 unsigned dc = 0;
351
352
2/4
✓ Branch 0 taken 458368 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 458368 times.
458368 av_assert0(log2w >= 0 && log2h >= 0);
353
354 458368 index = size2index[log2h][log2w];
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 458368 times.
458368 av_assert0(index >= 0);
356
357
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 458368 times.
458368 if (get_bits_left(&f->gb) < 1)
358 return AVERROR_INVALIDDATA;
359 458368 h = 1 << log2h;
360 458368 code = get_vlc2(&f->gb, block_type_vlc[1 - (f->version > 1)][index],
361 BLOCK_TYPE_VLC_BITS, 1);
362
2/4
✓ Branch 0 taken 458368 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 458368 times.
458368 av_assert0(code >= 0 && code <= 6);
363
364 458368 start = f->last_frame_buffer;
365 458368 end = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
366
367
2/2
✓ Branch 0 taken 72772 times.
✓ Branch 1 taken 385596 times.
458368 if (code == 1) {
368 72772 log2h--;
369
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 72772 times.
72772 if ((ret = decode_p_block(f, dst, src, log2w, log2h, stride)) < 0)
370 return ret;
371 72772 return decode_p_block(f, dst + (stride << log2h),
372 72772 src + (stride << log2h),
373 log2w, log2h, stride);
374
2/2
✓ Branch 0 taken 87322 times.
✓ Branch 1 taken 298274 times.
385596 } else if (code == 2) {
375 87322 log2w--;
376
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 87322 times.
87322 if ((ret = decode_p_block(f, dst , src, log2w, log2h, stride)) < 0)
377 return ret;
378 87322 return decode_p_block(f, dst + (1 << log2w),
379 87322 src + (1 << log2w),
380 log2w, log2h, stride);
381
2/2
✓ Branch 0 taken 3858 times.
✓ Branch 1 taken 294416 times.
298274 } else if (code == 6) {
382
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3858 times.
3858 if (bytestream2_get_bytes_left(&f->g2) < 4) {
383 av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
384 return AVERROR_INVALIDDATA;
385 }
386
2/2
✓ Branch 0 taken 2594 times.
✓ Branch 1 taken 1264 times.
3858 if (log2w) {
387 2594 dst[0] = bytestream2_get_le16u(&f->g2);
388 2594 dst[1] = bytestream2_get_le16u(&f->g2);
389 } else {
390 1264 dst[0] = bytestream2_get_le16u(&f->g2);
391 1264 dst[stride] = bytestream2_get_le16u(&f->g2);
392 }
393 3858 return 0;
394 }
395
396
3/4
✓ Branch 0 taken 197273 times.
✓ Branch 1 taken 97143 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 197273 times.
294416 if ((code&3)==0 && bytestream2_get_bytes_left(&f->g) < 1) {
397 av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
398 return AVERROR_INVALIDDATA;
399 }
400
401
2/2
✓ Branch 0 taken 165799 times.
✓ Branch 1 taken 128617 times.
294416 if (code == 0) {
402 165799 src += f->mv[bytestream2_get_byte(&f->g)];
403
4/4
✓ Branch 0 taken 88291 times.
✓ Branch 1 taken 40326 times.
✓ Branch 2 taken 36912 times.
✓ Branch 3 taken 51379 times.
128617 } else if (code == 3 && f->version >= 2) {
404 36912 return 0;
405
2/2
✓ Branch 0 taken 31474 times.
✓ Branch 1 taken 60231 times.
91705 } else if (code == 4) {
406 31474 src += f->mv[bytestream2_get_byte(&f->g)];
407
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 31474 times.
31474 if (bytestream2_get_bytes_left(&f->g2) < 2){
408 av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
409 return AVERROR_INVALIDDATA;
410 }
411 31474 dc = bytestream2_get_le16(&f->g2);
412
2/2
✓ Branch 0 taken 8852 times.
✓ Branch 1 taken 51379 times.
60231 } else if (code == 5) {
413
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8852 times.
8852 if (bytestream2_get_bytes_left(&f->g2) < 2){
414 av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
415 return AVERROR_INVALIDDATA;
416 }
417
2/4
✓ Branch 0 taken 8852 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8852 times.
8852 av_assert0(start <= src && src <= end);
418 8852 scale = 0;
419 8852 dc = bytestream2_get_le16(&f->g2);
420 }
421
422
2/4
✓ Branch 0 taken 257504 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 257504 times.
257504 if (start > src || src > end) {
423 av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
424 return AVERROR_INVALIDDATA;
425 }
426
427 257504 mcdc(dst, src, log2w, h, stride, scale, dc);
428
429 257504 return 0;
430 }
431
432 183 static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
433 {
434 int x, y;
435 183 const int width = f->avctx->width;
436 183 const int height = f->avctx->height;
437 183 uint16_t *dst = f->frame_buffer;
438 uint16_t *src;
439 unsigned int bitstream_size, bytestream_size, wordstream_size, extra,
440 bytestream_offset, wordstream_offset;
441 int ret;
442
443 183 src = f->last_frame_buffer;
444
445
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 169 times.
183 if (f->version > 1) {
446 14 extra = 20;
447
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (length < extra)
448 return AVERROR_INVALIDDATA;
449 14 bitstream_size = AV_RL32(buf + 8);
450 14 wordstream_size = AV_RL32(buf + 12);
451 14 bytestream_size = AV_RL32(buf + 16);
452 } else {
453 169 extra = 0;
454 169 bitstream_size = AV_RL16(buf - 4);
455 169 wordstream_size = AV_RL16(buf - 2);
456 169 bytestream_size = FFMAX(length - bitstream_size - wordstream_size, 0);
457 }
458
459
2/4
✓ Branch 0 taken 183 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 183 times.
✗ Branch 3 not taken.
183 if (bitstream_size > length || bitstream_size >= INT_MAX/8 ||
460
1/2
✓ Branch 0 taken 183 times.
✗ Branch 1 not taken.
183 bytestream_size > length - bitstream_size ||
461
1/2
✓ Branch 0 taken 183 times.
✗ Branch 1 not taken.
183 wordstream_size > length - bytestream_size - bitstream_size ||
462
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 183 times.
183 extra > length - bytestream_size - bitstream_size - wordstream_size) {
463 av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size,
464 bitstream_size+ bytestream_size+ wordstream_size - length);
465 return AVERROR_INVALIDDATA;
466 }
467
468 183 av_fast_padded_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
469 bitstream_size);
470
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 183 times.
183 if (!f->bitstream_buffer)
471 return AVERROR(ENOMEM);
472 183 f->bbdsp.bswap_buf(f->bitstream_buffer, (const uint32_t *) (buf + extra),
473 183 bitstream_size / 4);
474 183 init_get_bits(&f->gb, f->bitstream_buffer, 8 * bitstream_size);
475
476 183 wordstream_offset = extra + bitstream_size;
477 183 bytestream_offset = extra + bitstream_size + wordstream_size;
478 183 bytestream2_init(&f->g2, buf + wordstream_offset,
479 183 length - wordstream_offset);
480 183 bytestream2_init(&f->g, buf + bytestream_offset,
481 183 length - bytestream_offset);
482
483 183 init_mv(f, width * 2);
484
485
2/2
✓ Branch 0 taken 3206 times.
✓ Branch 1 taken 183 times.
3389 for (y = 0; y < height; y += 8) {
486
2/2
✓ Branch 0 taken 138180 times.
✓ Branch 1 taken 3206 times.
141386 for (x = 0; x < width; x += 8)
487
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 138180 times.
138180 if ((ret = decode_p_block(f, dst + x, src + x, 3, 3, width)) < 0)
488 return ret;
489 3206 src += 8 * width;
490 3206 dst += 8 * width;
491 }
492
493 183 return 0;
494 }
495
496 /**
497 * decode block and dequantize.
498 * Note this is almost identical to MJPEG.
499 */
500 7200 static int decode_i_block(FourXContext *f, int16_t *block)
501 {
502 int code, i, j, level, val;
503
504
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7200 times.
7200 if (get_bits_left(&f->pre_gb) < 2) {
505 av_log(f->avctx, AV_LOG_ERROR, "%d bits left before decode_i_block()\n", get_bits_left(&f->pre_gb));
506 return AVERROR_INVALIDDATA;
507 }
508
509 /* DC coef */
510 7200 val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
511
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7200 times.
7200 if (val >> 4) {
512 av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n");
513 return AVERROR_INVALIDDATA;
514 }
515
516
2/2
✓ Branch 0 taken 6688 times.
✓ Branch 1 taken 512 times.
7200 if (val)
517 6688 val = get_xbits(&f->gb, val);
518
519 7200 val = val * dequant_table[0] + f->last_dc;
520 7200 f->last_dc = block[0] = val;
521 /* AC coefs */
522 7200 i = 1;
523 for (;;) {
524 80423 code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
525
526 /* EOB */
527
2/2
✓ Branch 0 taken 7068 times.
✓ Branch 1 taken 73355 times.
80423 if (code == 0)
528 7068 break;
529
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 73299 times.
73355 if (code == 0xf0) {
530 56 i += 16;
531
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (i >= 64) {
532 av_log(f->avctx, AV_LOG_ERROR, "run %d overflow\n", i);
533 return 0;
534 }
535 } else {
536
1/2
✓ Branch 0 taken 73299 times.
✗ Branch 1 not taken.
73299 if (code & 0xf) {
537 73299 level = get_xbits(&f->gb, code & 0xf);
538 } else {
539 av_log(f->avctx, AV_LOG_ERROR, "0 coeff\n");
540 return AVERROR_INVALIDDATA;
541 }
542 73299 i += code >> 4;
543
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73299 times.
73299 if (i >= 64) {
544 av_log(f->avctx, AV_LOG_ERROR, "run %d overflow\n", i);
545 return 0;
546 }
547
548 73299 j = ff_zigzag_direct[i];
549 73299 block[j] = level * dequant_table[j];
550 73299 i++;
551
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 73167 times.
73299 if (i >= 64)
552 132 break;
553 }
554 }
555
556 7200 return 0;
557 }
558
559 1200 static inline void idct_put(FourXContext *f, int x, int y)
560 {
561 1200 int16_t (*block)[64] = f->block;
562 1200 int stride = f->avctx->width;
563 int i;
564 1200 uint16_t *dst = f->frame_buffer + y * stride + x;
565
566
2/2
✓ Branch 0 taken 4800 times.
✓ Branch 1 taken 1200 times.
6000 for (i = 0; i < 4; i++) {
567 4800 block[i][0] += 0x80 * 8 * 8;
568 4800 idct(block[i]);
569 }
570
571
1/2
✓ Branch 0 taken 1200 times.
✗ Branch 1 not taken.
1200 if (!(f->avctx->flags & AV_CODEC_FLAG_GRAY)) {
572
2/2
✓ Branch 0 taken 2400 times.
✓ Branch 1 taken 1200 times.
3600 for (i = 4; i < 6; i++)
573 2400 idct(block[i]);
574 }
575
576 /* Note transform is:
577 * y = ( 1b + 4g + 2r) / 14
578 * cb = ( 3b - 2g - 1r) / 14
579 * cr = (-1b - 4g + 5r) / 14 */
580
2/2
✓ Branch 0 taken 9600 times.
✓ Branch 1 taken 1200 times.
10800 for (y = 0; y < 8; y++) {
581
2/2
✓ Branch 0 taken 76800 times.
✓ Branch 1 taken 9600 times.
86400 for (x = 0; x < 8; x++) {
582 76800 int16_t *temp = block[(x >> 2) + 2 * (y >> 2)] +
583 76800 2 * (x & 3) + 2 * 8 * (y & 3); // FIXME optimize
584 76800 int cb = block[4][x + 8 * y];
585 76800 int cr = block[5][x + 8 * y];
586 76800 int cg = (cb + cr) >> 1;
587 int y;
588
589 76800 cb += cb;
590
591 76800 y = temp[0];
592 76800 dst[0] = ((y + cb) >> 3) + (((y - cg) & 0xFC) << 3) + (((y + cr) & 0xF8) << 8);
593 76800 y = temp[1];
594 76800 dst[1] = ((y + cb) >> 3) + (((y - cg) & 0xFC) << 3) + (((y + cr) & 0xF8) << 8);
595 76800 y = temp[8];
596 76800 dst[stride] = ((y + cb) >> 3) + (((y - cg) & 0xFC) << 3) + (((y + cr) & 0xF8) << 8);
597 76800 y = temp[9];
598 76800 dst[1 + stride] = ((y + cb) >> 3) + (((y - cg) & 0xFC) << 3) + (((y + cr) & 0xF8) << 8);
599 76800 dst += 2;
600 }
601 9600 dst += 2 * stride - 2 * 8;
602 }
603 1200 }
604
605 1200 static int decode_i_mb(FourXContext *f)
606 {
607 int ret;
608 int i;
609
610 1200 f->bdsp.clear_blocks(f->block[0]);
611
612
2/2
✓ Branch 0 taken 7200 times.
✓ Branch 1 taken 1200 times.
8400 for (i = 0; i < 6; i++)
613
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7200 times.
7200 if ((ret = decode_i_block(f, f->block[i])) < 0)
614 return ret;
615
616 1200 return 0;
617 }
618
619 1 static const uint8_t *read_huffman_tables(FourXContext *f,
620 const uint8_t * const buf,
621 int buf_size)
622 {
623 1 int frequency[512] = { 0 };
624 uint8_t flag[512];
625 int up[512];
626 uint8_t len_tab[257];
627 int bits_tab[257];
628 int start, end;
629 1 const uint8_t *ptr = buf;
630 1 const uint8_t *ptr_end = buf + buf_size;
631 int j;
632
633 1 memset(up, -1, sizeof(up));
634
635 1 start = *ptr++;
636 1 end = *ptr++;
637 15 for (;;) {
638 int i;
639
640
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ptr_end - ptr < FFMAX(end - start + 1, 0) + 1) {
641 av_log(f->avctx, AV_LOG_ERROR, "invalid data in read_huffman_tables\n");
642 return NULL;
643 }
644
645
2/2
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 16 times.
77 for (i = start; i <= end; i++)
646 61 frequency[i] = *ptr++;
647 16 start = *ptr++;
648
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 15 times.
16 if (start == 0)
649 1 break;
650
651 15 end = *ptr++;
652 }
653 1 frequency[256] = 1;
654
655
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 while ((ptr - buf) & 3)
656 2 ptr++; // 4byte align
657
658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ptr > ptr_end) {
659 av_log(f->avctx, AV_LOG_ERROR, "ptr overflow in read_huffman_tables\n");
660 return NULL;
661 }
662
663
1/2
✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
61 for (j = 257; j < 512; j++) {
664 61 int min_freq[2] = { 256 * 256, 256 * 256 };
665 61 int smallest[2] = { 0, 0 };
666 int i;
667
2/2
✓ Branch 0 taken 17507 times.
✓ Branch 1 taken 61 times.
17568 for (i = 0; i < j; i++) {
668
2/2
✓ Branch 0 taken 15616 times.
✓ Branch 1 taken 1891 times.
17507 if (frequency[i] == 0)
669 15616 continue;
670
2/2
✓ Branch 0 taken 722 times.
✓ Branch 1 taken 1169 times.
1891 if (frequency[i] < min_freq[1]) {
671
2/2
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 316 times.
722 if (frequency[i] < min_freq[0]) {
672 406 min_freq[1] = min_freq[0];
673 406 smallest[1] = smallest[0];
674 406 min_freq[0] = frequency[i];
675 406 smallest[0] = i;
676 } else {
677 316 min_freq[1] = frequency[i];
678 316 smallest[1] = i;
679 }
680 }
681 }
682
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 60 times.
61 if (min_freq[1] == 256 * 256)
683 1 break;
684
685 60 frequency[j] = min_freq[0] + min_freq[1];
686 60 flag[smallest[0]] = 0;
687 60 flag[smallest[1]] = 1;
688 60 up[smallest[0]] =
689 60 up[smallest[1]] = j;
690 60 frequency[smallest[0]] = frequency[smallest[1]] = 0;
691 }
692
693
2/2
✓ Branch 0 taken 257 times.
✓ Branch 1 taken 1 times.
258 for (j = 0; j < 257; j++) {
694 257 int node, len = 0, bits = 0;
695
696
2/2
✓ Branch 0 taken 510 times.
✓ Branch 1 taken 257 times.
767 for (node = j; up[node] != -1; node = up[node]) {
697 510 bits += flag[node] << len;
698 510 len++;
699
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 510 times.
510 if (len > 31)
700 // can this happen at all ?
701 av_log(f->avctx, AV_LOG_ERROR,
702 "vlc length overflow\n");
703 }
704
705 257 bits_tab[j] = bits;
706 257 len_tab[j] = len;
707 }
708
709 1 ff_vlc_free(&f->pre_vlc);
710
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (vlc_init(&f->pre_vlc, ACDC_VLC_BITS, 257, len_tab, 1, 1,
711 bits_tab, 4, 4, 0))
712 return NULL;
713
714 1 return ptr;
715 }
716
717 1050 static int mix(int c0, int c1)
718 {
719 1050 int blue = 2 * (c0 & 0x001F) + (c1 & 0x001F);
720 1050 int green = (2 * (c0 & 0x03E0) + (c1 & 0x03E0)) >> 5;
721 1050 int red = 2 * (c0 >> 10) + (c1 >> 10);
722 1050 return red / 3 * 1024 + green / 3 * 32 + blue / 3;
723 }
724
725 5 static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length)
726 {
727 int x, y, x2, y2;
728 5 const int width = f->avctx->width;
729 5 const int height = f->avctx->height;
730 5 const int mbs = (FFALIGN(width, 16) >> 4) * (FFALIGN(height, 16) >> 4);
731 5 uint16_t *dst = f->frame_buffer;
732 5 const uint8_t *buf_end = buf + length;
733 GetByteContext g3;
734
735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (length < mbs * 8) {
736 av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n");
737 return AVERROR_INVALIDDATA;
738 }
739 5 bytestream2_init(&g3, buf, length);
740
741
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 5 times.
40 for (y = 0; y < height; y += 16) {
742
2/2
✓ Branch 0 taken 525 times.
✓ Branch 1 taken 35 times.
560 for (x = 0; x < width; x += 16) {
743 525 unsigned int color[4] = { 0 }, bits;
744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 525 times.
525 if (buf_end - buf < 8)
745 return AVERROR_INVALIDDATA;
746 // warning following is purely guessed ...
747 525 color[0] = bytestream2_get_le16u(&g3);
748 525 color[1] = bytestream2_get_le16u(&g3);
749
750
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 525 times.
525 if (color[0] & 0x8000)
751 av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n");
752
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 525 times.
525 if (color[1] & 0x8000)
753 av_log(f->avctx, AV_LOG_ERROR, "unk bit 2\n");
754
755 525 color[2] = mix(color[0], color[1]);
756 525 color[3] = mix(color[1], color[0]);
757
758 525 bits = bytestream2_get_le32u(&g3);
759
2/2
✓ Branch 0 taken 8400 times.
✓ Branch 1 taken 525 times.
8925 for (y2 = 0; y2 < 16; y2++) {
760
2/2
✓ Branch 0 taken 134400 times.
✓ Branch 1 taken 8400 times.
142800 for (x2 = 0; x2 < 16; x2++) {
761 134400 int index = 2 * (x2 >> 2) + 8 * (y2 >> 2);
762 134400 dst[y2 * width + x2] = color[(bits >> index) & 3];
763 }
764 }
765 525 dst += 16;
766 }
767 35 dst += 16 * width - x;
768 }
769
770 5 return 0;
771 }
772
773 1 static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
774 {
775 int x, y, ret;
776 1 const int width = f->avctx->width;
777 1 const int height = f->avctx->height;
778 1 const unsigned int bitstream_size = AV_RL32(buf);
779 unsigned int prestream_size;
780 const uint8_t *prestream;
781
782
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (bitstream_size > (1 << 26))
783 return AVERROR_INVALIDDATA;
784
785
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (length < bitstream_size + 12) {
786 av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n");
787 return AVERROR_INVALIDDATA;
788 }
789
790 1 prestream_size = 4 * AV_RL32(buf + bitstream_size + 4);
791 1 prestream = buf + bitstream_size + 12;
792
793
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (prestream_size + bitstream_size + 12 != length
794
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 || prestream_size > (1 << 26)) {
795 av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n",
796 prestream_size, bitstream_size, length);
797 return AVERROR_INVALIDDATA;
798 }
799
800 1 prestream = read_huffman_tables(f, prestream, prestream_size);
801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!prestream) {
802 av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n");
803 return AVERROR_INVALIDDATA;
804 }
805
806
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 av_assert0(prestream <= buf + length);
807
808 1 init_get_bits(&f->gb, buf + 4, 8 * bitstream_size);
809
810 1 prestream_size = length + buf - prestream;
811
812 1 av_fast_padded_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
813 prestream_size);
814
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!f->bitstream_buffer)
815 return AVERROR(ENOMEM);
816 1 f->bbdsp.bswap_buf(f->bitstream_buffer, (const uint32_t *) prestream,
817 1 prestream_size / 4);
818 1 init_get_bits(&f->pre_gb, f->bitstream_buffer, 8 * prestream_size);
819
820 1 f->last_dc = 0 * 128 * 8 * 8;
821
822
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 1 times.
31 for (y = 0; y < height; y += 16) {
823
2/2
✓ Branch 0 taken 1200 times.
✓ Branch 1 taken 30 times.
1230 for (x = 0; x < width; x += 16) {
824
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1200 times.
1200 if ((ret = decode_i_mb(f)) < 0)
825 return ret;
826
827 1200 idct_put(f, x, y);
828 }
829 }
830
831
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256)
832 av_log(f->avctx, AV_LOG_ERROR, "end mismatch\n");
833
834 1 return 0;
835 }
836
837 201 static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
838 int *got_frame, AVPacket *avpkt)
839 {
840 201 const uint8_t *buf = avpkt->data;
841 201 int buf_size = avpkt->size;
842 201 FourXContext *const f = avctx->priv_data;
843 int i, frame_4cc, frame_size, ret;
844
845
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 201 times.
201 if (buf_size < 20)
846 return AVERROR_INVALIDDATA;
847
848
2/4
✓ Branch 0 taken 201 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 201 times.
201 av_assert0(avctx->width % 16 == 0 && avctx->height % 16 == 0);
849
850
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 201 times.
201 if (buf_size < AV_RL32(buf + 4) + 8) {
851 av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %"PRIu32"\n",
852 buf_size, AV_RL32(buf + 4));
853 return AVERROR_INVALIDDATA;
854 }
855
856 201 frame_4cc = AV_RL32(buf);
857
858
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 187 times.
201 if (frame_4cc == AV_RL32("cfrm")) {
859 14 int free_index = -1;
860 int id, whole_size;
861 14 const int data_size = buf_size - 20;
862 CFrameBuffer *cfrm;
863
864
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (f->version <= 1) {
865 av_log(f->avctx, AV_LOG_ERROR, "cfrm in version %d\n", f->version);
866 return AVERROR_INVALIDDATA;
867 }
868
869 14 id = AV_RL32(buf + 12);
870 14 whole_size = AV_RL32(buf + 16);
871
872
2/4
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 if (data_size < 0 || whole_size < 0) {
873 av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n");
874 return AVERROR_INVALIDDATA;
875 }
876
877
2/2
✓ Branch 0 taken 1400 times.
✓ Branch 1 taken 14 times.
1414 for (i = 0; i < CFRAME_BUFFER_COUNT; i++)
878
3/4
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 1385 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
1400 if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_num)
879 av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n",
880 f->cfrm[i].id);
881
882
2/2
✓ Branch 0 taken 1396 times.
✓ Branch 1 taken 2 times.
1398 for (i = 0; i < CFRAME_BUFFER_COUNT; i++) {
883
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1384 times.
1396 if (f->cfrm[i].id == id)
884 12 break;
885
2/2
✓ Branch 0 taken 1382 times.
✓ Branch 1 taken 2 times.
1384 if (f->cfrm[i].size == 0)
886 1382 free_index = i;
887 }
888
889
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
14 if (i >= CFRAME_BUFFER_COUNT) {
890
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (free_index < 0)
891 return AVERROR_INVALIDDATA;
892 2 i = free_index;
893 2 f->cfrm[i].id = id;
894 }
895 14 cfrm = &f->cfrm[i];
896
897
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (data_size > UINT_MAX - cfrm->size - AV_INPUT_BUFFER_PADDING_SIZE)
898 return AVERROR_INVALIDDATA;
899
900 28 cfrm->data = av_fast_realloc(cfrm->data, &cfrm->allocated_size,
901 14 cfrm->size + data_size + AV_INPUT_BUFFER_PADDING_SIZE);
902 // explicit check needed as memcpy below might not catch a NULL
903
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (!cfrm->data) {
904 av_log(f->avctx, AV_LOG_ERROR, "realloc failure\n");
905 return AVERROR(ENOMEM);
906 }
907
908 14 memcpy(cfrm->data + cfrm->size, buf + 20, data_size);
909 14 cfrm->size += data_size;
910
911
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
14 if (cfrm->size >= whole_size) {
912 2 buf = cfrm->data;
913 2 frame_size = cfrm->size;
914
915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (id != avctx->frame_num)
916 av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %"PRId64"\n",
917 id, avctx->frame_num);
918
919
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (f->version <= 1)
920 return AVERROR_INVALIDDATA;
921
922 2 cfrm->size = cfrm->id = 0;
923 2 frame_4cc = AV_RL32("pfrm");
924 } else
925 12 return buf_size;
926 } else {
927 187 buf = buf + 12;
928 187 frame_size = buf_size - 12;
929 }
930
931
4/4
✓ Branch 0 taken 184 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 183 times.
✓ Branch 3 taken 1 times.
189 if ( frame_4cc == AV_RL32("ifr2") || frame_4cc == AV_RL32("ifrm")
932
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 171 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
183 || frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
933
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 189 times.
189 if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
934 return ret;
935 }
936
937
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 184 times.
189 if (frame_4cc == AV_RL32("ifr2")) {
938 5 picture->pict_type = AV_PICTURE_TYPE_I;
939
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 if ((ret = decode_i2_frame(f, buf - 4, frame_size + 4)) < 0) {
940 av_log(f->avctx, AV_LOG_ERROR, "decode i2 frame failed\n");
941 return ret;
942 }
943
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 183 times.
184 } else if (frame_4cc == AV_RL32("ifrm")) {
944 1 picture->pict_type = AV_PICTURE_TYPE_I;
945
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if ((ret = decode_i_frame(f, buf, frame_size)) < 0) {
946 av_log(f->avctx, AV_LOG_ERROR, "decode i frame failed\n");
947 return ret;
948 }
949
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 171 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
183 } else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
950 183 picture->pict_type = AV_PICTURE_TYPE_P;
951
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 183 times.
183 if ((ret = decode_p_frame(f, buf, frame_size)) < 0) {
952 av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n");
953 return ret;
954 }
955 } else if (frame_4cc == AV_RL32("snd_")) {
956 av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n",
957 buf_size);
958 return AVERROR_INVALIDDATA;
959 } else {
960 av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n",
961 buf_size);
962 return AVERROR_INVALIDDATA;
963 }
964
965
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 183 times.
189 if (picture->pict_type == AV_PICTURE_TYPE_I)
966 6 picture->flags |= AV_FRAME_FLAG_KEY;
967 else
968 183 picture->flags &= ~AV_FRAME_FLAG_KEY;
969
970 189 av_image_copy_plane(picture->data[0], picture->linesize[0],
971 189 (const uint8_t*)f->frame_buffer, avctx->width * 2,
972 189 avctx->width * 2, avctx->height);
973 189 FFSWAP(uint16_t *, f->frame_buffer, f->last_frame_buffer);
974
975 189 *got_frame = 1;
976
977 189 return buf_size;
978 }
979
980 5 static av_cold int decode_end(AVCodecContext *avctx)
981 {
982 5 FourXContext * const f = avctx->priv_data;
983 int i;
984
985 5 av_freep(&f->frame_buffer);
986 5 av_freep(&f->last_frame_buffer);
987 5 av_freep(&f->bitstream_buffer);
988 5 f->bitstream_buffer_size = 0;
989
2/2
✓ Branch 0 taken 500 times.
✓ Branch 1 taken 5 times.
505 for (i = 0; i < CFRAME_BUFFER_COUNT; i++) {
990 500 av_freep(&f->cfrm[i].data);
991 500 f->cfrm[i].allocated_size = 0;
992 }
993 5 ff_vlc_free(&f->pre_vlc);
994
995 5 return 0;
996 }
997
998 5 static av_cold int decode_init(AVCodecContext *avctx)
999 {
1000 static AVOnce init_static_once = AV_ONCE_INIT;
1001 5 FourXContext * const f = avctx->priv_data;
1002 int ret;
1003
1004
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
5 if (avctx->extradata_size != 4 || !avctx->extradata) {
1005 av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n");
1006 return AVERROR_INVALIDDATA;
1007 }
1008
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
5 if((avctx->width % 16) || (avctx->height % 16)) {
1009 av_log(avctx, AV_LOG_ERROR, "unsupported width/height\n");
1010 return AVERROR_INVALIDDATA;
1011 }
1012
1013 5 ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
1014
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (ret < 0)
1015 return ret;
1016
1017 5 f->frame_buffer = av_mallocz(avctx->width * avctx->height * 2);
1018 5 f->last_frame_buffer = av_mallocz(avctx->width * avctx->height * 2);
1019
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
5 if (!f->frame_buffer || !f->last_frame_buffer)
1020 return AVERROR(ENOMEM);
1021
1022 5 f->version = AV_RL32(avctx->extradata) >> 16;
1023 5 ff_blockdsp_init(&f->bdsp);
1024 5 ff_bswapdsp_init(&f->bbdsp);
1025 5 f->avctx = avctx;
1026
1027
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 if (f->version > 2)
1028 3 avctx->pix_fmt = AV_PIX_FMT_RGB565;
1029 else
1030 2 avctx->pix_fmt = AV_PIX_FMT_BGR555;
1031
1032 5 ff_thread_once(&init_static_once, init_vlcs);
1033
1034 5 return 0;
1035 }
1036
1037 const FFCodec ff_fourxm_decoder = {
1038 .p.name = "4xm",
1039 CODEC_LONG_NAME("4X Movie"),
1040 .p.type = AVMEDIA_TYPE_VIDEO,
1041 .p.id = AV_CODEC_ID_4XM,
1042 .priv_data_size = sizeof(FourXContext),
1043 .init = decode_init,
1044 .close = decode_end,
1045 FF_CODEC_DECODE_CB(decode_frame),
1046 .p.capabilities = AV_CODEC_CAP_DR1,
1047 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1048 };
1049