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