/src/ffmpeg/libavcodec/4xm.c
Line | Count | 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 | 743k | #define BLOCK_TYPE_VLC_BITS 5 |
46 | 348k | #define ACDC_VLC_BITS 9 |
47 | | |
48 | 24.6M | #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 | 3.10M | #define MULTIPLY(var, const) ((int)((var) * (unsigned)(const)) >> 16) |
166 | | |
167 | | static void idct(int16_t block[64]) |
168 | 38.8k | { |
169 | 38.8k | int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; |
170 | 38.8k | int tmp10, tmp11, tmp12, tmp13; |
171 | 38.8k | int z5, z10, z11, z12, z13; |
172 | 38.8k | int i; |
173 | 38.8k | int temp[64]; |
174 | | |
175 | 349k | for (i = 0; i < 8; i++) { |
176 | 310k | tmp10 = block[8 * 0 + i] + block[8 * 4 + i]; |
177 | 310k | tmp11 = block[8 * 0 + i] - block[8 * 4 + i]; |
178 | | |
179 | 310k | tmp13 = block[8 * 2 + i] + block[8 * 6 + i]; |
180 | 310k | tmp12 = MULTIPLY(block[8 * 2 + i] - block[8 * 6 + i], FIX_1_414213562) - tmp13; |
181 | | |
182 | 310k | tmp0 = tmp10 + tmp13; |
183 | 310k | tmp3 = tmp10 - tmp13; |
184 | 310k | tmp1 = tmp11 + tmp12; |
185 | 310k | tmp2 = tmp11 - tmp12; |
186 | | |
187 | 310k | z13 = block[8 * 5 + i] + block[8 * 3 + i]; |
188 | 310k | z10 = block[8 * 5 + i] - block[8 * 3 + i]; |
189 | 310k | z11 = block[8 * 1 + i] + block[8 * 7 + i]; |
190 | 310k | z12 = block[8 * 1 + i] - block[8 * 7 + i]; |
191 | | |
192 | 310k | tmp7 = z11 + z13; |
193 | 310k | tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); |
194 | | |
195 | 310k | z5 = MULTIPLY(z10 + z12, FIX_1_847759065); |
196 | 310k | tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; |
197 | 310k | tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5; |
198 | | |
199 | 310k | tmp6 = tmp12 - tmp7; |
200 | 310k | tmp5 = tmp11 - tmp6; |
201 | 310k | tmp4 = tmp10 + tmp5; |
202 | | |
203 | 310k | temp[8 * 0 + i] = tmp0 + tmp7; |
204 | 310k | temp[8 * 7 + i] = tmp0 - tmp7; |
205 | 310k | temp[8 * 1 + i] = tmp1 + tmp6; |
206 | 310k | temp[8 * 6 + i] = tmp1 - tmp6; |
207 | 310k | temp[8 * 2 + i] = tmp2 + tmp5; |
208 | 310k | temp[8 * 5 + i] = tmp2 - tmp5; |
209 | 310k | temp[8 * 4 + i] = tmp3 + tmp4; |
210 | 310k | temp[8 * 3 + i] = tmp3 - tmp4; |
211 | 310k | } |
212 | | |
213 | 349k | for (i = 0; i < 8 * 8; i += 8) { |
214 | 310k | tmp10 = temp[0 + i] + temp[4 + i]; |
215 | 310k | tmp11 = temp[0 + i] - temp[4 + i]; |
216 | | |
217 | 310k | tmp13 = temp[2 + i] + temp[6 + i]; |
218 | 310k | tmp12 = MULTIPLY(temp[2 + i] - temp[6 + i], FIX_1_414213562) - tmp13; |
219 | | |
220 | 310k | tmp0 = tmp10 + tmp13; |
221 | 310k | tmp3 = tmp10 - tmp13; |
222 | 310k | tmp1 = tmp11 + tmp12; |
223 | 310k | tmp2 = tmp11 - tmp12; |
224 | | |
225 | 310k | z13 = temp[5 + i] + temp[3 + i]; |
226 | 310k | z10 = temp[5 + i] - temp[3 + i]; |
227 | 310k | z11 = temp[1 + i] + temp[7 + i]; |
228 | 310k | z12 = temp[1 + i] - temp[7 + i]; |
229 | | |
230 | 310k | tmp7 = z11 + z13; |
231 | 310k | tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); |
232 | | |
233 | 310k | z5 = MULTIPLY(z10 + z12, FIX_1_847759065); |
234 | 310k | tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; |
235 | 310k | tmp12 = MULTIPLY(z10, -FIX_2_613125930) + z5; |
236 | | |
237 | 310k | tmp6 = tmp12 - tmp7; |
238 | 310k | tmp5 = tmp11 - tmp6; |
239 | 310k | tmp4 = tmp10 + tmp5; |
240 | | |
241 | 310k | block[0 + i] = (tmp0 + tmp7) >> 6; |
242 | 310k | block[7 + i] = (tmp0 - tmp7) >> 6; |
243 | 310k | block[1 + i] = (tmp1 + tmp6) >> 6; |
244 | 310k | block[6 + i] = (tmp1 - tmp6) >> 6; |
245 | 310k | block[2 + i] = (tmp2 + tmp5) >> 6; |
246 | 310k | block[5 + i] = (tmp2 - tmp5) >> 6; |
247 | 310k | block[4 + i] = (tmp3 + tmp4) >> 6; |
248 | 310k | block[3 + i] = (tmp3 - tmp4) >> 6; |
249 | 310k | } |
250 | 38.8k | } |
251 | | |
252 | | static av_cold void init_vlcs(void) |
253 | 1 | { |
254 | 1 | int i, j; |
255 | | |
256 | 3 | for (i = 0; i < 2; i++) { |
257 | 10 | for (j = 0; j < 4; j++) { |
258 | 8 | ff_vlc_init_table_sparse(block_type_vlc[i][j], FF_ARRAY_ELEMS(block_type_vlc[i][j]), |
259 | 8 | BLOCK_TYPE_VLC_BITS, 7, |
260 | 8 | &block_type_tab[i][j][0][1], 2, 1, |
261 | 8 | &block_type_tab[i][j][0][0], 2, 1, |
262 | 8 | NULL, 0, 0, 0); |
263 | 8 | } |
264 | 2 | } |
265 | 1 | } |
266 | | |
267 | | static void init_mv(FourXContext *f, int linesize) |
268 | 5.72k | { |
269 | 5.72k | int i; |
270 | | |
271 | 1.47M | for (i = 0; i < 256; i++) { |
272 | 1.46M | if (f->version > 1) |
273 | 49.6k | f->mv[i] = mv[i][0] + mv[i][1] * linesize / 2; |
274 | 1.41M | else |
275 | 1.41M | f->mv[i] = (i & 15) - 8 + ((i >> 4) - 8) * linesize / 2; |
276 | 1.46M | } |
277 | 5.72k | } |
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 | 8.88M | { \ |
291 | 8.88M | unsigned tmpval = AV_RN32(src) * (scale) + (dc); \ |
292 | 8.88M | AV_WN32A(dst, tmpval); \ |
293 | 8.88M | } |
294 | | #endif |
295 | | |
296 | | static inline void mcdc(uint16_t *dst, const uint16_t *src, int log2w, |
297 | | int h, int stride, int scale, unsigned dc) |
298 | 508k | { |
299 | 508k | int i; |
300 | 508k | dc *= 0x10001; |
301 | | |
302 | 508k | switch (log2w) { |
303 | 175k | case 0: |
304 | 757k | for (i = 0; i < h; i++) { |
305 | 581k | dst[0] = scale * src[0] + dc; |
306 | 581k | if (scale) |
307 | 407k | src += stride; |
308 | 581k | dst += stride; |
309 | 581k | } |
310 | 175k | break; |
311 | 12.0k | case 1: |
312 | 73.4k | for (i = 0; i < h; i++) { |
313 | 61.4k | LE_CENTRIC_MUL(dst, src, scale, dc); |
314 | 61.4k | if (scale) |
315 | 56.1k | src += stride; |
316 | 61.4k | dst += stride; |
317 | 61.4k | } |
318 | 12.0k | break; |
319 | 62.4k | case 2: |
320 | 520k | for (i = 0; i < h; i++) { |
321 | 457k | LE_CENTRIC_MUL(dst, src, scale, dc); |
322 | 457k | LE_CENTRIC_MUL(dst + 2, src + 2, scale, dc); |
323 | 457k | if (scale) |
324 | 435k | src += stride; |
325 | 457k | dst += stride; |
326 | 457k | } |
327 | 62.4k | break; |
328 | 258k | case 3: |
329 | 2.23M | for (i = 0; i < h; i++) { |
330 | 1.97M | LE_CENTRIC_MUL(dst, src, scale, dc); |
331 | 1.97M | LE_CENTRIC_MUL(dst + 2, src + 2, scale, dc); |
332 | 1.97M | LE_CENTRIC_MUL(dst + 4, src + 4, scale, dc); |
333 | 1.97M | LE_CENTRIC_MUL(dst + 6, src + 6, scale, dc); |
334 | 1.97M | if (scale) |
335 | 1.77M | src += stride; |
336 | 1.97M | dst += stride; |
337 | 1.97M | } |
338 | 258k | break; |
339 | 0 | default: |
340 | 0 | av_unreachable("log2w starts at 3 and gets only decremented during " |
341 | 508k | "recursive calls to decode_p_block"); |
342 | 508k | } |
343 | 508k | } |
344 | | |
345 | | static int decode_p_block(FourXContext *f, uint16_t *dst, const uint16_t *src, |
346 | | int log2w, int log2h, int stride) |
347 | 747k | { |
348 | 747k | int index, h, code, ret, scale = 1; |
349 | 747k | uint16_t *start, *end; |
350 | 747k | unsigned dc = 0; |
351 | | |
352 | 747k | av_assert0(log2w >= 0 && log2h >= 0); |
353 | | |
354 | 747k | index = size2index[log2h][log2w]; |
355 | 747k | av_assert0(index >= 0); |
356 | | |
357 | 747k | if (get_bits_left(&f->gb) < 1) |
358 | 3.60k | return AVERROR_INVALIDDATA; |
359 | 743k | h = 1 << log2h; |
360 | 743k | code = get_vlc2(&f->gb, block_type_vlc[1 - (f->version > 1)][index], |
361 | 743k | BLOCK_TYPE_VLC_BITS, 1); |
362 | 743k | av_assert0(code >= 0 && code <= 6); |
363 | | |
364 | 743k | start = f->last_frame_buffer; |
365 | 743k | end = start + stride * (f->avctx->height - h + 1) - (1 << log2w); |
366 | | |
367 | 743k | if (code == 1) { |
368 | 122k | log2h--; |
369 | 122k | if ((ret = decode_p_block(f, dst, src, log2w, log2h, stride)) < 0) |
370 | 830 | return ret; |
371 | 121k | return decode_p_block(f, dst + (stride << log2h), |
372 | 121k | src + (stride << log2h), |
373 | 121k | log2w, log2h, stride); |
374 | 620k | } else if (code == 2) { |
375 | 105k | log2w--; |
376 | 105k | if ((ret = decode_p_block(f, dst , src, log2w, log2h, stride)) < 0) |
377 | 1.18k | return ret; |
378 | 103k | return decode_p_block(f, dst + (1 << log2w), |
379 | 103k | src + (1 << log2w), |
380 | 103k | log2w, log2h, stride); |
381 | 515k | } else if (code == 6) { |
382 | 1.72k | if (bytestream2_get_bytes_left(&f->g2) < 4) { |
383 | 203 | av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); |
384 | 203 | return AVERROR_INVALIDDATA; |
385 | 203 | } |
386 | 1.51k | if (log2w) { |
387 | 257 | dst[0] = bytestream2_get_le16u(&f->g2); |
388 | 257 | dst[1] = bytestream2_get_le16u(&f->g2); |
389 | 1.26k | } else { |
390 | 1.26k | dst[0] = bytestream2_get_le16u(&f->g2); |
391 | 1.26k | dst[stride] = bytestream2_get_le16u(&f->g2); |
392 | 1.26k | } |
393 | 1.51k | return 0; |
394 | 1.72k | } |
395 | | |
396 | 514k | if ((code&3)==0 && bytestream2_get_bytes_left(&f->g) < 1) { |
397 | 442 | av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n"); |
398 | 442 | return AVERROR_INVALIDDATA; |
399 | 442 | } |
400 | | |
401 | 513k | if (code == 0) { |
402 | 101k | src += f->mv[bytestream2_get_byte(&f->g)]; |
403 | 412k | } else if (code == 3 && f->version >= 2) { |
404 | 3.98k | return 0; |
405 | 408k | } else if (code == 4) { |
406 | 109k | src += f->mv[bytestream2_get_byte(&f->g)]; |
407 | 109k | if (bytestream2_get_bytes_left(&f->g2) < 2){ |
408 | 239 | av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); |
409 | 239 | return AVERROR_INVALIDDATA; |
410 | 239 | } |
411 | 109k | dc = bytestream2_get_le16(&f->g2); |
412 | 298k | } else if (code == 5) { |
413 | 115k | if (bytestream2_get_bytes_left(&f->g2) < 2){ |
414 | 251 | av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); |
415 | 251 | return AVERROR_INVALIDDATA; |
416 | 251 | } |
417 | 114k | av_assert0(start <= src && src <= end); |
418 | 114k | scale = 0; |
419 | 114k | dc = bytestream2_get_le16(&f->g2); |
420 | 114k | } |
421 | | |
422 | 509k | if (start > src || src > end) { |
423 | 632 | av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); |
424 | 632 | return AVERROR_INVALIDDATA; |
425 | 632 | } |
426 | | |
427 | 508k | mcdc(dst, src, log2w, h, stride, scale, dc); |
428 | | |
429 | 508k | return 0; |
430 | 509k | } |
431 | | |
432 | | static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length) |
433 | 9.53k | { |
434 | 9.53k | int x, y; |
435 | 9.53k | const int width = f->avctx->width; |
436 | 9.53k | const int height = f->avctx->height; |
437 | 9.53k | uint16_t *dst = f->frame_buffer; |
438 | 9.53k | uint16_t *src; |
439 | 9.53k | unsigned int bitstream_size, bytestream_size, wordstream_size, extra, |
440 | 9.53k | bytestream_offset, wordstream_offset; |
441 | 9.53k | int ret; |
442 | | |
443 | 9.53k | src = f->last_frame_buffer; |
444 | | |
445 | 9.53k | if (f->version > 1) { |
446 | 3.26k | extra = 20; |
447 | 3.26k | if (length < extra) |
448 | 1.34k | return AVERROR_INVALIDDATA; |
449 | 1.91k | bitstream_size = AV_RL32(buf + 8); |
450 | 1.91k | wordstream_size = AV_RL32(buf + 12); |
451 | 1.91k | bytestream_size = AV_RL32(buf + 16); |
452 | 6.27k | } else { |
453 | 6.27k | extra = 0; |
454 | 6.27k | bitstream_size = AV_RL16(buf - 4); |
455 | 6.27k | wordstream_size = AV_RL16(buf - 2); |
456 | 6.27k | bytestream_size = FFMAX(length - bitstream_size - wordstream_size, 0); |
457 | 6.27k | } |
458 | | |
459 | 8.18k | if (bitstream_size > length || bitstream_size >= INT_MAX/8 || |
460 | 7.06k | bytestream_size > length - bitstream_size || |
461 | 6.56k | wordstream_size > length - bytestream_size - bitstream_size || |
462 | 6.10k | extra > length - bytestream_size - bitstream_size - wordstream_size) { |
463 | 2.46k | av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size, |
464 | 2.46k | bitstream_size+ bytestream_size+ wordstream_size - length); |
465 | 2.46k | return AVERROR_INVALIDDATA; |
466 | 2.46k | } |
467 | | |
468 | 5.72k | av_fast_padded_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, |
469 | 5.72k | bitstream_size); |
470 | 5.72k | if (!f->bitstream_buffer) |
471 | 0 | return AVERROR(ENOMEM); |
472 | 5.72k | f->bbdsp.bswap_buf(f->bitstream_buffer, (const uint32_t *) (buf + extra), |
473 | 5.72k | bitstream_size / 4); |
474 | 5.72k | init_get_bits(&f->gb, f->bitstream_buffer, 8 * bitstream_size); |
475 | | |
476 | 5.72k | wordstream_offset = extra + bitstream_size; |
477 | 5.72k | bytestream_offset = extra + bitstream_size + wordstream_size; |
478 | 5.72k | bytestream2_init(&f->g2, buf + wordstream_offset, |
479 | 5.72k | length - wordstream_offset); |
480 | 5.72k | bytestream2_init(&f->g, buf + bytestream_offset, |
481 | 5.72k | length - bytestream_offset); |
482 | | |
483 | 5.72k | init_mv(f, width * 2); |
484 | | |
485 | 63.8k | for (y = 0; y < height; y += 8) { |
486 | 351k | for (x = 0; x < width; x += 8) |
487 | 293k | if ((ret = decode_p_block(f, dst + x, src + x, 3, 3, width)) < 0) |
488 | 5.36k | return ret; |
489 | 58.1k | src += 8 * width; |
490 | 58.1k | dst += 8 * width; |
491 | 58.1k | } |
492 | | |
493 | 357 | return 0; |
494 | 5.72k | } |
495 | | |
496 | | /** |
497 | | * decode block and dequantize. |
498 | | * Note this is almost identical to MJPEG. |
499 | | */ |
500 | | static int decode_i_block(FourXContext *f, int16_t *block) |
501 | 42.7k | { |
502 | 42.7k | int code, i, j, level, val; |
503 | | |
504 | 42.7k | if (get_bits_left(&f->pre_gb) < 2) { |
505 | 687 | av_log(f->avctx, AV_LOG_ERROR, "%d bits left before decode_i_block()\n", get_bits_left(&f->pre_gb)); |
506 | 687 | return AVERROR_INVALIDDATA; |
507 | 687 | } |
508 | | |
509 | | /* DC coef */ |
510 | 42.0k | val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); |
511 | 42.0k | if (val >> 4) { |
512 | 1.03k | av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n"); |
513 | 1.03k | return AVERROR_INVALIDDATA; |
514 | 1.03k | } |
515 | | |
516 | 41.0k | if (val) |
517 | 12.1k | val = get_xbits(&f->gb, val); |
518 | | |
519 | 41.0k | val = val * dequant_table[0] + f->last_dc; |
520 | 41.0k | f->last_dc = block[0] = val; |
521 | | /* AC coefs */ |
522 | 41.0k | i = 1; |
523 | 304k | for (;;) { |
524 | 304k | code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3); |
525 | | |
526 | | /* EOB */ |
527 | 304k | if (code == 0) |
528 | 35.9k | break; |
529 | 268k | if (code == 0xf0) { |
530 | 940 | i += 16; |
531 | 940 | if (i >= 64) { |
532 | 245 | av_log(f->avctx, AV_LOG_ERROR, "run %d overflow\n", i); |
533 | 245 | return 0; |
534 | 245 | } |
535 | 268k | } else { |
536 | 268k | if (code & 0xf) { |
537 | 267k | level = get_xbits(&f->gb, code & 0xf); |
538 | 267k | } else { |
539 | 251 | av_log(f->avctx, AV_LOG_ERROR, "0 coeff\n"); |
540 | 251 | return AVERROR_INVALIDDATA; |
541 | 251 | } |
542 | 267k | i += code >> 4; |
543 | 267k | if (i >= 64) { |
544 | 1.51k | av_log(f->avctx, AV_LOG_ERROR, "run %d overflow\n", i); |
545 | 1.51k | return 0; |
546 | 1.51k | } |
547 | | |
548 | 266k | j = ff_zigzag_direct[i]; |
549 | 266k | block[j] = level * dequant_table[j]; |
550 | 266k | i++; |
551 | 266k | if (i >= 64) |
552 | 3.04k | break; |
553 | 266k | } |
554 | 268k | } |
555 | | |
556 | 39.0k | return 0; |
557 | 41.0k | } |
558 | | |
559 | | static inline void idct_put(FourXContext *f, int x, int y) |
560 | 6.46k | { |
561 | 6.46k | int16_t (*block)[64] = f->block; |
562 | 6.46k | int stride = f->avctx->width; |
563 | 6.46k | int i; |
564 | 6.46k | uint16_t *dst = f->frame_buffer + y * stride + x; |
565 | | |
566 | 32.3k | for (i = 0; i < 4; i++) { |
567 | 25.8k | block[i][0] += 0x80 * 8 * 8; |
568 | 25.8k | idct(block[i]); |
569 | 25.8k | } |
570 | | |
571 | 6.46k | if (!(f->avctx->flags & AV_CODEC_FLAG_GRAY)) { |
572 | 19.4k | for (i = 4; i < 6; i++) |
573 | 12.9k | idct(block[i]); |
574 | 6.46k | } |
575 | | |
576 | | /* Note transform is: |
577 | | * y = ( 1b + 4g + 2r) / 14 |
578 | | * cb = ( 3b - 2g - 1r) / 14 |
579 | | * cr = (-1b - 4g + 5r) / 14 */ |
580 | 58.2k | for (y = 0; y < 8; y++) { |
581 | 465k | for (x = 0; x < 8; x++) { |
582 | 413k | int16_t *temp = block[(x >> 2) + 2 * (y >> 2)] + |
583 | 413k | 2 * (x & 3) + 2 * 8 * (y & 3); // FIXME optimize |
584 | 413k | int cb = block[4][x + 8 * y]; |
585 | 413k | int cr = block[5][x + 8 * y]; |
586 | 413k | int cg = (cb + cr) >> 1; |
587 | 413k | int y; |
588 | | |
589 | 413k | cb += cb; |
590 | | |
591 | 413k | y = temp[0]; |
592 | 413k | dst[0] = ((y + cb) >> 3) + (((y - cg) & 0xFC) << 3) + (((y + cr) & 0xF8) << 8); |
593 | 413k | y = temp[1]; |
594 | 413k | dst[1] = ((y + cb) >> 3) + (((y - cg) & 0xFC) << 3) + (((y + cr) & 0xF8) << 8); |
595 | 413k | y = temp[8]; |
596 | 413k | dst[stride] = ((y + cb) >> 3) + (((y - cg) & 0xFC) << 3) + (((y + cr) & 0xF8) << 8); |
597 | 413k | y = temp[9]; |
598 | 413k | dst[1 + stride] = ((y + cb) >> 3) + (((y - cg) & 0xFC) << 3) + (((y + cr) & 0xF8) << 8); |
599 | 413k | dst += 2; |
600 | 413k | } |
601 | 51.7k | dst += 2 * stride - 2 * 8; |
602 | 51.7k | } |
603 | 6.46k | } |
604 | | |
605 | | static int decode_i_mb(FourXContext *f) |
606 | 8.44k | { |
607 | 8.44k | int ret; |
608 | 8.44k | int i; |
609 | | |
610 | 8.44k | f->bdsp.clear_blocks(f->block[0]); |
611 | | |
612 | 49.2k | for (i = 0; i < 6; i++) |
613 | 42.7k | if ((ret = decode_i_block(f, f->block[i])) < 0) |
614 | 1.97k | return ret; |
615 | | |
616 | 6.46k | return 0; |
617 | 8.44k | } |
618 | | |
619 | | static const uint8_t *read_huffman_tables(FourXContext *f, |
620 | | const uint8_t * const buf, |
621 | | int buf_size) |
622 | 4.34k | { |
623 | 4.34k | int frequency[512] = { 0 }; |
624 | 4.34k | uint8_t flag[512]; |
625 | 4.34k | int up[512]; |
626 | 4.34k | uint8_t len_tab[257]; |
627 | 4.34k | int bits_tab[257]; |
628 | 4.34k | int start, end; |
629 | 4.34k | const uint8_t *ptr = buf; |
630 | 4.34k | const uint8_t *ptr_end = buf + buf_size; |
631 | 4.34k | int j; |
632 | | |
633 | 4.34k | memset(up, -1, sizeof(up)); |
634 | | |
635 | 4.34k | start = *ptr++; |
636 | 4.34k | end = *ptr++; |
637 | 122k | for (;;) { |
638 | 122k | int i; |
639 | | |
640 | 122k | if (ptr_end - ptr < FFMAX(end - start + 1, 0) + 1) { |
641 | 305 | av_log(f->avctx, AV_LOG_ERROR, "invalid data in read_huffman_tables\n"); |
642 | 305 | return NULL; |
643 | 305 | } |
644 | | |
645 | 1.08M | for (i = start; i <= end; i++) |
646 | 962k | frequency[i] = *ptr++; |
647 | 122k | start = *ptr++; |
648 | 122k | if (start == 0) |
649 | 4.03k | break; |
650 | | |
651 | 118k | end = *ptr++; |
652 | 118k | } |
653 | 4.03k | frequency[256] = 1; |
654 | | |
655 | 9.81k | while ((ptr - buf) & 3) |
656 | 5.78k | ptr++; // 4byte align |
657 | | |
658 | 4.03k | if (ptr > ptr_end) { |
659 | 0 | av_log(f->avctx, AV_LOG_ERROR, "ptr overflow in read_huffman_tables\n"); |
660 | 0 | return NULL; |
661 | 0 | } |
662 | | |
663 | 440k | for (j = 257; j < 512; j++) { |
664 | 438k | int min_freq[2] = { 256 * 256, 256 * 256 }; |
665 | 438k | int smallest[2] = { 0, 0 }; |
666 | 438k | int i; |
667 | 161M | for (i = 0; i < j; i++) { |
668 | 161M | if (frequency[i] == 0) |
669 | 111M | continue; |
670 | 49.6M | if (frequency[i] < min_freq[1]) { |
671 | 2.37M | if (frequency[i] < min_freq[0]) { |
672 | 1.15M | min_freq[1] = min_freq[0]; |
673 | 1.15M | smallest[1] = smallest[0]; |
674 | 1.15M | min_freq[0] = frequency[i]; |
675 | 1.15M | smallest[0] = i; |
676 | 1.22M | } else { |
677 | 1.22M | min_freq[1] = frequency[i]; |
678 | 1.22M | smallest[1] = i; |
679 | 1.22M | } |
680 | 2.37M | } |
681 | 49.6M | } |
682 | 438k | if (min_freq[1] == 256 * 256) |
683 | 2.85k | break; |
684 | | |
685 | 436k | frequency[j] = min_freq[0] + min_freq[1]; |
686 | 436k | flag[smallest[0]] = 0; |
687 | 436k | flag[smallest[1]] = 1; |
688 | 436k | up[smallest[0]] = |
689 | 436k | up[smallest[1]] = j; |
690 | 436k | frequency[smallest[0]] = frequency[smallest[1]] = 0; |
691 | 436k | } |
692 | | |
693 | 1.04M | for (j = 0; j < 257; j++) { |
694 | 1.03M | int node, len = 0, bits = 0; |
695 | | |
696 | 5.01M | for (node = j; up[node] != -1; node = up[node]) { |
697 | 3.97M | bits += flag[node] << len; |
698 | 3.97M | len++; |
699 | 3.97M | if (len > 31) |
700 | | // can this happen at all ? |
701 | 0 | av_log(f->avctx, AV_LOG_ERROR, |
702 | 0 | "vlc length overflow\n"); |
703 | 3.97M | } |
704 | | |
705 | 1.03M | bits_tab[j] = bits; |
706 | 1.03M | len_tab[j] = len; |
707 | 1.03M | } |
708 | | |
709 | 4.03k | ff_vlc_free(&f->pre_vlc); |
710 | 4.03k | if (vlc_init(&f->pre_vlc, ACDC_VLC_BITS, 257, len_tab, 1, 1, |
711 | 4.03k | bits_tab, 4, 4, 0)) |
712 | 1.01k | return NULL; |
713 | | |
714 | 3.02k | return ptr; |
715 | 4.03k | } |
716 | | |
717 | | static int mix(int c0, int c1) |
718 | 171k | { |
719 | 171k | int blue = 2 * (c0 & 0x001F) + (c1 & 0x001F); |
720 | 171k | int green = (2 * (c0 & 0x03E0) + (c1 & 0x03E0)) >> 5; |
721 | 171k | int red = 2 * (c0 >> 10) + (c1 >> 10); |
722 | 171k | return red / 3 * 1024 + green / 3 * 32 + blue / 3; |
723 | 171k | } |
724 | | |
725 | | static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length) |
726 | 1.75k | { |
727 | 1.75k | int x, y, x2, y2; |
728 | 1.75k | const int width = f->avctx->width; |
729 | 1.75k | const int height = f->avctx->height; |
730 | 1.75k | const int mbs = (FFALIGN(width, 16) >> 4) * (FFALIGN(height, 16) >> 4); |
731 | 1.75k | uint16_t *dst = f->frame_buffer; |
732 | 1.75k | const uint8_t *buf_end = buf + length; |
733 | 1.75k | GetByteContext g3; |
734 | | |
735 | 1.75k | if (length < mbs * 8) { |
736 | 464 | av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n"); |
737 | 464 | return AVERROR_INVALIDDATA; |
738 | 464 | } |
739 | 1.29k | bytestream2_init(&g3, buf, length); |
740 | | |
741 | 36.8k | for (y = 0; y < height; y += 16) { |
742 | 121k | for (x = 0; x < width; x += 16) { |
743 | 85.7k | unsigned int color[4] = { 0 }, bits; |
744 | 85.7k | if (buf_end - buf < 8) |
745 | 0 | return AVERROR_INVALIDDATA; |
746 | | // warning following is purely guessed ... |
747 | 85.7k | color[0] = bytestream2_get_le16u(&g3); |
748 | 85.7k | color[1] = bytestream2_get_le16u(&g3); |
749 | | |
750 | 85.7k | if (color[0] & 0x8000) |
751 | 37.4k | av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n"); |
752 | 85.7k | if (color[1] & 0x8000) |
753 | 38.0k | av_log(f->avctx, AV_LOG_ERROR, "unk bit 2\n"); |
754 | | |
755 | 85.7k | color[2] = mix(color[0], color[1]); |
756 | 85.7k | color[3] = mix(color[1], color[0]); |
757 | | |
758 | 85.7k | bits = bytestream2_get_le32u(&g3); |
759 | 1.45M | for (y2 = 0; y2 < 16; y2++) { |
760 | 23.3M | for (x2 = 0; x2 < 16; x2++) { |
761 | 21.9M | int index = 2 * (x2 >> 2) + 8 * (y2 >> 2); |
762 | 21.9M | dst[y2 * width + x2] = color[(bits >> index) & 3]; |
763 | 21.9M | } |
764 | 1.37M | } |
765 | 85.7k | dst += 16; |
766 | 85.7k | } |
767 | 35.5k | dst += 16 * width - x; |
768 | 35.5k | } |
769 | | |
770 | 1.29k | return 0; |
771 | 1.29k | } |
772 | | |
773 | | static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length) |
774 | 6.38k | { |
775 | 6.38k | int x, y, ret; |
776 | 6.38k | const int width = f->avctx->width; |
777 | 6.38k | const int height = f->avctx->height; |
778 | 6.38k | const unsigned int bitstream_size = AV_RL32(buf); |
779 | 6.38k | unsigned int prestream_size; |
780 | 6.38k | const uint8_t *prestream; |
781 | | |
782 | 6.38k | if (bitstream_size > (1 << 26)) |
783 | 607 | return AVERROR_INVALIDDATA; |
784 | | |
785 | 5.77k | if (length < bitstream_size + 12) { |
786 | 790 | av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n"); |
787 | 790 | return AVERROR_INVALIDDATA; |
788 | 790 | } |
789 | | |
790 | 4.98k | prestream_size = 4 * AV_RL32(buf + bitstream_size + 4); |
791 | 4.98k | prestream = buf + bitstream_size + 12; |
792 | | |
793 | 4.98k | if (prestream_size + bitstream_size + 12 != length |
794 | 4.34k | || prestream_size > (1 << 26)) { |
795 | 642 | av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", |
796 | 642 | prestream_size, bitstream_size, length); |
797 | 642 | return AVERROR_INVALIDDATA; |
798 | 642 | } |
799 | | |
800 | 4.34k | prestream = read_huffman_tables(f, prestream, prestream_size); |
801 | 4.34k | if (!prestream) { |
802 | 1.31k | av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n"); |
803 | 1.31k | return AVERROR_INVALIDDATA; |
804 | 1.31k | } |
805 | | |
806 | 3.02k | av_assert0(prestream <= buf + length); |
807 | | |
808 | 3.02k | init_get_bits(&f->gb, buf + 4, 8 * bitstream_size); |
809 | | |
810 | 3.02k | prestream_size = length + buf - prestream; |
811 | | |
812 | 3.02k | av_fast_padded_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, |
813 | 3.02k | prestream_size); |
814 | 3.02k | if (!f->bitstream_buffer) |
815 | 0 | return AVERROR(ENOMEM); |
816 | 3.02k | f->bbdsp.bswap_buf(f->bitstream_buffer, (const uint32_t *) prestream, |
817 | 3.02k | prestream_size / 4); |
818 | 3.02k | init_get_bits(&f->pre_gb, f->bitstream_buffer, 8 * prestream_size); |
819 | | |
820 | 3.02k | f->last_dc = 0 * 128 * 8 * 8; |
821 | | |
822 | 5.04k | for (y = 0; y < height; y += 16) { |
823 | 10.4k | for (x = 0; x < width; x += 16) { |
824 | 8.44k | if ((ret = decode_i_mb(f)) < 0) |
825 | 1.97k | return ret; |
826 | | |
827 | 6.46k | idct_put(f, x, y); |
828 | 6.46k | } |
829 | 3.99k | } |
830 | | |
831 | 1.05k | if (get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256) |
832 | 851 | av_log(f->avctx, AV_LOG_ERROR, "end mismatch\n"); |
833 | | |
834 | 1.05k | return 0; |
835 | 3.02k | } |
836 | | |
837 | | static int decode_frame(AVCodecContext *avctx, AVFrame *picture, |
838 | | int *got_frame, AVPacket *avpkt) |
839 | 237k | { |
840 | 237k | const uint8_t *buf = avpkt->data; |
841 | 237k | int buf_size = avpkt->size; |
842 | 237k | FourXContext *const f = avctx->priv_data; |
843 | 237k | int i, frame_4cc, frame_size, ret; |
844 | | |
845 | 237k | if (buf_size < 20) |
846 | 84.3k | return AVERROR_INVALIDDATA; |
847 | | |
848 | 152k | av_assert0(avctx->width % 16 == 0 && avctx->height % 16 == 0); |
849 | | |
850 | 152k | if (buf_size < AV_RL32(buf + 4) + 8) { |
851 | 5.12k | av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %"PRIu32"\n", |
852 | 5.12k | buf_size, AV_RL32(buf + 4)); |
853 | 5.12k | return AVERROR_INVALIDDATA; |
854 | 5.12k | } |
855 | | |
856 | 147k | frame_4cc = AV_RL32(buf); |
857 | | |
858 | 147k | if (frame_4cc == AV_RL32("cfrm")) { |
859 | 122k | int free_index = -1; |
860 | 122k | int id, whole_size; |
861 | 122k | const int data_size = buf_size - 20; |
862 | 122k | CFrameBuffer *cfrm; |
863 | | |
864 | 122k | if (f->version <= 1) { |
865 | 346 | av_log(f->avctx, AV_LOG_ERROR, "cfrm in version %d\n", f->version); |
866 | 346 | return AVERROR_INVALIDDATA; |
867 | 346 | } |
868 | | |
869 | 122k | id = AV_RL32(buf + 12); |
870 | 122k | whole_size = AV_RL32(buf + 16); |
871 | | |
872 | 122k | if (data_size < 0 || whole_size < 0) { |
873 | 428 | av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n"); |
874 | 428 | return AVERROR_INVALIDDATA; |
875 | 428 | } |
876 | | |
877 | 12.3M | for (i = 0; i < CFRAME_BUFFER_COUNT; i++) |
878 | 12.2M | if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_num) |
879 | 280k | av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", |
880 | 280k | f->cfrm[i].id); |
881 | | |
882 | 12.0M | for (i = 0; i < CFRAME_BUFFER_COUNT; i++) { |
883 | 12.0M | if (f->cfrm[i].id == id) |
884 | 117k | break; |
885 | 11.9M | if (f->cfrm[i].size == 0) |
886 | 11.4M | free_index = i; |
887 | 11.9M | } |
888 | | |
889 | 122k | if (i >= CFRAME_BUFFER_COUNT) { |
890 | 4.33k | if (free_index < 0) |
891 | 214 | return AVERROR_INVALIDDATA; |
892 | 4.11k | i = free_index; |
893 | 4.11k | f->cfrm[i].id = id; |
894 | 4.11k | } |
895 | 121k | cfrm = &f->cfrm[i]; |
896 | | |
897 | 121k | if (data_size > UINT_MAX - cfrm->size - AV_INPUT_BUFFER_PADDING_SIZE) |
898 | 0 | return AVERROR_INVALIDDATA; |
899 | | |
900 | 121k | cfrm->data = av_fast_realloc(cfrm->data, &cfrm->allocated_size, |
901 | 121k | cfrm->size + data_size + AV_INPUT_BUFFER_PADDING_SIZE); |
902 | | // explicit check needed as memcpy below might not catch a NULL |
903 | 121k | if (!cfrm->data) { |
904 | 0 | av_log(f->avctx, AV_LOG_ERROR, "realloc failure\n"); |
905 | 0 | return AVERROR(ENOMEM); |
906 | 0 | } |
907 | | |
908 | 121k | memcpy(cfrm->data + cfrm->size, buf + 20, data_size); |
909 | 121k | cfrm->size += data_size; |
910 | | |
911 | 121k | if (cfrm->size >= whole_size) { |
912 | 1.53k | buf = cfrm->data; |
913 | 1.53k | frame_size = cfrm->size; |
914 | | |
915 | 1.53k | if (id != avctx->frame_num) |
916 | 1.07k | av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %"PRId64"\n", |
917 | 1.07k | id, avctx->frame_num); |
918 | | |
919 | 1.53k | if (f->version <= 1) |
920 | 0 | return AVERROR_INVALIDDATA; |
921 | | |
922 | 1.53k | cfrm->size = cfrm->id = 0; |
923 | 1.53k | frame_4cc = AV_RL32("pfrm"); |
924 | 1.53k | } else |
925 | 120k | return buf_size; |
926 | 121k | } else { |
927 | 24.7k | buf = buf + 12; |
928 | 24.7k | frame_size = buf_size - 12; |
929 | 24.7k | } |
930 | | |
931 | 26.2k | if ( frame_4cc == AV_RL32("ifr2") || frame_4cc == AV_RL32("ifrm") |
932 | 26.2k | || frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) { |
933 | 17.6k | if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) |
934 | 0 | return ret; |
935 | 17.6k | } |
936 | | |
937 | 26.2k | if (frame_4cc == AV_RL32("ifr2")) { |
938 | 1.75k | picture->pict_type = AV_PICTURE_TYPE_I; |
939 | 1.75k | if ((ret = decode_i2_frame(f, buf - 4, frame_size + 4)) < 0) { |
940 | 464 | av_log(f->avctx, AV_LOG_ERROR, "decode i2 frame failed\n"); |
941 | 464 | return ret; |
942 | 464 | } |
943 | 24.5k | } else if (frame_4cc == AV_RL32("ifrm")) { |
944 | 6.38k | picture->pict_type = AV_PICTURE_TYPE_I; |
945 | 6.38k | if ((ret = decode_i_frame(f, buf, frame_size)) < 0) { |
946 | 5.33k | av_log(f->avctx, AV_LOG_ERROR, "decode i frame failed\n"); |
947 | 5.33k | return ret; |
948 | 5.33k | } |
949 | 18.1k | } else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) { |
950 | 9.53k | picture->pict_type = AV_PICTURE_TYPE_P; |
951 | 9.53k | if ((ret = decode_p_frame(f, buf, frame_size)) < 0) { |
952 | 9.18k | av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n"); |
953 | 9.18k | return ret; |
954 | 9.18k | } |
955 | 9.53k | } else if (frame_4cc == AV_RL32("snd_")) { |
956 | 333 | av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", |
957 | 333 | buf_size); |
958 | 333 | return AVERROR_INVALIDDATA; |
959 | 8.29k | } else { |
960 | 8.29k | av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n", |
961 | 8.29k | buf_size); |
962 | 8.29k | return AVERROR_INVALIDDATA; |
963 | 8.29k | } |
964 | | |
965 | 2.69k | if (picture->pict_type == AV_PICTURE_TYPE_I) |
966 | 2.34k | picture->flags |= AV_FRAME_FLAG_KEY; |
967 | 357 | else |
968 | 357 | picture->flags &= ~AV_FRAME_FLAG_KEY; |
969 | | |
970 | 2.69k | av_image_copy_plane(picture->data[0], picture->linesize[0], |
971 | 2.69k | (const uint8_t*)f->frame_buffer, avctx->width * 2, |
972 | 2.69k | avctx->width * 2, avctx->height); |
973 | 2.69k | FFSWAP(uint16_t *, f->frame_buffer, f->last_frame_buffer); |
974 | | |
975 | 2.69k | *got_frame = 1; |
976 | | |
977 | 2.69k | return buf_size; |
978 | 26.2k | } |
979 | | |
980 | | static av_cold int decode_end(AVCodecContext *avctx) |
981 | 1.30k | { |
982 | 1.30k | FourXContext * const f = avctx->priv_data; |
983 | 1.30k | int i; |
984 | | |
985 | 1.30k | av_freep(&f->frame_buffer); |
986 | 1.30k | av_freep(&f->last_frame_buffer); |
987 | 1.30k | av_freep(&f->bitstream_buffer); |
988 | 1.30k | f->bitstream_buffer_size = 0; |
989 | 132k | for (i = 0; i < CFRAME_BUFFER_COUNT; i++) { |
990 | 130k | av_freep(&f->cfrm[i].data); |
991 | 130k | f->cfrm[i].allocated_size = 0; |
992 | 130k | } |
993 | 1.30k | ff_vlc_free(&f->pre_vlc); |
994 | | |
995 | 1.30k | return 0; |
996 | 1.30k | } |
997 | | |
998 | | static av_cold int decode_init(AVCodecContext *avctx) |
999 | 1.30k | { |
1000 | 1.30k | static AVOnce init_static_once = AV_ONCE_INIT; |
1001 | 1.30k | FourXContext * const f = avctx->priv_data; |
1002 | 1.30k | int ret; |
1003 | | |
1004 | 1.30k | if (avctx->extradata_size != 4 || !avctx->extradata) { |
1005 | 198 | av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n"); |
1006 | 198 | return AVERROR_INVALIDDATA; |
1007 | 198 | } |
1008 | 1.10k | if((avctx->width % 16) || (avctx->height % 16)) { |
1009 | 6 | av_log(avctx, AV_LOG_ERROR, "unsupported width/height\n"); |
1010 | 6 | return AVERROR_INVALIDDATA; |
1011 | 6 | } |
1012 | | |
1013 | 1.10k | ret = av_image_check_size(avctx->width, avctx->height, 0, avctx); |
1014 | 1.10k | if (ret < 0) |
1015 | 1 | return ret; |
1016 | | |
1017 | 1.10k | f->frame_buffer = av_mallocz(avctx->width * avctx->height * 2); |
1018 | 1.10k | f->last_frame_buffer = av_mallocz(avctx->width * avctx->height * 2); |
1019 | 1.10k | if (!f->frame_buffer || !f->last_frame_buffer) |
1020 | 0 | return AVERROR(ENOMEM); |
1021 | | |
1022 | 1.10k | f->version = AV_RL32(avctx->extradata) >> 16; |
1023 | 1.10k | ff_blockdsp_init(&f->bdsp); |
1024 | 1.10k | ff_bswapdsp_init(&f->bbdsp); |
1025 | 1.10k | f->avctx = avctx; |
1026 | | |
1027 | 1.10k | if (f->version > 2) |
1028 | 736 | avctx->pix_fmt = AV_PIX_FMT_RGB565; |
1029 | 366 | else |
1030 | 366 | avctx->pix_fmt = AV_PIX_FMT_BGR555; |
1031 | | |
1032 | 1.10k | ff_thread_once(&init_static_once, init_vlcs); |
1033 | | |
1034 | 1.10k | return 0; |
1035 | 1.10k | } |
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 | | }; |