Line |
Branch |
Exec |
Source |
1 |
|
|
/* |
2 |
|
|
* Amuse Graphics Movie decoder |
3 |
|
|
* |
4 |
|
|
* Copyright (c) 2018 Paul B Mahol |
5 |
|
|
* |
6 |
|
|
* This file is part of FFmpeg. |
7 |
|
|
* |
8 |
|
|
* FFmpeg is free software; you can redistribute it and/or |
9 |
|
|
* modify it under the terms of the GNU Lesser General Public |
10 |
|
|
* License as published by the Free Software Foundation; either |
11 |
|
|
* version 2.1 of the License, or (at your option) any later version. |
12 |
|
|
* |
13 |
|
|
* FFmpeg is distributed in the hope that it will be useful, |
14 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 |
|
|
* Lesser General Public License for more details. |
17 |
|
|
* |
18 |
|
|
* You should have received a copy of the GNU Lesser General Public |
19 |
|
|
* License along with FFmpeg; if not, write to the Free Software |
20 |
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
21 |
|
|
*/ |
22 |
|
|
|
23 |
|
|
#include <string.h> |
24 |
|
|
|
25 |
|
|
#define BITSTREAM_READER_LE |
26 |
|
|
|
27 |
|
|
#include "libavutil/mem.h" |
28 |
|
|
#include "libavutil/mem_internal.h" |
29 |
|
|
|
30 |
|
|
#include "avcodec.h" |
31 |
|
|
#include "bytestream.h" |
32 |
|
|
#include "codec_internal.h" |
33 |
|
|
#include "copy_block.h" |
34 |
|
|
#include "decode.h" |
35 |
|
|
#include "get_bits.h" |
36 |
|
|
#include "idctdsp.h" |
37 |
|
|
#include "jpegquanttables.h" |
38 |
|
|
|
39 |
|
|
typedef struct MotionVector { |
40 |
|
|
int16_t x, y; |
41 |
|
|
} MotionVector; |
42 |
|
|
|
43 |
|
|
typedef struct AGMContext { |
44 |
|
|
const AVClass *class; |
45 |
|
|
AVCodecContext *avctx; |
46 |
|
|
GetBitContext gb; |
47 |
|
|
GetByteContext gbyte; |
48 |
|
|
|
49 |
|
|
int key_frame; |
50 |
|
|
int bitstream_size; |
51 |
|
|
int compression; |
52 |
|
|
int blocks_w; |
53 |
|
|
int blocks_h; |
54 |
|
|
int size[3]; |
55 |
|
|
int plus; |
56 |
|
|
int dct; |
57 |
|
|
int rgb; |
58 |
|
|
unsigned flags; |
59 |
|
|
unsigned fflags; |
60 |
|
|
|
61 |
|
|
uint8_t *output; |
62 |
|
|
unsigned padded_output_size; |
63 |
|
|
unsigned output_size; |
64 |
|
|
|
65 |
|
|
MotionVector *mvectors; |
66 |
|
|
unsigned mvectors_size; |
67 |
|
|
|
68 |
|
|
VLC vlc; |
69 |
|
|
|
70 |
|
|
AVFrame *prev_frame; |
71 |
|
|
|
72 |
|
|
int luma_quant_matrix[64]; |
73 |
|
|
int chroma_quant_matrix[64]; |
74 |
|
|
|
75 |
|
|
uint8_t permutated_scantable[64]; |
76 |
|
|
DECLARE_ALIGNED(32, int16_t, block)[64]; |
77 |
|
|
|
78 |
|
|
int16_t *wblocks; |
79 |
|
|
unsigned wblocks_size; |
80 |
|
|
|
81 |
|
|
int *map; |
82 |
|
|
unsigned map_size; |
83 |
|
|
|
84 |
|
|
IDCTDSPContext idsp; |
85 |
|
|
} AGMContext; |
86 |
|
|
|
87 |
|
✗ |
static int read_code(GetBitContext *gb, int *oskip, int *level, int *map, int mode) |
88 |
|
|
{ |
89 |
|
✗ |
int len = 0, skip = 0, max; |
90 |
|
|
|
91 |
|
✗ |
if (get_bits_left(gb) < 2) |
92 |
|
✗ |
return AVERROR_INVALIDDATA; |
93 |
|
|
|
94 |
|
✗ |
if (show_bits(gb, 2)) { |
95 |
|
✗ |
switch (show_bits(gb, 4)) { |
96 |
|
✗ |
case 1: |
97 |
|
|
case 9: |
98 |
|
✗ |
len = 1; |
99 |
|
✗ |
skip = 3; |
100 |
|
✗ |
break; |
101 |
|
✗ |
case 2: |
102 |
|
✗ |
len = 3; |
103 |
|
✗ |
skip = 4; |
104 |
|
✗ |
break; |
105 |
|
✗ |
case 3: |
106 |
|
✗ |
len = 7; |
107 |
|
✗ |
skip = 4; |
108 |
|
✗ |
break; |
109 |
|
✗ |
case 5: |
110 |
|
|
case 13: |
111 |
|
✗ |
len = 2; |
112 |
|
✗ |
skip = 3; |
113 |
|
✗ |
break; |
114 |
|
✗ |
case 6: |
115 |
|
✗ |
len = 4; |
116 |
|
✗ |
skip = 4; |
117 |
|
✗ |
break; |
118 |
|
✗ |
case 7: |
119 |
|
✗ |
len = 8; |
120 |
|
✗ |
skip = 4; |
121 |
|
✗ |
break; |
122 |
|
✗ |
case 10: |
123 |
|
✗ |
len = 5; |
124 |
|
✗ |
skip = 4; |
125 |
|
✗ |
break; |
126 |
|
✗ |
case 11: |
127 |
|
✗ |
len = 9; |
128 |
|
✗ |
skip = 4; |
129 |
|
✗ |
break; |
130 |
|
✗ |
case 14: |
131 |
|
✗ |
len = 6; |
132 |
|
✗ |
skip = 4; |
133 |
|
✗ |
break; |
134 |
|
✗ |
case 15: |
135 |
|
✗ |
len = ((show_bits(gb, 5) & 0x10) | 0xA0) >> 4; |
136 |
|
✗ |
skip = 5; |
137 |
|
✗ |
break; |
138 |
|
✗ |
default: |
139 |
|
✗ |
return AVERROR_INVALIDDATA; |
140 |
|
|
} |
141 |
|
|
|
142 |
|
✗ |
skip_bits(gb, skip); |
143 |
|
✗ |
*level = get_bits(gb, len); |
144 |
|
✗ |
*map = 1; |
145 |
|
✗ |
*oskip = 0; |
146 |
|
✗ |
max = 1 << (len - 1); |
147 |
|
✗ |
if (*level < max) |
148 |
|
✗ |
*level = -(max + *level); |
149 |
|
✗ |
} else if (show_bits(gb, 3) & 4) { |
150 |
|
✗ |
skip_bits(gb, 3); |
151 |
|
✗ |
if (mode == 1) { |
152 |
|
✗ |
if (show_bits(gb, 4)) { |
153 |
|
✗ |
if (show_bits(gb, 4) == 1) { |
154 |
|
✗ |
skip_bits(gb, 4); |
155 |
|
✗ |
*oskip = get_bits(gb, 16); |
156 |
|
|
} else { |
157 |
|
✗ |
*oskip = get_bits(gb, 4); |
158 |
|
|
} |
159 |
|
|
} else { |
160 |
|
✗ |
skip_bits(gb, 4); |
161 |
|
✗ |
*oskip = get_bits(gb, 10); |
162 |
|
|
} |
163 |
|
✗ |
} else if (mode == 0) { |
164 |
|
✗ |
*oskip = get_bits(gb, 10); |
165 |
|
|
} |
166 |
|
✗ |
*level = 0; |
167 |
|
|
} else { |
168 |
|
✗ |
skip_bits(gb, 3); |
169 |
|
✗ |
if (mode == 0) |
170 |
|
✗ |
*oskip = get_bits(gb, 4); |
171 |
|
✗ |
else if (mode == 1) |
172 |
|
✗ |
*oskip = 0; |
173 |
|
✗ |
*level = 0; |
174 |
|
|
} |
175 |
|
|
|
176 |
|
✗ |
return 0; |
177 |
|
|
} |
178 |
|
|
|
179 |
|
✗ |
static int decode_intra_blocks(AGMContext *s, GetBitContext *gb, |
180 |
|
|
const int *quant_matrix, int *skip, int *dc_level) |
181 |
|
|
{ |
182 |
|
✗ |
const uint8_t *scantable = s->permutated_scantable; |
183 |
|
✗ |
int level, ret, map = 0; |
184 |
|
|
|
185 |
|
✗ |
memset(s->wblocks, 0, s->wblocks_size); |
186 |
|
|
|
187 |
|
✗ |
for (int i = 0; i < 64; i++) { |
188 |
|
✗ |
int16_t *block = s->wblocks + scantable[i]; |
189 |
|
|
|
190 |
|
✗ |
for (int j = 0; j < s->blocks_w;) { |
191 |
|
✗ |
if (*skip > 0) { |
192 |
|
|
int rskip; |
193 |
|
|
|
194 |
|
✗ |
rskip = FFMIN(*skip, s->blocks_w - j); |
195 |
|
✗ |
j += rskip; |
196 |
|
✗ |
if (i == 0) { |
197 |
|
✗ |
for (int k = 0; k < rskip; k++) |
198 |
|
✗ |
block[64 * k] = *dc_level * quant_matrix[0]; |
199 |
|
|
} |
200 |
|
✗ |
block += rskip * 64; |
201 |
|
✗ |
*skip -= rskip; |
202 |
|
|
} else { |
203 |
|
✗ |
ret = read_code(gb, skip, &level, &map, s->flags & 1); |
204 |
|
✗ |
if (ret < 0) |
205 |
|
✗ |
return ret; |
206 |
|
|
|
207 |
|
✗ |
if (i == 0) |
208 |
|
✗ |
*dc_level += level; |
209 |
|
|
|
210 |
|
✗ |
block[0] = (i == 0 ? *dc_level : level) * quant_matrix[i]; |
211 |
|
✗ |
block += 64; |
212 |
|
✗ |
j++; |
213 |
|
|
} |
214 |
|
|
} |
215 |
|
|
} |
216 |
|
|
|
217 |
|
✗ |
return 0; |
218 |
|
|
} |
219 |
|
|
|
220 |
|
✗ |
static int decode_inter_blocks(AGMContext *s, GetBitContext *gb, |
221 |
|
|
const int *quant_matrix, int *skip, |
222 |
|
|
int *map) |
223 |
|
|
{ |
224 |
|
✗ |
const uint8_t *scantable = s->permutated_scantable; |
225 |
|
|
int level, ret; |
226 |
|
|
|
227 |
|
✗ |
memset(s->wblocks, 0, s->wblocks_size); |
228 |
|
✗ |
memset(s->map, 0, s->map_size); |
229 |
|
|
|
230 |
|
✗ |
for (int i = 0; i < 64; i++) { |
231 |
|
✗ |
int16_t *block = s->wblocks + scantable[i]; |
232 |
|
|
|
233 |
|
✗ |
for (int j = 0; j < s->blocks_w;) { |
234 |
|
✗ |
if (*skip > 0) { |
235 |
|
|
int rskip; |
236 |
|
|
|
237 |
|
✗ |
rskip = FFMIN(*skip, s->blocks_w - j); |
238 |
|
✗ |
j += rskip; |
239 |
|
✗ |
block += rskip * 64; |
240 |
|
✗ |
*skip -= rskip; |
241 |
|
|
} else { |
242 |
|
✗ |
ret = read_code(gb, skip, &level, &map[j], s->flags & 1); |
243 |
|
✗ |
if (ret < 0) |
244 |
|
✗ |
return ret; |
245 |
|
|
|
246 |
|
✗ |
block[0] = level * quant_matrix[i]; |
247 |
|
✗ |
block += 64; |
248 |
|
✗ |
j++; |
249 |
|
|
} |
250 |
|
|
} |
251 |
|
|
} |
252 |
|
|
|
253 |
|
✗ |
return 0; |
254 |
|
|
} |
255 |
|
|
|
256 |
|
✗ |
static int decode_intra_block(AGMContext *s, GetBitContext *gb, |
257 |
|
|
const int *quant_matrix, int *skip, int *dc_level) |
258 |
|
|
{ |
259 |
|
✗ |
const uint8_t *scantable = s->permutated_scantable; |
260 |
|
✗ |
const int offset = s->plus ? 0 : 1024; |
261 |
|
✗ |
int16_t *block = s->block; |
262 |
|
✗ |
int level, ret, map = 0; |
263 |
|
|
|
264 |
|
✗ |
memset(block, 0, sizeof(s->block)); |
265 |
|
|
|
266 |
|
✗ |
if (*skip > 0) { |
267 |
|
✗ |
(*skip)--; |
268 |
|
|
} else { |
269 |
|
✗ |
ret = read_code(gb, skip, &level, &map, s->flags & 1); |
270 |
|
✗ |
if (ret < 0) |
271 |
|
✗ |
return ret; |
272 |
|
✗ |
*dc_level += level; |
273 |
|
|
} |
274 |
|
✗ |
block[scantable[0]] = offset + *dc_level * quant_matrix[0]; |
275 |
|
|
|
276 |
|
✗ |
for (int i = 1; i < 64;) { |
277 |
|
✗ |
if (*skip > 0) { |
278 |
|
|
int rskip; |
279 |
|
|
|
280 |
|
✗ |
rskip = FFMIN(*skip, 64 - i); |
281 |
|
✗ |
i += rskip; |
282 |
|
✗ |
*skip -= rskip; |
283 |
|
|
} else { |
284 |
|
✗ |
ret = read_code(gb, skip, &level, &map, s->flags & 1); |
285 |
|
✗ |
if (ret < 0) |
286 |
|
✗ |
return ret; |
287 |
|
|
|
288 |
|
✗ |
block[scantable[i]] = level * quant_matrix[i]; |
289 |
|
✗ |
i++; |
290 |
|
|
} |
291 |
|
|
} |
292 |
|
|
|
293 |
|
✗ |
return 0; |
294 |
|
|
} |
295 |
|
|
|
296 |
|
✗ |
static int decode_intra_plane(AGMContext *s, GetBitContext *gb, int size, |
297 |
|
|
const int *quant_matrix, AVFrame *frame, |
298 |
|
|
int plane) |
299 |
|
|
{ |
300 |
|
✗ |
int ret, skip = 0, dc_level = 0; |
301 |
|
✗ |
const int offset = s->plus ? 0 : 1024; |
302 |
|
|
|
303 |
|
✗ |
if ((ret = init_get_bits8(gb, s->gbyte.buffer, size)) < 0) |
304 |
|
✗ |
return ret; |
305 |
|
|
|
306 |
|
✗ |
if (s->flags & 1) { |
307 |
|
✗ |
av_fast_padded_malloc(&s->wblocks, &s->wblocks_size, |
308 |
|
✗ |
64 * s->blocks_w * sizeof(*s->wblocks)); |
309 |
|
✗ |
if (!s->wblocks) |
310 |
|
✗ |
return AVERROR(ENOMEM); |
311 |
|
|
|
312 |
|
✗ |
for (int y = 0; y < s->blocks_h; y++) { |
313 |
|
✗ |
ret = decode_intra_blocks(s, gb, quant_matrix, &skip, &dc_level); |
314 |
|
✗ |
if (ret < 0) |
315 |
|
✗ |
return ret; |
316 |
|
|
|
317 |
|
✗ |
for (int x = 0; x < s->blocks_w; x++) { |
318 |
|
✗ |
s->wblocks[64 * x] += offset; |
319 |
|
✗ |
s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
320 |
|
✗ |
frame->linesize[plane], s->wblocks + 64 * x); |
321 |
|
|
} |
322 |
|
|
} |
323 |
|
|
} else { |
324 |
|
✗ |
for (int y = 0; y < s->blocks_h; y++) { |
325 |
|
✗ |
for (int x = 0; x < s->blocks_w; x++) { |
326 |
|
✗ |
ret = decode_intra_block(s, gb, quant_matrix, &skip, &dc_level); |
327 |
|
✗ |
if (ret < 0) |
328 |
|
✗ |
return ret; |
329 |
|
|
|
330 |
|
✗ |
s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
331 |
|
✗ |
frame->linesize[plane], s->block); |
332 |
|
|
} |
333 |
|
|
} |
334 |
|
|
} |
335 |
|
|
|
336 |
|
✗ |
align_get_bits(gb); |
337 |
|
✗ |
if (get_bits_left(gb) < 0) |
338 |
|
✗ |
av_log(s->avctx, AV_LOG_WARNING, "overread\n"); |
339 |
|
✗ |
if (get_bits_left(gb) > 0) |
340 |
|
✗ |
av_log(s->avctx, AV_LOG_WARNING, "underread: %d\n", get_bits_left(gb)); |
341 |
|
|
|
342 |
|
✗ |
return 0; |
343 |
|
|
} |
344 |
|
|
|
345 |
|
✗ |
static int decode_inter_block(AGMContext *s, GetBitContext *gb, |
346 |
|
|
const int *quant_matrix, int *skip, |
347 |
|
|
int *map) |
348 |
|
|
{ |
349 |
|
✗ |
const uint8_t *scantable = s->permutated_scantable; |
350 |
|
✗ |
int16_t *block = s->block; |
351 |
|
|
int level, ret; |
352 |
|
|
|
353 |
|
✗ |
memset(block, 0, sizeof(s->block)); |
354 |
|
|
|
355 |
|
✗ |
for (int i = 0; i < 64;) { |
356 |
|
✗ |
if (*skip > 0) { |
357 |
|
|
int rskip; |
358 |
|
|
|
359 |
|
✗ |
rskip = FFMIN(*skip, 64 - i); |
360 |
|
✗ |
i += rskip; |
361 |
|
✗ |
*skip -= rskip; |
362 |
|
|
} else { |
363 |
|
✗ |
ret = read_code(gb, skip, &level, map, s->flags & 1); |
364 |
|
✗ |
if (ret < 0) |
365 |
|
✗ |
return ret; |
366 |
|
|
|
367 |
|
✗ |
block[scantable[i]] = level * quant_matrix[i]; |
368 |
|
✗ |
i++; |
369 |
|
|
} |
370 |
|
|
} |
371 |
|
|
|
372 |
|
✗ |
return 0; |
373 |
|
|
} |
374 |
|
|
|
375 |
|
✗ |
static int decode_inter_plane(AGMContext *s, GetBitContext *gb, int size, |
376 |
|
|
const int *quant_matrix, AVFrame *frame, |
377 |
|
|
AVFrame *prev, int plane) |
378 |
|
|
{ |
379 |
|
✗ |
int ret, skip = 0; |
380 |
|
|
|
381 |
|
✗ |
if ((ret = init_get_bits8(gb, s->gbyte.buffer, size)) < 0) |
382 |
|
✗ |
return ret; |
383 |
|
|
|
384 |
|
✗ |
if (s->flags == 3) { |
385 |
|
✗ |
av_fast_padded_malloc(&s->wblocks, &s->wblocks_size, |
386 |
|
✗ |
64 * s->blocks_w * sizeof(*s->wblocks)); |
387 |
|
✗ |
if (!s->wblocks) |
388 |
|
✗ |
return AVERROR(ENOMEM); |
389 |
|
|
|
390 |
|
✗ |
av_fast_padded_malloc(&s->map, &s->map_size, |
391 |
|
✗ |
s->blocks_w * sizeof(*s->map)); |
392 |
|
✗ |
if (!s->map) |
393 |
|
✗ |
return AVERROR(ENOMEM); |
394 |
|
|
|
395 |
|
✗ |
for (int y = 0; y < s->blocks_h; y++) { |
396 |
|
✗ |
ret = decode_inter_blocks(s, gb, quant_matrix, &skip, s->map); |
397 |
|
✗ |
if (ret < 0) |
398 |
|
✗ |
return ret; |
399 |
|
|
|
400 |
|
✗ |
for (int x = 0; x < s->blocks_w; x++) { |
401 |
|
✗ |
int shift = plane == 0; |
402 |
|
✗ |
int mvpos = (y >> shift) * (s->blocks_w >> shift) + (x >> shift); |
403 |
|
✗ |
int orig_mv_x = s->mvectors[mvpos].x; |
404 |
|
✗ |
int mv_x = s->mvectors[mvpos].x / (1 + !shift); |
405 |
|
✗ |
int mv_y = s->mvectors[mvpos].y / (1 + !shift); |
406 |
|
✗ |
int h = s->avctx->coded_height >> !shift; |
407 |
|
✗ |
int w = s->avctx->coded_width >> !shift; |
408 |
|
✗ |
int map = s->map[x]; |
409 |
|
|
|
410 |
|
✗ |
if (orig_mv_x >= -32) { |
411 |
|
✗ |
if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 > h || |
412 |
|
✗ |
x * 8 + mv_x < 0 || x * 8 + mv_x + 8 > w) |
413 |
|
✗ |
return AVERROR_INVALIDDATA; |
414 |
|
|
|
415 |
|
✗ |
copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
416 |
|
✗ |
prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x), |
417 |
|
✗ |
frame->linesize[plane], prev->linesize[plane], 8); |
418 |
|
✗ |
if (map) { |
419 |
|
✗ |
s->idsp.idct(s->wblocks + x * 64); |
420 |
|
✗ |
for (int i = 0; i < 64; i++) |
421 |
|
✗ |
s->wblocks[i + x * 64] = (s->wblocks[i + x * 64] + 1) & 0xFFFC; |
422 |
|
✗ |
s->idsp.add_pixels_clamped(&s->wblocks[x*64], frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
423 |
|
✗ |
frame->linesize[plane]); |
424 |
|
|
} |
425 |
|
✗ |
} else if (map) { |
426 |
|
✗ |
s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
427 |
|
✗ |
frame->linesize[plane], s->wblocks + x * 64); |
428 |
|
|
} |
429 |
|
|
} |
430 |
|
|
} |
431 |
|
✗ |
} else if (s->flags & 2) { |
432 |
|
✗ |
for (int y = 0; y < s->blocks_h; y++) { |
433 |
|
✗ |
for (int x = 0; x < s->blocks_w; x++) { |
434 |
|
✗ |
int shift = plane == 0; |
435 |
|
✗ |
int mvpos = (y >> shift) * (s->blocks_w >> shift) + (x >> shift); |
436 |
|
✗ |
int orig_mv_x = s->mvectors[mvpos].x; |
437 |
|
✗ |
int mv_x = s->mvectors[mvpos].x / (1 + !shift); |
438 |
|
✗ |
int mv_y = s->mvectors[mvpos].y / (1 + !shift); |
439 |
|
✗ |
int h = s->avctx->coded_height >> !shift; |
440 |
|
✗ |
int w = s->avctx->coded_width >> !shift; |
441 |
|
✗ |
int map = 0; |
442 |
|
|
|
443 |
|
✗ |
ret = decode_inter_block(s, gb, quant_matrix, &skip, &map); |
444 |
|
✗ |
if (ret < 0) |
445 |
|
✗ |
return ret; |
446 |
|
|
|
447 |
|
✗ |
if (orig_mv_x >= -32) { |
448 |
|
✗ |
if (y * 8 + mv_y < 0 || y * 8 + mv_y + 8 > h || |
449 |
|
✗ |
x * 8 + mv_x < 0 || x * 8 + mv_x + 8 > w) |
450 |
|
✗ |
return AVERROR_INVALIDDATA; |
451 |
|
|
|
452 |
|
✗ |
copy_block8(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
453 |
|
✗ |
prev->data[plane] + ((s->blocks_h - 1 - y) * 8 - mv_y) * prev->linesize[plane] + (x * 8 + mv_x), |
454 |
|
✗ |
frame->linesize[plane], prev->linesize[plane], 8); |
455 |
|
✗ |
if (map) { |
456 |
|
✗ |
s->idsp.idct(s->block); |
457 |
|
✗ |
for (int i = 0; i < 64; i++) |
458 |
|
✗ |
s->block[i] = (s->block[i] + 1) & 0xFFFC; |
459 |
|
✗ |
s->idsp.add_pixels_clamped(s->block, frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
460 |
|
✗ |
frame->linesize[plane]); |
461 |
|
|
} |
462 |
|
✗ |
} else if (map) { |
463 |
|
✗ |
s->idsp.idct_put(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
464 |
|
✗ |
frame->linesize[plane], s->block); |
465 |
|
|
} |
466 |
|
|
} |
467 |
|
|
} |
468 |
|
✗ |
} else if (s->flags & 1) { |
469 |
|
✗ |
av_fast_padded_malloc(&s->wblocks, &s->wblocks_size, |
470 |
|
✗ |
64 * s->blocks_w * sizeof(*s->wblocks)); |
471 |
|
✗ |
if (!s->wblocks) |
472 |
|
✗ |
return AVERROR(ENOMEM); |
473 |
|
|
|
474 |
|
✗ |
av_fast_padded_malloc(&s->map, &s->map_size, |
475 |
|
✗ |
s->blocks_w * sizeof(*s->map)); |
476 |
|
✗ |
if (!s->map) |
477 |
|
✗ |
return AVERROR(ENOMEM); |
478 |
|
|
|
479 |
|
✗ |
for (int y = 0; y < s->blocks_h; y++) { |
480 |
|
✗ |
ret = decode_inter_blocks(s, gb, quant_matrix, &skip, s->map); |
481 |
|
✗ |
if (ret < 0) |
482 |
|
✗ |
return ret; |
483 |
|
|
|
484 |
|
✗ |
for (int x = 0; x < s->blocks_w; x++) { |
485 |
|
✗ |
if (!s->map[x]) |
486 |
|
✗ |
continue; |
487 |
|
✗ |
s->idsp.idct_add(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
488 |
|
✗ |
frame->linesize[plane], s->wblocks + 64 * x); |
489 |
|
|
} |
490 |
|
|
} |
491 |
|
|
} else { |
492 |
|
✗ |
for (int y = 0; y < s->blocks_h; y++) { |
493 |
|
✗ |
for (int x = 0; x < s->blocks_w; x++) { |
494 |
|
✗ |
int map = 0; |
495 |
|
|
|
496 |
|
✗ |
ret = decode_inter_block(s, gb, quant_matrix, &skip, &map); |
497 |
|
✗ |
if (ret < 0) |
498 |
|
✗ |
return ret; |
499 |
|
|
|
500 |
|
✗ |
if (!map) |
501 |
|
✗ |
continue; |
502 |
|
✗ |
s->idsp.idct_add(frame->data[plane] + (s->blocks_h - 1 - y) * 8 * frame->linesize[plane] + x * 8, |
503 |
|
✗ |
frame->linesize[plane], s->block); |
504 |
|
|
} |
505 |
|
|
} |
506 |
|
|
} |
507 |
|
|
|
508 |
|
✗ |
align_get_bits(gb); |
509 |
|
✗ |
if (get_bits_left(gb) < 0) |
510 |
|
✗ |
av_log(s->avctx, AV_LOG_WARNING, "overread\n"); |
511 |
|
✗ |
if (get_bits_left(gb) > 0) |
512 |
|
✗ |
av_log(s->avctx, AV_LOG_WARNING, "underread: %d\n", get_bits_left(gb)); |
513 |
|
|
|
514 |
|
✗ |
return 0; |
515 |
|
|
} |
516 |
|
|
|
517 |
|
✗ |
static void compute_quant_matrix(AGMContext *s, double qscale) |
518 |
|
|
{ |
519 |
|
|
int luma[64], chroma[64]; |
520 |
|
✗ |
double f = 1.0 - fabs(qscale); |
521 |
|
|
|
522 |
|
✗ |
if (!s->key_frame && (s->flags & 2)) { |
523 |
|
✗ |
if (qscale >= 0.0) { |
524 |
|
✗ |
for (int i = 0; i < 64; i++) { |
525 |
|
✗ |
luma[i] = FFMAX(1, 16 * f); |
526 |
|
✗ |
chroma[i] = FFMAX(1, 16 * f); |
527 |
|
|
} |
528 |
|
|
} else { |
529 |
|
✗ |
for (int i = 0; i < 64; i++) { |
530 |
|
✗ |
luma[i] = FFMAX(1, 16 - qscale * 32); |
531 |
|
✗ |
chroma[i] = FFMAX(1, 16 - qscale * 32); |
532 |
|
|
} |
533 |
|
|
} |
534 |
|
|
} else { |
535 |
|
✗ |
if (qscale >= 0.0) { |
536 |
|
✗ |
for (int i = 0; i < 64; i++) { |
537 |
|
✗ |
luma[i] = FFMAX(1, ff_mjpeg_std_luminance_quant_tbl [(i & 7) * 8 + (i >> 3)] * f); |
538 |
|
✗ |
chroma[i] = FFMAX(1, ff_mjpeg_std_chrominance_quant_tbl[(i & 7) * 8 + (i >> 3)] * f); |
539 |
|
|
} |
540 |
|
|
} else { |
541 |
|
✗ |
for (int i = 0; i < 64; i++) { |
542 |
|
✗ |
luma[i] = FFMAX(1, 255.0 - (255 - ff_mjpeg_std_luminance_quant_tbl [(i & 7) * 8 + (i >> 3)]) * f); |
543 |
|
✗ |
chroma[i] = FFMAX(1, 255.0 - (255 - ff_mjpeg_std_chrominance_quant_tbl[(i & 7) * 8 + (i >> 3)]) * f); |
544 |
|
|
} |
545 |
|
|
} |
546 |
|
|
} |
547 |
|
|
|
548 |
|
✗ |
for (int i = 0; i < 64; i++) { |
549 |
|
✗ |
int pos = ff_zigzag_direct[i]; |
550 |
|
|
|
551 |
|
✗ |
s->luma_quant_matrix[i] = luma[pos] * ((pos / 8) & 1 ? -1 : 1); |
552 |
|
✗ |
s->chroma_quant_matrix[i] = chroma[pos] * ((pos / 8) & 1 ? -1 : 1); |
553 |
|
|
} |
554 |
|
✗ |
} |
555 |
|
|
|
556 |
|
✗ |
static int decode_raw_intra_rgb(AVCodecContext *avctx, GetByteContext *gbyte, AVFrame *frame) |
557 |
|
|
{ |
558 |
|
✗ |
uint8_t *dst = frame->data[0] + (avctx->height - 1) * frame->linesize[0]; |
559 |
|
✗ |
uint8_t r = 0, g = 0, b = 0; |
560 |
|
|
|
561 |
|
✗ |
if (bytestream2_get_bytes_left(gbyte) < 3 * avctx->width * avctx->height) |
562 |
|
✗ |
return AVERROR_INVALIDDATA; |
563 |
|
|
|
564 |
|
✗ |
for (int y = 0; y < avctx->height; y++) { |
565 |
|
✗ |
for (int x = 0; x < avctx->width; x++) { |
566 |
|
✗ |
dst[x*3+0] = bytestream2_get_byteu(gbyte) + r; |
567 |
|
✗ |
r = dst[x*3+0]; |
568 |
|
✗ |
dst[x*3+1] = bytestream2_get_byteu(gbyte) + g; |
569 |
|
✗ |
g = dst[x*3+1]; |
570 |
|
✗ |
dst[x*3+2] = bytestream2_get_byteu(gbyte) + b; |
571 |
|
✗ |
b = dst[x*3+2]; |
572 |
|
|
} |
573 |
|
✗ |
dst -= frame->linesize[0]; |
574 |
|
|
} |
575 |
|
|
|
576 |
|
✗ |
return 0; |
577 |
|
|
} |
578 |
|
|
|
579 |
|
✗ |
av_always_inline static int fill_pixels(uint8_t **y0, uint8_t **y1, |
580 |
|
|
uint8_t **u, uint8_t **v, |
581 |
|
|
int ylinesize, int ulinesize, int vlinesize, |
582 |
|
|
uint8_t *fill, |
583 |
|
|
int *nx, int *ny, int *np, int w, int h) |
584 |
|
|
{ |
585 |
|
✗ |
uint8_t *y0dst = *y0; |
586 |
|
✗ |
uint8_t *y1dst = *y1; |
587 |
|
✗ |
uint8_t *udst = *u; |
588 |
|
✗ |
uint8_t *vdst = *v; |
589 |
|
✗ |
int x = *nx, y = *ny, pos = *np; |
590 |
|
|
|
591 |
|
✗ |
if (pos == 0) { |
592 |
|
✗ |
y0dst[2*x+0] += fill[0]; |
593 |
|
✗ |
y0dst[2*x+1] += fill[1]; |
594 |
|
✗ |
y1dst[2*x+0] += fill[2]; |
595 |
|
✗ |
y1dst[2*x+1] += fill[3]; |
596 |
|
✗ |
pos++; |
597 |
|
✗ |
} else if (pos == 1) { |
598 |
|
✗ |
udst[x] += fill[0]; |
599 |
|
✗ |
vdst[x] += fill[1]; |
600 |
|
✗ |
x++; |
601 |
|
✗ |
if (x >= w) { |
602 |
|
✗ |
x = 0; |
603 |
|
✗ |
y++; |
604 |
|
✗ |
if (y >= h) |
605 |
|
✗ |
return 1; |
606 |
|
✗ |
y0dst -= 2*ylinesize; |
607 |
|
✗ |
y1dst -= 2*ylinesize; |
608 |
|
✗ |
udst -= ulinesize; |
609 |
|
✗ |
vdst -= vlinesize; |
610 |
|
|
} |
611 |
|
✗ |
y0dst[2*x+0] += fill[2]; |
612 |
|
✗ |
y0dst[2*x+1] += fill[3]; |
613 |
|
✗ |
pos++; |
614 |
|
✗ |
} else if (pos == 2) { |
615 |
|
✗ |
y1dst[2*x+0] += fill[0]; |
616 |
|
✗ |
y1dst[2*x+1] += fill[1]; |
617 |
|
✗ |
udst[x] += fill[2]; |
618 |
|
✗ |
vdst[x] += fill[3]; |
619 |
|
✗ |
x++; |
620 |
|
✗ |
if (x >= w) { |
621 |
|
✗ |
x = 0; |
622 |
|
✗ |
y++; |
623 |
|
✗ |
if (y >= h) |
624 |
|
✗ |
return 1; |
625 |
|
✗ |
y0dst -= 2*ylinesize; |
626 |
|
✗ |
y1dst -= 2*ylinesize; |
627 |
|
✗ |
udst -= ulinesize; |
628 |
|
✗ |
vdst -= vlinesize; |
629 |
|
|
} |
630 |
|
✗ |
pos = 0; |
631 |
|
|
} |
632 |
|
|
|
633 |
|
✗ |
*y0 = y0dst; |
634 |
|
✗ |
*y1 = y1dst; |
635 |
|
✗ |
*u = udst; |
636 |
|
✗ |
*v = vdst; |
637 |
|
✗ |
*np = pos; |
638 |
|
✗ |
*nx = x; |
639 |
|
✗ |
*ny = y; |
640 |
|
|
|
641 |
|
✗ |
return 0; |
642 |
|
|
} |
643 |
|
|
|
644 |
|
✗ |
static int decode_runlen_rgb(AVCodecContext *avctx, GetByteContext *gbyte, AVFrame *frame) |
645 |
|
|
{ |
646 |
|
✗ |
uint8_t *dst = frame->data[0] + (avctx->height - 1) * frame->linesize[0]; |
647 |
|
✗ |
int runlen, y = 0, x = 0; |
648 |
|
|
uint8_t fill[4]; |
649 |
|
|
unsigned code; |
650 |
|
|
|
651 |
|
✗ |
while (bytestream2_get_bytes_left(gbyte) > 0) { |
652 |
|
✗ |
code = bytestream2_peek_le32(gbyte); |
653 |
|
✗ |
runlen = code & 0xFFFFFF; |
654 |
|
|
|
655 |
|
✗ |
if (code >> 24 == 0x77) { |
656 |
|
✗ |
bytestream2_skip(gbyte, 4); |
657 |
|
|
|
658 |
|
✗ |
for (int i = 0; i < 4; i++) |
659 |
|
✗ |
fill[i] = bytestream2_get_byte(gbyte); |
660 |
|
|
|
661 |
|
✗ |
while (runlen > 0) { |
662 |
|
✗ |
runlen--; |
663 |
|
|
|
664 |
|
✗ |
for (int i = 0; i < 4; i++) { |
665 |
|
✗ |
dst[x] += fill[i]; |
666 |
|
✗ |
x++; |
667 |
|
✗ |
if (x >= frame->width * 3) { |
668 |
|
✗ |
x = 0; |
669 |
|
✗ |
y++; |
670 |
|
✗ |
dst -= frame->linesize[0]; |
671 |
|
✗ |
if (y >= frame->height) |
672 |
|
✗ |
return 0; |
673 |
|
|
} |
674 |
|
|
} |
675 |
|
|
} |
676 |
|
|
} else { |
677 |
|
✗ |
for (int i = 0; i < 4; i++) |
678 |
|
✗ |
fill[i] = bytestream2_get_byte(gbyte); |
679 |
|
|
|
680 |
|
✗ |
for (int i = 0; i < 4; i++) { |
681 |
|
✗ |
dst[x] += fill[i]; |
682 |
|
✗ |
x++; |
683 |
|
✗ |
if (x >= frame->width * 3) { |
684 |
|
✗ |
x = 0; |
685 |
|
✗ |
y++; |
686 |
|
✗ |
dst -= frame->linesize[0]; |
687 |
|
✗ |
if (y >= frame->height) |
688 |
|
✗ |
return 0; |
689 |
|
|
} |
690 |
|
|
} |
691 |
|
|
} |
692 |
|
|
} |
693 |
|
|
|
694 |
|
✗ |
return 0; |
695 |
|
|
} |
696 |
|
|
|
697 |
|
✗ |
static int decode_runlen(AVCodecContext *avctx, GetByteContext *gbyte, AVFrame *frame) |
698 |
|
|
{ |
699 |
|
✗ |
uint8_t *y0dst = frame->data[0] + (avctx->height - 1) * frame->linesize[0]; |
700 |
|
✗ |
uint8_t *y1dst = y0dst - frame->linesize[0]; |
701 |
|
✗ |
uint8_t *udst = frame->data[1] + ((avctx->height >> 1) - 1) * frame->linesize[1]; |
702 |
|
✗ |
uint8_t *vdst = frame->data[2] + ((avctx->height >> 1) - 1) * frame->linesize[2]; |
703 |
|
✗ |
int runlen, y = 0, x = 0, pos = 0; |
704 |
|
|
uint8_t fill[4]; |
705 |
|
|
unsigned code; |
706 |
|
|
|
707 |
|
✗ |
while (bytestream2_get_bytes_left(gbyte) > 0) { |
708 |
|
✗ |
code = bytestream2_peek_le32(gbyte); |
709 |
|
✗ |
runlen = code & 0xFFFFFF; |
710 |
|
|
|
711 |
|
✗ |
if (code >> 24 == 0x77) { |
712 |
|
✗ |
bytestream2_skip(gbyte, 4); |
713 |
|
|
|
714 |
|
✗ |
for (int i = 0; i < 4; i++) |
715 |
|
✗ |
fill[i] = bytestream2_get_byte(gbyte); |
716 |
|
|
|
717 |
|
✗ |
while (runlen > 0) { |
718 |
|
✗ |
runlen--; |
719 |
|
|
|
720 |
|
✗ |
if (fill_pixels(&y0dst, &y1dst, &udst, &vdst, |
721 |
|
|
frame->linesize[0], |
722 |
|
|
frame->linesize[1], |
723 |
|
|
frame->linesize[2], |
724 |
|
|
fill, &x, &y, &pos, |
725 |
|
✗ |
avctx->width / 2, |
726 |
|
✗ |
avctx->height / 2)) |
727 |
|
✗ |
return 0; |
728 |
|
|
} |
729 |
|
|
} else { |
730 |
|
✗ |
for (int i = 0; i < 4; i++) |
731 |
|
✗ |
fill[i] = bytestream2_get_byte(gbyte); |
732 |
|
|
|
733 |
|
✗ |
if (fill_pixels(&y0dst, &y1dst, &udst, &vdst, |
734 |
|
|
frame->linesize[0], |
735 |
|
|
frame->linesize[1], |
736 |
|
|
frame->linesize[2], |
737 |
|
|
fill, &x, &y, &pos, |
738 |
|
✗ |
avctx->width / 2, |
739 |
|
✗ |
avctx->height / 2)) |
740 |
|
✗ |
return 0; |
741 |
|
|
} |
742 |
|
|
} |
743 |
|
|
|
744 |
|
✗ |
return 0; |
745 |
|
|
} |
746 |
|
|
|
747 |
|
✗ |
static int decode_raw_intra(AVCodecContext *avctx, GetByteContext *gbyte, AVFrame *frame) |
748 |
|
|
{ |
749 |
|
✗ |
uint8_t *y0dst = frame->data[0] + (avctx->height - 1) * frame->linesize[0]; |
750 |
|
✗ |
uint8_t *y1dst = y0dst - frame->linesize[0]; |
751 |
|
✗ |
uint8_t *udst = frame->data[1] + ((avctx->height >> 1) - 1) * frame->linesize[1]; |
752 |
|
✗ |
uint8_t *vdst = frame->data[2] + ((avctx->height >> 1) - 1) * frame->linesize[2]; |
753 |
|
✗ |
uint8_t ly0 = 0, ly1 = 0, ly2 = 0, ly3 = 0, lu = 0, lv = 0; |
754 |
|
|
|
755 |
|
✗ |
for (int y = 0; y < avctx->height / 2; y++) { |
756 |
|
✗ |
for (int x = 0; x < avctx->width / 2; x++) { |
757 |
|
✗ |
y0dst[x*2+0] = bytestream2_get_byte(gbyte) + ly0; |
758 |
|
✗ |
ly0 = y0dst[x*2+0]; |
759 |
|
✗ |
y0dst[x*2+1] = bytestream2_get_byte(gbyte) + ly1; |
760 |
|
✗ |
ly1 = y0dst[x*2+1]; |
761 |
|
✗ |
y1dst[x*2+0] = bytestream2_get_byte(gbyte) + ly2; |
762 |
|
✗ |
ly2 = y1dst[x*2+0]; |
763 |
|
✗ |
y1dst[x*2+1] = bytestream2_get_byte(gbyte) + ly3; |
764 |
|
✗ |
ly3 = y1dst[x*2+1]; |
765 |
|
✗ |
udst[x] = bytestream2_get_byte(gbyte) + lu; |
766 |
|
✗ |
lu = udst[x]; |
767 |
|
✗ |
vdst[x] = bytestream2_get_byte(gbyte) + lv; |
768 |
|
✗ |
lv = vdst[x]; |
769 |
|
|
} |
770 |
|
|
|
771 |
|
✗ |
y0dst -= 2*frame->linesize[0]; |
772 |
|
✗ |
y1dst -= 2*frame->linesize[0]; |
773 |
|
✗ |
udst -= frame->linesize[1]; |
774 |
|
✗ |
vdst -= frame->linesize[2]; |
775 |
|
|
} |
776 |
|
|
|
777 |
|
✗ |
return 0; |
778 |
|
|
} |
779 |
|
|
|
780 |
|
✗ |
static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame) |
781 |
|
|
{ |
782 |
|
✗ |
AGMContext *s = avctx->priv_data; |
783 |
|
|
int ret; |
784 |
|
|
|
785 |
|
✗ |
compute_quant_matrix(s, (2 * s->compression - 100) / 100.0); |
786 |
|
|
|
787 |
|
✗ |
s->blocks_w = avctx->coded_width >> 3; |
788 |
|
✗ |
s->blocks_h = avctx->coded_height >> 3; |
789 |
|
|
|
790 |
|
✗ |
ret = decode_intra_plane(s, gb, s->size[0], s->luma_quant_matrix, frame, 0); |
791 |
|
✗ |
if (ret < 0) |
792 |
|
✗ |
return ret; |
793 |
|
|
|
794 |
|
✗ |
bytestream2_skip(&s->gbyte, s->size[0]); |
795 |
|
|
|
796 |
|
✗ |
s->blocks_w = avctx->coded_width >> 4; |
797 |
|
✗ |
s->blocks_h = avctx->coded_height >> 4; |
798 |
|
|
|
799 |
|
✗ |
ret = decode_intra_plane(s, gb, s->size[1], s->chroma_quant_matrix, frame, 2); |
800 |
|
✗ |
if (ret < 0) |
801 |
|
✗ |
return ret; |
802 |
|
|
|
803 |
|
✗ |
bytestream2_skip(&s->gbyte, s->size[1]); |
804 |
|
|
|
805 |
|
✗ |
s->blocks_w = avctx->coded_width >> 4; |
806 |
|
✗ |
s->blocks_h = avctx->coded_height >> 4; |
807 |
|
|
|
808 |
|
✗ |
ret = decode_intra_plane(s, gb, s->size[2], s->chroma_quant_matrix, frame, 1); |
809 |
|
✗ |
if (ret < 0) |
810 |
|
✗ |
return ret; |
811 |
|
|
|
812 |
|
✗ |
return 0; |
813 |
|
|
} |
814 |
|
|
|
815 |
|
✗ |
static int decode_motion_vectors(AVCodecContext *avctx, GetBitContext *gb) |
816 |
|
|
{ |
817 |
|
✗ |
AGMContext *s = avctx->priv_data; |
818 |
|
✗ |
int nb_mvs = ((avctx->coded_height + 15) >> 4) * ((avctx->coded_width + 15) >> 4); |
819 |
|
✗ |
int ret, skip = 0, value, map; |
820 |
|
|
|
821 |
|
✗ |
av_fast_padded_malloc(&s->mvectors, &s->mvectors_size, |
822 |
|
|
nb_mvs * sizeof(*s->mvectors)); |
823 |
|
✗ |
if (!s->mvectors) |
824 |
|
✗ |
return AVERROR(ENOMEM); |
825 |
|
|
|
826 |
|
✗ |
if ((ret = init_get_bits8(gb, s->gbyte.buffer, bytestream2_get_bytes_left(&s->gbyte) - |
827 |
|
✗ |
(s->size[0] + s->size[1] + s->size[2]))) < 0) |
828 |
|
✗ |
return ret; |
829 |
|
|
|
830 |
|
✗ |
memset(s->mvectors, 0, sizeof(*s->mvectors) * nb_mvs); |
831 |
|
|
|
832 |
|
✗ |
for (int i = 0; i < nb_mvs; i++) { |
833 |
|
✗ |
ret = read_code(gb, &skip, &value, &map, 1); |
834 |
|
✗ |
if (ret < 0) |
835 |
|
✗ |
return ret; |
836 |
|
✗ |
s->mvectors[i].x = value; |
837 |
|
✗ |
i += skip; |
838 |
|
|
} |
839 |
|
|
|
840 |
|
✗ |
for (int i = 0; i < nb_mvs; i++) { |
841 |
|
✗ |
ret = read_code(gb, &skip, &value, &map, 1); |
842 |
|
✗ |
if (ret < 0) |
843 |
|
✗ |
return ret; |
844 |
|
✗ |
s->mvectors[i].y = value; |
845 |
|
✗ |
i += skip; |
846 |
|
|
} |
847 |
|
|
|
848 |
|
✗ |
if (get_bits_left(gb) <= 0) |
849 |
|
✗ |
return AVERROR_INVALIDDATA; |
850 |
|
✗ |
skip = (get_bits_count(gb) >> 3) + 1; |
851 |
|
✗ |
bytestream2_skip(&s->gbyte, skip); |
852 |
|
|
|
853 |
|
✗ |
return 0; |
854 |
|
|
} |
855 |
|
|
|
856 |
|
✗ |
static int decode_inter(AVCodecContext *avctx, GetBitContext *gb, |
857 |
|
|
AVFrame *frame, AVFrame *prev) |
858 |
|
|
{ |
859 |
|
✗ |
AGMContext *s = avctx->priv_data; |
860 |
|
|
int ret; |
861 |
|
|
|
862 |
|
✗ |
compute_quant_matrix(s, (2 * s->compression - 100) / 100.0); |
863 |
|
|
|
864 |
|
✗ |
if (s->flags & 2) { |
865 |
|
✗ |
ret = decode_motion_vectors(avctx, gb); |
866 |
|
✗ |
if (ret < 0) |
867 |
|
✗ |
return ret; |
868 |
|
|
} |
869 |
|
|
|
870 |
|
✗ |
s->blocks_w = avctx->coded_width >> 3; |
871 |
|
✗ |
s->blocks_h = avctx->coded_height >> 3; |
872 |
|
|
|
873 |
|
✗ |
ret = decode_inter_plane(s, gb, s->size[0], s->luma_quant_matrix, frame, prev, 0); |
874 |
|
✗ |
if (ret < 0) |
875 |
|
✗ |
return ret; |
876 |
|
|
|
877 |
|
✗ |
bytestream2_skip(&s->gbyte, s->size[0]); |
878 |
|
|
|
879 |
|
✗ |
s->blocks_w = avctx->coded_width >> 4; |
880 |
|
✗ |
s->blocks_h = avctx->coded_height >> 4; |
881 |
|
|
|
882 |
|
✗ |
ret = decode_inter_plane(s, gb, s->size[1], s->chroma_quant_matrix, frame, prev, 2); |
883 |
|
✗ |
if (ret < 0) |
884 |
|
✗ |
return ret; |
885 |
|
|
|
886 |
|
✗ |
bytestream2_skip(&s->gbyte, s->size[1]); |
887 |
|
|
|
888 |
|
✗ |
s->blocks_w = avctx->coded_width >> 4; |
889 |
|
✗ |
s->blocks_h = avctx->coded_height >> 4; |
890 |
|
|
|
891 |
|
✗ |
ret = decode_inter_plane(s, gb, s->size[2], s->chroma_quant_matrix, frame, prev, 1); |
892 |
|
✗ |
if (ret < 0) |
893 |
|
✗ |
return ret; |
894 |
|
|
|
895 |
|
✗ |
return 0; |
896 |
|
|
} |
897 |
|
|
|
898 |
|
|
typedef struct Node { |
899 |
|
|
int parent; |
900 |
|
|
int child[2]; |
901 |
|
|
} Node; |
902 |
|
|
|
903 |
|
✗ |
static void get_tree_codes(uint32_t *codes, Node *nodes, int idx, uint32_t pfx, int bitpos) |
904 |
|
|
{ |
905 |
|
✗ |
if (idx < 256 && idx >= 0) { |
906 |
|
✗ |
codes[idx] = pfx; |
907 |
|
✗ |
} else if (idx >= 0) { |
908 |
|
✗ |
get_tree_codes(codes, nodes, nodes[idx].child[0], pfx + (0 << bitpos), bitpos + 1); |
909 |
|
✗ |
get_tree_codes(codes, nodes, nodes[idx].child[1], pfx + (1U << bitpos), bitpos + 1); |
910 |
|
|
} |
911 |
|
✗ |
} |
912 |
|
|
|
913 |
|
✗ |
static int make_new_tree(const uint8_t *bitlens, uint32_t *codes) |
914 |
|
|
{ |
915 |
|
✗ |
int zlcount = 0, curlen, idx, nindex, last, llast; |
916 |
|
✗ |
int blcounts[32] = { 0 }; |
917 |
|
|
int syms[8192]; |
918 |
|
|
Node nodes[512]; |
919 |
|
|
int node_idx[1024]; |
920 |
|
|
int old_idx[512]; |
921 |
|
|
|
922 |
|
✗ |
for (int i = 0; i < 256; i++) { |
923 |
|
✗ |
int bitlen = bitlens[i]; |
924 |
|
✗ |
int blcount = blcounts[bitlen]; |
925 |
|
|
|
926 |
|
✗ |
zlcount += bitlen < 1; |
927 |
|
✗ |
syms[(bitlen << 8) + blcount] = i; |
928 |
|
✗ |
blcounts[bitlen]++; |
929 |
|
|
} |
930 |
|
|
|
931 |
|
✗ |
for (int i = 0; i < 512; i++) { |
932 |
|
✗ |
nodes[i].child[0] = -1; |
933 |
|
✗ |
nodes[i].child[1] = -1; |
934 |
|
|
} |
935 |
|
|
|
936 |
|
✗ |
for (int i = 0; i < 256; i++) { |
937 |
|
✗ |
node_idx[i] = 257 + i; |
938 |
|
|
} |
939 |
|
|
|
940 |
|
✗ |
curlen = 1; |
941 |
|
✗ |
node_idx[512] = 256; |
942 |
|
✗ |
last = 255; |
943 |
|
✗ |
nindex = 1; |
944 |
|
|
|
945 |
|
✗ |
for (curlen = 1; curlen < 32; curlen++) { |
946 |
|
✗ |
if (blcounts[curlen] > 0) { |
947 |
|
✗ |
int max_zlcount = zlcount + blcounts[curlen]; |
948 |
|
|
|
949 |
|
✗ |
for (int i = 0; zlcount < 256 && zlcount < max_zlcount; zlcount++, i++) { |
950 |
|
✗ |
int p = node_idx[nindex - 1 + 512]; |
951 |
|
✗ |
int ch = syms[256 * curlen + i]; |
952 |
|
|
|
953 |
|
✗ |
if (nindex <= 0) |
954 |
|
✗ |
return AVERROR_INVALIDDATA; |
955 |
|
|
|
956 |
|
✗ |
if (nodes[p].child[0] == -1) { |
957 |
|
✗ |
nodes[p].child[0] = ch; |
958 |
|
|
} else { |
959 |
|
✗ |
nodes[p].child[1] = ch; |
960 |
|
✗ |
nindex--; |
961 |
|
|
} |
962 |
|
✗ |
nodes[ch].parent = p; |
963 |
|
|
} |
964 |
|
|
} |
965 |
|
✗ |
llast = last - 1; |
966 |
|
✗ |
idx = 0; |
967 |
|
✗ |
while (nindex > 0) { |
968 |
|
|
int p, ch; |
969 |
|
|
|
970 |
|
✗ |
last = llast - idx; |
971 |
|
✗ |
p = node_idx[nindex - 1 + 512]; |
972 |
|
✗ |
ch = node_idx[last]; |
973 |
|
✗ |
if (nodes[p].child[0] == -1) { |
974 |
|
✗ |
nodes[p].child[0] = ch; |
975 |
|
|
} else { |
976 |
|
✗ |
nodes[p].child[1] = ch; |
977 |
|
✗ |
nindex--; |
978 |
|
|
} |
979 |
|
✗ |
old_idx[idx] = ch; |
980 |
|
✗ |
nodes[ch].parent = p; |
981 |
|
✗ |
if (idx == llast) |
982 |
|
✗ |
goto next; |
983 |
|
✗ |
idx++; |
984 |
|
✗ |
if (nindex <= 0) { |
985 |
|
✗ |
for (int i = 0; i < idx; i++) |
986 |
|
✗ |
node_idx[512 + i] = old_idx[i]; |
987 |
|
|
} |
988 |
|
|
} |
989 |
|
✗ |
nindex = idx; |
990 |
|
|
} |
991 |
|
|
|
992 |
|
✗ |
next: |
993 |
|
|
|
994 |
|
✗ |
get_tree_codes(codes, nodes, 256, 0, 0); |
995 |
|
✗ |
return 0; |
996 |
|
|
} |
997 |
|
|
|
998 |
|
✗ |
static int build_huff(const uint8_t *bitlen, VLC *vlc) |
999 |
|
|
{ |
1000 |
|
|
uint32_t new_codes[256]; |
1001 |
|
|
uint8_t bits[256]; |
1002 |
|
|
uint8_t symbols[256]; |
1003 |
|
|
uint32_t codes[256]; |
1004 |
|
✗ |
int nb_codes = 0; |
1005 |
|
|
|
1006 |
|
✗ |
int ret = make_new_tree(bitlen, new_codes); |
1007 |
|
✗ |
if (ret < 0) |
1008 |
|
✗ |
return ret; |
1009 |
|
|
|
1010 |
|
✗ |
for (int i = 0; i < 256; i++) { |
1011 |
|
✗ |
if (bitlen[i]) { |
1012 |
|
✗ |
bits[nb_codes] = bitlen[i]; |
1013 |
|
✗ |
codes[nb_codes] = new_codes[i]; |
1014 |
|
✗ |
symbols[nb_codes] = i; |
1015 |
|
✗ |
nb_codes++; |
1016 |
|
|
} |
1017 |
|
|
} |
1018 |
|
|
|
1019 |
|
✗ |
ff_vlc_free(vlc); |
1020 |
|
✗ |
return ff_vlc_init_sparse(vlc, 13, nb_codes, |
1021 |
|
|
bits, 1, 1, |
1022 |
|
|
codes, 4, 4, |
1023 |
|
|
symbols, 1, 1, |
1024 |
|
|
VLC_INIT_LE); |
1025 |
|
|
} |
1026 |
|
|
|
1027 |
|
✗ |
static int decode_huffman2(AVCodecContext *avctx, int header, int size) |
1028 |
|
|
{ |
1029 |
|
✗ |
AGMContext *s = avctx->priv_data; |
1030 |
|
✗ |
GetBitContext *gb = &s->gb; |
1031 |
|
|
uint8_t lens[256]; |
1032 |
|
|
int ret, x, len; |
1033 |
|
|
|
1034 |
|
✗ |
if ((ret = init_get_bits8(gb, s->gbyte.buffer, |
1035 |
|
|
bytestream2_get_bytes_left(&s->gbyte))) < 0) |
1036 |
|
✗ |
return ret; |
1037 |
|
|
|
1038 |
|
✗ |
s->output_size = get_bits_long(gb, 32); |
1039 |
|
|
|
1040 |
|
✗ |
if (s->output_size > avctx->width * avctx->height * 9LL + 10000) |
1041 |
|
✗ |
return AVERROR_INVALIDDATA; |
1042 |
|
|
|
1043 |
|
✗ |
av_fast_padded_malloc(&s->output, &s->padded_output_size, s->output_size); |
1044 |
|
✗ |
if (!s->output) |
1045 |
|
✗ |
return AVERROR(ENOMEM); |
1046 |
|
|
|
1047 |
|
✗ |
x = get_bits(gb, 1); |
1048 |
|
✗ |
len = 4 + get_bits(gb, 1); |
1049 |
|
✗ |
if (x) { |
1050 |
|
✗ |
int cb[8] = { 0 }; |
1051 |
|
✗ |
int count = get_bits(gb, 3) + 1; |
1052 |
|
|
|
1053 |
|
✗ |
for (int i = 0; i < count; i++) |
1054 |
|
✗ |
cb[i] = get_bits(gb, len); |
1055 |
|
|
|
1056 |
|
✗ |
for (int i = 0; i < 256; i++) { |
1057 |
|
✗ |
int idx = get_bits(gb, 3); |
1058 |
|
✗ |
lens[i] = cb[idx]; |
1059 |
|
|
} |
1060 |
|
|
} else { |
1061 |
|
✗ |
for (int i = 0; i < 256; i++) |
1062 |
|
✗ |
lens[i] = get_bits(gb, len); |
1063 |
|
|
} |
1064 |
|
|
|
1065 |
|
✗ |
if ((ret = build_huff(lens, &s->vlc)) < 0) |
1066 |
|
✗ |
return ret; |
1067 |
|
|
|
1068 |
|
✗ |
x = 0; |
1069 |
|
✗ |
while (get_bits_left(gb) > 0 && x < s->output_size) { |
1070 |
|
✗ |
int val = get_vlc2(gb, s->vlc.table, s->vlc.bits, 3); |
1071 |
|
✗ |
if (val < 0) |
1072 |
|
✗ |
return AVERROR_INVALIDDATA; |
1073 |
|
✗ |
s->output[x++] = val; |
1074 |
|
|
} |
1075 |
|
|
|
1076 |
|
✗ |
return 0; |
1077 |
|
|
} |
1078 |
|
|
|
1079 |
|
✗ |
static int decode_frame(AVCodecContext *avctx, AVFrame *frame, |
1080 |
|
|
int *got_frame, AVPacket *avpkt) |
1081 |
|
|
{ |
1082 |
|
✗ |
AGMContext *s = avctx->priv_data; |
1083 |
|
✗ |
GetBitContext *gb = &s->gb; |
1084 |
|
✗ |
GetByteContext *gbyte = &s->gbyte; |
1085 |
|
|
int w, h, width, height, header; |
1086 |
|
|
unsigned compressed_size; |
1087 |
|
|
long skip; |
1088 |
|
|
int ret; |
1089 |
|
|
|
1090 |
|
✗ |
if (!avpkt->size) |
1091 |
|
✗ |
return 0; |
1092 |
|
|
|
1093 |
|
✗ |
bytestream2_init(gbyte, avpkt->data, avpkt->size); |
1094 |
|
|
|
1095 |
|
✗ |
header = bytestream2_get_le32(gbyte); |
1096 |
|
✗ |
s->fflags = bytestream2_get_le32(gbyte); |
1097 |
|
✗ |
s->bitstream_size = s->fflags & 0x1FFFFFFF; |
1098 |
|
✗ |
s->fflags >>= 29; |
1099 |
|
✗ |
av_log(avctx, AV_LOG_DEBUG, "fflags: %X\n", s->fflags); |
1100 |
|
✗ |
if (avpkt->size < s->bitstream_size + 8) |
1101 |
|
✗ |
return AVERROR_INVALIDDATA; |
1102 |
|
|
|
1103 |
|
✗ |
s->key_frame = (avpkt->flags & AV_PKT_FLAG_KEY); |
1104 |
|
✗ |
if (s->key_frame) |
1105 |
|
✗ |
frame->flags |= AV_FRAME_FLAG_KEY; |
1106 |
|
|
else |
1107 |
|
✗ |
frame->flags &= ~AV_FRAME_FLAG_KEY; |
1108 |
|
✗ |
frame->pict_type = s->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; |
1109 |
|
|
|
1110 |
|
✗ |
if (!s->key_frame) { |
1111 |
|
✗ |
if (!s->prev_frame->data[0]) { |
1112 |
|
✗ |
av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n"); |
1113 |
|
✗ |
return AVERROR_INVALIDDATA; |
1114 |
|
|
} |
1115 |
|
|
} |
1116 |
|
|
|
1117 |
|
✗ |
if (header) { |
1118 |
|
✗ |
if (avctx->codec_tag == MKTAG('A', 'G', 'M', '0') || |
1119 |
|
✗ |
avctx->codec_tag == MKTAG('A', 'G', 'M', '1')) |
1120 |
|
✗ |
return AVERROR_PATCHWELCOME; |
1121 |
|
|
else |
1122 |
|
✗ |
ret = decode_huffman2(avctx, header, (avpkt->size - s->bitstream_size) - 8); |
1123 |
|
✗ |
if (ret < 0) |
1124 |
|
✗ |
return ret; |
1125 |
|
✗ |
bytestream2_init(gbyte, s->output, s->output_size); |
1126 |
|
✗ |
} else if (!s->dct) { |
1127 |
|
✗ |
bytestream2_skip(gbyte, 4); |
1128 |
|
|
} |
1129 |
|
|
|
1130 |
|
✗ |
if (s->dct) { |
1131 |
|
✗ |
s->flags = 0; |
1132 |
|
✗ |
w = bytestream2_get_le32(gbyte); |
1133 |
|
✗ |
h = bytestream2_get_le32(gbyte); |
1134 |
|
✗ |
if (w == INT32_MIN || h == INT32_MIN) |
1135 |
|
✗ |
return AVERROR_INVALIDDATA; |
1136 |
|
✗ |
if (w < 0) { |
1137 |
|
✗ |
w = -w; |
1138 |
|
✗ |
s->flags |= 2; |
1139 |
|
|
} |
1140 |
|
✗ |
if (h < 0) { |
1141 |
|
✗ |
h = -h; |
1142 |
|
✗ |
s->flags |= 1; |
1143 |
|
|
} |
1144 |
|
|
|
1145 |
|
✗ |
width = avctx->width; |
1146 |
|
✗ |
height = avctx->height; |
1147 |
|
✗ |
if (w < width || h < height || w & 7 || h & 7) |
1148 |
|
✗ |
return AVERROR_INVALIDDATA; |
1149 |
|
|
|
1150 |
|
✗ |
ret = ff_set_dimensions(avctx, w, h); |
1151 |
|
✗ |
if (ret < 0) |
1152 |
|
✗ |
return ret; |
1153 |
|
✗ |
avctx->width = width; |
1154 |
|
✗ |
avctx->height = height; |
1155 |
|
|
|
1156 |
|
✗ |
s->compression = bytestream2_get_le32(gbyte); |
1157 |
|
✗ |
if (s->compression < 0 || s->compression > 100) |
1158 |
|
✗ |
return AVERROR_INVALIDDATA; |
1159 |
|
|
|
1160 |
|
✗ |
for (int i = 0; i < 3; i++) |
1161 |
|
✗ |
s->size[i] = bytestream2_get_le32(gbyte); |
1162 |
|
✗ |
if (header) { |
1163 |
|
✗ |
compressed_size = s->output_size; |
1164 |
|
✗ |
skip = 8LL; |
1165 |
|
|
} else { |
1166 |
|
✗ |
compressed_size = avpkt->size; |
1167 |
|
✗ |
skip = 32LL; |
1168 |
|
|
} |
1169 |
|
✗ |
if (s->size[0] < 0 || s->size[1] < 0 || s->size[2] < 0 || |
1170 |
|
✗ |
skip + s->size[0] + s->size[1] + s->size[2] > compressed_size) { |
1171 |
|
✗ |
return AVERROR_INVALIDDATA; |
1172 |
|
|
} |
1173 |
|
|
} |
1174 |
|
|
|
1175 |
|
✗ |
if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) |
1176 |
|
✗ |
return ret; |
1177 |
|
|
|
1178 |
|
✗ |
if (frame->flags & AV_FRAME_FLAG_KEY) { |
1179 |
|
✗ |
if (!s->dct && !s->rgb) |
1180 |
|
✗ |
ret = decode_raw_intra(avctx, gbyte, frame); |
1181 |
|
✗ |
else if (!s->dct && s->rgb) |
1182 |
|
✗ |
ret = decode_raw_intra_rgb(avctx, gbyte, frame); |
1183 |
|
|
else |
1184 |
|
✗ |
ret = decode_intra(avctx, gb, frame); |
1185 |
|
|
} else { |
1186 |
|
✗ |
if (s->prev_frame-> width != frame->width || |
1187 |
|
✗ |
s->prev_frame->height != frame->height) |
1188 |
|
✗ |
return AVERROR_INVALIDDATA; |
1189 |
|
|
|
1190 |
|
✗ |
if (!(s->flags & 2)) { |
1191 |
|
✗ |
ret = av_frame_copy(frame, s->prev_frame); |
1192 |
|
✗ |
if (ret < 0) |
1193 |
|
✗ |
return ret; |
1194 |
|
|
} |
1195 |
|
|
|
1196 |
|
✗ |
if (s->dct) { |
1197 |
|
✗ |
ret = decode_inter(avctx, gb, frame, s->prev_frame); |
1198 |
|
✗ |
} else if (!s->dct && !s->rgb) { |
1199 |
|
✗ |
ret = decode_runlen(avctx, gbyte, frame); |
1200 |
|
|
} else { |
1201 |
|
✗ |
ret = decode_runlen_rgb(avctx, gbyte, frame); |
1202 |
|
|
} |
1203 |
|
|
} |
1204 |
|
✗ |
if (ret < 0) |
1205 |
|
✗ |
return ret; |
1206 |
|
|
|
1207 |
|
✗ |
if ((ret = av_frame_replace(s->prev_frame, frame)) < 0) |
1208 |
|
✗ |
return ret; |
1209 |
|
|
|
1210 |
|
✗ |
frame->crop_top = avctx->coded_height - avctx->height; |
1211 |
|
✗ |
frame->crop_left = avctx->coded_width - avctx->width; |
1212 |
|
|
|
1213 |
|
✗ |
*got_frame = 1; |
1214 |
|
|
|
1215 |
|
✗ |
return avpkt->size; |
1216 |
|
|
} |
1217 |
|
|
|
1218 |
|
✗ |
static av_cold int decode_init(AVCodecContext *avctx) |
1219 |
|
|
{ |
1220 |
|
✗ |
AGMContext *s = avctx->priv_data; |
1221 |
|
|
|
1222 |
|
✗ |
s->rgb = avctx->codec_tag == MKTAG('A', 'G', 'M', '4'); |
1223 |
|
✗ |
avctx->pix_fmt = s->rgb ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_YUV420P; |
1224 |
|
✗ |
s->avctx = avctx; |
1225 |
|
✗ |
s->plus = avctx->codec_tag == MKTAG('A', 'G', 'M', '3') || |
1226 |
|
✗ |
avctx->codec_tag == MKTAG('A', 'G', 'M', '7'); |
1227 |
|
|
|
1228 |
|
✗ |
s->dct = avctx->codec_tag != MKTAG('A', 'G', 'M', '4') && |
1229 |
|
✗ |
avctx->codec_tag != MKTAG('A', 'G', 'M', '5'); |
1230 |
|
|
|
1231 |
|
✗ |
if (!s->rgb && !s->dct) { |
1232 |
|
✗ |
if ((avctx->width & 1) || (avctx->height & 1)) |
1233 |
|
✗ |
return AVERROR_INVALIDDATA; |
1234 |
|
|
} |
1235 |
|
|
|
1236 |
|
✗ |
avctx->idct_algo = FF_IDCT_SIMPLE; |
1237 |
|
✗ |
ff_idctdsp_init(&s->idsp, avctx); |
1238 |
|
✗ |
ff_permute_scantable(s->permutated_scantable, ff_zigzag_direct, |
1239 |
|
✗ |
s->idsp.idct_permutation); |
1240 |
|
|
|
1241 |
|
✗ |
s->prev_frame = av_frame_alloc(); |
1242 |
|
✗ |
if (!s->prev_frame) |
1243 |
|
✗ |
return AVERROR(ENOMEM); |
1244 |
|
|
|
1245 |
|
✗ |
return 0; |
1246 |
|
|
} |
1247 |
|
|
|
1248 |
|
✗ |
static void decode_flush(AVCodecContext *avctx) |
1249 |
|
|
{ |
1250 |
|
✗ |
AGMContext *s = avctx->priv_data; |
1251 |
|
|
|
1252 |
|
✗ |
av_frame_unref(s->prev_frame); |
1253 |
|
✗ |
} |
1254 |
|
|
|
1255 |
|
✗ |
static av_cold int decode_close(AVCodecContext *avctx) |
1256 |
|
|
{ |
1257 |
|
✗ |
AGMContext *s = avctx->priv_data; |
1258 |
|
|
|
1259 |
|
✗ |
ff_vlc_free(&s->vlc); |
1260 |
|
✗ |
av_frame_free(&s->prev_frame); |
1261 |
|
✗ |
av_freep(&s->mvectors); |
1262 |
|
✗ |
s->mvectors_size = 0; |
1263 |
|
✗ |
av_freep(&s->wblocks); |
1264 |
|
✗ |
s->wblocks_size = 0; |
1265 |
|
✗ |
av_freep(&s->output); |
1266 |
|
✗ |
s->padded_output_size = 0; |
1267 |
|
✗ |
av_freep(&s->map); |
1268 |
|
✗ |
s->map_size = 0; |
1269 |
|
|
|
1270 |
|
✗ |
return 0; |
1271 |
|
|
} |
1272 |
|
|
|
1273 |
|
|
const FFCodec ff_agm_decoder = { |
1274 |
|
|
.p.name = "agm", |
1275 |
|
|
CODEC_LONG_NAME("Amuse Graphics Movie"), |
1276 |
|
|
.p.type = AVMEDIA_TYPE_VIDEO, |
1277 |
|
|
.p.id = AV_CODEC_ID_AGM, |
1278 |
|
|
.p.capabilities = AV_CODEC_CAP_DR1, |
1279 |
|
|
.priv_data_size = sizeof(AGMContext), |
1280 |
|
|
.init = decode_init, |
1281 |
|
|
.close = decode_close, |
1282 |
|
|
FF_CODEC_DECODE_CB(decode_frame), |
1283 |
|
|
.flush = decode_flush, |
1284 |
|
|
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP | |
1285 |
|
|
FF_CODEC_CAP_EXPORTS_CROPPING, |
1286 |
|
|
}; |
1287 |
|
|
|