diff --git a/stepmania/src/RageSurface_Load_PNG.cpp b/stepmania/src/RageSurface_Load_PNG.cpp index 57b1bfacb5..0216237ca7 100644 --- a/stepmania/src/RageSurface_Load_PNG.cpp +++ b/stepmania/src/RageSurface_Load_PNG.cpp @@ -39,11 +39,20 @@ namespace { void RageFile_png_read( png_struct *png, png_byte *p, png_size_t size ) { + CHECKPOINT; RageFile *f = (RageFile *) png->io_ptr; int got = f->Read( p, size ); 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 ) png_error( png, "Unexpected EOF" ); } @@ -56,6 +65,7 @@ struct error_info void PNG_Error( png_struct *png, const char *error ) { + CHECKPOINT; error_info *info = (error_info *) png->error_ptr; strncpy( info->err, error, 1024 ); 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 ) { + CHECKPOINT; error_info *info = (error_info *) png->error_ptr; 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; + CHECKPOINT; if( setjmp(png_jmpbuf(png)) ) { png_destroy_read_struct( &png, &info_ptr, NULL ); delete img; return NULL; } + CHECKPOINT; 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. */ if( bHeaderOnly ) { + CHECKPOINT; img = CreateSurfaceFrom( width, height, 32, 0, 0, 0, 0, NULL, width*4 ); 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_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) ); } + CHECKPOINT; if( color_type == PNG_COLOR_TYPE_GRAY ) { 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 ); + CHECKPOINT; png_read_update_info( png, info_ptr ); 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 */ png_byte **row_pointers = (png_byte **) alloca( sizeof(png_byte*) * height ); + CHECKPOINT_M( ssprintf("%p",row_pointers) ); 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; } + CHECKPOINT; png_read_image( png, row_pointers ); + CHECKPOINT; png_read_end( png, info_ptr ); png_destroy_read_struct( &png, &info_ptr, NULL );