@ -86,9 +86,7 @@ static int read_uncompressed_sgi(const SGIInfo *si,
AVPicture * pict , ByteIOContext * f )
{
int x , y , z , chan_offset , ret = 0 ;
uint8_t * dest_row , * tmp_row = NULL ;
tmp_row = av_malloc ( si - > xsize ) ;
uint8_t * dest_row ;
/* skip header */
url_fseek ( f , SGI_HEADER_SIZE , SEEK_SET ) ;
@ -108,28 +106,23 @@ static int read_uncompressed_sgi(const SGIInfo *si,
for ( y = si - > ysize - 1 ; y > = 0 ; y - - ) {
dest_row = pict - > data [ 0 ] + ( y * si - > xsize * si - > zsize ) ;
if ( ! get_buffer ( f , tmp_row , si - > xsize ) ) {
ret = - 1 ;
goto cleanup ;
}
for ( x = 0 ; x < si - > xsize ; x + + ) {
dest_row [ chan_offset ] = tmp_row [ x ] ;
dest_row [ chan_offset ] = get_byte ( f ) ;
dest_row + = si - > zsize ;
}
}
}
cleanup :
av_free ( tmp_row ) ;
return ret ;
}
/* expand an rle row into a channel */
static void expand_rle_row ( unsigned char * optr , unsigned char * iptr ,
static int expand_rle_row ( ByteIOContext * f , unsigned char * optr ,
int chan_offset , int pixelstride )
{
unsigned char pixel , count ;
int length = 0 ;
# ifndef WORDS_BIGENDIAN
/* rgba -> bgra for rgba32 on little endian cpus */
@ -141,22 +134,23 @@ static void expand_rle_row(unsigned char *optr, unsigned char *iptr,
optr + = chan_offset ;
while ( 1 ) {
pixel = * iptr + + ;
pixel = get_byte ( f ) ;
if ( ! ( count = ( pixel & 0x7f ) ) ) {
return ;
return length ;
}
if ( pixel & 0x80 ) {
while ( count - - ) {
* optr = * iptr ;
* optr = get_byte ( f ) ;
length + + ;
optr + = pixelstride ;
iptr + + ;
}
} else {
pixel = * iptr + + ;
pixel = get_byte ( f ) ;
while ( count - - ) {
* optr = pixel ;
length + + ;
optr + = pixelstride ;
}
}
@ -168,18 +162,16 @@ static void expand_rle_row(unsigned char *optr, unsigned char *iptr,
static int read_rle_sgi ( const SGIInfo * sgi_info ,
AVPicture * pict , ByteIOContext * f )
{
uint8_t * dest_row , * rle_data = NULL ;
unsigned long * start_table , * length_table ;
uint8_t * dest_row ;
unsigned long * start_table ;
int y , z , xsize , ysize , zsize , tablen ;
long start_offset , run_length ;
long start_offset ;
int ret = 0 ;
xsize = sgi_info - > xsize ;
ysize = sgi_info - > ysize ;
zsize = sgi_info - > zsize ;
rle_data = av_malloc ( xsize ) ;
/* skip header */
url_fseek ( f , SGI_HEADER_SIZE , SEEK_SET ) ;
@ -187,40 +179,35 @@ static int read_rle_sgi(const SGIInfo *sgi_info,
tablen = ysize * zsize * sizeof ( long ) ;
start_table = ( unsigned long * ) av_malloc ( tablen ) ;
length_table = ( unsigned long * ) av_malloc ( tablen ) ;
if ( ! get_buffer ( f , ( uint8_t * ) start_table , tablen ) ) {
ret = - 1 ;
ret = AVERROR_IO ;
goto fail ;
}
if ( ! get_buffer ( f , ( uint8_t * ) length_table , tablen ) ) {
ret = - 1 ;
goto fail ;
}
/* skip run length table */
url_fseek ( f , tablen , SEEK_CUR ) ;
for ( z = 0 ; z < zsize ; z + + ) {
for ( y = 0 ; y < ysize ; y + + ) {
dest_row = pict - > data [ 0 ] + ( ysize - 1 - y ) * ( xsize * zsize ) ;
start_offset = BE_32 ( & start_table [ y + z * ysize ] ) ;
run_length = BE_32 ( & length_table [ y + z * ysize ] ) ;
/* don't seek if already in the correct spo t */
/* don't seek if already at the next rle start offse t */
if ( url_ftell ( f ) ! = start_offset ) {
url_fseek ( f , start_offset , SEEK_SET ) ;
}
get_buffer ( f , rle_data , run_length ) ;
expand_rle_row ( dest_row , rle_data , z , zsize ) ;
if ( expand_rle_row ( f , dest_row , z , zsize ) ! = xsize ) {
ret = AVERROR_INVALIDDATA ;
goto fail ;
}
}
}
fail :
av_free ( start_table ) ;
av_free ( length_table ) ;
av_free ( rle_data ) ;
return ret ;
}