|
|
|
@@ -26,6 +26,8 @@ |
|
|
|
* by Ewald Snel <ewald@rambo.its.tudelft.nl> |
|
|
|
* For more information on the Cinepak algorithm, visit: |
|
|
|
* http://www.csse.monash.edu.au/~timf/ |
|
|
|
* For more information on the quirky data inside Sega FILM/CPK files, visit: |
|
|
|
* http://wiki.multimedia.cx/index.php?title=Sega_FILM |
|
|
|
*/ |
|
|
|
|
|
|
|
#include <stdio.h> |
|
|
|
@@ -67,6 +69,8 @@ typedef struct CinepakContext { |
|
|
|
int palette_video; |
|
|
|
cvid_strip_t strips[MAX_STRIPS]; |
|
|
|
|
|
|
|
int sega_film_skip_bytes; |
|
|
|
|
|
|
|
} CinepakContext; |
|
|
|
|
|
|
|
static void cinepak_decode_codebook (cvid_codebook_t *codebook, |
|
|
|
@@ -319,8 +323,6 @@ static int cinepak_decode (CinepakContext *s) |
|
|
|
int i, result, strip_size, frame_flags, num_strips; |
|
|
|
int y0 = 0; |
|
|
|
int encoded_buf_size; |
|
|
|
/* if true, Cinepak data is from a Sega FILM/CPK file */ |
|
|
|
int sega_film_data = 0; |
|
|
|
|
|
|
|
if (s->size < 10) |
|
|
|
return -1; |
|
|
|
@@ -328,12 +330,29 @@ static int cinepak_decode (CinepakContext *s) |
|
|
|
frame_flags = s->data[0]; |
|
|
|
num_strips = BE_16 (&s->data[8]); |
|
|
|
encoded_buf_size = ((s->data[1] << 16) | BE_16 (&s->data[2])); |
|
|
|
if (encoded_buf_size != s->size) |
|
|
|
sega_film_data = 1; |
|
|
|
if (sega_film_data) |
|
|
|
s->data += 12; |
|
|
|
else |
|
|
|
s->data += 10; |
|
|
|
|
|
|
|
/* if this is the first frame, check for deviant Sega FILM data */ |
|
|
|
if (s->sega_film_skip_bytes == -1) { |
|
|
|
if (encoded_buf_size != s->size) { |
|
|
|
/* If the encoded frame size differs from the frame size as indicated |
|
|
|
* by the container file, this data likely comes from a Sega FILM/CPK file. |
|
|
|
* If the frame header is followed by the bytes FE 00 00 06 00 00 then |
|
|
|
* this is probably one of the two known files that have 6 extra bytes |
|
|
|
* after the frame header. Else, assume 2 extra bytes. */ |
|
|
|
if ((s->data[10] == 0xFE) && |
|
|
|
(s->data[11] == 0x00) && |
|
|
|
(s->data[12] == 0x00) && |
|
|
|
(s->data[13] == 0x06) && |
|
|
|
(s->data[14] == 0x00) && |
|
|
|
(s->data[15] == 0x00)) |
|
|
|
s->sega_film_skip_bytes = 6; |
|
|
|
else |
|
|
|
s->sega_film_skip_bytes = 2; |
|
|
|
} else |
|
|
|
s->sega_film_skip_bytes = 0; |
|
|
|
} |
|
|
|
|
|
|
|
s->data += 10 + s->sega_film_skip_bytes; |
|
|
|
|
|
|
|
if (num_strips > MAX_STRIPS) |
|
|
|
num_strips = MAX_STRIPS; |
|
|
|
@@ -377,6 +396,7 @@ static int cinepak_decode_init(AVCodecContext *avctx) |
|
|
|
s->avctx = avctx; |
|
|
|
s->width = (avctx->width + 3) & ~3; |
|
|
|
s->height = (avctx->height + 3) & ~3; |
|
|
|
s->sega_film_skip_bytes = -1; /* uninitialized state */ |
|
|
|
|
|
|
|
// check for paletted data |
|
|
|
if ((avctx->palctrl == NULL) || (avctx->bits_per_sample == 40)) { |
|
|
|
|