Mercurial > libavcodec.hg
annotate smacker.c @ 8228:416ffc3907bf libavcodec
Remove ineffectual hack that attempts to build ppc/check_altivec.o without
AltiVec flags. The flags are set by configure and used to compile all files
anyway. Setting extra AltiVec options here just duplicates them for the files
for which they are set.
author | diego |
---|---|
date | Sun, 30 Nov 2008 16:57:28 +0000 |
parents | f11197441364 |
children | 57d9d1f7955a |
rev | line source |
---|---|
3209 | 1 /* |
2 * Smacker decoder | |
3 * Copyright (c) 2006 Konstantin Shishkov | |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
3209 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
3209 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
3209 | 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 | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3800
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3209 | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 */ | |
21 | |
22 /** | |
23 * @file smacker.c | |
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 "avcodec.h" | |
35 | |
36 #define ALT_BITSTREAM_READER_LE | |
37 #include "bitstream.h" | |
6316
80f5ff30ba58
Use bytestream_get_be24 to simplify palette parsing.
reimar
parents:
6251
diff
changeset
|
38 #include "bytestream.h" |
3209 | 39 |
40 #define SMKTREE_BITS 9 | |
41 #define SMK_NODE 0x80000000 | |
42 | |
43 /* | |
44 * Decoder context | |
45 */ | |
46 typedef struct SmackVContext { | |
47 AVCodecContext *avctx; | |
48 AVFrame pic; | |
49 | |
50 int *mmap_tbl, *mclr_tbl, *full_tbl, *type_tbl; | |
51 int mmap_last[3], mclr_last[3], full_last[3], type_last[3]; | |
52 } SmackVContext; | |
53 | |
54 /** | |
55 * Context used for code reconstructing | |
56 */ | |
57 typedef struct HuffContext { | |
58 int length; | |
59 int maxlength; | |
60 int current; | |
61 uint32_t *bits; | |
62 int *lengths; | |
63 int *values; | |
64 } HuffContext; | |
65 | |
66 /* common parameters used for decode_bigtree */ | |
67 typedef struct DBCtx { | |
68 VLC *v1, *v2; | |
69 int *recode1, *recode2; | |
70 int escapes[3]; | |
71 int *last; | |
72 int lcur; | |
73 } DBCtx; | |
74 | |
75 /* possible runs of blocks */ | |
76 static const int block_runs[64] = { | |
77 1, 2, 3, 4, 5, 6, 7, 8, | |
78 9, 10, 11, 12, 13, 14, 15, 16, | |
79 17, 18, 19, 20, 21, 22, 23, 24, | |
80 25, 26, 27, 28, 29, 30, 31, 32, | |
81 33, 34, 35, 36, 37, 38, 39, 40, | |
82 41, 42, 43, 44, 45, 46, 47, 48, | |
83 49, 50, 51, 52, 53, 54, 55, 56, | |
84 57, 58, 59, 128, 256, 512, 1024, 2048 }; | |
85 | |
86 enum SmkBlockTypes { | |
87 SMK_BLK_MONO = 0, | |
88 SMK_BLK_FULL = 1, | |
89 SMK_BLK_SKIP = 2, | |
90 SMK_BLK_FILL = 3 }; | |
91 | |
92 /** | |
93 * Decode local frame tree | |
94 */ | |
95 static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t prefix, int length) | |
96 { | |
97 if(!get_bits1(gb)){ //Leaf | |
98 if(hc->current >= 256){ | |
99 av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); | |
100 return -1; | |
101 } | |
102 if(length){ | |
103 hc->bits[hc->current] = prefix; | |
104 hc->lengths[hc->current] = length; | |
105 } else { | |
106 hc->bits[hc->current] = 0; | |
107 hc->lengths[hc->current] = 0; | |
108 } | |
109 hc->values[hc->current] = get_bits(gb, 8); | |
110 hc->current++; | |
111 if(hc->maxlength < length) | |
112 hc->maxlength = length; | |
113 return 0; | |
114 } else { //Node | |
115 int r; | |
116 length++; | |
117 r = smacker_decode_tree(gb, hc, prefix, length); | |
118 if(r) | |
119 return r; | |
120 return smacker_decode_tree(gb, hc, prefix | (1 << (length - 1)), length); | |
121 } | |
122 } | |
123 | |
124 /** | |
125 * Decode header tree | |
126 */ | |
127 static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx) | |
128 { | |
129 if(!get_bits1(gb)){ //Leaf | |
130 int val, i1, i2, b1, b2; | |
131 if(hc->current >= hc->length){ | |
132 av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); | |
133 return -1; | |
134 } | |
135 b1 = get_bits_count(gb); | |
136 i1 = get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3); | |
137 b1 = get_bits_count(gb) - b1; | |
138 b2 = get_bits_count(gb); | |
139 i2 = get_vlc2(gb, ctx->v2->table, SMKTREE_BITS, 3); | |
140 b2 = get_bits_count(gb) - b2; | |
141 val = ctx->recode1[i1] | (ctx->recode2[i2] << 8); | |
142 if(val == ctx->escapes[0]) { | |
143 ctx->last[0] = hc->current; | |
144 val = 0; | |
145 } else if(val == ctx->escapes[1]) { | |
146 ctx->last[1] = hc->current; | |
147 val = 0; | |
148 } else if(val == ctx->escapes[2]) { | |
149 ctx->last[2] = hc->current; | |
150 val = 0; | |
151 } | |
152 | |
153 hc->values[hc->current++] = val; | |
154 return 1; | |
155 } else { //Node | |
156 int r = 0, t; | |
157 | |
158 t = hc->current++; | |
159 r = smacker_decode_bigtree(gb, hc, ctx); | |
160 if(r < 0) | |
161 return r; | |
162 hc->values[t] = SMK_NODE | r; | |
163 r++; | |
164 r += smacker_decode_bigtree(gb, hc, ctx); | |
165 return r; | |
166 } | |
167 } | |
168 | |
169 /** | |
170 * Store large tree as FFmpeg's vlc codes | |
171 */ | |
172 static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int **recodes, int *last, int size) | |
173 { | |
174 int res; | |
175 HuffContext huff; | |
176 HuffContext tmp1, tmp2; | |
177 VLC vlc[2]; | |
178 int escapes[3]; | |
179 DBCtx ctx; | |
180 | |
3303
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3220
diff
changeset
|
181 if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow |
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3220
diff
changeset
|
182 av_log(smk->avctx, AV_LOG_ERROR, "size too large\n"); |
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3220
diff
changeset
|
183 return -1; |
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3220
diff
changeset
|
184 } |
68721b62a528
sanity checks, some might have been exploitable ...
michael
parents:
3220
diff
changeset
|
185 |
3209 | 186 tmp1.length = 256; |
187 tmp1.maxlength = 0; | |
188 tmp1.current = 0; | |
189 tmp1.bits = av_mallocz(256 * 4); | |
190 tmp1.lengths = av_mallocz(256 * sizeof(int)); | |
191 tmp1.values = av_mallocz(256 * sizeof(int)); | |
192 | |
193 tmp2.length = 256; | |
194 tmp2.maxlength = 0; | |
195 tmp2.current = 0; | |
196 tmp2.bits = av_mallocz(256 * 4); | |
197 tmp2.lengths = av_mallocz(256 * sizeof(int)); | |
198 tmp2.values = av_mallocz(256 * sizeof(int)); | |
199 | |
200 memset(&vlc[0], 0, sizeof(VLC)); | |
201 memset(&vlc[1], 0, sizeof(VLC)); | |
202 | |
203 if(get_bits1(gb)) { | |
204 smacker_decode_tree(gb, &tmp1, 0, 0); | |
5518 | 205 skip_bits1(gb); |
3209 | 206 res = init_vlc(&vlc[0], SMKTREE_BITS, tmp1.length, |
207 tmp1.lengths, sizeof(int), sizeof(int), | |
208 tmp1.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); | |
209 if(res < 0) { | |
210 av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); | |
211 return -1; | |
212 } | |
213 } else { | |
214 av_log(smk->avctx, AV_LOG_ERROR, "Skipping low bytes tree\n"); | |
215 } | |
216 if(get_bits1(gb)){ | |
217 smacker_decode_tree(gb, &tmp2, 0, 0); | |
5518 | 218 skip_bits1(gb); |
3209 | 219 res = init_vlc(&vlc[1], SMKTREE_BITS, tmp2.length, |
220 tmp2.lengths, sizeof(int), sizeof(int), | |
221 tmp2.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); | |
222 if(res < 0) { | |
223 av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); | |
224 return -1; | |
225 } | |
226 } else { | |
227 av_log(smk->avctx, AV_LOG_ERROR, "Skipping high bytes tree\n"); | |
228 } | |
229 | |
230 escapes[0] = get_bits(gb, 8); | |
231 escapes[0] |= get_bits(gb, 8) << 8; | |
232 escapes[1] = get_bits(gb, 8); | |
233 escapes[1] |= get_bits(gb, 8) << 8; | |
234 escapes[2] = get_bits(gb, 8); | |
235 escapes[2] |= get_bits(gb, 8) << 8; | |
236 | |
237 last[0] = last[1] = last[2] = -1; | |
238 | |
239 ctx.escapes[0] = escapes[0]; | |
240 ctx.escapes[1] = escapes[1]; | |
241 ctx.escapes[2] = escapes[2]; | |
242 ctx.v1 = &vlc[0]; | |
243 ctx.v2 = &vlc[1]; | |
244 ctx.recode1 = tmp1.values; | |
245 ctx.recode2 = tmp2.values; | |
246 ctx.last = last; | |
247 | |
248 huff.length = ((size + 3) >> 2) + 3; | |
249 huff.maxlength = 0; | |
250 huff.current = 0; | |
251 huff.values = av_mallocz(huff.length * sizeof(int)); | |
252 | |
253 smacker_decode_bigtree(gb, &huff, &ctx); | |
5518 | 254 skip_bits1(gb); |
3209 | 255 if(ctx.last[0] == -1) ctx.last[0] = huff.current++; |
256 if(ctx.last[1] == -1) ctx.last[1] = huff.current++; | |
257 if(ctx.last[2] == -1) ctx.last[2] = huff.current++; | |
258 | |
259 *recodes = huff.values; | |
260 | |
261 if(vlc[0].table) | |
262 free_vlc(&vlc[0]); | |
263 if(vlc[1].table) | |
264 free_vlc(&vlc[1]); | |
265 av_free(tmp1.bits); | |
266 av_free(tmp1.lengths); | |
267 av_free(tmp1.values); | |
268 av_free(tmp2.bits); | |
269 av_free(tmp2.lengths); | |
270 av_free(tmp2.values); | |
271 | |
272 return 0; | |
273 } | |
274 | |
275 static int decode_header_trees(SmackVContext *smk) { | |
276 GetBitContext gb; | |
277 int mmap_size, mclr_size, full_size, type_size; | |
278 | |
4364 | 279 mmap_size = AV_RL32(smk->avctx->extradata); |
280 mclr_size = AV_RL32(smk->avctx->extradata + 4); | |
281 full_size = AV_RL32(smk->avctx->extradata + 8); | |
282 type_size = AV_RL32(smk->avctx->extradata + 12); | |
3209 | 283 |
284 init_get_bits(&gb, smk->avctx->extradata + 16, (smk->avctx->extradata_size - 16) * 8); | |
285 | |
286 if(!get_bits1(&gb)) { | |
287 av_log(smk->avctx, AV_LOG_INFO, "Skipping MMAP tree\n"); | |
288 smk->mmap_tbl = av_malloc(sizeof(int) * 2); | |
289 smk->mmap_tbl[0] = 0; | |
290 smk->mmap_last[0] = smk->mmap_last[1] = smk->mmap_last[2] = 1; | |
291 } else { | |
292 smacker_decode_header_tree(smk, &gb, &smk->mmap_tbl, smk->mmap_last, mmap_size); | |
293 } | |
5513 | 294 if(!get_bits1(&gb)) { |
3209 | 295 av_log(smk->avctx, AV_LOG_INFO, "Skipping MCLR tree\n"); |
296 smk->mclr_tbl = av_malloc(sizeof(int) * 2); | |
297 smk->mclr_tbl[0] = 0; | |
298 smk->mclr_last[0] = smk->mclr_last[1] = smk->mclr_last[2] = 1; | |
299 } else { | |
300 smacker_decode_header_tree(smk, &gb, &smk->mclr_tbl, smk->mclr_last, mclr_size); | |
301 } | |
5513 | 302 if(!get_bits1(&gb)) { |
3209 | 303 av_log(smk->avctx, AV_LOG_INFO, "Skipping FULL tree\n"); |
304 smk->full_tbl = av_malloc(sizeof(int) * 2); | |
305 smk->full_tbl[0] = 0; | |
306 smk->full_last[0] = smk->full_last[1] = smk->full_last[2] = 1; | |
307 } else { | |
308 smacker_decode_header_tree(smk, &gb, &smk->full_tbl, smk->full_last, full_size); | |
309 } | |
5513 | 310 if(!get_bits1(&gb)) { |
3209 | 311 av_log(smk->avctx, AV_LOG_INFO, "Skipping TYPE tree\n"); |
312 smk->type_tbl = av_malloc(sizeof(int) * 2); | |
313 smk->type_tbl[0] = 0; | |
314 smk->type_last[0] = smk->type_last[1] = smk->type_last[2] = 1; | |
315 } else { | |
316 smacker_decode_header_tree(smk, &gb, &smk->type_tbl, smk->type_last, type_size); | |
317 } | |
318 | |
319 return 0; | |
320 } | |
321 | |
4283
d6f83e2f8804
rename always_inline to av_always_inline and move to common.h
mru
parents:
3947
diff
changeset
|
322 static av_always_inline void last_reset(int *recode, int *last) { |
3209 | 323 recode[last[0]] = recode[last[1]] = recode[last[2]] = 0; |
324 } | |
325 | |
326 /* get code and update history */ | |
4283
d6f83e2f8804
rename always_inline to av_always_inline and move to common.h
mru
parents:
3947
diff
changeset
|
327 static av_always_inline int smk_get_code(GetBitContext *gb, int *recode, int *last) { |
3209 | 328 register int *table = recode; |
329 int v, b; | |
330 | |
331 b = get_bits_count(gb); | |
332 while(*table & SMK_NODE) { | |
333 if(get_bits1(gb)) | |
334 table += (*table) & (~SMK_NODE); | |
335 table++; | |
336 } | |
337 v = *table; | |
338 b = get_bits_count(gb) - b; | |
339 | |
340 if(v != recode[last[0]]) { | |
341 recode[last[2]] = recode[last[1]]; | |
342 recode[last[1]] = recode[last[0]]; | |
343 recode[last[0]] = v; | |
344 } | |
345 return v; | |
346 } | |
347 | |
6251 | 348 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) |
3209 | 349 { |
4827 | 350 SmackVContext * const smk = avctx->priv_data; |
3209 | 351 uint8_t *out; |
352 uint32_t *pal; | |
353 GetBitContext gb; | |
354 int blocks, blk, bw, bh; | |
355 int i; | |
356 int stride; | |
357 | |
6317
2f44646383c8
100l, since we already check for buf_size == 769 we should also
reimar
parents:
6316
diff
changeset
|
358 if(buf_size <= 769) |
3209 | 359 return 0; |
360 if(smk->pic.data[0]) | |
361 avctx->release_buffer(avctx, &smk->pic); | |
362 | |
363 smk->pic.reference = 1; | |
364 smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; | |
365 if(avctx->reget_buffer(avctx, &smk->pic) < 0){ | |
366 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
367 return -1; | |
368 } | |
369 | |
370 /* make the palette available on the way out */ | |
371 pal = (uint32_t*)smk->pic.data[1]; | |
372 smk->pic.palette_has_changed = buf[0] & 1; | |
373 smk->pic.key_frame = !!(buf[0] & 2); | |
374 if(smk->pic.key_frame) | |
375 smk->pic.pict_type = FF_I_TYPE; | |
376 else | |
377 smk->pic.pict_type = FF_P_TYPE; | |
378 | |
6316
80f5ff30ba58
Use bytestream_get_be24 to simplify palette parsing.
reimar
parents:
6251
diff
changeset
|
379 buf++; |
80f5ff30ba58
Use bytestream_get_be24 to simplify palette parsing.
reimar
parents:
6251
diff
changeset
|
380 for(i = 0; i < 256; i++) |
80f5ff30ba58
Use bytestream_get_be24 to simplify palette parsing.
reimar
parents:
6251
diff
changeset
|
381 *pal++ = bytestream_get_be24(&buf); |
80f5ff30ba58
Use bytestream_get_be24 to simplify palette parsing.
reimar
parents:
6251
diff
changeset
|
382 buf_size -= 769; |
3209 | 383 |
384 last_reset(smk->mmap_tbl, smk->mmap_last); | |
385 last_reset(smk->mclr_tbl, smk->mclr_last); | |
386 last_reset(smk->full_tbl, smk->full_last); | |
387 last_reset(smk->type_tbl, smk->type_last); | |
6316
80f5ff30ba58
Use bytestream_get_be24 to simplify palette parsing.
reimar
parents:
6251
diff
changeset
|
388 init_get_bits(&gb, buf, buf_size * 8); |
3209 | 389 |
390 blk = 0; | |
391 bw = avctx->width >> 2; | |
392 bh = avctx->height >> 2; | |
393 blocks = bw * bh; | |
394 out = smk->pic.data[0]; | |
395 stride = smk->pic.linesize[0]; | |
396 while(blk < blocks) { | |
397 int type, run, mode; | |
398 uint16_t pix; | |
399 | |
400 type = smk_get_code(&gb, smk->type_tbl, smk->type_last); | |
401 run = block_runs[(type >> 2) & 0x3F]; | |
402 switch(type & 3){ | |
403 case SMK_BLK_MONO: | |
404 while(run-- && blk < blocks){ | |
405 int clr, map; | |
406 int hi, lo; | |
407 clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last); | |
408 map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last); | |
409 out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; | |
410 hi = clr >> 8; | |
411 lo = clr & 0xFF; | |
412 for(i = 0; i < 4; i++) { | |
413 if(map & 1) out[0] = hi; else out[0] = lo; | |
414 if(map & 2) out[1] = hi; else out[1] = lo; | |
415 if(map & 4) out[2] = hi; else out[2] = lo; | |
416 if(map & 8) out[3] = hi; else out[3] = lo; | |
417 map >>= 4; | |
418 out += stride; | |
419 } | |
420 blk++; | |
421 } | |
422 break; | |
423 case SMK_BLK_FULL: | |
424 mode = 0; | |
3310
48fc664f7348
Now MPlayer should understand Smacker audio and video codecs.
kostya
parents:
3303
diff
changeset
|
425 if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes |
3209 | 426 if(get_bits1(&gb)) mode = 1; |
427 else if(get_bits1(&gb)) mode = 2; | |
428 } | |
429 while(run-- && blk < blocks){ | |
430 out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; | |
431 switch(mode){ | |
432 case 0: | |
433 for(i = 0; i < 4; i++) { | |
434 pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); | |
5089 | 435 AV_WL16(out+2,pix); |
3209 | 436 pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
5089 | 437 AV_WL16(out,pix); |
3209 | 438 out += stride; |
439 } | |
440 break; | |
441 case 1: | |
442 pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); | |
443 out[0] = out[1] = pix & 0xFF; | |
444 out[2] = out[3] = pix >> 8; | |
445 out += stride; | |
446 out[0] = out[1] = pix & 0xFF; | |
447 out[2] = out[3] = pix >> 8; | |
448 out += stride; | |
449 pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); | |
450 out[0] = out[1] = pix & 0xFF; | |
451 out[2] = out[3] = pix >> 8; | |
452 out += stride; | |
453 out[0] = out[1] = pix & 0xFF; | |
454 out[2] = out[3] = pix >> 8; | |
455 out += stride; | |
456 break; | |
457 case 2: | |
458 for(i = 0; i < 2; i++) { | |
459 uint16_t pix1, pix2; | |
460 pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last); | |
461 pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last); | |
5089 | 462 AV_WL16(out,pix1); |
463 AV_WL16(out+2,pix2); | |
3209 | 464 out += stride; |
5089 | 465 AV_WL16(out,pix1); |
466 AV_WL16(out+2,pix2); | |
3209 | 467 out += stride; |
468 } | |
469 break; | |
470 } | |
471 blk++; | |
472 } | |
473 break; | |
474 case SMK_BLK_SKIP: | |
475 while(run-- && blk < blocks) | |
476 blk++; | |
477 break; | |
478 case SMK_BLK_FILL: | |
479 mode = type >> 8; | |
480 while(run-- && blk < blocks){ | |
481 uint32_t col; | |
482 out = smk->pic.data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; | |
483 col = mode * 0x01010101; | |
484 for(i = 0; i < 4; i++) { | |
485 *((uint32_t*)out) = col; | |
486 out += stride; | |
487 } | |
488 blk++; | |
489 } | |
490 break; | |
491 } | |
492 | |
493 } | |
494 | |
495 *data_size = sizeof(AVFrame); | |
496 *(AVFrame*)data = smk->pic; | |
497 | |
498 /* always report that the buffer was completely consumed */ | |
499 return buf_size; | |
500 } | |
501 | |
502 | |
503 | |
504 /* | |
505 * | |
506 * Init smacker decoder | |
507 * | |
508 */ | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6317
diff
changeset
|
509 static av_cold int decode_init(AVCodecContext *avctx) |
3209 | 510 { |
4827 | 511 SmackVContext * const c = avctx->priv_data; |
3209 | 512 |
513 c->avctx = avctx; | |
514 | |
515 c->pic.data[0] = NULL; | |
516 | |
3800
9b75ab171fa9
1l: correct argument order in avcodec_check_dimensions
kostya
parents:
3694
diff
changeset
|
517 if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { |
3209 | 518 return 1; |
519 } | |
520 | |
521 avctx->pix_fmt = PIX_FMT_PAL8; | |
522 | |
523 | |
524 /* decode huffman trees from extradata */ | |
525 if(avctx->extradata_size < 16){ | |
526 av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n"); | |
527 return -1; | |
528 } | |
529 | |
530 decode_header_trees(c); | |
531 | |
532 | |
533 return 0; | |
534 } | |
535 | |
536 | |
537 | |
538 /* | |
539 * | |
540 * Uninit smacker decoder | |
541 * | |
542 */ | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6317
diff
changeset
|
543 static av_cold int decode_end(AVCodecContext *avctx) |
3209 | 544 { |
4827 | 545 SmackVContext * const smk = avctx->priv_data; |
3209 | 546 |
3694
8765ee4eaa45
Drop unneeded checks before av_free() and change to av_freep() where it's more suitable.
kostya
parents:
3310
diff
changeset
|
547 av_freep(&smk->mmap_tbl); |
8765ee4eaa45
Drop unneeded checks before av_free() and change to av_freep() where it's more suitable.
kostya
parents:
3310
diff
changeset
|
548 av_freep(&smk->mclr_tbl); |
8765ee4eaa45
Drop unneeded checks before av_free() and change to av_freep() where it's more suitable.
kostya
parents:
3310
diff
changeset
|
549 av_freep(&smk->full_tbl); |
8765ee4eaa45
Drop unneeded checks before av_free() and change to av_freep() where it's more suitable.
kostya
parents:
3310
diff
changeset
|
550 av_freep(&smk->type_tbl); |
3209 | 551 |
552 if (smk->pic.data[0]) | |
553 avctx->release_buffer(avctx, &smk->pic); | |
554 | |
555 return 0; | |
556 } | |
557 | |
558 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6317
diff
changeset
|
559 static av_cold int smka_decode_init(AVCodecContext *avctx) |
3209 | 560 { |
7451
85ab7655ad4d
Modify all codecs to report their supported input and output sample format(s).
pross
parents:
7040
diff
changeset
|
561 avctx->sample_fmt = SAMPLE_FMT_S16; |
8174
f11197441364
Add channel layout to several audio decoders I maintain
kostya
parents:
7451
diff
changeset
|
562 avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO; |
3209 | 563 return 0; |
564 } | |
565 | |
566 /** | |
567 * Decode Smacker audio data | |
568 */ | |
6251 | 569 static int smka_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) |
3209 | 570 { |
571 GetBitContext gb; | |
572 HuffContext h[4]; | |
573 VLC vlc[4]; | |
574 int16_t *samples = data; | |
575 int val; | |
576 int i, res; | |
577 int unp_size; | |
578 int bits, stereo; | |
579 int pred[2] = {0, 0}; | |
580 | |
4364 | 581 unp_size = AV_RL32(buf); |
3209 | 582 |
583 init_get_bits(&gb, buf + 4, (buf_size - 4) * 8); | |
584 | |
585 if(!get_bits1(&gb)){ | |
586 av_log(avctx, AV_LOG_INFO, "Sound: no data\n"); | |
587 *data_size = 0; | |
588 return 1; | |
589 } | |
590 stereo = get_bits1(&gb); | |
591 bits = get_bits1(&gb); | |
5676 | 592 if (unp_size & 0xC0000000 || (unp_size << !bits) > *data_size) { |
5674
ca944f1db2b3
Add checks on input/output buffers size for some audio decoders
kostya
parents:
5518
diff
changeset
|
593 av_log(avctx, AV_LOG_ERROR, "Frame is too large to fit in buffer\n"); |
ca944f1db2b3
Add checks on input/output buffers size for some audio decoders
kostya
parents:
5518
diff
changeset
|
594 return -1; |
ca944f1db2b3
Add checks on input/output buffers size for some audio decoders
kostya
parents:
5518
diff
changeset
|
595 } |
3209 | 596 |
597 memset(vlc, 0, sizeof(VLC) * 4); | |
598 memset(h, 0, sizeof(HuffContext) * 4); | |
599 // Initialize | |
600 for(i = 0; i < (1 << (bits + stereo)); i++) { | |
601 h[i].length = 256; | |
602 h[i].maxlength = 0; | |
603 h[i].current = 0; | |
604 h[i].bits = av_mallocz(256 * 4); | |
605 h[i].lengths = av_mallocz(256 * sizeof(int)); | |
606 h[i].values = av_mallocz(256 * sizeof(int)); | |
5518 | 607 skip_bits1(&gb); |
3209 | 608 smacker_decode_tree(&gb, &h[i], 0, 0); |
5518 | 609 skip_bits1(&gb); |
3220
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
610 if(h[i].current > 1) { |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
611 res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, |
3209 | 612 h[i].lengths, sizeof(int), sizeof(int), |
613 h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE); | |
3220
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
614 if(res < 0) { |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
615 av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
616 return -1; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
617 } |
3209 | 618 } |
619 } | |
620 if(bits) { //decode 16-bit data | |
4693 | 621 for(i = stereo; i >= 0; i--) |
622 pred[i] = bswap_16(get_bits(&gb, 16)); | |
623 for(i = 0; i < stereo; i++) | |
624 *samples++ = pred[i]; | |
3209 | 625 for(i = 0; i < unp_size / 2; i++) { |
626 if(i & stereo) { | |
3220
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
627 if(vlc[2].table) |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
628 res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
629 else |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
630 res = 0; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
631 val = h[2].values[res]; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
632 if(vlc[3].table) |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
633 res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
634 else |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
635 res = 0; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
636 val |= h[3].values[res] << 8; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
637 pred[1] += (int16_t)val; |
3209 | 638 *samples++ = pred[1]; |
639 } else { | |
3220
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
640 if(vlc[0].table) |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
641 res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
642 else |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
643 res = 0; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
644 val = h[0].values[res]; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
645 if(vlc[1].table) |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
646 res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
647 else |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
648 res = 0; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
649 val |= h[1].values[res] << 8; |
3209 | 650 pred[0] += val; |
651 *samples++ = pred[0]; | |
652 } | |
653 } | |
654 } else { //8-bit data | |
4693 | 655 for(i = stereo; i >= 0; i--) |
656 pred[i] = get_bits(&gb, 8); | |
657 for(i = 0; i < stereo; i++) | |
658 *samples++ = (pred[i] - 0x80) << 8; | |
3209 | 659 for(i = 0; i < unp_size; i++) { |
660 if(i & stereo){ | |
3220
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
661 if(vlc[1].table) |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
662 res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
663 else |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
664 res = 0; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
665 pred[1] += (int8_t)h[1].values[res]; |
3209 | 666 *samples++ = (pred[1] - 0x80) << 8; |
667 } else { | |
3220
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
668 if(vlc[0].table) |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
669 res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
670 else |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
671 res = 0; |
a931984ec6ab
Don't use get_vlc2() when tree is one symbol. This fixes audio decoding
kostya
parents:
3209
diff
changeset
|
672 pred[0] += (int8_t)h[0].values[res]; |
3209 | 673 *samples++ = (pred[0] - 0x80) << 8; |
674 } | |
675 } | |
676 unp_size *= 2; | |
677 } | |
678 | |
679 for(i = 0; i < 4; i++) { | |
680 if(vlc[i].table) | |
681 free_vlc(&vlc[i]); | |
682 if(h[i].bits) | |
683 av_free(h[i].bits); | |
684 if(h[i].lengths) | |
685 av_free(h[i].lengths); | |
686 if(h[i].values) | |
687 av_free(h[i].values); | |
688 } | |
689 | |
690 *data_size = unp_size; | |
691 return buf_size; | |
692 } | |
693 | |
694 AVCodec smacker_decoder = { | |
695 "smackvid", | |
696 CODEC_TYPE_VIDEO, | |
697 CODEC_ID_SMACKVIDEO, | |
698 sizeof(SmackVContext), | |
699 decode_init, | |
700 NULL, | |
701 decode_end, | |
6712 | 702 decode_frame, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
703 .long_name = NULL_IF_CONFIG_SMALL("Smacker video"), |
3209 | 704 }; |
705 | |
706 AVCodec smackaud_decoder = { | |
707 "smackaud", | |
708 CODEC_TYPE_AUDIO, | |
709 CODEC_ID_SMACKAUDIO, | |
710 0, | |
711 smka_decode_init, | |
712 NULL, | |
713 NULL, | |
6712 | 714 smka_decode_frame, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
715 .long_name = NULL_IF_CONFIG_SMALL("Smacker audio"), |
3209 | 716 }; |
717 |