@ -191,7 +191,7 @@ int RGBE_ReadHeader(FILE *fp, int *width, int *height, rgbe_header_info *info)
info - > valid | = RGBE_VALID_PROGRAMTYPE ;
for ( i = 0 ; i < static_cast < int > ( sizeof ( info - > programtype ) - 1 ) ; i + + ) {
if ( ( buf [ i + 2 ] = = 0 ) | | isspace ( buf [ i + 2 ] ) )
break ;
break ;
info - > programtype [ i ] = buf [ i + 2 ] ;
}
info - > programtype [ i ] = 0 ;
@ -285,34 +285,37 @@ static int RGBE_WriteBytes_RLE(FILE *fp, unsigned char *data, int numbytes)
run_count = 1 ;
while ( ( beg_run + run_count < numbytes ) & & ( run_count < 127 )
& & ( data [ beg_run ] = = data [ beg_run + run_count ] ) )
run_count + + ;
run_count + + ;
}
/* if data before next big run is a short run then write it as such */
if ( ( old_run_count > 1 ) & & ( old_run_count = = beg_run - cur ) ) {
buf [ 0 ] = static_cast < unsigned char > ( 128 + old_run_count ) ; /*write short run*/
buf [ 1 ] = data [ cur ] ;
if ( fwrite ( buf , sizeof ( buf [ 0 ] ) * 2 , 1 , fp ) < 1 )
return rgbe_error ( rgbe_write_error , NULL ) ;
return rgbe_error ( rgbe_write_error , NULL ) ;
cur = beg_run ;
}
/* write out bytes until we reach the start of the next run */
while ( cur < beg_run ) {
nonrun_count = beg_run - cur ;
if ( nonrun_count > 128 )
nonrun_count = 128 ;
nonrun_count = 128 ;
buf [ 0 ] = static_cast < unsigned char > ( nonrun_count ) ;
if ( fwrite ( buf , sizeof ( buf [ 0 ] ) , 1 , fp ) < 1 )
return rgbe_error ( rgbe_write_error , NULL ) ;
return rgbe_error ( rgbe_write_error , NULL ) ;
if ( fwrite ( & data [ cur ] , sizeof ( data [ 0 ] ) * nonrun_count , 1 , fp ) < 1 )
return rgbe_error ( rgbe_write_error , NULL ) ;
return rgbe_error ( rgbe_write_error , NULL ) ;
cur + = nonrun_count ;
}
/* write out next run if one was found */
if ( run_count > = MINRUNLENGTH ) {
buf [ 0 ] = static_cast < unsigned char > ( 128 + run_count ) ;
buf [ 1 ] = data [ beg_run ] ;
if ( fwrite ( buf , sizeof ( buf [ 0 ] ) * 2 , 1 , fp ) < 1 )
return rgbe_error ( rgbe_write_error , NULL ) ;
return rgbe_error ( rgbe_write_error , NULL ) ;
cur + = run_count ;
}
}
@ -330,19 +333,23 @@ int RGBE_WritePixels_RLE(FILE *fp, float *data, int scanline_width,
if ( ( scanline_width < 8 ) | | ( scanline_width > 0x7fff ) )
/* run length encoding is not allowed so write flat*/
return RGBE_WritePixels ( fp , data , scanline_width * num_scanlines ) ;
buffer = ( unsigned char * ) malloc ( sizeof ( unsigned char ) * 4 * scanline_width ) ;
if ( buffer = = NULL )
/* no buffer space so write flat */
return RGBE_WritePixels ( fp , data , scanline_width * num_scanlines ) ;
while ( num_scanlines - - > 0 ) {
rgbe [ 0 ] = 2 ;
rgbe [ 1 ] = 2 ;
rgbe [ 2 ] = static_cast < unsigned char > ( scanline_width > > 8 ) ;
rgbe [ 3 ] = scanline_width & 0xFF ;
if ( fwrite ( rgbe , sizeof ( rgbe ) , 1 , fp ) < 1 ) {
free ( buffer ) ;
return rgbe_error ( rgbe_write_error , NULL ) ;
}
for ( i = 0 ; i < scanline_width ; i + + ) {
float2rgbe ( rgbe , data [ RGBE_DATA_RED ] ,
data [ RGBE_DATA_GREEN ] , data [ RGBE_DATA_BLUE ] ) ;
@ -352,13 +359,16 @@ int RGBE_WritePixels_RLE(FILE *fp, float *data, int scanline_width,
buffer [ i + 3 * scanline_width ] = rgbe [ 3 ] ;
data + = RGBE_DATA_SIZE ;
}
/* write out each of the four channels separately run length encoded */
/* first red, then green, then blue, then exponent */
for ( i = 0 ; i < 4 ; i + + ) {
for ( i = 0 ; i < 4 ; i + + )
{
if ( ( err = RGBE_WriteBytes_RLE ( fp , & buffer [ i * scanline_width ] ,
scanline_width ) ) ! = RGBE_RETURN_SUCCESS ) {
free ( buffer ) ;
return err ;
scanline_width ) ) ! = RGBE_RETURN_SUCCESS )
{
free ( buffer ) ;
return err ;
}
}
}
@ -376,6 +386,7 @@ int RGBE_ReadPixels_RLE(FILE *fp, float *data, int scanline_width,
if ( ( scanline_width < 8 ) | | ( scanline_width > 0x7fff ) )
/* run length encoding is not allowed so read flat*/
return RGBE_ReadPixels ( fp , data , scanline_width * num_scanlines ) ;
scanline_buffer = NULL ;
/* read in each successive scanline */
while ( num_scanlines > 0 ) {
@ -383,6 +394,7 @@ int RGBE_ReadPixels_RLE(FILE *fp, float *data, int scanline_width,
free ( scanline_buffer ) ;
return rgbe_error ( rgbe_read_error , NULL ) ;
}
if ( ( rgbe [ 0 ] ! = 2 ) | | ( rgbe [ 1 ] ! = 2 ) | | ( rgbe [ 2 ] & 0x80 ) ) {
/* this file is not run length encoded */
rgbe2float ( & data [ RGBE_DATA_RED ] , & data [ RGBE_DATA_GREEN ] , & data [ RGBE_DATA_BLUE ] , rgbe ) ;
@ -390,13 +402,15 @@ int RGBE_ReadPixels_RLE(FILE *fp, float *data, int scanline_width,
free ( scanline_buffer ) ;
return RGBE_ReadPixels ( fp , data , scanline_width * num_scanlines - 1 ) ;
}
if ( ( ( ( int ) rgbe [ 2 ] ) < < 8 | rgbe [ 3 ] ) ! = scanline_width ) {
free ( scanline_buffer ) ;
return rgbe_error ( rgbe_format_error , " wrong scanline width " ) ;
}
if ( scanline_buffer = = NULL )
scanline_buffer = ( unsigned char * )
malloc ( sizeof ( unsigned char ) * 4 * scanline_width ) ;
scanline_buffer = ( unsigned char * ) malloc ( sizeof ( unsigned char ) * 4 * scanline_width ) ;
if ( scanline_buffer = = NULL )
return rgbe_error ( rgbe_memory_error , " unable to allocate buffer space " ) ;
@ -404,47 +418,56 @@ int RGBE_ReadPixels_RLE(FILE *fp, float *data, int scanline_width,
/* read each of the four channels for the scanline into the buffer */
for ( i = 0 ; i < 4 ; i + + ) {
ptr_end = & scanline_buffer [ ( i + 1 ) * scanline_width ] ;
while ( ptr < ptr_end ) {
if ( fread ( buf , sizeof ( buf [ 0 ] ) * 2 , 1 , fp ) < 1 ) {
free ( scanline_buffer ) ;
return rgbe_error ( rgbe_read_error , NULL ) ;
}
if ( buf [ 0 ] > 128 ) {
/* a run of the same value */
count = buf [ 0 ] - 128 ;
if ( ( count = = 0 ) | | ( count > ptr_end - ptr ) ) {
free ( scanline_buffer ) ;
return rgbe_error ( rgbe_format_error , " bad scanline data " ) ;
}
while ( count - - > 0 )
* ptr + + = buf [ 1 ] ;
}
else {
/* a non-run */
count = buf [ 0 ] ;
if ( ( count = = 0 ) | | ( count > ptr_end - ptr ) ) {
free ( scanline_buffer ) ;
return rgbe_error ( rgbe_format_error , " bad scanline data " ) ;
}
* ptr + + = buf [ 1 ] ;
if ( - - count > 0 ) {
if ( fread ( ptr , sizeof ( * ptr ) * count , 1 , fp ) < 1 ) {
free ( scanline_buffer ) ;
return rgbe_error ( rgbe_read_error , NULL ) ;
}
ptr + = count ;
}
}
while ( ptr < ptr_end )
{
if ( fread ( buf , sizeof ( buf [ 0 ] ) * 2 , 1 , fp ) < 1 )
{
free ( scanline_buffer ) ;
return rgbe_error ( rgbe_read_error , NULL ) ;
}
if ( buf [ 0 ] > 128 )
{
/* a run of the same value */
count = buf [ 0 ] - 128 ;
if ( ( count = = 0 ) | | ( count > ptr_end - ptr ) ) {
free ( scanline_buffer ) ;
return rgbe_error ( rgbe_format_error , " bad scanline data " ) ;
}
while ( count - - > 0 )
* ptr + + = buf [ 1 ] ;
}
else
{
/* a non-run */
count = buf [ 0 ] ;
if ( ( count = = 0 ) | | ( count > ptr_end - ptr ) )
{
free ( scanline_buffer ) ;
return rgbe_error ( rgbe_format_error , " bad scanline data " ) ;
}
* ptr + + = buf [ 1 ] ;
if ( - - count > 0 ) {
if ( fread ( ptr , sizeof ( * ptr ) * count , 1 , fp ) < 1 )
{
free ( scanline_buffer ) ;
return rgbe_error ( rgbe_read_error , NULL ) ;
}
ptr + = count ;
}
}
}
}
/* now convert data from buffer into floats */
for ( i = 0 ; i < scanline_width ; i + + ) {
rgbe [ 0 ] = scanline_buffer [ i ] ;
rgbe [ 1 ] = scanline_buffer [ i + scanline_width ] ;
rgbe [ 2 ] = scanline_buffer [ i + 2 * scanline_width ] ;
rgbe [ 3 ] = scanline_buffer [ i + 3 * scanline_width ] ;
rgbe2float ( & data [ RGBE_DATA_RED ] , & data [ RGBE_DATA_GREEN ] ,
& data [ RGBE_DATA_BLUE ] , rgbe ) ;
rgbe2float ( & data [ RGBE_DATA_RED ] , & data [ RGBE_DATA_GREEN ] , & data [ RGBE_DATA_BLUE ] , rgbe ) ;
data + = RGBE_DATA_SIZE ;
}
num_scanlines - - ;