Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Escape 124 Video Decoder | ||
3 | * Copyright (C) 2008 Eli Friedman (eli.friedman@gmail.com) | ||
4 | * | ||
5 | * This file is part of FFmpeg. | ||
6 | * | ||
7 | * FFmpeg is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU Lesser General Public | ||
9 | * License as published by the Free Software Foundation; either | ||
10 | * version 2.1 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * FFmpeg is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with FFmpeg; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | */ | ||
21 | |||
22 | #define BITSTREAM_READER_LE | ||
23 | #include "libavutil/mem.h" | ||
24 | #include "avcodec.h" | ||
25 | #include "codec_internal.h" | ||
26 | #include "decode.h" | ||
27 | #include "get_bits.h" | ||
28 | |||
29 | typedef union MacroBlock { | ||
30 | uint16_t pixels[4]; | ||
31 | uint32_t pixels32[2]; | ||
32 | } MacroBlock; | ||
33 | |||
34 | typedef union SuperBlock { | ||
35 | uint16_t pixels[64]; | ||
36 | uint32_t pixels32[32]; | ||
37 | } SuperBlock; | ||
38 | |||
39 | typedef struct CodeBook { | ||
40 | unsigned depth; | ||
41 | unsigned size; | ||
42 | MacroBlock* blocks; | ||
43 | } CodeBook; | ||
44 | |||
45 | typedef struct Escape124Context { | ||
46 | AVFrame *frame; | ||
47 | |||
48 | unsigned num_superblocks; | ||
49 | |||
50 | CodeBook codebooks[3]; | ||
51 | } Escape124Context; | ||
52 | |||
53 | /** | ||
54 | * Initialize the decoder | ||
55 | * @param avctx decoder context | ||
56 | * @return 0 success, negative on error | ||
57 | */ | ||
58 | 2 | static av_cold int escape124_decode_init(AVCodecContext *avctx) | |
59 | { | ||
60 | 2 | Escape124Context *s = avctx->priv_data; | |
61 | |||
62 | 2 | avctx->pix_fmt = AV_PIX_FMT_RGB555; | |
63 | |||
64 | 2 | s->num_superblocks = ((unsigned)avctx->width / 8) * | |
65 | 2 | ((unsigned)avctx->height / 8); | |
66 | |||
67 | 2 | s->frame = av_frame_alloc(); | |
68 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (!s->frame) |
69 | ✗ | return AVERROR(ENOMEM); | |
70 | |||
71 | 2 | return 0; | |
72 | } | ||
73 | |||
74 | 2 | static av_cold int escape124_decode_close(AVCodecContext *avctx) | |
75 | { | ||
76 | unsigned i; | ||
77 | 2 | Escape124Context *s = avctx->priv_data; | |
78 | |||
79 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
|
8 | for (i = 0; i < 3; i++) |
80 | 6 | av_freep(&s->codebooks[i].blocks); | |
81 | |||
82 | 2 | av_frame_free(&s->frame); | |
83 | |||
84 | 2 | return 0; | |
85 | } | ||
86 | |||
87 | 12 | static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth, | |
88 | unsigned size) | ||
89 | { | ||
90 | unsigned i, j; | ||
91 | 12 | CodeBook cb = { 0 }; | |
92 | |||
93 |
1/2✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
|
12 | cb.blocks = av_malloc(size ? size * sizeof(MacroBlock) : 1); |
94 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | if (!cb.blocks) |
95 | ✗ | return cb; | |
96 | |||
97 | 12 | cb.depth = depth; | |
98 | 12 | cb.size = size; | |
99 |
2/2✓ Branch 0 taken 21243 times.
✓ Branch 1 taken 12 times.
|
21255 | for (i = 0; i < size; i++) { |
100 | 21243 | unsigned mask_bits = get_bits(gb, 4); | |
101 | unsigned color[2]; | ||
102 | 21243 | color[0] = get_bits(gb, 15); | |
103 | 21243 | color[1] = get_bits(gb, 15); | |
104 | |||
105 |
2/2✓ Branch 0 taken 84972 times.
✓ Branch 1 taken 21243 times.
|
106215 | for (j = 0; j < 4; j++) |
106 | 84972 | cb.blocks[i].pixels[j] = color[(mask_bits>>j) & 1]; | |
107 | } | ||
108 | 12 | return cb; | |
109 | } | ||
110 | |||
111 | 69095 | static unsigned decode_skip_count(GetBitContext* gb) | |
112 | { | ||
113 | unsigned value; | ||
114 | // This function reads a maximum of 23 bits, | ||
115 | // which is within the padding space | ||
116 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 69095 times.
|
69095 | if (get_bits_left(gb) < 1) |
117 | ✗ | return -1; | |
118 | 69095 | value = get_bits1(gb); | |
119 |
2/2✓ Branch 0 taken 59778 times.
✓ Branch 1 taken 9317 times.
|
69095 | if (!value) |
120 | 59778 | return value; | |
121 | |||
122 | 9317 | value += get_bits(gb, 3); | |
123 |
2/2✓ Branch 0 taken 8204 times.
✓ Branch 1 taken 1113 times.
|
9317 | if (value != (1 + ((1 << 3) - 1))) |
124 | 8204 | return value; | |
125 | |||
126 | 1113 | value += get_bits(gb, 7); | |
127 |
2/2✓ Branch 0 taken 1086 times.
✓ Branch 1 taken 27 times.
|
1113 | if (value != (1 + ((1 << 3) - 1)) + ((1 << 7) - 1)) |
128 | 1086 | return value; | |
129 | |||
130 | 27 | return value + get_bits(gb, 12); | |
131 | } | ||
132 | |||
133 | 339543 | static MacroBlock decode_macroblock(Escape124Context* s, GetBitContext* gb, | |
134 | int* codebook_index, int superblock_index) | ||
135 | { | ||
136 | // This function reads a maximum of 22 bits; the callers | ||
137 | // guard this function appropriately | ||
138 | unsigned block_index, depth; | ||
139 | 339543 | int value = get_bits1(gb); | |
140 |
2/2✓ Branch 0 taken 131966 times.
✓ Branch 1 taken 207577 times.
|
339543 | if (value) { |
141 | static const int8_t transitions[3][2] = { {2, 1}, {0, 2}, {1, 0} }; | ||
142 | 131966 | value = get_bits1(gb); | |
143 | 131966 | *codebook_index = transitions[*codebook_index][value]; | |
144 | } | ||
145 | |||
146 | 339543 | depth = s->codebooks[*codebook_index].depth; | |
147 | |||
148 | // depth = 0 means that this shouldn't read any bits; | ||
149 | // in theory, this is the same as get_bits(gb, 0), but | ||
150 | // that doesn't actually work. | ||
151 | 339543 | block_index = get_bitsz(gb, depth); | |
152 | |||
153 |
2/2✓ Branch 0 taken 33088 times.
✓ Branch 1 taken 306455 times.
|
339543 | if (*codebook_index == 1) { |
154 | 33088 | block_index += superblock_index << s->codebooks[1].depth; | |
155 | } | ||
156 | |||
157 | // This condition can occur with invalid bitstreams and | ||
158 | // *codebook_index == 2 | ||
159 |
2/4✓ Branch 0 taken 339543 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 339543 times.
|
339543 | if (block_index >= s->codebooks[*codebook_index].size || !s->codebooks[*codebook_index].blocks) |
160 | ✗ | return (MacroBlock) { { 0 } }; | |
161 | |||
162 | 339543 | return s->codebooks[*codebook_index].blocks[block_index]; | |
163 | } | ||
164 | |||
165 | 492736 | static void insert_mb_into_sb(SuperBlock* sb, MacroBlock mb, unsigned index) { | |
166 | // Formula: ((index / 4) * 16 + (index % 4) * 2) / 2 | ||
167 | 492736 | uint32_t *dst = sb->pixels32 + index + (index & -4); | |
168 | |||
169 | // This technically violates C99 aliasing rules, but it should be safe. | ||
170 | 492736 | dst[0] = mb.pixels32[0]; | |
171 | 492736 | dst[4] = mb.pixels32[1]; | |
172 | 492736 | } | |
173 | |||
174 | 189026 | static void copy_superblock(uint16_t* dest, ptrdiff_t dest_stride, | |
175 | uint16_t* src, ptrdiff_t src_stride) | ||
176 | { | ||
177 | unsigned y; | ||
178 |
2/2✓ Branch 0 taken 187826 times.
✓ Branch 1 taken 1200 times.
|
189026 | if (src) |
179 |
2/2✓ Branch 0 taken 1502608 times.
✓ Branch 1 taken 187826 times.
|
1690434 | for (y = 0; y < 8; y++) |
180 | 1502608 | memcpy(dest + y * dest_stride, src + y * src_stride, | |
181 | sizeof(uint16_t) * 8); | ||
182 | else | ||
183 |
2/2✓ Branch 0 taken 9600 times.
✓ Branch 1 taken 1200 times.
|
10800 | for (y = 0; y < 8; y++) |
184 | 9600 | memset(dest + y * dest_stride, 0, sizeof(uint16_t) * 8); | |
185 | 189026 | } | |
186 | |||
187 | static const uint16_t mask_matrix[] = {0x1, 0x2, 0x10, 0x20, | ||
188 | 0x4, 0x8, 0x40, 0x80, | ||
189 | 0x100, 0x200, 0x1000, 0x2000, | ||
190 | 0x400, 0x800, 0x4000, 0x8000}; | ||
191 | |||
192 | 100 | static int escape124_decode_frame(AVCodecContext *avctx, AVFrame *frame, | |
193 | int *got_frame, AVPacket *avpkt) | ||
194 | { | ||
195 | 100 | int buf_size = avpkt->size; | |
196 | 100 | Escape124Context *s = avctx->priv_data; | |
197 | |||
198 | GetBitContext gb; | ||
199 | unsigned frame_flags, frame_size; | ||
200 | unsigned i; | ||
201 | |||
202 | 100 | unsigned superblock_index, cb_index = 1, | |
203 | 100 | superblock_col_index = 0, | |
204 | 100 | superblocks_per_row = avctx->width / 8, skip = -1; | |
205 | |||
206 | uint16_t* old_frame_data, *new_frame_data; | ||
207 | ptrdiff_t old_stride, new_stride; | ||
208 | |||
209 | int ret; | ||
210 | |||
211 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 100 times.
|
100 | if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) |
212 | ✗ | return ret; | |
213 | |||
214 | // This call also guards the potential depth reads for the | ||
215 | // codebook unpacking. | ||
216 | // Check if the amount we will read minimally is available on input. | ||
217 | // The 64 represent the immediately next 2 frame_* elements read, the 23/4320 | ||
218 | // represent a lower bound of the space needed for skipped superblocks. Non | ||
219 | // skipped SBs need more space. | ||
220 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 100 times.
|
100 | if (get_bits_left(&gb) < 64 + s->num_superblocks * 23LL / 4320) |
221 | ✗ | return AVERROR_INVALIDDATA; | |
222 | |||
223 | 100 | frame_flags = get_bits_long(&gb, 32); | |
224 | 100 | frame_size = get_bits_long(&gb, 32); | |
225 | |||
226 | // Leave last frame unchanged | ||
227 | // FIXME: Is this necessary? I haven't seen it in any real samples | ||
228 |
2/4✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 100 times.
|
100 | if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) { |
229 | ✗ | if (!s->frame->data[0]) | |
230 | ✗ | return AVERROR_INVALIDDATA; | |
231 | |||
232 | ✗ | av_log(avctx, AV_LOG_DEBUG, "Skipping frame\n"); | |
233 | |||
234 | ✗ | *got_frame = 1; | |
235 | ✗ | if ((ret = av_frame_ref(frame, s->frame)) < 0) | |
236 | ✗ | return ret; | |
237 | |||
238 | ✗ | return 0; | |
239 | } | ||
240 | |||
241 |
2/2✓ Branch 0 taken 300 times.
✓ Branch 1 taken 100 times.
|
400 | for (i = 0; i < 3; i++) { |
242 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 288 times.
|
300 | if (frame_flags & (1 << (17 + i))) { |
243 | unsigned cb_depth, cb_size; | ||
244 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 8 times.
|
12 | if (i == 2) { |
245 | // This codebook can be cut off at places other than | ||
246 | // powers of 2, leaving some of the entries undefined. | ||
247 | 4 | cb_size = get_bits(&gb, 20); | |
248 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!cb_size) { |
249 | ✗ | av_log(avctx, AV_LOG_ERROR, "Invalid codebook size 0.\n"); | |
250 | ✗ | return AVERROR_INVALIDDATA; | |
251 | } | ||
252 | 4 | cb_depth = av_log2(cb_size - 1) + 1; | |
253 | } else { | ||
254 | 8 | cb_depth = get_bits(&gb, 4); | |
255 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
|
8 | if (i == 0) { |
256 | // This is the most basic codebook: pow(2,depth) entries | ||
257 | // for a depth-length key | ||
258 | 4 | cb_size = 1 << cb_depth; | |
259 | } else { | ||
260 | // This codebook varies per superblock | ||
261 | // FIXME: I don't think this handles integer overflow | ||
262 | // properly | ||
263 | 4 | cb_size = s->num_superblocks << cb_depth; | |
264 | } | ||
265 | } | ||
266 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | if (s->num_superblocks >= INT_MAX >> cb_depth) { |
267 | ✗ | av_log(avctx, AV_LOG_ERROR, "Depth or num_superblocks are too large\n"); | |
268 | ✗ | return AVERROR_INVALIDDATA; | |
269 | } | ||
270 | |||
271 | 12 | av_freep(&s->codebooks[i].blocks); | |
272 |
2/4✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
|
12 | if (cb_size >= INT_MAX / 34 || get_bits_left(&gb) < (int)cb_size * 34) |
273 | ✗ | return AVERROR_INVALIDDATA; | |
274 | |||
275 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | if (cb_size >= INT_MAX / sizeof(MacroBlock)) |
276 | ✗ | return AVERROR_INVALIDDATA; | |
277 | 12 | s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size); | |
278 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
|
12 | if (!s->codebooks[i].blocks) |
279 | ✗ | return AVERROR(ENOMEM); | |
280 | } | ||
281 | } | ||
282 | |||
283 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 100 times.
|
100 | if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) |
284 | ✗ | return ret; | |
285 | |||
286 | 100 | new_frame_data = (uint16_t*)frame->data[0]; | |
287 | 100 | new_stride = frame->linesize[0] / 2; | |
288 | 100 | old_frame_data = (uint16_t*)s->frame->data[0]; | |
289 | 100 | old_stride = s->frame->linesize[0] / 2; | |
290 | |||
291 |
2/2✓ Branch 0 taken 120000 times.
✓ Branch 1 taken 100 times.
|
120100 | for (superblock_index = 0; superblock_index < s->num_superblocks; |
292 | 120000 | superblock_index++) { | |
293 | MacroBlock mb; | ||
294 | SuperBlock sb; | ||
295 | 120000 | unsigned multi_mask = 0; | |
296 | |||
297 |
2/2✓ Branch 0 taken 69095 times.
✓ Branch 1 taken 50905 times.
|
120000 | if (skip == -1) { |
298 | // Note that this call will make us skip the rest of the blocks | ||
299 | // if the frame prematurely ends | ||
300 | 69095 | skip = decode_skip_count(&gb); | |
301 | } | ||
302 | |||
303 |
2/2✓ Branch 0 taken 50974 times.
✓ Branch 1 taken 69026 times.
|
120000 | if (skip) { |
304 | 50974 | copy_superblock(new_frame_data, new_stride, | |
305 | old_frame_data, old_stride); | ||
306 | } else { | ||
307 | 69026 | copy_superblock(sb.pixels, 8, | |
308 | old_frame_data, old_stride); | ||
309 | |||
310 |
3/4✓ Branch 1 taken 100930 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 31904 times.
✓ Branch 5 taken 69026 times.
|
100930 | while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) { |
311 | unsigned mask; | ||
312 | 31904 | mb = decode_macroblock(s, &gb, &cb_index, superblock_index); | |
313 | 31904 | mask = get_bits(&gb, 16); | |
314 | 31904 | multi_mask |= mask; | |
315 |
2/2✓ Branch 0 taken 510464 times.
✓ Branch 1 taken 31904 times.
|
542368 | for (i = 0; i < 16; i++) { |
316 |
2/2✓ Branch 0 taken 185097 times.
✓ Branch 1 taken 325367 times.
|
510464 | if (mask & mask_matrix[i]) { |
317 | 185097 | insert_mb_into_sb(&sb, mb, i); | |
318 | } | ||
319 | } | ||
320 | } | ||
321 | |||
322 |
2/2✓ Branch 1 taken 29605 times.
✓ Branch 2 taken 39421 times.
|
69026 | if (!get_bits1(&gb)) { |
323 | 29605 | unsigned inv_mask = get_bits(&gb, 4); | |
324 |
2/2✓ Branch 0 taken 118420 times.
✓ Branch 1 taken 29605 times.
|
148025 | for (i = 0; i < 4; i++) { |
325 |
2/2✓ Branch 0 taken 45362 times.
✓ Branch 1 taken 73058 times.
|
118420 | if (inv_mask & (1 << i)) { |
326 | 45362 | multi_mask ^= 0xF << i*4; | |
327 | } else { | ||
328 | 73058 | multi_mask ^= get_bits(&gb, 4) << i*4; | |
329 | } | ||
330 | } | ||
331 | |||
332 |
2/2✓ Branch 0 taken 473680 times.
✓ Branch 1 taken 29605 times.
|
503285 | for (i = 0; i < 16; i++) { |
333 |
2/2✓ Branch 0 taken 251422 times.
✓ Branch 1 taken 222258 times.
|
473680 | if (multi_mask & mask_matrix[i]) { |
334 | 251422 | mb = decode_macroblock(s, &gb, &cb_index, | |
335 | superblock_index); | ||
336 | 251422 | insert_mb_into_sb(&sb, mb, i); | |
337 | } | ||
338 | } | ||
339 |
1/2✓ Branch 0 taken 39421 times.
✗ Branch 1 not taken.
|
39421 | } else if (frame_flags & (1 << 16)) { |
340 |
3/4✓ Branch 1 taken 95638 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 56217 times.
✓ Branch 5 taken 39421 times.
|
95638 | while (get_bits_left(&gb) >= 1 && !get_bits1(&gb)) { |
341 | 56217 | mb = decode_macroblock(s, &gb, &cb_index, superblock_index); | |
342 | 56217 | insert_mb_into_sb(&sb, mb, get_bits(&gb, 4)); | |
343 | } | ||
344 | } | ||
345 | |||
346 | 69026 | copy_superblock(new_frame_data, new_stride, sb.pixels, 8); | |
347 | } | ||
348 | |||
349 | 120000 | superblock_col_index++; | |
350 | 120000 | new_frame_data += 8; | |
351 |
2/2✓ Branch 0 taken 118800 times.
✓ Branch 1 taken 1200 times.
|
120000 | if (old_frame_data) |
352 | 118800 | old_frame_data += 8; | |
353 |
2/2✓ Branch 0 taken 3000 times.
✓ Branch 1 taken 117000 times.
|
120000 | if (superblock_col_index == superblocks_per_row) { |
354 | 3000 | new_frame_data += new_stride * 8 - superblocks_per_row * 8; | |
355 |
2/2✓ Branch 0 taken 2970 times.
✓ Branch 1 taken 30 times.
|
3000 | if (old_frame_data) |
356 | 2970 | old_frame_data += old_stride * 8 - superblocks_per_row * 8; | |
357 | 3000 | superblock_col_index = 0; | |
358 | } | ||
359 | 120000 | skip--; | |
360 | } | ||
361 | |||
362 | 100 | av_log(avctx, AV_LOG_DEBUG, | |
363 | "Escape sizes: %i, %i, %i\n", | ||
364 | 100 | frame_size, buf_size, get_bits_count(&gb) / 8); | |
365 | |||
366 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 100 times.
|
100 | if ((ret = av_frame_replace(s->frame, frame)) < 0) |
367 | ✗ | return ret; | |
368 | |||
369 | 100 | *got_frame = 1; | |
370 | |||
371 | 100 | return 0; | |
372 | } | ||
373 | |||
374 | |||
375 | const FFCodec ff_escape124_decoder = { | ||
376 | .p.name = "escape124", | ||
377 | CODEC_LONG_NAME("Escape 124"), | ||
378 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
379 | .p.id = AV_CODEC_ID_ESCAPE124, | ||
380 | .priv_data_size = sizeof(Escape124Context), | ||
381 | .init = escape124_decode_init, | ||
382 | .close = escape124_decode_close, | ||
383 | FF_CODEC_DECODE_CB(escape124_decode_frame), | ||
384 | .p.capabilities = AV_CODEC_CAP_DR1, | ||
385 | }; | ||
386 |