fix possible memleak

litter the code with checkpoints to try to track down osx crash
This commit is contained in:
Glenn Maynard
2004-09-27 01:09:03 +00:00
parent b990c14789
commit 3d81205616
+21 -1
View File
@@ -39,11 +39,20 @@ namespace
{ {
void RageFile_png_read( png_struct *png, png_byte *p, png_size_t size ) void RageFile_png_read( png_struct *png, png_byte *p, png_size_t size )
{ {
CHECKPOINT;
RageFile *f = (RageFile *) png->io_ptr; RageFile *f = (RageFile *) png->io_ptr;
int got = f->Read( p, size ); int got = f->Read( p, size );
if( got == -1 ) if( got == -1 )
png_error( png, f->GetError() ); {
/* png_error will call PNG_Error, which will longjmp. If we just pass
* GetError().c_str() to it, a temporary may be created; since control
* never returns here, it may never be destructed and we could leak. */
static char error[256];
strncpy( error, f->GetError(), sizeof(error) );
error[sizeof(error)-1] = 0;
png_error( png, error );
}
else if( got != (int) size ) else if( got != (int) size )
png_error( png, "Unexpected EOF" ); png_error( png, "Unexpected EOF" );
} }
@@ -56,6 +65,7 @@ struct error_info
void PNG_Error( png_struct *png, const char *error ) void PNG_Error( png_struct *png, const char *error )
{ {
CHECKPOINT;
error_info *info = (error_info *) png->error_ptr; error_info *info = (error_info *) png->error_ptr;
strncpy( info->err, error, 1024 ); strncpy( info->err, error, 1024 );
info->err[1023] = 0; info->err[1023] = 0;
@@ -65,6 +75,7 @@ void PNG_Error( png_struct *png, const char *error )
void PNG_Warning( png_struct *png, const char *warning ) void PNG_Warning( png_struct *png, const char *warning )
{ {
CHECKPOINT;
error_info *info = (error_info *) png->error_ptr; error_info *info = (error_info *) png->error_ptr;
LOG->Trace( "loading \"%s\": warning: %s", info->fn, warning ); LOG->Trace( "loading \"%s\": warning: %s", info->fn, warning );
} }
@@ -93,12 +104,14 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro
} }
RageSurface *volatile img = NULL; RageSurface *volatile img = NULL;
CHECKPOINT;
if( setjmp(png_jmpbuf(png)) ) if( setjmp(png_jmpbuf(png)) )
{ {
png_destroy_read_struct( &png, &info_ptr, NULL ); png_destroy_read_struct( &png, &info_ptr, NULL );
delete img; delete img;
return NULL; return NULL;
} }
CHECKPOINT;
png_set_read_fn( png, f, RageFile_png_read ); png_set_read_fn( png, f, RageFile_png_read );
@@ -112,6 +125,7 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro
* the image. Just return an empty surface with only the width and height set. */ * the image. Just return an empty surface with only the width and height set. */
if( bHeaderOnly ) if( bHeaderOnly )
{ {
CHECKPOINT;
img = CreateSurfaceFrom( width, height, 32, 0, 0, 0, 0, NULL, width*4 ); img = CreateSurfaceFrom( width, height, 32, 0, 0, 0, 0, NULL, width*4 );
png_destroy_read_struct( &png, &info_ptr, NULL ); png_destroy_read_struct( &png, &info_ptr, NULL );
@@ -119,6 +133,7 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro
} }
CHECKPOINT;
png_set_strip_16(png); /* 16bit->8bit */ png_set_strip_16(png); /* 16bit->8bit */
png_set_packing( png ); /* 1,2,4 bit->8 bit */ png_set_packing( png ); /* 1,2,4 bit->8 bit */
@@ -168,6 +183,7 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro
FAIL_M(ssprintf( "%i", color_type) ); FAIL_M(ssprintf( "%i", color_type) );
} }
CHECKPOINT;
if( color_type == PNG_COLOR_TYPE_GRAY ) if( color_type == PNG_COLOR_TYPE_GRAY )
{ {
png_color_16 *trans; png_color_16 *trans;
@@ -211,6 +227,7 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro
png_set_interlace_handling( png ); png_set_interlace_handling( png );
CHECKPOINT;
png_read_update_info( png, info_ptr ); png_read_update_info( png, info_ptr );
switch( type ) switch( type )
@@ -238,6 +255,7 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro
/* alloca to prevent memleaks if libpng longjmps us */ /* alloca to prevent memleaks if libpng longjmps us */
png_byte **row_pointers = (png_byte **) alloca( sizeof(png_byte*) * height ); png_byte **row_pointers = (png_byte **) alloca( sizeof(png_byte*) * height );
CHECKPOINT_M( ssprintf("%p",row_pointers) );
for( unsigned y = 0; y < height; ++y ) for( unsigned y = 0; y < height; ++y )
{ {
@@ -245,8 +263,10 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro
row_pointers[y] = p + img->pitch*y; row_pointers[y] = p + img->pitch*y;
} }
CHECKPOINT;
png_read_image( png, row_pointers ); png_read_image( png, row_pointers );
CHECKPOINT;
png_read_end( png, info_ptr ); png_read_end( png, info_ptr );
png_destroy_read_struct( &png, &info_ptr, NULL ); png_destroy_read_struct( &png, &info_ptr, NULL );