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 |
|
|
|
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 "get_bits.h" |
54 |
|
|
#include "internal.h" |
55 |
|
|
#include "mathops.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(GetBitContext *gb, HuffContext *hc, int length) |
112 |
|
|
{ |
113 |
✓✗✗✓
|
9904 |
if (length > SMKTREE_DECODE_MAX_RECURSION || length > 3 * SMKTREE_BITS) { |
114 |
|
|
av_log(NULL, AV_LOG_ERROR, "Maximum tree recursion level exceeded.\n"); |
115 |
|
|
return AVERROR_INVALIDDATA; |
116 |
|
|
} |
117 |
|
|
|
118 |
✓✓ |
9904 |
if(!get_bits1(gb)){ //Leaf |
119 |
✗✓ |
5007 |
if (hc->current >= 256) { |
120 |
|
|
av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); |
121 |
|
|
return AVERROR_INVALIDDATA; |
122 |
|
|
} |
123 |
✗✓ |
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(gb, hc, length); |
131 |
✗✓ |
4897 |
if(r) |
132 |
|
|
return r; |
133 |
|
4897 |
return smacker_decode_tree(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(GetBitContext *gb, DBCtx *ctx, int length) |
143 |
|
|
{ |
144 |
|
|
// Larger length can cause segmentation faults due to too deep recursion. |
145 |
✗✓ |
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 |
✗✓ |
81192 |
if (ctx->current >= ctx->length) { |
151 |
|
|
av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); |
152 |
|
|
return AVERROR_INVALIDDATA; |
153 |
|
|
} |
154 |
✗✓ |
81192 |
if (get_bits_left(gb) <= 0) |
155 |
|
|
return AVERROR_INVALIDDATA; |
156 |
✓✓ |
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 |
✓✗ |
40602 |
: ctx->vals[0]; |
160 |
|
40602 |
i2 = ctx->v2->table ? get_vlc2(gb, ctx->v2->table, SMKTREE_BITS, 3) |
161 |
✓✗ |
40602 |
: ctx->vals[1]; |
162 |
|
40602 |
val = i1 | (i2 << 8); |
163 |
✓✓ |
40602 |
if(val == ctx->escapes[0]) { |
164 |
|
9 |
ctx->last[0] = ctx->current; |
165 |
|
9 |
val = 0; |
166 |
✓✓ |
40593 |
} else if(val == ctx->escapes[1]) { |
167 |
|
12 |
ctx->last[1] = ctx->current; |
168 |
|
12 |
val = 0; |
169 |
✓✓ |
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(gb, ctx, length + 1); |
181 |
✗✓ |
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(gb, ctx, length + 1); |
186 |
✗✓ |
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 |
✗✓ |
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 |
✓✓ |
36 |
for (int i = 0; i < 2; i++) { |
211 |
|
|
HuffContext h; |
212 |
|
24 |
h.current = 0; |
213 |
✗✓ |
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(gb, &h, 0); |
220 |
✗✓ |
24 |
if (err < 0) |
221 |
|
|
goto error; |
222 |
|
24 |
skip_bits1(gb); |
223 |
✓✗ |
24 |
if (h.current > 1) { |
224 |
|
24 |
err = ff_init_vlc_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, INIT_VLC_OUTPUT_LE, smk->avctx); |
228 |
✗✓ |
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 |
✗✓ |
12 |
if (!ctx.values) { |
252 |
|
|
err = AVERROR(ENOMEM); |
253 |
|
|
goto error; |
254 |
|
|
} |
255 |
|
12 |
*recodes = ctx.values; |
256 |
|
|
|
257 |
|
12 |
err = smacker_decode_bigtree(gb, &ctx, 0); |
258 |
✗✓ |
12 |
if (err < 0) |
259 |
|
|
goto error; |
260 |
|
12 |
skip_bits1(gb); |
261 |
✓✓ |
12 |
if (ctx.last[0] == -1) ctx.last[0] = ctx.current++; |
262 |
✗✓ |
12 |
if (ctx.last[1] == -1) ctx.last[1] = ctx.current++; |
263 |
✗✓ |
12 |
if (ctx.last[2] == -1) ctx.last[2] = ctx.current++; |
264 |
|
|
|
265 |
|
12 |
err = 0; |
266 |
|
12 |
error: |
267 |
✓✓ |
36 |
for (int i = 0; i < 2; i++) { |
268 |
|
24 |
ff_free_vlc(&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 |
✗✓ |
3 |
if (ret < 0) |
286 |
|
|
return ret; |
287 |
|
|
|
288 |
✗✓ |
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 |
✗✓ |
3 |
if (ret < 0) |
299 |
|
|
return ret; |
300 |
|
|
} |
301 |
✗✓ |
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 |
✗✓ |
3 |
if (ret < 0) |
312 |
|
|
return ret; |
313 |
|
|
} |
314 |
✗✓ |
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 |
✗✓ |
3 |
if (ret < 0) |
325 |
|
|
return ret; |
326 |
|
|
} |
327 |
✗✓ |
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 |
✗✓ |
3 |
if (ret < 0) |
338 |
|
|
return ret; |
339 |
|
|
} |
340 |
✓✗✗✓
|
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 |
✓✓ |
5893869 |
while(*table & SMK_NODE) { |
357 |
✗✓ |
5171932 |
if (get_bits_left(gb) < 1) |
358 |
|
|
return AVERROR_INVALIDDATA; |
359 |
✓✓ |
5171932 |
if(get_bits1(gb)) |
360 |
|
2453865 |
table += (*table) & (~SMK_NODE); |
361 |
|
5171932 |
table++; |
362 |
|
|
} |
363 |
|
721937 |
v = *table; |
364 |
|
|
|
365 |
✓✓ |
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, void *data, int *got_frame, |
374 |
|
|
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 |
✗✓ |
100 |
if (avpkt->size <= 769) |
387 |
|
|
return AVERROR_INVALIDDATA; |
388 |
|
|
|
389 |
✗✓ |
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 |
|
100 |
smk->pic->palette_has_changed = flags & 1; |
397 |
|
100 |
smk->pic->key_frame = !!(flags & 2); |
398 |
✗✓ |
100 |
if (smk->pic->key_frame) |
399 |
|
|
smk->pic->pict_type = AV_PICTURE_TYPE_I; |
400 |
|
|
else |
401 |
|
100 |
smk->pic->pict_type = AV_PICTURE_TYPE_P; |
402 |
|
|
|
403 |
✓✓ |
25700 |
for(i = 0; i < 256; i++) |
404 |
|
25600 |
*pal++ = 0xFFU << 24 | bytestream2_get_be24u(&gb2); |
405 |
|
|
|
406 |
|
100 |
last_reset(smk->mmap_tbl, smk->mmap_last); |
407 |
|
100 |
last_reset(smk->mclr_tbl, smk->mclr_last); |
408 |
|
100 |
last_reset(smk->full_tbl, smk->full_last); |
409 |
|
100 |
last_reset(smk->type_tbl, smk->type_last); |
410 |
✗✓ |
100 |
if ((ret = init_get_bits8(&gb, avpkt->data + 769, avpkt->size - 769)) < 0) |
411 |
|
|
return ret; |
412 |
|
|
|
413 |
|
100 |
blk = 0; |
414 |
|
100 |
bw = avctx->width >> 2; |
415 |
|
100 |
bh = avctx->height >> 2; |
416 |
|
100 |
blocks = bw * bh; |
417 |
|
100 |
stride = smk->pic->linesize[0]; |
418 |
|
100 |
while(blk < blocks) { |
419 |
|
|
int type, run, mode; |
420 |
|
|
uint16_t pix; |
421 |
|
|
|
422 |
|
44593 |
type = smk_get_code(&gb, smk->type_tbl, smk->type_last); |
423 |
✗✓ |
44593 |
if (type < 0) |
424 |
|
|
return type; |
425 |
|
44593 |
run = block_runs[(type >> 2) & 0x3F]; |
426 |
✓✓✓✓ ✗ |
44593 |
switch(type & 3){ |
427 |
|
15331 |
case SMK_BLK_MONO: |
428 |
✓✓✓✗
|
43679 |
while(run-- && blk < blocks){ |
429 |
|
|
int clr, map; |
430 |
|
|
int hi, lo; |
431 |
|
28348 |
clr = smk_get_code(&gb, smk->mclr_tbl, smk->mclr_last); |
432 |
|
28348 |
map = smk_get_code(&gb, smk->mmap_tbl, smk->mmap_last); |
433 |
|
28348 |
out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; |
434 |
|
28348 |
hi = clr >> 8; |
435 |
|
28348 |
lo = clr & 0xFF; |
436 |
✓✓ |
141740 |
for(i = 0; i < 4; i++) { |
437 |
✓✓ |
113392 |
if(map & 1) out[0] = hi; else out[0] = lo; |
438 |
✓✓ |
113392 |
if(map & 2) out[1] = hi; else out[1] = lo; |
439 |
✓✓ |
113392 |
if(map & 4) out[2] = hi; else out[2] = lo; |
440 |
✓✓ |
113392 |
if(map & 8) out[3] = hi; else out[3] = lo; |
441 |
|
113392 |
map >>= 4; |
442 |
|
113392 |
out += stride; |
443 |
|
|
} |
444 |
|
28348 |
blk++; |
445 |
|
|
} |
446 |
|
15331 |
break; |
447 |
|
11617 |
case SMK_BLK_FULL: |
448 |
|
11617 |
mode = 0; |
449 |
✗✓ |
11617 |
if(avctx->codec_tag == MKTAG('S', 'M', 'K', '4')) { // In case of Smacker v4 we have three modes |
450 |
|
|
if (get_bits_left(&gb) < 1) |
451 |
|
|
return AVERROR_INVALIDDATA; |
452 |
|
|
if(get_bits1(&gb)) mode = 1; |
453 |
|
|
else if(get_bits1(&gb)) mode = 2; |
454 |
|
|
} |
455 |
✓✓✓✗
|
89198 |
while(run-- && blk < blocks){ |
456 |
✓✗✗✗
|
77581 |
out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; |
457 |
|
|
switch(mode){ |
458 |
|
77581 |
case 0: |
459 |
✓✓ |
387905 |
for(i = 0; i < 4; i++) { |
460 |
|
310324 |
pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
461 |
|
310324 |
AV_WL16(out+2,pix); |
462 |
|
310324 |
pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
463 |
|
310324 |
AV_WL16(out,pix); |
464 |
|
310324 |
out += stride; |
465 |
|
|
} |
466 |
|
77581 |
break; |
467 |
|
|
case 1: |
468 |
|
|
pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
469 |
|
|
out[0] = out[1] = pix & 0xFF; |
470 |
|
|
out[2] = out[3] = pix >> 8; |
471 |
|
|
out += stride; |
472 |
|
|
out[0] = out[1] = pix & 0xFF; |
473 |
|
|
out[2] = out[3] = pix >> 8; |
474 |
|
|
out += stride; |
475 |
|
|
pix = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
476 |
|
|
out[0] = out[1] = pix & 0xFF; |
477 |
|
|
out[2] = out[3] = pix >> 8; |
478 |
|
|
out += stride; |
479 |
|
|
out[0] = out[1] = pix & 0xFF; |
480 |
|
|
out[2] = out[3] = pix >> 8; |
481 |
|
|
break; |
482 |
|
|
case 2: |
483 |
|
|
for(i = 0; i < 2; i++) { |
484 |
|
|
uint16_t pix1, pix2; |
485 |
|
|
pix2 = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
486 |
|
|
pix1 = smk_get_code(&gb, smk->full_tbl, smk->full_last); |
487 |
|
|
AV_WL16(out,pix1); |
488 |
|
|
AV_WL16(out+2,pix2); |
489 |
|
|
out += stride; |
490 |
|
|
AV_WL16(out,pix1); |
491 |
|
|
AV_WL16(out+2,pix2); |
492 |
|
|
out += stride; |
493 |
|
|
} |
494 |
|
|
break; |
495 |
|
|
} |
496 |
|
77581 |
blk++; |
497 |
|
|
} |
498 |
|
11617 |
break; |
499 |
|
10001 |
case SMK_BLK_SKIP: |
500 |
✓✓✓✗
|
288422 |
while(run-- && blk < blocks) |
501 |
|
278421 |
blk++; |
502 |
|
10001 |
break; |
503 |
|
7644 |
case SMK_BLK_FILL: |
504 |
|
7644 |
mode = type >> 8; |
505 |
✓✓✓✗
|
23294 |
while(run-- && blk < blocks){ |
506 |
|
|
uint32_t col; |
507 |
|
15650 |
out = smk->pic->data[0] + (blk / bw) * (stride * 4) + (blk % bw) * 4; |
508 |
|
15650 |
col = mode * 0x01010101U; |
509 |
✓✓ |
78250 |
for(i = 0; i < 4; i++) { |
510 |
|
62600 |
*((uint32_t*)out) = col; |
511 |
|
62600 |
out += stride; |
512 |
|
|
} |
513 |
|
15650 |
blk++; |
514 |
|
|
} |
515 |
|
7644 |
break; |
516 |
|
|
} |
517 |
|
|
|
518 |
✓✓ |
44693 |
} |
519 |
|
|
|
520 |
✗✓ |
100 |
if ((ret = av_frame_ref(data, smk->pic)) < 0) |
521 |
|
|
return ret; |
522 |
|
|
|
523 |
|
100 |
*got_frame = 1; |
524 |
|
|
|
525 |
|
|
/* always report that the buffer was completely consumed */ |
526 |
|
100 |
return avpkt->size; |
527 |
|
|
} |
528 |
|
|
|
529 |
|
|
|
530 |
|
3 |
static av_cold int decode_end(AVCodecContext *avctx) |
531 |
|
|
{ |
532 |
|
3 |
SmackVContext * const smk = avctx->priv_data; |
533 |
|
|
|
534 |
|
3 |
av_freep(&smk->mmap_tbl); |
535 |
|
3 |
av_freep(&smk->mclr_tbl); |
536 |
|
3 |
av_freep(&smk->full_tbl); |
537 |
|
3 |
av_freep(&smk->type_tbl); |
538 |
|
|
|
539 |
|
3 |
av_frame_free(&smk->pic); |
540 |
|
|
|
541 |
|
3 |
return 0; |
542 |
|
|
} |
543 |
|
|
|
544 |
|
|
|
545 |
|
3 |
static av_cold int decode_init(AVCodecContext *avctx) |
546 |
|
|
{ |
547 |
|
3 |
SmackVContext * const c = avctx->priv_data; |
548 |
|
|
int ret; |
549 |
|
|
|
550 |
|
3 |
c->avctx = avctx; |
551 |
|
|
|
552 |
|
3 |
avctx->pix_fmt = AV_PIX_FMT_PAL8; |
553 |
|
|
|
554 |
|
3 |
c->pic = av_frame_alloc(); |
555 |
✗✓ |
3 |
if (!c->pic) |
556 |
|
|
return AVERROR(ENOMEM); |
557 |
|
|
|
558 |
|
|
/* decode huffman trees from extradata */ |
559 |
✗✓ |
3 |
if (avctx->extradata_size <= 16){ |
560 |
|
|
av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n"); |
561 |
|
|
return AVERROR(EINVAL); |
562 |
|
|
} |
563 |
|
|
|
564 |
|
3 |
ret = decode_header_trees(c); |
565 |
✗✓ |
3 |
if (ret < 0) { |
566 |
|
|
return ret; |
567 |
|
|
} |
568 |
|
|
|
569 |
|
3 |
return 0; |
570 |
|
|
} |
571 |
|
|
|
572 |
|
|
|
573 |
|
3 |
static av_cold int smka_decode_init(AVCodecContext *avctx) |
574 |
|
|
{ |
575 |
✓✗✗✓
|
3 |
if (avctx->channels < 1 || avctx->channels > 2) { |
576 |
|
|
av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n"); |
577 |
|
|
return AVERROR_INVALIDDATA; |
578 |
|
|
} |
579 |
✗✓ |
3 |
avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; |
580 |
|
3 |
avctx->sample_fmt = avctx->bits_per_coded_sample == 8 ? AV_SAMPLE_FMT_U8 : AV_SAMPLE_FMT_S16; |
581 |
|
|
|
582 |
|
3 |
return 0; |
583 |
|
|
} |
584 |
|
|
|
585 |
|
|
/** |
586 |
|
|
* Decode Smacker audio data |
587 |
|
|
*/ |
588 |
|
86 |
static int smka_decode_frame(AVCodecContext *avctx, void *data, |
589 |
|
|
int *got_frame_ptr, AVPacket *avpkt) |
590 |
|
|
{ |
591 |
|
86 |
AVFrame *frame = data; |
592 |
|
86 |
const uint8_t *buf = avpkt->data; |
593 |
|
86 |
int buf_size = avpkt->size; |
594 |
|
|
GetBitContext gb; |
595 |
|
86 |
VLC vlc[4] = { { 0 } }; |
596 |
|
|
int16_t *samples; |
597 |
|
|
uint8_t *samples8; |
598 |
|
|
uint8_t values[4]; |
599 |
|
|
int i, res, ret; |
600 |
|
|
int unp_size; |
601 |
|
|
int bits, stereo; |
602 |
|
|
unsigned pred[2], val; |
603 |
|
|
|
604 |
✗✓ |
86 |
if (buf_size <= 4) { |
605 |
|
|
av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); |
606 |
|
|
return AVERROR_INVALIDDATA; |
607 |
|
|
} |
608 |
|
|
|
609 |
|
86 |
unp_size = AV_RL32(buf); |
610 |
|
|
|
611 |
✗✓ |
86 |
if (unp_size > (1U<<24)) { |
612 |
|
|
av_log(avctx, AV_LOG_ERROR, "packet is too big\n"); |
613 |
|
|
return AVERROR_INVALIDDATA; |
614 |
|
|
} |
615 |
|
|
|
616 |
✗✓ |
86 |
if ((ret = init_get_bits8(&gb, buf + 4, buf_size - 4)) < 0) |
617 |
|
|
return ret; |
618 |
|
|
|
619 |
✗✓ |
86 |
if(!get_bits1(&gb)){ |
620 |
|
|
av_log(avctx, AV_LOG_INFO, "Sound: no data\n"); |
621 |
|
|
*got_frame_ptr = 0; |
622 |
|
|
return 1; |
623 |
|
|
} |
624 |
|
86 |
stereo = get_bits1(&gb); |
625 |
|
86 |
bits = get_bits1(&gb); |
626 |
✗✓ |
86 |
if (stereo ^ (avctx->channels != 1)) { |
627 |
|
|
av_log(avctx, AV_LOG_ERROR, "channels mismatch\n"); |
628 |
|
|
return AVERROR_INVALIDDATA; |
629 |
|
|
} |
630 |
✗✓ |
86 |
if (bits == (avctx->sample_fmt == AV_SAMPLE_FMT_U8)) { |
631 |
|
|
av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n"); |
632 |
|
|
return AVERROR_INVALIDDATA; |
633 |
|
|
} |
634 |
|
|
|
635 |
|
|
/* get output buffer */ |
636 |
|
86 |
frame->nb_samples = unp_size / (avctx->channels * (bits + 1)); |
637 |
✗✓ |
86 |
if (unp_size % (avctx->channels * (bits + 1))) { |
638 |
|
|
av_log(avctx, AV_LOG_ERROR, |
639 |
|
|
"The buffer does not contain an integer number of samples\n"); |
640 |
|
|
return AVERROR_INVALIDDATA; |
641 |
|
|
} |
642 |
✗✓ |
86 |
if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) |
643 |
|
|
return ret; |
644 |
|
86 |
samples = (int16_t *)frame->data[0]; |
645 |
|
86 |
samples8 = frame->data[0]; |
646 |
|
|
|
647 |
|
|
// Initialize |
648 |
✓✓ |
172 |
for(i = 0; i < (1 << (bits + stereo)); i++) { |
649 |
|
|
HuffContext h; |
650 |
|
86 |
h.current = 0; |
651 |
|
86 |
skip_bits1(&gb); |
652 |
✗✓ |
86 |
if ((ret = smacker_decode_tree(&gb, &h, 0)) < 0) |
653 |
|
|
goto error; |
654 |
|
86 |
skip_bits1(&gb); |
655 |
✓✓ |
86 |
if (h.current > 1) { |
656 |
|
80 |
ret = ff_init_vlc_from_lengths(&vlc[i], SMKTREE_BITS, h.current, |
657 |
|
|
&h.entries[0].length, sizeof(*h.entries), |
658 |
|
|
&h.entries[0].value, sizeof(*h.entries), 1, |
659 |
|
|
0, INIT_VLC_OUTPUT_LE, avctx); |
660 |
✗✓ |
80 |
if (ret < 0) { |
661 |
|
|
av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n"); |
662 |
|
|
goto error; |
663 |
|
|
} |
664 |
|
|
} else |
665 |
|
6 |
values[i] = h.entries[0].value; |
666 |
|
|
} |
667 |
|
|
/* this codec relies on wraparound instead of clipping audio */ |
668 |
✗✓ |
86 |
if(bits) { //decode 16-bit data |
669 |
|
|
for(i = stereo; i >= 0; i--) |
670 |
|
|
pred[i] = av_bswap16(get_bits(&gb, 16)); |
671 |
|
|
for(i = 0; i <= stereo; i++) |
672 |
|
|
*samples++ = pred[i]; |
673 |
|
|
for(; i < unp_size / 2; i++) { |
674 |
|
|
unsigned idx = 2 * (i & stereo); |
675 |
|
|
if (get_bits_left(&gb) < 0) { |
676 |
|
|
ret = AVERROR_INVALIDDATA; |
677 |
|
|
goto error; |
678 |
|
|
} |
679 |
|
|
if (vlc[idx].table) |
680 |
|
|
res = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3); |
681 |
|
|
else |
682 |
|
|
res = values[idx]; |
683 |
|
|
val = res; |
684 |
|
|
if (vlc[++idx].table) |
685 |
|
|
res = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3); |
686 |
|
|
else |
687 |
|
|
res = values[idx]; |
688 |
|
|
val |= res << 8; |
689 |
|
|
pred[idx / 2] += val; |
690 |
|
|
*samples++ = pred[idx / 2]; |
691 |
|
|
} |
692 |
|
|
} else { //8-bit data |
693 |
✓✓ |
172 |
for(i = stereo; i >= 0; i--) |
694 |
|
86 |
pred[i] = get_bits(&gb, 8); |
695 |
✓✓ |
172 |
for(i = 0; i <= stereo; i++) |
696 |
|
86 |
*samples8++ = pred[i]; |
697 |
✓✓ |
156552 |
for(; i < unp_size; i++) { |
698 |
|
156466 |
unsigned idx = i & stereo; |
699 |
✗✓ |
156466 |
if (get_bits_left(&gb) < 0) { |
700 |
|
|
ret = AVERROR_INVALIDDATA; |
701 |
|
|
goto error; |
702 |
|
|
} |
703 |
✓✓ |
156466 |
if (vlc[idx].table) |
704 |
|
147216 |
val = get_vlc2(&gb, vlc[idx].table, SMKTREE_BITS, 3); |
705 |
|
|
else |
706 |
|
9250 |
val = values[idx]; |
707 |
|
156466 |
pred[idx] += val; |
708 |
|
156466 |
*samples8++ = pred[idx]; |
709 |
|
|
} |
710 |
|
|
} |
711 |
|
|
|
712 |
|
86 |
*got_frame_ptr = 1; |
713 |
|
86 |
ret = buf_size; |
714 |
|
|
|
715 |
|
86 |
error: |
716 |
✓✓ |
430 |
for(i = 0; i < 4; i++) { |
717 |
|
344 |
ff_free_vlc(&vlc[i]); |
718 |
|
|
} |
719 |
|
|
|
720 |
|
86 |
return ret; |
721 |
|
|
} |
722 |
|
|
|
723 |
|
|
AVCodec ff_smacker_decoder = { |
724 |
|
|
.name = "smackvid", |
725 |
|
|
.long_name = NULL_IF_CONFIG_SMALL("Smacker video"), |
726 |
|
|
.type = AVMEDIA_TYPE_VIDEO, |
727 |
|
|
.id = AV_CODEC_ID_SMACKVIDEO, |
728 |
|
|
.priv_data_size = sizeof(SmackVContext), |
729 |
|
|
.init = decode_init, |
730 |
|
|
.close = decode_end, |
731 |
|
|
.decode = decode_frame, |
732 |
|
|
.capabilities = AV_CODEC_CAP_DR1, |
733 |
|
|
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, |
734 |
|
|
}; |
735 |
|
|
|
736 |
|
|
AVCodec ff_smackaud_decoder = { |
737 |
|
|
.name = "smackaud", |
738 |
|
|
.long_name = NULL_IF_CONFIG_SMALL("Smacker audio"), |
739 |
|
|
.type = AVMEDIA_TYPE_AUDIO, |
740 |
|
|
.id = AV_CODEC_ID_SMACKAUDIO, |
741 |
|
|
.init = smka_decode_init, |
742 |
|
|
.decode = smka_decode_frame, |
743 |
|
|
.capabilities = AV_CODEC_CAP_DR1, |
744 |
|
|
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, |
745 |
|
|
}; |