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
|
// global parms
|
||||||
rgba_t fogParams; // some water textures has info about underwater fog
|
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
|
byte *tempbuffer; // for convert operations
|
||||||
int cmd_flags; // global imglib flags
|
int cmd_flags; // global imglib flags
|
||||||
int force_flags; // override cmd_flags
|
int force_flags; // override cmd_flags
|
||||||
@ -171,7 +171,6 @@ rgbdata_t *Image_Quantize( rgbdata_t *pic );
|
|||||||
// img_utils.c
|
// img_utils.c
|
||||||
//
|
//
|
||||||
void Image_Reset( void );
|
void Image_Reset( void );
|
||||||
rgbdata_t *ImagePack( void );
|
|
||||||
byte *Image_Copy( size_t size );
|
byte *Image_Copy( size_t size );
|
||||||
void Image_CopyParms( rgbdata_t *src );
|
void Image_CopyParms( rgbdata_t *src );
|
||||||
qboolean Image_ValidSize( const char *name );
|
qboolean Image_ValidSize( const char *name );
|
||||||
|
@ -110,20 +110,21 @@ void Image_Reset( void )
|
|||||||
image.size = 0;
|
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
|
// clear any force flags
|
||||||
image.force_flags = 0;
|
image.force_flags = 0;
|
||||||
|
|
||||||
if( image.cubemap && image.num_sides != 6 )
|
if( image.cubemap && image.num_sides != 6 )
|
||||||
{
|
{
|
||||||
// this never be happens, just in case
|
// this never can happen, just in case
|
||||||
FS_FreeImage( pack );
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pack = Mem_Calloc( host.imagepool, sizeof( *pack ));
|
||||||
|
|
||||||
if( image.cubemap )
|
if( image.cubemap )
|
||||||
{
|
{
|
||||||
image.flags |= 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;
|
byte *out, *flipped;
|
||||||
qboolean resampled = false;
|
qboolean resampled = false;
|
||||||
@ -203,6 +204,88 @@ qboolean FS_AddSideToPack( const char *name, int adjust_flags )
|
|||||||
return true;
|
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
|
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 )
|
rgbdata_t *FS_LoadImage( const char *filename, const byte *buffer, size_t size )
|
||||||
{
|
{
|
||||||
const char *ext = COM_FileExtension( filename );
|
const char *ext = COM_FileExtension( filename );
|
||||||
string path, loadname, sidename;
|
string loadname;
|
||||||
qboolean anyformat = true;
|
|
||||||
int i;
|
int i;
|
||||||
fs_offset_t filesize = 0;
|
const loadpixformat_t *extfmt;
|
||||||
const loadpixformat_t *format;
|
|
||||||
const cubepack_t *cmap;
|
const cubepack_t *cmap;
|
||||||
byte *f;
|
|
||||||
|
|
||||||
Q_strncpy( loadname, filename, sizeof( loadname ));
|
Q_strncpy( loadname, filename, sizeof( loadname ));
|
||||||
Image_Reset(); // clear old image
|
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
|
||||||
// we needs to compare file extension with list of supported formats
|
if(( extfmt = Image_GetLoadFormatForExtension( ext )))
|
||||||
// and be sure what is real extension, not a filename with dot
|
COM_StripExtension( loadname );
|
||||||
for( format = image.loadformats; format && format->formatstring; format++ )
|
|
||||||
{
|
|
||||||
if( !Q_stricmp( format->ext, ext ))
|
|
||||||
{
|
|
||||||
COM_StripExtension( loadname );
|
|
||||||
anyformat = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// special mode: skip any checks, load file from buffer
|
// special mode: skip any checks, load file from buffer
|
||||||
if( filename[0] == '#' && buffer && size )
|
if( filename[0] == '#' && buffer && size )
|
||||||
goto load_internal;
|
goto load_internal;
|
||||||
|
|
||||||
// now try all the formats in the selected list
|
if( Image_ProbeLoad( extfmt, loadname, "", -1 ))
|
||||||
for( format = image.loadformats; format && format->formatstring; format++)
|
return ImagePack();
|
||||||
{
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check all cubemap sides with package suffix
|
// check all cubemap sides with package suffix
|
||||||
for( cmap = load_cubemap; cmap && cmap->type; cmap++ )
|
for( cmap = load_cubemap; cmap && cmap->type; cmap++ )
|
||||||
{
|
{
|
||||||
for( i = 0; i < 6; i++ )
|
for( i = 0; i < 6; i++ )
|
||||||
{
|
{
|
||||||
// for support mixed cubemaps e.g. sky_ft.bmp, sky_rt.tga
|
if( Image_ProbeLoad( extfmt, loadname, cmap->type[i].suf, cmap->type[i].hint ) &&
|
||||||
// NOTE: all loaders must keep sides in one format for all
|
FS_AddSideToPack( cmap->type[i].flags )) // process flags to flip some sides
|
||||||
for( format = image.loadformats; format && format->formatstring; format++ )
|
|
||||||
{
|
{
|
||||||
if( anyformat || !Q_stricmp( ext, format->ext ))
|
break;
|
||||||
{
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( image.num_sides != i + 1 ) // check side
|
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
|
return ImagePack(); // all done
|
||||||
|
|
||||||
load_internal:
|
load_internal:
|
||||||
for( format = image.loadformats; format && format->formatstring; format++ )
|
if( buffer && size )
|
||||||
{
|
{
|
||||||
if( anyformat || !Q_stricmp( ext, format->ext ))
|
if( Image_ProbeLoadBuffer( extfmt, loadname, buffer, size, -1 ))
|
||||||
{
|
return ImagePack();
|
||||||
image.hint = format->hint;
|
|
||||||
if( buffer && size > 0 )
|
|
||||||
{
|
|
||||||
if( format->loadfunc( loadname, buffer, size ))
|
|
||||||
return ImagePack(); // loaded
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( filename[0] != '#' )
|
if( loadname[0] != '#' )
|
||||||
Con_Reportf( S_WARN "FS_LoadImage: couldn't load \"%s\"\n", loadname );
|
Con_Reportf( S_WARN "FS_LoadImage: couldn't load \"%s\"\n", loadname );
|
||||||
|
|
||||||
// clear any force flags
|
// clear any force flags
|
||||||
@ -345,6 +369,8 @@ load_internal:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Image_Save
|
Image_Save
|
||||||
|
Loading…
x
Reference in New Issue
Block a user