FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/4xm.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 453 539 84.0%
Functions: 16 16 100.0%
Branches: 210 287 73.2%

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_assert0(0);
341 }
342 257504 }
343
344 458368 static int decode_p_block(FourXContext *f, uint16_t *dst, const uint16_t *src,
345 int log2w, int log2h, int stride)
346 {
347 458368 int index, h, code, ret, scale = 1;
348 uint16_t *start, *end;
349 458368 unsigned dc = 0;
350
351
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);
352
353 458368 index = size2index[log2h][log2w];
354
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 458368 times.
458368 av_assert0(index >= 0);
355
356
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 458368 times.
458368 if (get_bits_left(&f->gb) < 1)
357 return AVERROR_INVALIDDATA;
358 458368 h = 1 << log2h;
359 458368 code = get_vlc2(&f->gb, block_type_vlc[1 - (f->version > 1)][index],
360 BLOCK_TYPE_VLC_BITS, 1);
361
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);
362
363 458368 start = f->last_frame_buffer;
364 458368 end = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
365
366
2/2
✓ Branch 0 taken 72772 times.
✓ Branch 1 taken 385596 times.
458368 if (code == 1) {
367 72772 log2h--;
368
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 72772 times.
72772 if ((ret = decode_p_block(f, dst, src, log2w, log2h, stride)) < 0)
369 return ret;
370 72772 return decode_p_block(f, dst + (stride << log2h),
371 72772 src + (stride << log2h),
372 log2w, log2h, stride);
373
2/2
✓ Branch 0 taken 87322 times.
✓ Branch 1 taken 298274 times.
385596 } else if (code == 2) {
374 87322 log2w--;
375
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 87322 times.
87322 if ((ret = decode_p_block(f, dst , src, log2w, log2h, stride)) < 0)
376 return ret;
377 87322 return decode_p_block(f, dst + (1 << log2w),
378 87322 src + (1 << log2w),
379 log2w, log2h, stride);
380
2/2
✓ Branch 0 taken 3858 times.
✓ Branch 1 taken 294416 times.
298274 } else if (code == 6) {
381
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3858 times.
3858 if (bytestream2_get_bytes_left(&f->g2) < 4) {
382 av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
383 return AVERROR_INVALIDDATA;
384 }
385
2/2
✓ Branch 0 taken 2594 times.
✓ Branch 1 taken 1264 times.
3858 if (log2w) {
386 2594 dst[0] = bytestream2_get_le16u(&f->g2);
387 2594 dst[1] = bytestream2_get_le16u(&f->g2);
388 } else {
389 1264 dst[0] = bytestream2_get_le16u(&f->g2);
390 1264 dst[stride] = bytestream2_get_le16u(&f->g2);
391 }
392 3858 return 0;
393 }
394
395
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) {
396 av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
397 return AVERROR_INVALIDDATA;
398 }
399
400
2/2
✓ Branch 0 taken 165799 times.
✓ Branch 1 taken 128617 times.
294416 if (code == 0) {
401 165799 src += f->mv[bytestream2_get_byte(&f->g)];
402
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) {
403 36912 return 0;
404
2/2
✓ Branch 0 taken 31474 times.
✓ Branch 1 taken 60231 times.
91705 } else if (code == 4) {
405 31474 src += f->mv[bytestream2_get_byte(&f->g)];
406
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 31474 times.
31474 if (bytestream2_get_bytes_left(&f->g2) < 2){
407 av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
408 return AVERROR_INVALIDDATA;
409 }
410 31474 dc = bytestream2_get_le16(&f->g2);
411
2/2
✓ Branch 0 taken 8852 times.
✓ Branch 1 taken 51379 times.
60231 } else if (code == 5) {
412
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8852 times.
8852 if (bytestream2_get_bytes_left(&f->g2) < 2){
413 av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
414 return AVERROR_INVALIDDATA;
415 }
416
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);
417 8852 scale = 0;
418 8852 dc = bytestream2_get_le16(&f->g2);
419 }
420
421
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) {
422 av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
423 return AVERROR_INVALIDDATA;
424 }
425
426 257504 mcdc(dst, src, log2w, h, stride, scale, dc);
427
428 257504 return 0;
429 }
430
431 183 static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
432 {
433 int x, y;
434 183 const int width = f->avctx->width;
435 183 const int height = f->avctx->height;
436 183 uint16_t *dst = f->frame_buffer;
437 uint16_t *src;
438 unsigned int bitstream_size, bytestream_size, wordstream_size, extra,
439 bytestream_offset, wordstream_offset;
440 int ret;
441
442 183 src = f->last_frame_buffer;
443
444
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 169 times.
183 if (f->version > 1) {
445 14 extra = 20;
446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (length < extra)
447 return AVERROR_INVALIDDATA;
448 14 bitstream_size = AV_RL32(buf + 8);
449 14 wordstream_size = AV_RL32(buf + 12);
450 14 bytestream_size = AV_RL32(buf + 16);
451 } else {
452 169 extra = 0;
453 169 bitstream_size = AV_RL16(buf - 4);
454 169 wordstream_size = AV_RL16(buf - 2);
455 169 bytestream_size = FFMAX(length - bitstream_size - wordstream_size, 0);
456 }
457
458
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 ||
459
1/2
✓ Branch 0 taken 183 times.
✗ Branch 1 not taken.
183 bytestream_size > length - bitstream_size ||
460
1/2
✓ Branch 0 taken 183 times.
✗ Branch 1 not taken.
183 wordstream_size > length - bytestream_size - bitstream_size ||
461
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 183 times.
183 extra > length - bytestream_size - bitstream_size - wordstream_size) {
462 av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size,
463 bitstream_size+ bytestream_size+ wordstream_size - length);
464 return AVERROR_INVALIDDATA;
465 }
466
467 183 av_fast_padded_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
468 bitstream_size);
469
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 183 times.
183 if (!f->bitstream_buffer)
470 return AVERROR(ENOMEM);
471 183 f->bbdsp.bswap_buf(f->bitstream_buffer, (const uint32_t *) (buf + extra),
472 183 bitstream_size / 4);
473 183 init_get_bits(&f->gb, f->bitstream_buffer, 8 * bitstream_size);
474
475 183 wordstream_offset = extra + bitstream_size;
476 183 bytestream_offset = extra + bitstream_size + wordstream_size;
477 183 bytestream2_init(&f->g2, buf + wordstream_offset,
478 183 length - wordstream_offset);
479 183 bytestream2_init(&f->g, buf + bytestream_offset,
480 183 length - bytestream_offset);
481
482 183 init_mv(f, width * 2);
483
484
2/2
✓ Branch 0 taken 3206 times.
✓ Branch 1 taken 183 times.
3389 for (y = 0; y < height; y += 8) {
485
2/2
✓ Branch 0 taken 138180 times.
✓ Branch 1 taken 3206 times.
141386 for (x = 0; x < width; x += 8)
486
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)
487 return ret;
488 3206 src += 8 * width;
489 3206 dst += 8 * width;
490 }
491
492 183 return 0;
493 }
494
495 /**
496 * decode block and dequantize.
497 * Note this is almost identical to MJPEG.
498 */
499 7200 static int decode_i_block(FourXContext *f, int16_t *block)
500 {
501 int code, i, j, level, val;
502
503
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7200 times.
7200 if (get_bits_left(&f->pre_gb) < 2) {
504 av_log(f->avctx, AV_LOG_ERROR, "%d bits left before decode_i_block()\n", get_bits_left(&f->pre_gb));
505 return AVERROR_INVALIDDATA;
506 }
507
508 /* DC coef */
509 7200 val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7200 times.
7200 if (val >> 4) {
511 av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n");
512 return AVERROR_INVALIDDATA;
513 }
514
515
2/2
✓ Branch 0 taken 6688 times.
✓ Branch 1 taken 512 times.
7200 if (val)
516 6688 val = get_xbits(&f->gb, val);
517
518 7200 val = val * dequant_table[0] + f->last_dc;
519 7200 f->last_dc = block[0] = val;
520 /* AC coefs */
521 7200 i = 1;
522 for (;;) {
523 80423 code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
524
525 /* EOB */
526
2/2
✓ Branch 0 taken 7068 times.
✓ Branch 1 taken 73355 times.
80423 if (code == 0)
527 7068 break;
528
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 73299 times.
73355 if (code == 0xf0) {
529 56 i += 16;
530
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (i >= 64) {
531 av_log(f->avctx, AV_LOG_ERROR, "run %d overflow\n", i);
532 return 0;
533 }
534 } else {
535
1/2
✓ Branch 0 taken 73299 times.
✗ Branch 1 not taken.
73299 if (code & 0xf) {
536 73299 level = get_xbits(&f->gb, code & 0xf);
537 } else {
538 av_log(f->avctx, AV_LOG_ERROR, "0 coeff\n");
539 return AVERROR_INVALIDDATA;
540 }
541 73299 i += code >> 4;
542
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73299 times.
73299 if (i >= 64) {
543 av_log(f->avctx, AV_LOG_ERROR, "run %d overflow\n", i);
544 return 0;
545 }
546
547 73299 j = ff_zigzag_direct[i];
548 73299 block[j] = level * dequant_table[j];
549 73299 i++;
550
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 73167 times.
73299 if (i >= 64)
551 132 break;
552 }
553 }
554
555 7200 return 0;
556 }
557
558 1200 static inline void idct_put(FourXContext *f, int x, int y)
559 {
560 1200 int16_t (*block)[64] = f->block;
561 1200 int stride = f->avctx->width;
562 int i;
563 1200 uint16_t *dst = f->frame_buffer + y * stride + x;
564
565
2/2
✓ Branch 0 taken 4800 times.
✓ Branch 1 taken 1200 times.
6000 for (i = 0; i < 4; i++) {
566 4800 block[i][0] += 0x80 * 8 * 8;
567 4800 idct(block[i]);
568 }
569
570
1/2
✓ Branch 0 taken 1200 times.
✗ Branch 1 not taken.
1200 if (!(f->avctx->flags & AV_CODEC_FLAG_GRAY)) {
571
2/2
✓ Branch 0 taken 2400 times.
✓ Branch 1 taken 1200 times.
3600 for (i = 4; i < 6; i++)
572 2400 idct(block[i]);
573 }
574
575 /* Note transform is:
576 * y = ( 1b + 4g + 2r) / 14
577 * cb = ( 3b - 2g - 1r) / 14
578 * cr = (-1b - 4g + 5r) / 14 */
579
2/2
✓ Branch 0 taken 9600 times.
✓ Branch 1 taken 1200 times.
10800 for (y = 0; y < 8; y++) {
580
2/2
✓ Branch 0 taken 76800 times.
✓ Branch 1 taken 9600 times.
86400 for (x = 0; x < 8; x++) {
581 76800 int16_t *temp = block[(x >> 2) + 2 * (y >> 2)] +
582 76800 2 * (x & 3) + 2 * 8 * (y & 3); // FIXME optimize
583 76800 int cb = block[4][x + 8 * y];
584 76800 int cr = block[5][x + 8 * y];
585 76800 int cg = (cb + cr) >> 1;
586 int y;
587
588 76800 cb += cb;
589
590 76800 y = temp[0];
591 76800 dst[0] = ((y + cb) >> 3) + (((y - cg) & 0xFC) << 3) + (((y + cr) & 0xF8) << 8);
592 76800 y = temp[1];
593 76800 dst[1] = ((y + cb) >> 3) + (((y - cg) & 0xFC) << 3) + (((y + cr) & 0xF8) << 8);
594 76800 y = temp[8];
595 76800 dst[stride] = ((y + cb) >> 3) + (((y - cg) & 0xFC) << 3) + (((y + cr) & 0xF8) << 8);
596 76800 y = temp[9];
597 76800 dst[1 + stride] = ((y + cb) >> 3) + (((y - cg) & 0xFC) << 3) + (((y + cr) & 0xF8) << 8);
598 76800 dst += 2;
599 }
600 9600 dst += 2 * stride - 2 * 8;
601 }
602 1200 }
603
604 1200 static int decode_i_mb(FourXContext *f)
605 {
606 int ret;
607 int i;
608
609 1200 f->bdsp.clear_blocks(f->block[0]);
610
611
2/2
✓ Branch 0 taken 7200 times.
✓ Branch 1 taken 1200 times.
8400 for (i = 0; i < 6; i++)
612
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7200 times.
7200 if ((ret = decode_i_block(f, f->block[i])) < 0)
613 return ret;
614
615 1200 return 0;
616 }
617
618 1 static const uint8_t *read_huffman_tables(FourXContext *f,
619 const uint8_t * const buf,
620 int buf_size)
621 {
622 1 int frequency[512] = { 0 };
623 uint8_t flag[512];
624 int up[512];
625 uint8_t len_tab[257];
626 int bits_tab[257];
627 int start, end;
628 1 const uint8_t *ptr = buf;
629 1 const uint8_t *ptr_end = buf + buf_size;
630 int j;
631
632 1 memset(up, -1, sizeof(up));
633
634 1 start = *ptr++;
635 1 end = *ptr++;
636 15 for (;;) {
637 int i;
638
639
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ptr_end - ptr < FFMAX(end - start + 1, 0) + 1) {
640 av_log(f->avctx, AV_LOG_ERROR, "invalid data in read_huffman_tables\n");
641 return NULL;
642 }
643
644
2/2
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 16 times.
77 for (i = start; i <= end; i++)
645 61 frequency[i] = *ptr++;
646 16 start = *ptr++;
647
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 15 times.
16 if (start == 0)
648 1 break;
649
650 15 end = *ptr++;
651 }
652 1 frequency[256] = 1;
653
654
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 while ((ptr - buf) & 3)
655 2 ptr++; // 4byte align
656
657
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ptr > ptr_end) {
658 av_log(f->avctx, AV_LOG_ERROR, "ptr overflow in read_huffman_tables\n");
659 return NULL;
660 }
661
662
1/2
✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
61 for (j = 257; j < 512; j++) {
663 61 int min_freq[2] = { 256 * 256, 256 * 256 };
664 61 int smallest[2] = { 0, 0 };
665 int i;
666
2/2
✓ Branch 0 taken 17507 times.
✓ Branch 1 taken 61 times.
17568 for (i = 0; i < j; i++) {
667
2/2
✓ Branch 0 taken 15616 times.
✓ Branch 1 taken 1891 times.
17507 if (frequency[i] == 0)
668 15616 continue;
669
2/2
✓ Branch 0 taken 722 times.
✓ Branch 1 taken 1169 times.
1891 if (frequency[i] < min_freq[1]) {
670
2/2
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 316 times.
722 if (frequency[i] < min_freq[0]) {
671 406 min_freq[1] = min_freq[0];
672 406 smallest[1] = smallest[0];
673 406 min_freq[0] = frequency[i];
674 406 smallest[0] = i;
675 } else {
676 316 min_freq[1] = frequency[i];
677 316 smallest[1] = i;
678 }
679 }
680 }
681
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 60 times.
61 if (min_freq[1] == 256 * 256)
682 1 break;
683
684 60 frequency[j] = min_freq[0] + min_freq[1];
685 60 flag[smallest[0]] = 0;
686 60 flag[smallest[1]] = 1;
687 60 up[smallest[0]] =
688 60 up[smallest[1]] = j;
689 60 frequency[smallest[0]] = frequency[smallest[1]] = 0;
690 }
691
692
2/2
✓ Branch 0 taken 257 times.
✓ Branch 1 taken 1 times.
258 for (j = 0; j < 257; j++) {
693 257 int node, len = 0, bits = 0;
694
695
2/2
✓ Branch 0 taken 510 times.
✓ Branch 1 taken 257 times.
767 for (node = j; up[node] != -1; node = up[node]) {
696 510 bits += flag[node] << len;
697 510 len++;
698
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 510 times.
510 if (len > 31)
699 // can this happen at all ?
700 av_log(f->avctx, AV_LOG_ERROR,
701 "vlc length overflow\n");
702 }
703
704 257 bits_tab[j] = bits;
705 257 len_tab[j] = len;
706 }
707
708 1 ff_vlc_free(&f->pre_vlc);
709
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,
710 bits_tab, 4, 4, 0))
711 return NULL;
712
713 1 return ptr;
714 }
715
716 1050 static int mix(int c0, int c1)
717 {
718 1050 int blue = 2 * (c0 & 0x001F) + (c1 & 0x001F);
719 1050 int green = (2 * (c0 & 0x03E0) + (c1 & 0x03E0)) >> 5;
720 1050 int red = 2 * (c0 >> 10) + (c1 >> 10);
721 1050 return red / 3 * 1024 + green / 3 * 32 + blue / 3;
722 }
723
724 5 static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length)
725 {
726 int x, y, x2, y2;
727 5 const int width = f->avctx->width;
728 5 const int height = f->avctx->height;
729 5 const int mbs = (FFALIGN(width, 16) >> 4) * (FFALIGN(height, 16) >> 4);
730 5 uint16_t *dst = f->frame_buffer;
731 5 const uint8_t *buf_end = buf + length;
732 GetByteContext g3;
733
734
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (length < mbs * 8) {
735 av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n");
736 return AVERROR_INVALIDDATA;
737 }
738 5 bytestream2_init(&g3, buf, length);
739
740
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 5 times.
40 for (y = 0; y < height; y += 16) {
741
2/2
✓ Branch 0 taken 525 times.
✓ Branch 1 taken 35 times.
560 for (x = 0; x < width; x += 16) {
742 525 unsigned int color[4] = { 0 }, bits;
743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 525 times.
525 if (buf_end - buf < 8)
744 return AVERROR_INVALIDDATA;
745 // warning following is purely guessed ...
746 525 color[0] = bytestream2_get_le16u(&g3);
747 525 color[1] = bytestream2_get_le16u(&g3);
748
749
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 525 times.
525 if (color[0] & 0x8000)
750 av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n");
751
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 525 times.
525 if (color[1] & 0x8000)
752 av_log(f->avctx, AV_LOG_ERROR, "unk bit 2\n");
753
754 525 color[2] = mix(color[0], color[1]);
755 525 color[3] = mix(color[1], color[0]);
756
757 525 bits = bytestream2_get_le32u(&g3);
758
2/2
✓ Branch 0 taken 8400 times.
✓ Branch 1 taken 525 times.
8925 for (y2 = 0; y2 < 16; y2++) {
759
2/2
✓ Branch 0 taken 134400 times.
✓ Branch 1 taken 8400 times.
142800 for (x2 = 0; x2 < 16; x2++) {
760 134400 int index = 2 * (x2 >> 2) + 8 * (y2 >> 2);
761 134400 dst[y2 * width + x2] = color[(bits >> index) & 3];
762 }
763 }
764 525 dst += 16;
765 }
766 35 dst += 16 * width - x;
767 }
768
769 5 return 0;
770 }
771
772 1 static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
773 {
774 int x, y, ret;
775 1 const int width = f->avctx->width;
776 1 const int height = f->avctx->height;
777 1 const unsigned int bitstream_size = AV_RL32(buf);
778 unsigned int prestream_size;
779 const uint8_t *prestream;
780
781
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (bitstream_size > (1 << 26))
782 return AVERROR_INVALIDDATA;
783
784
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (length < bitstream_size + 12) {
785 av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n");
786 return AVERROR_INVALIDDATA;
787 }
788
789 1 prestream_size = 4 * AV_RL32(buf + bitstream_size + 4);
790 1 prestream = buf + bitstream_size + 12;
791
792
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (prestream_size + bitstream_size + 12 != length
793
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 || prestream_size > (1 << 26)) {
794 av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n",
795 prestream_size, bitstream_size, length);
796 return AVERROR_INVALIDDATA;
797 }
798
799 1 prestream = read_huffman_tables(f, prestream, prestream_size);
800
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!prestream) {
801 av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n");
802 return AVERROR_INVALIDDATA;
803 }
804
805
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 av_assert0(prestream <= buf + length);
806
807 1 init_get_bits(&f->gb, buf + 4, 8 * bitstream_size);
808
809 1 prestream_size = length + buf - prestream;
810
811 1 av_fast_padded_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size,
812 prestream_size);
813
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!f->bitstream_buffer)
814 return AVERROR(ENOMEM);
815 1 f->bbdsp.bswap_buf(f->bitstream_buffer, (const uint32_t *) prestream,
816 1 prestream_size / 4);
817 1 init_get_bits(&f->pre_gb, f->bitstream_buffer, 8 * prestream_size);
818
819 1 f->last_dc = 0 * 128 * 8 * 8;
820
821
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 1 times.
31 for (y = 0; y < height; y += 16) {
822
2/2
✓ Branch 0 taken 1200 times.
✓ Branch 1 taken 30 times.
1230 for (x = 0; x < width; x += 16) {
823
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1200 times.
1200 if ((ret = decode_i_mb(f)) < 0)
824 return ret;
825
826 1200 idct_put(f, x, y);
827 }
828 }
829
830
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)
831 av_log(f->avctx, AV_LOG_ERROR, "end mismatch\n");
832
833 1 return 0;
834 }
835
836 201 static int decode_frame(AVCodecContext *avctx, AVFrame *picture,
837 int *got_frame, AVPacket *avpkt)
838 {
839 201 const uint8_t *buf = avpkt->data;
840 201 int buf_size = avpkt->size;
841 201 FourXContext *const f = avctx->priv_data;
842 int i, frame_4cc, frame_size, ret;
843
844
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 201 times.
201 if (buf_size < 20)
845 return AVERROR_INVALIDDATA;
846
847
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);
848
849
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 201 times.
201 if (buf_size < AV_RL32(buf + 4) + 8) {
850 av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %"PRIu32"\n",
851 buf_size, AV_RL32(buf + 4));
852 return AVERROR_INVALIDDATA;
853 }
854
855 201 frame_4cc = AV_RL32(buf);
856
857
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 187 times.
201 if (frame_4cc == AV_RL32("cfrm")) {
858 14 int free_index = -1;
859 int id, whole_size;
860 14 const int data_size = buf_size - 20;
861 CFrameBuffer *cfrm;
862
863
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (f->version <= 1) {
864 av_log(f->avctx, AV_LOG_ERROR, "cfrm in version %d\n", f->version);
865 return AVERROR_INVALIDDATA;
866 }
867
868 14 id = AV_RL32(buf + 12);
869 14 whole_size = AV_RL32(buf + 16);
870
871
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) {
872 av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n");
873 return AVERROR_INVALIDDATA;
874 }
875
876
2/2
✓ Branch 0 taken 1400 times.
✓ Branch 1 taken 14 times.
1414 for (i = 0; i < CFRAME_BUFFER_COUNT; i++)
877
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)
878 av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n",
879 f->cfrm[i].id);
880
881
2/2
✓ Branch 0 taken 1396 times.
✓ Branch 1 taken 2 times.
1398 for (i = 0; i < CFRAME_BUFFER_COUNT; i++) {
882
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1384 times.
1396 if (f->cfrm[i].id == id)
883 12 break;
884
2/2
✓ Branch 0 taken 1382 times.
✓ Branch 1 taken 2 times.
1384 if (f->cfrm[i].size == 0)
885 1382 free_index = i;
886 }
887
888
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
14 if (i >= CFRAME_BUFFER_COUNT) {
889
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (free_index < 0)
890 return AVERROR_INVALIDDATA;
891 2 i = free_index;
892 2 f->cfrm[i].id = id;
893 }
894 14 cfrm = &f->cfrm[i];
895
896
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (data_size > UINT_MAX - cfrm->size - AV_INPUT_BUFFER_PADDING_SIZE)
897 return AVERROR_INVALIDDATA;
898
899 28 cfrm->data = av_fast_realloc(cfrm->data, &cfrm->allocated_size,
900 14 cfrm->size + data_size + AV_INPUT_BUFFER_PADDING_SIZE);
901 // explicit check needed as memcpy below might not catch a NULL
902
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (!cfrm->data) {
903 av_log(f->avctx, AV_LOG_ERROR, "realloc failure\n");
904 return AVERROR(ENOMEM);
905 }
906
907 14 memcpy(cfrm->data + cfrm->size, buf + 20, data_size);
908 14 cfrm->size += data_size;
909
910
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
14 if (cfrm->size >= whole_size) {
911 2 buf = cfrm->data;
912 2 frame_size = cfrm->size;
913
914
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (id != avctx->frame_num)
915 av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %"PRId64"\n",
916 id, avctx->frame_num);
917
918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (f->version <= 1)
919 return AVERROR_INVALIDDATA;
920
921 2 cfrm->size = cfrm->id = 0;
922 2 frame_4cc = AV_RL32("pfrm");
923 } else
924 12 return buf_size;
925 } else {
926 187 buf = buf + 12;
927 187 frame_size = buf_size - 12;
928 }
929
930
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 189 times.
189 if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
931 return ret;
932
933
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 184 times.
189 if (frame_4cc == AV_RL32("ifr2")) {
934 5 picture->pict_type = AV_PICTURE_TYPE_I;
935
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 if ((ret = decode_i2_frame(f, buf - 4, frame_size + 4)) < 0) {
936 av_log(f->avctx, AV_LOG_ERROR, "decode i2 frame failed\n");
937 return ret;
938 }
939
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 183 times.
184 } else if (frame_4cc == AV_RL32("ifrm")) {
940 1 picture->pict_type = AV_PICTURE_TYPE_I;
941
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if ((ret = decode_i_frame(f, buf, frame_size)) < 0) {
942 av_log(f->avctx, AV_LOG_ERROR, "decode i frame failed\n");
943 return ret;
944 }
945
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")) {
946 183 picture->pict_type = AV_PICTURE_TYPE_P;
947
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 183 times.
183 if ((ret = decode_p_frame(f, buf, frame_size)) < 0) {
948 av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n");
949 return ret;
950 }
951 } else if (frame_4cc == AV_RL32("snd_")) {
952 av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n",
953 buf_size);
954 return AVERROR_INVALIDDATA;
955 } else {
956 av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n",
957 buf_size);
958 return AVERROR_INVALIDDATA;
959 }
960
961
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 183 times.
189 if (picture->pict_type == AV_PICTURE_TYPE_I)
962 6 picture->flags |= AV_FRAME_FLAG_KEY;
963 else
964 183 picture->flags &= ~AV_FRAME_FLAG_KEY;
965
966 189 av_image_copy_plane(picture->data[0], picture->linesize[0],
967 189 (const uint8_t*)f->frame_buffer, avctx->width * 2,
968 189 avctx->width * 2, avctx->height);
969 189 FFSWAP(uint16_t *, f->frame_buffer, f->last_frame_buffer);
970
971 189 *got_frame = 1;
972
973 189 return buf_size;
974 }
975
976 5 static av_cold int decode_end(AVCodecContext *avctx)
977 {
978 5 FourXContext * const f = avctx->priv_data;
979 int i;
980
981 5 av_freep(&f->frame_buffer);
982 5 av_freep(&f->last_frame_buffer);
983 5 av_freep(&f->bitstream_buffer);
984 5 f->bitstream_buffer_size = 0;
985
2/2
✓ Branch 0 taken 500 times.
✓ Branch 1 taken 5 times.
505 for (i = 0; i < CFRAME_BUFFER_COUNT; i++) {
986 500 av_freep(&f->cfrm[i].data);
987 500 f->cfrm[i].allocated_size = 0;
988 }
989 5 ff_vlc_free(&f->pre_vlc);
990
991 5 return 0;
992 }
993
994 5 static av_cold int decode_init(AVCodecContext *avctx)
995 {
996 static AVOnce init_static_once = AV_ONCE_INIT;
997 5 FourXContext * const f = avctx->priv_data;
998 int ret;
999
1000
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) {
1001 av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n");
1002 return AVERROR_INVALIDDATA;
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->width % 16) || (avctx->height % 16)) {
1005 av_log(avctx, AV_LOG_ERROR, "unsupported width/height\n");
1006 return AVERROR_INVALIDDATA;
1007 }
1008
1009 5 ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
1010
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (ret < 0)
1011 return ret;
1012
1013 5 f->frame_buffer = av_mallocz(avctx->width * avctx->height * 2);
1014 5 f->last_frame_buffer = av_mallocz(avctx->width * avctx->height * 2);
1015
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)
1016 return AVERROR(ENOMEM);
1017
1018 5 f->version = AV_RL32(avctx->extradata) >> 16;
1019 5 ff_blockdsp_init(&f->bdsp);
1020 5 ff_bswapdsp_init(&f->bbdsp);
1021 5 f->avctx = avctx;
1022
1023
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 if (f->version > 2)
1024 3 avctx->pix_fmt = AV_PIX_FMT_RGB565;
1025 else
1026 2 avctx->pix_fmt = AV_PIX_FMT_BGR555;
1027
1028 5 ff_thread_once(&init_static_once, init_vlcs);
1029
1030 5 return 0;
1031 }
1032
1033 const FFCodec ff_fourxm_decoder = {
1034 .p.name = "4xm",
1035 CODEC_LONG_NAME("4X Movie"),
1036 .p.type = AVMEDIA_TYPE_VIDEO,
1037 .p.id = AV_CODEC_ID_4XM,
1038 .priv_data_size = sizeof(FourXContext),
1039 .init = decode_init,
1040 .close = decode_end,
1041 FF_CODEC_DECODE_CB(decode_frame),
1042 .p.capabilities = AV_CODEC_CAP_DR1,
1043 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1044 };
1045