Commit | Line | Data |
---|---|---|
2ba45a60 DM |
1 | /* |
2 | * Smacker decoder | |
3 | * Copyright (c) 2006 Konstantin Shishkov | |
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 | * Smacker decoder | |
25 | */ | |
26 | ||
27 | /* | |
28 | * Based on http://wiki.multimedia.cx/index.php?title=Smacker | |
29 | */ | |
30 | ||
31 | #include <stdio.h> | |
32 | #include <stdlib.h> | |
33 | ||
34 | #include "libavutil/channel_layout.h" | |
35 | #include "avcodec.h" | |
36 | #include "internal.h" | |
37 | #include "mathops.h" | |
38 | ||
39 | #define BITSTREAM_READER_LE | |
40 | #include "get_bits.h" | |
41 | #include "bytestream.h" | |
42 | ||
43 | #define SMKTREE_BITS 9 | |
44 | #define SMK_NODE 0x80000000 | |
45 | ||
46 | /* | |
47 | * Decoder context | |
48 | */ | |
49 | typedef struct SmackVContext { | |
50 | AVCodecContext *avctx; | |
51 | AVFrame *pic; | |
52 | ||
53 | int *mmap_tbl, *mclr_tbl, *full_tbl, *type_tbl; | |
54 | int mmap_last[3], mclr_last[3], full_last[3], type_last[3]; | |
55 | } SmackVContext; | |
56 | ||
57 | /** | |
58 | * Context used for code reconstructing | |
59 | */ | |
60 | typedef struct HuffContext { | |
61 | int length; | |
62 | int maxlength; | |
63 | int current; | |
64 | uint32_t *bits; | |
65 | int *lengths; | |
66 | int *values; | |
67 | } HuffContext; | |
68 | ||
69 | /* common parameters used for decode_bigtree */ | |
70 | typedef struct DBCtx { | |
71 | VLC *v1, *v2; | |
72 | int *recode1, *recode2; | |
73 | int escapes[3]; | |
74 | int *last; | |
75 | int lcur; | |
76 | } DBCtx; | |
77 | ||
78 | /* possible runs of blocks */ | |
79 | static const int block_runs[64] = { | |
80 | 1, 2, 3, 4, 5, 6, 7, 8, | |
81 | 9, 10, 11, 12, 13, 14, 15, 16, | |
82 | 17, 18, 19, 20, 21, 22, 23, 24, | |
83 | 25, 26, 27, 28, 29, 30, 31, 32, | |
84 | 33, 34, 35, 36, 37, 38, 39, 40, | |
85 | 41, 42, 43, 44, 45, 46, 47, 48, | |
86 | 49, 50, 51, 52, 53, 54, 55, 56, | |
87 | 57, 58, 59, 128, 256, 512, 1024, 2048 }; | |
88 | ||
89 | enum SmkBlockTypes { | |
90 | SMK_BLK_MONO = 0, | |
91 | SMK_BLK_FULL = 1, | |
92 | SMK_BLK_SKIP = 2, | |
93 | SMK_BLK_FILL = 3 }; | |
94 | ||
95 | /** | |
96 | * Decode local frame tree | |
97 | */ | |
98 | static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t prefix, int length) | |
99 | { | |
100 | if(length > 32 || length > 3*SMKTREE_BITS) { | |
101 | av_log(NULL, AV_LOG_ERROR, "length too long\n"); | |
102 | return AVERROR_INVALIDDATA; | |
103 | } | |
104 | if(!get_bits1(gb)){ //Leaf | |
105 | if(hc->current >= hc->length){ | |
106 | av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); | |
107 | return AVERROR_INVALIDDATA; | |
108 | } | |
109 | if(length){ | |
110 | hc->bits[hc->current] = prefix; | |
111 | hc->lengths[hc->current] = length; | |
112 | } else { | |
113 | hc->bits[hc->current] = 0; | |
114 | hc->lengths[hc->current] = 0; | |
115 | } | |
116 | hc->values[hc->current] = get_bits(gb, 8); | |
117 | hc->current++; | |
118 | if(hc->maxlength < length) | |
119 | hc->maxlength = length; | |
120 | return 0; | |
121 | } else { //Node | |
122 | int r; | |
123 | length++; | |
124 | r = smacker_decode_tree(gb, hc, prefix, length); | |
125 | if(r) | |
126 | return r; | |
127 | return smacker_decode_tree(gb, hc, prefix | (1 << (length - 1)), length); | |
128 | } | |
129 | } | |
130 | ||
131 | /** | |
132 | * Decode header tree | |
133 | */ | |
134 | static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx) | |
135 | { | |
136 | if (hc->current + 1 >= hc->length) { | |
137 | av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); | |
138 | return AVERROR_INVALIDDATA; | |
139 | } | |
140 | if(!get_bits1(gb)){ //Leaf | |
141 | int val, i1, i2; | |
142 | i1 = ctx->v1->table ? get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3) : 0; | |
143 | i2 = ctx->v2->table ? get_vlc2(gb, ctx->v2->table, SMKTREE_BITS, 3) : 0; | |
144 | if (i1 < 0 || i2 < 0) | |
145 | return AVERROR_INVALIDDATA; | |
146 | val = ctx->recode1[i1] | (ctx->recode2[i2] << 8); | |
147 | if(val == ctx->escapes[0]) { | |
148 | ctx->last[0] = hc->current; | |
149 | val = 0; | |
150 | } else if(val == ctx->escapes[1]) { | |
151 | ctx->last[1] = hc->current; | |
152 | val = 0; | |
153 | } else if(val == ctx->escapes[2]) { | |
154 | ctx->last[2] = hc->current; | |
155 | val = 0; | |
156 | } | |
157 | ||
158 | hc->values[hc->current++] = val; | |
159 | return 1; | |
160 | } else { //Node | |
161 | int r = 0, r_new, t; | |
162 | ||
163 | t = hc->current++; | |
164 | r = smacker_decode_bigtree(gb, hc, ctx); | |
165 | if(r < 0) | |
166 | return r; | |
167 | hc->values[t] = SMK_NODE | r; | |
168 | r++; | |
169 | r_new = smacker_decode_bigtree(gb, hc, ctx); | |
170 | if (r_new < 0) | |
171 | return r_new; | |
172 | return r + r_new; | |
173 | } | |
174 | } | |
175 | ||
176 | /** | |
177 | * Store large tree as FFmpeg's vlc codes | |
178 | */ | |
179 | static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int **recodes, int *last, int size) | |
180 | { | |
181 | int res; | |
182 | HuffContext huff; | |
183 | HuffContext tmp1, tmp2; | |
184 | VLC vlc[2] = { { 0 } }; | |
185 | int escapes[3]; | |
186 | DBCtx ctx; | |
187 | int err = 0; | |
188 | ||
189 | if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow | |
190 | av_log(smk->avctx, AV_LOG_ERROR, "size too large\n"); | |
191 | return AVERROR_INVALIDDATA; | |
192 | } | |
193 | ||
194 | tmp1.length = 256; | |
195 | tmp1.maxlength = 0; | |
196 | tmp1.current = 0; | |
197 | tmp1.bits = av_mallocz(256 * 4); | |
198 | tmp1.lengths = av_mallocz(256 * sizeof(int)); | |
199 | tmp1.values = av_mallocz(256 * sizeof(int)); | |
200 | ||
201 | tmp2.length = 256; | |
202 | tmp2.maxlength = 0; | |
203 | tmp2.current = 0; | |
204 | tmp2.bits = av_mallocz(256 * 4); | |
205 | tmp2.lengths = av_mallocz(256 * sizeof(int)); | |
206 | tmp2.values = av_mallocz(256 * sizeof(int)); | |
207 | if (!tmp1.bits || !tmp1.lengths || !tmp1.values || | |
208 | !tmp2.bits || !tmp2.lengths || !tmp2.values) { | |
209 | err = AVERROR(ENOMEM); | |
210 | goto error; | |
211 | } | |
212 | ||
213 | if(get_bits1(gb)) { | |
214 | res = smacker_decode_tree(gb, &tmp1, 0, 0); | |
215 | if (res < 0) { | |
216 | err = res; | |
217 | goto error; | |
218 | } | |
219 | skip_bits1(gb); | |
220 | if(tmp1.current > 1) { | |
221 | res = init_vlc(&vlc[0], SMKTREE_BITS, tmp1.length, | |
222 | tmp1.lengths, sizeof(int), sizeof(int), | |
223 | tmp1.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); | |
224 | if(res < 0) { | |
225 | av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); | |
226 | err = res; | |
227 | goto error; | |
228 | } | |
229 | } | |
230 | } | |
231 | if (!vlc[0].table) { | |
232 | av_log(smk->avctx, AV_LOG_ERROR, "Skipping low bytes tree\n"); | |
233 | } | |
234 | if(get_bits1(gb)){ | |
235 | res = smacker_decode_tree(gb, &tmp2, 0, 0); | |
236 | if (res < 0) { | |
237 | err = res; | |
238 | goto error; | |
239 | } | |
240 | skip_bits1(gb); | |
241 | if(tmp2.current > 1) { | |
242 | res = init_vlc(&vlc[1], SMKTREE_BITS, tmp2.length, | |
243 | tmp2.lengths, sizeof(int), sizeof(int), | |
244 | tmp2.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); | |
245 | if(res < 0) { | |
246 | av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); | |
247 | err = res; | |
248 | goto error; | |
249 | } | |
250 | } | |
251 | } | |
252 | if (!vlc[1].table) { | |
253 | av_log(smk->avctx, AV_LOG_ERROR, "Skipping high bytes tree\n"); | |
254 | } | |
255 | ||
256 | escapes[0] = get_bits(gb, 16); | |
257 | escapes[1] = get_bits(gb, 16); | |
258 | escapes[2] = get_bits(gb, 16); | |
259 | ||
260 | last[0] = last[1] = last[2] = -1; | |
261 | ||
262 | ctx.escapes[0] = escapes[0]; | |
263 | ctx.escapes[1] = escapes[1]; | |
264 | ctx.escapes[2] = escapes[2]; | |
265 | ctx.v1 = &vlc[0]; | |
266 | ctx.v2 = &vlc[1]; | |
267 | ctx.recode1 = tmp1.values; | |
268 | ctx.recode2 = tmp2.values; | |
269 | ctx.last = last; | |
270 | ||
271 | huff.length = ((size + 3) >> 2) + 4; | |
272 | huff.maxlength = 0; | |
273 | huff.current = 0; | |
274 | huff.values = av_mallocz_array(huff.length, sizeof(int)); | |
275 | if (!huff.values) { | |
276 | err = AVERROR(ENOMEM); | |
277 | goto error; | |
278 | } | |
279 | ||
280 | if (smacker_decode_bigtree(gb, &huff, &ctx) < 0) | |
281 | err = -1; | |
282 | skip_bits1(gb); | |
283 | if(ctx.last[0] == -1) ctx.last[0] = huff.current++; | |
284 | if(ctx.last[1] == -1) ctx.last[1] = huff.current++; | |
285 | if(ctx.last[2] == -1) ctx.last[2] = huff.current++; | |
286 | if (ctx.last[0] >= huff.length || | |
287 | ctx.last[1] >= huff.length || | |
288 | ctx.last[2] >= huff.length) { | |
289 | av_log(smk->avctx, AV_LOG_ERROR, "Huffman codes out of range\n"); | |
290 | err = AVERROR_INVALIDDATA; | |
291 | } | |
292 | ||
293 | *recodes = huff.values; | |
294 | ||
295 | error: | |
296 | if(vlc[0].table) | |
297 | ff_free_vlc(&vlc[0]); | |
298 | if(vlc[1].table) | |
299 | ff_free_vlc(&vlc[1]); | |
300 | av_free(tmp1.bits); | |
301 | av_free(tmp1.lengths); | |
302 | av_free(tmp1.values); | |
303 | av_free(tmp2.bits); | |
304 | av_free(tmp2.lengths); | |
305 | av_free(tmp2.values); | |
306 | ||
307 | return err; | |
308 | } | |
309 | ||
310 | static int decode_header_trees(SmackVContext *smk) { | |
311 | GetBitContext gb; | |
312 | int mmap_size, mclr_size, full_size, type_size, ret; | |
313 | ||
314 | mmap_size = AV_RL32(smk->avctx->extradata); | |
315 | mclr_size = AV_RL32(smk->avctx->extradata + 4); | |
316 | full_size = AV_RL32(smk->avctx->extradata + 8); | |
317 | type_size = AV_RL32(smk->avctx->extradata + 12); | |
318 | ||
319 | init_get_bits8(&gb, smk->avctx->extradata + 16, smk->avctx->extradata_size - 16); | |
320 | ||
321 | if(!get_bits1(&gb)) { | |
322 | av_log(smk->avctx, AV_LOG_INFO, "Skipping MMAP tree\n"); | |
323 | smk->mmap_tbl = av_malloc(sizeof(int) * 2); | |
324 | if (!smk->mmap_tbl) | |
325 | return AVERROR(ENOMEM); | |
326 | smk->mmap_tbl[0] = 0; | |
327 | smk->mmap_last[0] = smk->mmap_last[1] = smk->mmap_last[2] = 1; | |
328 | } else { | |
329 | ret = smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size); | |
330 | if (ret < 0) | |
331 | return ret; | |
332 | } | |
333 | if(!get_bits1(&gb)) { | |
334 | av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n"); | |
335 | smk->mclr_tbl = av_malloc(sizeof(int) * 2); | |
336 | if (!smk->mclr_tbl) | |
337 | return AVERROR(ENOMEM); | |
338 | smk->mclr_tbl[0] = 0; | |
339 | smk->mclr_last[0] = smk->mclr_last[1] = smk->mclr_last[2] = 1; | |
340 | } else { | |
341 | ret = smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size); | |
342 | if (ret < 0) | |
343 | return ret; | |
344 | } | |
345 | if(!get_bits1(&gb)) { | |
346 | av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n"); | |
347 | smk->full_tbl = av_malloc(sizeof(int) * 2); | |
348 | if (!smk->full_tbl) | |
349 | return AVERROR(ENOMEM); | |
350 | smk->full_tbl[0] = 0; | |
351 | smk->full_last[0] = smk->full_last[1] = smk->full_last[2] = 1; | |
352 | } else { | |
353 | ret = smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size); | |
354 | if (ret < 0) | |
355 | return ret; | |
356 | } | |
357 | if(!get_bits1(&gb)) { | |
358 | av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n"); | |
359 | smk->type_tbl = av_malloc(sizeof(int) * 2); | |
360 | if (!smk->type_tbl) | |
361 | return AVERROR(ENOMEM); | |
362 | smk->type_tbl[0] = 0; | |
363 | smk->type_last[0] = smk->type_last[1] = smk->type_last[2] = 1; | |
364 | } else { | |
365 | ret = smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size); | |
366 | if (ret < 0) | |
367 | return ret; | |
368 | } | |
369 | ||
370 | return 0; | |
371 | } | |
372 | ||
373 | static av_always_inline void last_reset(int *recode, int *last) { | |
374 | recode[last[0]] = recode[last[1]] = recode[last[2]] = 0; | |
375 | } | |
376 | ||
377 | /* get code and update history */ | |
378 | static av_always_inline int smk_get_code(GetBitContext *gb, int *recode, int *last) { | |
379 | register int *table = recode; | |
380 | int v; | |
381 | ||
382 | while(*table & SMK_NODE) { | |
383 | if(get_bits1(gb)) | |
384 | table += (*table) & (~SMK_NODE); | |
385 | table++; | |
386 | } | |
387 | v = *table; | |
388 | ||
389 | if(v != recode[last[0]]) { | |
390 | recode[last[2]] = recode[last[1]]; | |
391 | recode[last[1]] = recode[last[0]]; | |
392 | recode[last[0]] = v; | |
393 | } | |
394 | return v; | |
395 | } | |
396 | ||
397 | static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, | |
398 | AVPacket *avpkt) | |
399 | { | |
400 | SmackVContext * const smk = avctx->priv_data; | |
401 | uint8_t *out; | |
402 | uint32_t *pal; | |
403 | GetByteContext gb2; | |
404 | GetBitContext gb; | |
405 | int blocks, blk, bw, bh; | |
406 | int i, ret; | |
407 | int stride; | |
408 | int flags; | |
409 | ||
410 | if (avpkt->size <= 769) | |
411 | return AVERROR_INVALIDDATA; | |
412 | ||
413 | if ((ret = ff_reget_buffer(avctx, smk->pic)) < 0) | |
414 | return ret; | |
415 | ||
416 | /* make the palette available on the way out */ | |
417 | pal = (uint32_t*)smk->pic->data[1]; | |
418 | bytestream2_init(&gb2, avpkt->data, avpkt->size); | |
419 | flags = bytestream2_get_byteu(&gb2); | |
420 | smk->pic->palette_has_changed = flags & 1; | |
421 | smk->pic->key_frame = !!(flags & 2); | |
422 | if (smk->pic->key_frame) | |
423 | smk->pic->pict_type = AV_PICTURE_TYPE_I; | |
424 | else | |
425 | smk->pic->pict_type = AV_PICTURE_TYPE_P; | |
426 | ||
427 | for(i = 0; i < 256; i++) | |
428 | *pal++ = 0xFFU << 24 | bytestream2_get_be24u(&gb2); | |
429 | ||
430 | last_reset(smk->mmap_tbl, smk->mmap_last); | |
431 | last_reset(smk->mclr_tbl, smk->mclr_last); | |
432 | last_reset(smk->full_tbl, smk->full_last); | |
433 | last_reset(smk->type_tbl, smk->type_last); | |
434 | if ((ret = init_get_bits8(&gb, avpkt->data + 769, avpkt->size - 769)) < 0) | |
435 | return ret; | |
436 | ||
437 | blk = 0; | |
438 | bw = avctx->width >> 2; | |
439 | bh = avctx->height >> 2; | |
440 | blocks = bw * bh; | |
441 | stride = smk->pic->linesize[0]; | |
442 | while(blk < blocks) { | |
443 | int type, run, mode; | |
444 | uint16_t pix; | |
445 | ||
446 | type = smk_get_code(&gb, smk->type_tbl, smk->type_last); | |
447 | run = block_runs[(type >> 2) & 0x3F]; | |
448 | switch(type & 3){ | |
449 | case SMK_BLK_MONO: | |
450 | while(run-- && blk < blocks){ | |
451 | int clr, map; | |
452 | int hi, lo; | |
453 | clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last); | |
454 | map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last); | |
455 | out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; | |
456 | hi = clr >> 8; | |
457 | lo = clr & 0xFF; | |
458 | for(i = 0; i < 4; i++) { | |
459 | if(map & 1) out[0] = hi; else out[0] = lo; | |
460 | if(map & 2) out[1] = hi; else out[1] = lo; | |
461 | if(map & 4) out[2] = hi; else out[2] = lo; | |
462 | if(map & 8) out[3] = hi; else out[3] = lo; | |
463 | map >>= 4; | |
464 | out += stride; | |
465 | } | |
466 | blk++; | |
467 | } | |
468 | break; | |
469 | case SMK_BLK_FULL: | |
470 | mode = 0; | |
471 | if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes | |
472 | if(get_bits1(&gb)) mode = 1; | |
473 | else if(get_bits1(&gb)) mode = 2; | |
474 | } | |
475 | while(run-- && blk < blocks){ | |
476 | out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; | |
477 | switch(mode){ | |
478 | case 0: | |
479 | for(i = 0; i < 4; i++) { | |
480 | pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); | |
481 | AV_WL16(out+2,pix); | |
482 | pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); | |
483 | AV_WL16(out,pix); | |
484 | out += stride; | |
485 | } | |
486 | break; | |
487 | case 1: | |
488 | pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); | |
489 | out[0] = out[1] = pix & 0xFF; | |
490 | out[2] = out[3] = pix >> 8; | |
491 | out += stride; | |
492 | out[0] = out[1] = pix & 0xFF; | |
493 | out[2] = out[3] = pix >> 8; | |
494 | out += stride; | |
495 | pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); | |
496 | out[0] = out[1] = pix & 0xFF; | |
497 | out[2] = out[3] = pix >> 8; | |
498 | out += stride; | |
499 | out[0] = out[1] = pix & 0xFF; | |
500 | out[2] = out[3] = pix >> 8; | |
501 | break; | |
502 | case 2: | |
503 | for(i = 0; i < 2; i++) { | |
504 | uint16_t pix1, pix2; | |
505 | pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last); | |
506 | pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last); | |
507 | AV_WL16(out,pix1); | |
508 | AV_WL16(out+2,pix2); | |
509 | out += stride; | |
510 | AV_WL16(out,pix1); | |
511 | AV_WL16(out+2,pix2); | |
512 | out += stride; | |
513 | } | |
514 | break; | |
515 | } | |
516 | blk++; | |
517 | } | |
518 | break; | |
519 | case SMK_BLK_SKIP: | |
520 | while(run-- && blk < blocks) | |
521 | blk++; | |
522 | break; | |
523 | case SMK_BLK_FILL: | |
524 | mode = type >> 8; | |
525 | while(run-- && blk < blocks){ | |
526 | uint32_t col; | |
527 | out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; | |
528 | col = mode * 0x01010101; | |
529 | for(i = 0; i < 4; i++) { | |
530 | *((uint32_t*)out) = col; | |
531 | out += stride; | |
532 | } | |
533 | blk++; | |
534 | } | |
535 | break; | |
536 | } | |
537 | ||
538 | } | |
539 | ||
540 | if ((ret = av_frame_ref(data, smk->pic)) < 0) | |
541 | return ret; | |
542 | ||
543 | *got_frame = 1; | |
544 | ||
545 | /* always report that the buffer was completely consumed */ | |
546 | return avpkt->size; | |
547 | } | |
548 | ||
549 | ||
550 | ||
551 | /* | |
552 | * | |
553 | * Uninit smacker decoder | |
554 | * | |
555 | */ | |
556 | static av_cold int decode_end(AVCodecContext *avctx) | |
557 | { | |
558 | SmackVContext * const smk = avctx->priv_data; | |
559 | ||
560 | av_freep(&smk->mmap_tbl); | |
561 | av_freep(&smk->mclr_tbl); | |
562 | av_freep(&smk->full_tbl); | |
563 | av_freep(&smk->type_tbl); | |
564 | ||
565 | av_frame_free(&smk->pic); | |
566 | ||
567 | return 0; | |
568 | } | |
569 | ||
570 | ||
571 | /* | |
572 | * | |
573 | * Init smacker decoder | |
574 | * | |
575 | */ | |
576 | static av_cold int decode_init(AVCodecContext *avctx) | |
577 | { | |
578 | SmackVContext * const c = avctx->priv_data; | |
579 | int ret; | |
580 | ||
581 | c->avctx = avctx; | |
582 | ||
583 | avctx->pix_fmt = AV_PIX_FMT_PAL8; | |
584 | ||
585 | c->pic = av_frame_alloc(); | |
586 | if (!c->pic) | |
587 | return AVERROR(ENOMEM); | |
588 | ||
589 | /* decode huffman trees from extradata */ | |
590 | if(avctx->extradata_size < 16){ | |
591 | av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n"); | |
f6fa7814 | 592 | decode_end(avctx); |
2ba45a60 DM |
593 | return AVERROR(EINVAL); |
594 | } | |
595 | ||
596 | ret = decode_header_trees(c); | |
597 | if (ret < 0) { | |
598 | decode_end(avctx); | |
599 | return ret; | |
600 | } | |
601 | ||
602 | return 0; | |
603 | } | |
604 | ||
605 | ||
606 | static av_cold int smka_decode_init(AVCodecContext *avctx) | |
607 | { | |
608 | if (avctx->channels < 1 || avctx->channels > 2) { | |
609 | av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n"); | |
610 | return AVERROR(EINVAL); | |
611 | } | |
612 | avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; | |
613 | avctx->sample_fmt = avctx->bits_per_coded_sample == 8 ? AV_SAMPLE_FMT_U8 : AV_SAMPLE_FMT_S16; | |
614 | ||
615 | return 0; | |
616 | } | |
617 | ||
618 | /** | |
619 | * Decode Smacker audio data | |
620 | */ | |
621 | static int smka_decode_frame(AVCodecContext *avctx, void *data, | |
622 | int *got_frame_ptr, AVPacket *avpkt) | |
623 | { | |
624 | AVFrame *frame = data; | |
625 | const uint8_t *buf = avpkt->data; | |
626 | int buf_size = avpkt->size; | |
627 | GetBitContext gb; | |
628 | HuffContext h[4] = { { 0 } }; | |
629 | VLC vlc[4] = { { 0 } }; | |
630 | int16_t *samples; | |
631 | uint8_t *samples8; | |
632 | int val; | |
633 | int i, res, ret; | |
634 | int unp_size; | |
635 | int bits, stereo; | |
636 | int pred[2] = {0, 0}; | |
637 | ||
638 | if (buf_size <= 4) { | |
639 | av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); | |
640 | return AVERROR(EINVAL); | |
641 | } | |
642 | ||
643 | unp_size = AV_RL32(buf); | |
644 | ||
645 | if (unp_size > (1U<<24)) { | |
646 | av_log(avctx, AV_LOG_ERROR, "packet is too big\n"); | |
647 | return AVERROR_INVALIDDATA; | |
648 | } | |
649 | ||
650 | if ((ret = init_get_bits8(&gb, buf + 4, buf_size - 4)) < 0) | |
651 | return ret; | |
652 | ||
653 | if(!get_bits1(&gb)){ | |
654 | av_log(avctx, AV_LOG_INFO, "Sound: no data\n"); | |
655 | *got_frame_ptr = 0; | |
656 | return 1; | |
657 | } | |
658 | stereo = get_bits1(&gb); | |
659 | bits = get_bits1(&gb); | |
660 | if (stereo ^ (avctx->channels != 1)) { | |
661 | av_log(avctx, AV_LOG_ERROR, "channels mismatch\n"); | |
662 | return AVERROR(EINVAL); | |
663 | } | |
664 | if (bits == (avctx->sample_fmt == AV_SAMPLE_FMT_U8)) { | |
665 | av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n"); | |
666 | return AVERROR(EINVAL); | |
667 | } | |
668 | ||
669 | /* get output buffer */ | |
670 | frame->nb_samples = unp_size / (avctx->channels * (bits + 1)); | |
671 | if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) | |
672 | return ret; | |
673 | samples = (int16_t *)frame->data[0]; | |
674 | samples8 = frame->data[0]; | |
675 | ||
676 | // Initialize | |
677 | for(i = 0; i < (1 << (bits + stereo)); i++) { | |
678 | h[i].length = 256; | |
679 | h[i].maxlength = 0; | |
680 | h[i].current = 0; | |
681 | h[i].bits = av_mallocz(256 * 4); | |
682 | h[i].lengths = av_mallocz(256 * sizeof(int)); | |
683 | h[i].values = av_mallocz(256 * sizeof(int)); | |
684 | if (!h[i].bits || !h[i].lengths || !h[i].values) { | |
685 | ret = AVERROR(ENOMEM); | |
686 | goto error; | |
687 | } | |
688 | skip_bits1(&gb); | |
689 | if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) { | |
690 | ret = AVERROR_INVALIDDATA; | |
691 | goto error; | |
692 | } | |
693 | skip_bits1(&gb); | |
694 | if(h[i].current > 1) { | |
695 | res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, | |
696 | h[i].lengths, sizeof(int), sizeof(int), | |
697 | h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); | |
698 | if(res < 0) { | |
699 | av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); | |
700 | ret = AVERROR_INVALIDDATA; | |
701 | goto error; | |
702 | } | |
703 | } | |
704 | } | |
705 | /* this codec relies on wraparound instead of clipping audio */ | |
706 | if(bits) { //decode 16-bit data | |
707 | for(i = stereo; i >= 0; i--) | |
708 | pred[i] = sign_extend(av_bswap16(get_bits(&gb, 16)), 16); | |
709 | for(i = 0; i <= stereo; i++) | |
710 | *samples++ = pred[i]; | |
711 | for(; i < unp_size / 2; i++) { | |
712 | if(get_bits_left(&gb)<0) | |
713 | return AVERROR_INVALIDDATA; | |
714 | if(i & stereo) { | |
715 | if(vlc[2].table) | |
716 | res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); | |
717 | else | |
718 | res = 0; | |
719 | if (res < 0) { | |
720 | av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); | |
721 | return AVERROR_INVALIDDATA; | |
722 | } | |
723 | val = h[2].values[res]; | |
724 | if(vlc[3].table) | |
725 | res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); | |
726 | else | |
727 | res = 0; | |
728 | if (res < 0) { | |
729 | av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); | |
730 | return AVERROR_INVALIDDATA; | |
731 | } | |
732 | val |= h[3].values[res] << 8; | |
733 | pred[1] += sign_extend(val, 16); | |
734 | *samples++ = pred[1]; | |
735 | } else { | |
736 | if(vlc[0].table) | |
737 | res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); | |
738 | else | |
739 | res = 0; | |
740 | if (res < 0) { | |
741 | av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); | |
742 | return AVERROR_INVALIDDATA; | |
743 | } | |
744 | val = h[0].values[res]; | |
745 | if(vlc[1].table) | |
746 | res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); | |
747 | else | |
748 | res = 0; | |
749 | if (res < 0) { | |
750 | av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); | |
751 | return AVERROR_INVALIDDATA; | |
752 | } | |
753 | val |= h[1].values[res] << 8; | |
754 | pred[0] += sign_extend(val, 16); | |
755 | *samples++ = pred[0]; | |
756 | } | |
757 | } | |
758 | } else { //8-bit data | |
759 | for(i = stereo; i >= 0; i--) | |
760 | pred[i] = get_bits(&gb, 8); | |
761 | for(i = 0; i <= stereo; i++) | |
762 | *samples8++ = pred[i]; | |
763 | for(; i < unp_size; i++) { | |
764 | if(get_bits_left(&gb)<0) | |
765 | return AVERROR_INVALIDDATA; | |
766 | if(i & stereo){ | |
767 | if(vlc[1].table) | |
768 | res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); | |
769 | else | |
770 | res = 0; | |
771 | if (res < 0) { | |
772 | av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); | |
773 | return AVERROR_INVALIDDATA; | |
774 | } | |
775 | pred[1] += sign_extend(h[1].values[res], 8); | |
776 | *samples8++ = pred[1]; | |
777 | } else { | |
778 | if(vlc[0].table) | |
779 | res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); | |
780 | else | |
781 | res = 0; | |
782 | if (res < 0) { | |
783 | av_log(avctx, AV_LOG_ERROR, "invalid vlc\n"); | |
784 | return AVERROR_INVALIDDATA; | |
785 | } | |
786 | pred[0] += sign_extend(h[0].values[res], 8); | |
787 | *samples8++ = pred[0]; | |
788 | } | |
789 | } | |
790 | } | |
791 | ||
792 | *got_frame_ptr = 1; | |
793 | ret = buf_size; | |
794 | ||
795 | error: | |
796 | for(i = 0; i < 4; i++) { | |
797 | if(vlc[i].table) | |
798 | ff_free_vlc(&vlc[i]); | |
799 | av_free(h[i].bits); | |
800 | av_free(h[i].lengths); | |
801 | av_free(h[i].values); | |
802 | } | |
803 | ||
804 | return ret; | |
805 | } | |
806 | ||
807 | AVCodec ff_smacker_decoder = { | |
808 | .name = "smackvid", | |
809 | .long_name = NULL_IF_CONFIG_SMALL("Smacker video"), | |
810 | .type = AVMEDIA_TYPE_VIDEO, | |
811 | .id = AV_CODEC_ID_SMACKVIDEO, | |
812 | .priv_data_size = sizeof(SmackVContext), | |
813 | .init = decode_init, | |
814 | .close = decode_end, | |
815 | .decode = decode_frame, | |
816 | .capabilities = CODEC_CAP_DR1, | |
817 | }; | |
818 | ||
819 | AVCodec ff_smackaud_decoder = { | |
820 | .name = "smackaud", | |
821 | .long_name = NULL_IF_CONFIG_SMALL("Smacker audio"), | |
822 | .type = AVMEDIA_TYPE_AUDIO, | |
823 | .id = AV_CODEC_ID_SMACKAUDIO, | |
824 | .init = smka_decode_init, | |
825 | .decode = smka_decode_frame, | |
826 | .capabilities = CODEC_CAP_DR1, | |
827 | }; |