1 /*
2 * Smacker demuxer
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 * Based on http://wiki.multimedia.cx/index.php?title=Smacker
24 */
25
26 #include <inttypes.h>
27
33
34 #define SMACKER_PAL 0x01
35 #define SMACKER_FLAG_RING_FRAME 0x01
36
43 };
44
46 /* Smacker file header */
58 /* frame info */
61 /* internal variables */
65 /* current frame for demuxing */
76
81
82 /* palette used in Smacker */
84 0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x18, 0x1C,
85 0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C,
86 0x41, 0x45, 0x49, 0x4D, 0x51, 0x55, 0x59, 0x5D,
87 0x61, 0x65, 0x69, 0x6D, 0x71, 0x75, 0x79, 0x7D,
88 0x82, 0x86, 0x8A, 0x8E, 0x92, 0x96, 0x9A, 0x9E,
89 0xA2, 0xA6, 0xAA, 0xAE, 0xB2, 0xB6, 0xBA, 0xBE,
90 0xC3, 0xC7, 0xCB, 0xCF, 0xD3, 0xD7, 0xDB, 0xDF,
91 0xE3, 0xE7, 0xEB, 0xEF, 0xF3, 0xF7, 0xFB, 0xFF
92 };
93
94
96 {
99 return 0;
100
103
105 }
106
108 {
113 int tbase;
114
115 /* read and check header */
126 for(i = 0; i < 7; i++)
129
130 if(smk->
treesize >= UINT_MAX/4){
// smk->treesize + 16 must not overflow (this check is probably redundant)
133 }
134
135 //FIXME remove extradata "rebuilding"
140 for(i = 0; i < 7; i++) {
143 }
145 /* setup data */
146 if(smk->
frames > 0xFFFFFF) {
149 }
156 }
157
159
160 /* read frame info */
161 for(i = 0; i < smk->
frames; i++) {
163 }
164 for(i = 0; i < smk->
frames; i++) {
166 }
167
168 /* init video codec */
170 if (!st)
179 /* Smacker uses 100000 as internal timebase */
182 else
184 tbase = 100000;
188 /* handle possible audio streams */
189 for(i = 0; i < 7; i++) {
193 if (!ast[i])
204 } else {
206 }
210 } else {
213 }
220 }
221 }
222
223
224 /* load trees to extradata, they will be unpacked by decoder */
227 "Cannot allocate %"PRIu32" bytes of extradata\n",
232 }
238 }
243
246
247 return 0;
248 }
249
250
252 {
256 int i;
258 int palchange = 0;
259
262
263 /* if we demuxed all streams, pass another frame */
268 /* handle palette change event */
270 int size, sz, t, off, j, pos;
273
274 memcpy(oldpal, pal, 768);
276 size = size * 4 - 1;
277 if(size + 1 > frame_size)
280 frame_size--;
281 sz = 0;
283 while(sz < 256){
285 if(t & 0x80){ /* skip palette entries */
286 sz += (t & 0x7F) + 1;
287 pal += ((t & 0x7F) + 1) * 3;
288 } else if(t & 0x40){ /* copy with offset */
290 j = (t & 0x3F) + 1;
291 if (off + j > 0x100) {
293 "Invalid palette update, offset=%d length=%d extends beyond palette size\n",
294 off, j);
296 }
297 off *= 3;
298 while(j-- && sz < 256) {
299 *pal++ = oldpal[off + 0];
300 *pal++ = oldpal[off + 1];
301 *pal++ = oldpal[off + 2];
302 sz++;
303 off += 3;
304 }
305 } else { /* new entries */
309 sz++;
310 }
311 }
313 palchange |= 1;
314 }
315 flags >>= 1;
317 /* if audio chunks are present, put them to stack and retrieve later */
318 for(i = 0; i < 7; i++) {
319 if(flags & 1) {
321 int err;
322
324 if (!size || size + 4LL > frame_size) {
327 }
329 frame_size -= 4;
333 return err;
334 }
337 if(ret != size)
340 }
341 flags >>= 1;
342 }
343 if (frame_size < 0 || frame_size >= INT_MAX/2)
348 palchange |= 2;
349 pkt->
data[0] = palchange;
350 memcpy(pkt->
data + 1, smk->
pal, 768);
352 if(ret != frame_size)
356 pkt->
size = ret + 769;
359 } else {
370 }
371
372 return 0;
373 }
374
376 {
378 int i;
379
380 for(i = 0; i < 7; i++)
384
385 return 0;
386 }
387
396 };