@ -26,6 +26,8 @@
* by Ewald Snel < ewald @ rambo . its . tudelft . nl >
* by Ewald Snel < ewald @ rambo . its . tudelft . nl >
* For more information on the Cinepak algorithm , visit :
* For more information on the Cinepak algorithm , visit :
* http : //www.csse.monash.edu.au/~timf/
* 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>
# include <stdio.h>
@ -67,6 +69,8 @@ typedef struct CinepakContext {
int palette_video ;
int palette_video ;
cvid_strip_t strips [ MAX_STRIPS ] ;
cvid_strip_t strips [ MAX_STRIPS ] ;
int sega_film_skip_bytes ;
} CinepakContext ;
} CinepakContext ;
static void cinepak_decode_codebook ( cvid_codebook_t * codebook ,
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 i , result , strip_size , frame_flags , num_strips ;
int y0 = 0 ;
int y0 = 0 ;
int encoded_buf_size ;
int encoded_buf_size ;
/* if true, Cinepak data is from a Sega FILM/CPK file */
int sega_film_data = 0 ;
if ( s - > size < 10 )
if ( s - > size < 10 )
return - 1 ;
return - 1 ;
@ -328,12 +330,29 @@ static int cinepak_decode (CinepakContext *s)
frame_flags = s - > data [ 0 ] ;
frame_flags = s - > data [ 0 ] ;
num_strips = BE_16 ( & s - > data [ 8 ] ) ;
num_strips = BE_16 ( & s - > data [ 8 ] ) ;
encoded_buf_size = ( ( s - > data [ 1 ] < < 16 ) | BE_16 ( & s - > data [ 2 ] ) ) ;
encoded_buf_size = ( ( s - > data [ 1 ] < < 16 ) | BE_16 ( & s - > data [ 2 ] ) ) ;
if ( encoded_buf_size ! = s - > size )
sega_film_data = 1 ;
/* if this is the first frame, check for deviant Sega FILM data */
if ( sega_film_data )
if ( s - > sega_film_skip_bytes = = - 1 ) {
s - > data + = 12 ;
if ( encoded_buf_size ! = s - > size ) {
else
/* If the encoded frame size differs from the frame size as indicated
s - > data + = 10 ;
* 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 )
if ( num_strips > MAX_STRIPS )
num_strips = MAX_STRIPS ;
num_strips = MAX_STRIPS ;
@ -377,6 +396,7 @@ static int cinepak_decode_init(AVCodecContext *avctx)
s - > avctx = avctx ;
s - > avctx = avctx ;
s - > width = ( avctx - > width + 3 ) & ~ 3 ;
s - > width = ( avctx - > width + 3 ) & ~ 3 ;
s - > height = ( avctx - > height + 3 ) & ~ 3 ;
s - > height = ( avctx - > height + 3 ) & ~ 3 ;
s - > sega_film_skip_bytes = - 1 ; /* uninitialized state */
// check for paletted data
// check for paletted data
if ( ( avctx - > palctrl = = NULL ) | | ( avctx - > bits_per_sample = = 40 ) ) {
if ( ( avctx - > palctrl = = NULL ) | | ( avctx - > bits_per_sample = = 40 ) ) {