Commit 10f865c9 authored by Mike Melanson's avatar Mike Melanson

Another hack to allow the Cinepak decoder to detect both types of deviant Cinepak

data. Tested against both known FILM files, several CPK files, and normal
CVID-encoded files.

Originally committed as revision 7215 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent b40a061f
......@@ -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)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment