mirror of
https://github.com/YGGverse/xash3d-fwgs.git
synced 2025-01-17 18:40:02 +00:00
engine: imagelib: refactor image loading function
This commit is contained in:
parent
eabbd0061f
commit
ccf7619ae5
@ -91,7 +91,7 @@ typedef struct imglib_s
|
||||
// global parms
|
||||
rgba_t fogParams; // some water textures has info about underwater fog
|
||||
|
||||
image_hint_t hint; // hint for some loaders
|
||||
int hint; // hint for some loaders
|
||||
byte *tempbuffer; // for convert operations
|
||||
int cmd_flags; // global imglib flags
|
||||
int force_flags; // override cmd_flags
|
||||
@ -171,7 +171,6 @@ rgbdata_t *Image_Quantize( rgbdata_t *pic );
|
||||
// img_utils.c
|
||||
//
|
||||
void Image_Reset( void );
|
||||
rgbdata_t *ImagePack( void );
|
||||
byte *Image_Copy( size_t size );
|
||||
void Image_CopyParms( rgbdata_t *src );
|
||||
qboolean Image_ValidSize( const char *name );
|
||||
|
@ -110,20 +110,21 @@ void Image_Reset( void )
|
||||
image.size = 0;
|
||||
}
|
||||
|
||||
rgbdata_t *ImagePack( void )
|
||||
static rgbdata_t *ImagePack( void )
|
||||
{
|
||||
rgbdata_t *pack = Mem_Calloc( host.imagepool, sizeof( rgbdata_t ));
|
||||
rgbdata_t *pack;
|
||||
|
||||
// clear any force flags
|
||||
image.force_flags = 0;
|
||||
|
||||
if( image.cubemap && image.num_sides != 6 )
|
||||
{
|
||||
// this never be happens, just in case
|
||||
FS_FreeImage( pack );
|
||||
// this never can happen, just in case
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pack = Mem_Calloc( host.imagepool, sizeof( *pack ));
|
||||
|
||||
if( image.cubemap )
|
||||
{
|
||||
image.flags |= IMAGE_CUBEMAP;
|
||||
@ -163,7 +164,7 @@ FS_AddSideToPack
|
||||
|
||||
================
|
||||
*/
|
||||
qboolean FS_AddSideToPack( const char *name, int adjust_flags )
|
||||
static qboolean FS_AddSideToPack( int adjust_flags )
|
||||
{
|
||||
byte *out, *flipped;
|
||||
qboolean resampled = false;
|
||||
@ -203,6 +204,88 @@ qboolean FS_AddSideToPack( const char *name, int adjust_flags )
|
||||
return true;
|
||||
}
|
||||
|
||||
static const loadpixformat_t *Image_GetLoadFormatForExtension( const char *ext )
|
||||
{
|
||||
const loadpixformat_t *format;
|
||||
|
||||
if( !COM_CheckStringEmpty( ext ))
|
||||
return NULL;
|
||||
|
||||
for( format = image.loadformats; format->formatstring; format++ )
|
||||
{
|
||||
if( !Q_stricmp( ext, format->ext ))
|
||||
return format;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static qboolean Image_ProbeLoadBuffer_( const loadpixformat_t *fmt, const char *name, const byte *buf, size_t size, int override_hint )
|
||||
{
|
||||
if( override_hint > 0 )
|
||||
image.hint = override_hint;
|
||||
else image.hint = fmt->hint;
|
||||
|
||||
return fmt->loadfunc( name, buf, size );
|
||||
}
|
||||
|
||||
static qboolean Image_ProbeLoadBuffer( const loadpixformat_t *fmt, const char *name, const byte *buf, size_t size, int override_hint )
|
||||
{
|
||||
if( size <= 0 )
|
||||
return false;
|
||||
|
||||
// bruteforce all loaders
|
||||
if( !fmt )
|
||||
{
|
||||
for( fmt = image.loadformats; fmt->formatstring; fmt++ )
|
||||
{
|
||||
if( Image_ProbeLoadBuffer_( fmt, name, buf, size, override_hint ))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return Image_ProbeLoadBuffer_( fmt, name, buf, size, override_hint );
|
||||
}
|
||||
|
||||
static qboolean Image_ProbeLoad_( const loadpixformat_t *fmt, const char *name, const char *suffix, int override_hint )
|
||||
{
|
||||
qboolean success = false;
|
||||
fs_offset_t filesize;
|
||||
string path;
|
||||
byte *f;
|
||||
|
||||
Q_snprintf( path, sizeof( path ), fmt->formatstring, name, suffix, fmt->ext );
|
||||
f = FS_LoadFile( path, &filesize, false );
|
||||
|
||||
if( f )
|
||||
{
|
||||
success = Image_ProbeLoadBuffer( fmt, path, f, filesize, override_hint );
|
||||
|
||||
Mem_Free( f );
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static qboolean Image_ProbeLoad( const loadpixformat_t *fmt, const char *name, const char *suffix, int override_hint )
|
||||
{
|
||||
if( !fmt )
|
||||
{
|
||||
// bruteforce all formats to allow implicit extension
|
||||
for( fmt = image.loadformats; fmt->formatstring; fmt++ )
|
||||
{
|
||||
if( Image_ProbeLoad_( fmt, name, suffix, override_hint ))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return Image_ProbeLoad_( fmt, name, suffix, override_hint );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_LoadImage
|
||||
@ -213,87 +296,35 @@ loading and unpack to rgba any known image
|
||||
rgbdata_t *FS_LoadImage( const char *filename, const byte *buffer, size_t size )
|
||||
{
|
||||
const char *ext = COM_FileExtension( filename );
|
||||
string path, loadname, sidename;
|
||||
qboolean anyformat = true;
|
||||
string loadname;
|
||||
int i;
|
||||
fs_offset_t filesize = 0;
|
||||
const loadpixformat_t *format;
|
||||
const loadpixformat_t *extfmt;
|
||||
const cubepack_t *cmap;
|
||||
byte *f;
|
||||
|
||||
Q_strncpy( loadname, filename, sizeof( loadname ));
|
||||
Image_Reset(); // clear old image
|
||||
|
||||
if( COM_CheckStringEmpty( ext ))
|
||||
{
|
||||
// we needs to compare file extension with list of supported formats
|
||||
// and be sure what is real extension, not a filename with dot
|
||||
for( format = image.loadformats; format && format->formatstring; format++ )
|
||||
{
|
||||
if( !Q_stricmp( format->ext, ext ))
|
||||
{
|
||||
COM_StripExtension( loadname );
|
||||
anyformat = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// we needs to compare file extension with list of supported formats
|
||||
// and be sure what is real extension, not a filename with dot
|
||||
if(( extfmt = Image_GetLoadFormatForExtension( ext )))
|
||||
COM_StripExtension( loadname );
|
||||
|
||||
// special mode: skip any checks, load file from buffer
|
||||
if( filename[0] == '#' && buffer && size )
|
||||
goto load_internal;
|
||||
|
||||
// now try all the formats in the selected list
|
||||
for( format = image.loadformats; format && format->formatstring; format++)
|
||||
{
|
||||
if( anyformat || !Q_stricmp( ext, format->ext ))
|
||||
{
|
||||
Q_sprintf( path, format->formatstring, loadname, "", format->ext );
|
||||
image.hint = format->hint;
|
||||
f = FS_LoadFile( path, &filesize, false );
|
||||
|
||||
if( f && filesize > 0 )
|
||||
{
|
||||
if( format->loadfunc( path, f, filesize ))
|
||||
{
|
||||
Mem_Free( f ); // release buffer
|
||||
return ImagePack(); // loaded
|
||||
}
|
||||
else Mem_Free( f ); // release buffer
|
||||
}
|
||||
}
|
||||
}
|
||||
if( Image_ProbeLoad( extfmt, loadname, "", -1 ))
|
||||
return ImagePack();
|
||||
|
||||
// check all cubemap sides with package suffix
|
||||
for( cmap = load_cubemap; cmap && cmap->type; cmap++ )
|
||||
{
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
// for support mixed cubemaps e.g. sky_ft.bmp, sky_rt.tga
|
||||
// NOTE: all loaders must keep sides in one format for all
|
||||
for( format = image.loadformats; format && format->formatstring; format++ )
|
||||
if( Image_ProbeLoad( extfmt, loadname, cmap->type[i].suf, cmap->type[i].hint ) &&
|
||||
FS_AddSideToPack( cmap->type[i].flags )) // process flags to flip some sides
|
||||
{
|
||||
if( anyformat || !Q_stricmp( ext, format->ext ))
|
||||
{
|
||||
Q_sprintf( path, format->formatstring, loadname, cmap->type[i].suf, format->ext );
|
||||
image.hint = (image_hint_t)cmap->type[i].hint; // side hint
|
||||
|
||||
f = FS_LoadFile( path, &filesize, false );
|
||||
if( f && filesize > 0 )
|
||||
{
|
||||
// this name will be used only for tell user about problems
|
||||
if( format->loadfunc( path, f, filesize ))
|
||||
{
|
||||
Q_snprintf( sidename, sizeof( sidename ), "%s%s.%s", loadname, cmap->type[i].suf, format->ext );
|
||||
if( FS_AddSideToPack( sidename, cmap->type[i].flags )) // process flags to flip some sides
|
||||
{
|
||||
Mem_Free( f );
|
||||
break; // loaded
|
||||
}
|
||||
}
|
||||
Mem_Free( f );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( image.num_sides != i + 1 ) // check side
|
||||
@ -323,20 +354,13 @@ rgbdata_t *FS_LoadImage( const char *filename, const byte *buffer, size_t size )
|
||||
return ImagePack(); // all done
|
||||
|
||||
load_internal:
|
||||
for( format = image.loadformats; format && format->formatstring; format++ )
|
||||
if( buffer && size )
|
||||
{
|
||||
if( anyformat || !Q_stricmp( ext, format->ext ))
|
||||
{
|
||||
image.hint = format->hint;
|
||||
if( buffer && size > 0 )
|
||||
{
|
||||
if( format->loadfunc( loadname, buffer, size ))
|
||||
return ImagePack(); // loaded
|
||||
}
|
||||
}
|
||||
if( Image_ProbeLoadBuffer( extfmt, loadname, buffer, size, -1 ))
|
||||
return ImagePack();
|
||||
}
|
||||
|
||||
if( filename[0] != '#' )
|
||||
if( loadname[0] != '#' )
|
||||
Con_Reportf( S_WARN "FS_LoadImage: couldn't load \"%s\"\n", loadname );
|
||||
|
||||
// clear any force flags
|
||||
@ -345,6 +369,8 @@ load_internal:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Image_Save
|
||||
|
Loading…
x
Reference in New Issue
Block a user