From 703ebfca587e40afd6d4ed189476c17fcb614274 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Wed, 19 May 2004 05:10:23 +0000 Subject: [PATCH] LoadFile( bHeaderOnly ): only load image dimensions caching TM4: 37 secs -> 28 secs only implemented for PNG; 90% of song images are PNG anyway --- stepmania/src/RageSurface_Load.cpp | 4 ++-- stepmania/src/RageSurface_Load.h | 4 +++- stepmania/src/RageSurface_Load_PNG.cpp | 26 +++++++++++++++++++++----- stepmania/src/RageSurface_Load_PNG.h | 2 +- stepmania/src/Song.cpp | 3 ++- 5 files changed, 29 insertions(+), 10 deletions(-) diff --git a/stepmania/src/RageSurface_Load.cpp b/stepmania/src/RageSurface_Load.cpp index 2031f4123d..4667f0b795 100644 --- a/stepmania/src/RageSurface_Load.cpp +++ b/stepmania/src/RageSurface_Load.cpp @@ -6,14 +6,14 @@ #include "RageUtil.h" #include "RageFile.h" -SDL_Surface *RageSurface::LoadFile( const CString &sPath ) +SDL_Surface *RageSurface::LoadFile( const CString &sPath, bool bHeaderOnly ) { const CString ext = GetExtension( sPath ); CString error; SDL_Surface *ret = NULL; if( !ext.CompareNoCase("png") ) - ret = RageSurface_Load_PNG( sPath, error ); + ret = RageSurface_Load_PNG( sPath, bHeaderOnly, error ); else if( !ext.CompareNoCase("gif") ) ret = RageSurface_Load_GIF( sPath, error ); else if( !ext.CompareNoCase("jpg") ) diff --git a/stepmania/src/RageSurface_Load.h b/stepmania/src/RageSurface_Load.h index 682097bddd..30622e4e65 100644 --- a/stepmania/src/RageSurface_Load.h +++ b/stepmania/src/RageSurface_Load.h @@ -4,7 +4,9 @@ struct SDL_Surface; namespace RageSurface { - SDL_Surface *LoadFile( const CString &sPath ); + /* If bHeaderOnly is true, the loader is only required to return a surface + * with the width and height set (but may return a complete surface). */ + SDL_Surface *LoadFile( const CString &sPath, bool bHeaderOnly=false ); } #endif diff --git a/stepmania/src/RageSurface_Load_PNG.cpp b/stepmania/src/RageSurface_Load_PNG.cpp index d0372247d7..48d8187048 100644 --- a/stepmania/src/RageSurface_Load_PNG.cpp +++ b/stepmania/src/RageSurface_Load_PNG.cpp @@ -52,7 +52,7 @@ static void PNG_Warning( png_struct *png, const char *warning ) /* Since libpng forces us to use longjmp (gross!), this function shouldn't create any C++ * objects, and needs to watch out for memleaks. */ -static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char errorbuf[1024] ) +static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char errorbuf[1024], bool bHeaderOnly ) { error_info error; error.err = errorbuf; @@ -76,7 +76,7 @@ static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro SDL_Surface *volatile img = NULL; if( setjmp(png_jmpbuf(png)) ) { - png_destroy_read_struct( &png, &info_ptr, png_infopp_NULL ); + png_destroy_read_struct( &png, &info_ptr, NULL ); if( img ) SDL_FreeSurface( img ); return NULL; @@ -90,6 +90,22 @@ static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro int bit_depth, color_type; png_get_IHDR( png, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL ); + /* If bHeaderOnly is true, don't allocate the pixel storage space or decompress + * the image. Just return an empty surface with only the width and height set. */ + if( bHeaderOnly ) + { + img = SDL_CreateRGBSurfaceFrom( SDL_SWSURFACE, width, height, 32, 0, 0, 0, 0, NULL ); + png_destroy_read_struct( &png, &info_ptr, NULL ); + if( !img ) + { + strcpy( errorbuf, SDL_GetError() ); + return NULL; + } + + return img; + } + + png_set_strip_16(png); /* 16bit->8bit */ png_set_packing( png ); /* 1,2,4 bit->8 bit */ @@ -206,13 +222,13 @@ static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro png_read_row( png, pixels + img->pitch*y, NULL ); png_read_end( png, info_ptr ); - png_destroy_read_struct( &png, &info_ptr, png_infopp_NULL ); + png_destroy_read_struct( &png, &info_ptr, NULL ); return img; } -SDL_Surface *RageSurface_Load_PNG( const CString &sPath, CString &error ) +SDL_Surface *RageSurface_Load_PNG( const CString &sPath, bool bHeaderOnly, CString &error ) { RageFile f; if( !f.Open( sPath ) ) @@ -222,7 +238,7 @@ SDL_Surface *RageSurface_Load_PNG( const CString &sPath, CString &error ) } char errorbuf[1024]; - SDL_Surface *ret = RageSurface_Load_PNG( &f, sPath, errorbuf ); + SDL_Surface *ret = RageSurface_Load_PNG( &f, sPath, errorbuf, bHeaderOnly ); if( ret == NULL ) { error = errorbuf; diff --git a/stepmania/src/RageSurface_Load_PNG.h b/stepmania/src/RageSurface_Load_PNG.h index 646055e147..dc3d006771 100644 --- a/stepmania/src/RageSurface_Load_PNG.h +++ b/stepmania/src/RageSurface_Load_PNG.h @@ -3,7 +3,7 @@ #include "SDL_utils.h" -SDL_Surface *RageSurface_Load_PNG( const CString &sPath, CString &error ); +SDL_Surface *RageSurface_Load_PNG( const CString &sPath, bool bHeaderOnly, CString &error ); #endif diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index ed2d1b1c07..4e696ad4c9 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -684,7 +684,8 @@ void Song::TidyUpData() continue; // skip CString sPath = m_sSongDir + arrayImages[i]; - SDL_Surface *img = RageSurface::LoadFile( sPath ); + /* We only care about the dimensions. */ + SDL_Surface *img = RageSurface::LoadFile( sPath, true ); if( !img ) { LOG->Trace("Couldn't load '%s': %s", sPath.c_str(), SDL_GetError());