LoadFile( bHeaderOnly ): only load image dimensions

caching TM4: 37 secs -> 28 secs
only implemented for PNG; 90% of song images are PNG anyway
This commit is contained in:
Glenn Maynard
2004-05-19 05:10:23 +00:00
parent 792cecd972
commit 703ebfca58
5 changed files with 29 additions and 10 deletions
+2 -2
View File
@@ -6,14 +6,14 @@
#include "RageUtil.h" #include "RageUtil.h"
#include "RageFile.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 ); const CString ext = GetExtension( sPath );
CString error; CString error;
SDL_Surface *ret = NULL; SDL_Surface *ret = NULL;
if( !ext.CompareNoCase("png") ) if( !ext.CompareNoCase("png") )
ret = RageSurface_Load_PNG( sPath, error ); ret = RageSurface_Load_PNG( sPath, bHeaderOnly, error );
else if( !ext.CompareNoCase("gif") ) else if( !ext.CompareNoCase("gif") )
ret = RageSurface_Load_GIF( sPath, error ); ret = RageSurface_Load_GIF( sPath, error );
else if( !ext.CompareNoCase("jpg") ) else if( !ext.CompareNoCase("jpg") )
+3 -1
View File
@@ -4,7 +4,9 @@
struct SDL_Surface; struct SDL_Surface;
namespace RageSurface 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 #endif
+21 -5
View File
@@ -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++ /* Since libpng forces us to use longjmp (gross!), this function shouldn't create any C++
* objects, and needs to watch out for memleaks. */ * 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_info error;
error.err = errorbuf; 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; SDL_Surface *volatile img = NULL;
if( setjmp(png_jmpbuf(png)) ) 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 ) if( img )
SDL_FreeSurface( img ); SDL_FreeSurface( img );
return NULL; return NULL;
@@ -90,6 +90,22 @@ static SDL_Surface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro
int bit_depth, color_type; int bit_depth, color_type;
png_get_IHDR( png, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL ); 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_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 */
@@ -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_row( png, pixels + img->pitch*y, NULL );
png_read_end( png, info_ptr ); 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; 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; RageFile f;
if( !f.Open( sPath ) ) if( !f.Open( sPath ) )
@@ -222,7 +238,7 @@ SDL_Surface *RageSurface_Load_PNG( const CString &sPath, CString &error )
} }
char errorbuf[1024]; 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 ) if( ret == NULL )
{ {
error = errorbuf; error = errorbuf;
+1 -1
View File
@@ -3,7 +3,7 @@
#include "SDL_utils.h" #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 #endif
+2 -1
View File
@@ -684,7 +684,8 @@ void Song::TidyUpData()
continue; // skip continue; // skip
CString sPath = m_sSongDir + arrayImages[i]; 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 ) if( !img )
{ {
LOG->Trace("Couldn't load '%s': %s", sPath.c_str(), SDL_GetError()); LOG->Trace("Couldn't load '%s': %s", sPath.c_str(), SDL_GetError());