@ -77,9 +77,9 @@ static int decode_frame(AVCodecContext *avctx,
unsigned int offset ;
int magic_num , endian ;
int x , y , i , ret ;
int w , h , bits_per_color , descriptor , elements , packing , total_size ;
int encoding ;
int x , y , stride , i , ret ;
int w , h , bits_per_color , descriptor , elements , packing ;
int encoding , need_align = 0 ;
unsigned int rgbBuffer = 0 ;
int n_datum = 0 ;
@ -185,24 +185,24 @@ static int decode_frame(AVCodecContext *avctx,
switch ( bits_per_color ) {
case 8 :
total_siz e = avctx - > width * avctx - > height * elements ;
strid e = avctx - > width * elements ;
break ;
case 10 :
if ( ! packing ) {
av_log ( avctx , AV_LOG_ERROR , " Packing to 32bit required \n " ) ;
return - 1 ;
}
total_siz e = ( avctx - > width * elements + 2 ) / 3 * 4 * avctx - > height ;
strid e = ( avctx - > width * elements + 2 ) / 3 * 4 ;
break ;
case 12 :
if ( ! packing ) {
av_log ( avctx , AV_LOG_ERROR , " Packing to 16bit required \n " ) ;
return - 1 ;
}
total_siz e = 2 * avctx - > width * avctx - > height * elements ;
strid e = 2 * avctx - > width * elements ;
break ;
case 16 :
total_siz e = 2 * avctx - > width * avctx - > height * elements ;
strid e = 2 * avctx - > width * elements ;
break ;
case 1 :
case 32 :
@ -213,6 +213,26 @@ static int decode_frame(AVCodecContext *avctx,
return AVERROR_INVALIDDATA ;
}
// Table 3c: Runs will always break at scan line boundaries. Packing
// will always break to the next 32-bit word at scan-line boundaries.
// Unfortunately, the encoder produced invalid files, so attempt
// to detect it
need_align = FFALIGN ( stride , 4 ) ;
if ( need_align * avctx - > height + ( int64_t ) offset > avpkt - > size ) {
// Alignment seems unappliable, try without
if ( stride * avctx - > height + ( int64_t ) offset > avpkt - > size ) {
av_log ( avctx , AV_LOG_ERROR , " Overread buffer. Invalid header? \n " ) ;
return AVERROR_INVALIDDATA ;
} else {
av_log ( avctx , AV_LOG_INFO , " Decoding DPX without scanline "
" alignment. \n " ) ;
need_align = 0 ;
}
} else {
need_align - = stride ;
stride = FFALIGN ( stride , 4 ) ;
}
switch ( 1000 * descriptor + 10 * bits_per_color + endian ) {
case 6081 :
case 6080 :
@ -276,10 +296,6 @@ static int decode_frame(AVCodecContext *avctx,
for ( i = 0 ; i < AV_NUM_DATA_POINTERS ; i + + )
ptr [ i ] = p - > data [ i ] ;
if ( total_size + ( int64_t ) offset > avpkt - > size ) {
av_log ( avctx , AV_LOG_ERROR , " Overread buffer. Invalid header? \n " ) ;
return AVERROR_INVALIDDATA ;
}
switch ( bits_per_color ) {
case 10 :
for ( x = 0 ; x < avctx - > height ; x + + ) {
@ -318,6 +334,8 @@ static int decode_frame(AVCodecContext *avctx,
// For 12 bit, ignore alpha
if ( elements = = 4 )
buf + = 2 ;
// Jump to next aligned position
buf + = need_align ;
}
for ( i = 0 ; i < 3 ; i + + )
ptr [ i ] + = p - > linesize [ i ] ;
@ -327,7 +345,7 @@ static int decode_frame(AVCodecContext *avctx,
elements * = 2 ;
case 8 :
av_image_copy_plane ( ptr [ 0 ] , p - > linesize [ 0 ] ,
buf , elements * avctx - > width ,
buf , stride ,
elements * avctx - > width , avctx - > height ) ;
break ;
}