@ -54,6 +54,7 @@ typedef struct PGSSubPicture {
int h ;
int h ;
uint8_t * rle ;
uint8_t * rle ;
unsigned int rle_buffer_size , rle_data_len ;
unsigned int rle_buffer_size , rle_data_len ;
unsigned int rle_remaining_len ;
} PGSSubPicture ;
} PGSSubPicture ;
typedef struct PGSSubContext {
typedef struct PGSSubContext {
@ -159,6 +160,10 @@ static int parse_picture_segment(AVCodecContext *avctx,
uint8_t sequence_desc ;
uint8_t sequence_desc ;
unsigned int rle_bitmap_len , width , height ;
unsigned int rle_bitmap_len , width , height ;
if ( buf_size < = 4 )
return - 1 ;
buf_size - = 4 ;
/* skip 3 unknown bytes: Object ID (2 bytes), Version Number */
/* skip 3 unknown bytes: Object ID (2 bytes), Version Number */
buf + = 3 ;
buf + = 3 ;
@ -166,20 +171,22 @@ static int parse_picture_segment(AVCodecContext *avctx,
sequence_desc = bytestream_get_byte ( & buf ) ;
sequence_desc = bytestream_get_byte ( & buf ) ;
if ( ! ( sequence_desc & 0x80 ) ) {
if ( ! ( sequence_desc & 0x80 ) ) {
av_log ( avctx , AV_LOG_ERROR , " Decoder does not support object data over multiple packets. \n " ) ;
/* Additional RLE data */
return - 1 ;
if ( buf_size > ctx - > picture . rle_remaining_len )
}
return - 1 ;
/* Decode rle bitmap length */
memcpy ( ctx - > picture . rle + ctx - > picture . rle_data_len , buf , buf_size ) ;
rle_bitmap_len = bytestream_get_be24 ( & buf ) ;
ctx - > picture . rle_data_len + = buf_size ;
/* Check to ensure we have enough data for rle_bitmap_length if just a single packet */
return 0 ;
if ( rle_bitmap_len > buf_size - 7 ) {
av_log ( avctx , AV_LOG_ERROR , " Not enough RLE data for specified length of %d. \n " , rle_bitmap_len ) ;
return - 1 ;
}
}
ctx - > picture . rle_data_len = rle_bitmap_len ;
if ( buf_size < = 7 )
return - 1 ;
buf_size - = 7 ;
/* Decode rle bitmap length, stored size includes width/height data */
rle_bitmap_len = bytestream_get_be24 ( & buf ) - 2 * 2 ;
/* Get bitmap dimensions from data */
/* Get bitmap dimensions from data */
width = bytestream_get_be16 ( & buf ) ;
width = bytestream_get_be16 ( & buf ) ;
@ -199,7 +206,9 @@ static int parse_picture_segment(AVCodecContext *avctx,
if ( ! ctx - > picture . rle )
if ( ! ctx - > picture . rle )
return - 1 ;
return - 1 ;
memcpy ( ctx - > picture . rle , buf , rle_bitmap_len ) ;
memcpy ( ctx - > picture . rle , buf , buf_size ) ;
ctx - > picture . rle_data_len = buf_size ;
ctx - > picture . rle_remaining_len = rle_bitmap_len - buf_size ;
return 0 ;
return 0 ;
}
}
@ -364,10 +373,13 @@ static int display_end_segment(AVCodecContext *avctx, void *data,
/* Process bitmap */
/* Process bitmap */
sub - > rects [ 0 ] - > pict . linesize [ 0 ] = ctx - > picture . w ;
sub - > rects [ 0 ] - > pict . linesize [ 0 ] = ctx - > picture . w ;
if ( ctx - > picture . rle )
if ( ctx - > picture . rle ) {
if ( ctx - > picture . rle_remaining_len )
av_log ( avctx , AV_LOG_ERROR , " RLE data length %u is %u bytes shorter than expected \n " ,
ctx - > picture . rle_data_len , ctx - > picture . rle_remaining_len ) ;
if ( decode_rle ( avctx , sub , ctx - > picture . rle , ctx - > picture . rle_data_len ) < 0 )
if ( decode_rle ( avctx , sub , ctx - > picture . rle , ctx - > picture . rle_data_len ) < 0 )
return 0 ;
return 0 ;
}
/* Allocate memory for colors */
/* Allocate memory for colors */
sub - > rects [ 0 ] - > nb_colors = 256 ;
sub - > rects [ 0 ] - > nb_colors = 256 ;
sub - > rects [ 0 ] - > pict . data [ 1 ] = av_mallocz ( AVPALETTE_SIZE ) ;
sub - > rects [ 0 ] - > pict . data [ 1 ] = av_mallocz ( AVPALETTE_SIZE ) ;