Add support for image-loading plugins.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6103 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
57746acd5a
commit
ab2dc14f49
4 changed files with 148 additions and 1 deletions
|
@ -230,6 +230,44 @@ static float HalfToFloat(unsigned short val);
|
||||||
static unsigned short FloatToHalf(float val);
|
static unsigned short FloatToHalf(float val);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
void *module;
|
||||||
|
plugimageloaderfuncs_t *funcs;
|
||||||
|
} *imageloader;
|
||||||
|
static size_t imageloader_count;
|
||||||
|
qboolean Image_RegisterLoader(void *module, plugimageloaderfuncs_t *driver)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (!driver)
|
||||||
|
{
|
||||||
|
for (i = 0; i < imageloader_count; )
|
||||||
|
{
|
||||||
|
if (imageloader[i].module == module)
|
||||||
|
{
|
||||||
|
memmove(&imageloader[i], &imageloader[i+1], imageloader_count-(i+1));
|
||||||
|
imageloader_count--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
void *n = BZ_Malloc(sizeof(*imageloader)*(imageloader_count+1));
|
||||||
|
memcpy(n, imageloader, sizeof(*imageloader)*imageloader_count);
|
||||||
|
Z_Free(imageloader);
|
||||||
|
imageloader = n;
|
||||||
|
imageloader[imageloader_count].module = module;
|
||||||
|
imageloader[imageloader_count].funcs = driver;
|
||||||
|
imageloader_count++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(AVAIL_JPEGLIB) || defined(AVAIL_PNGLIB)
|
#if defined(AVAIL_JPEGLIB) || defined(AVAIL_PNGLIB)
|
||||||
static void GenerateXMPData(char *blob, size_t blobsize, int width, int height, unsigned int metainfo)
|
static void GenerateXMPData(char *blob, size_t blobsize, int width, int height, unsigned int metainfo)
|
||||||
{ //XMP is a general thing that applies to multiple formats - or at least png+jpeg.
|
{ //XMP is a general thing that applies to multiple formats - or at least png+jpeg.
|
||||||
|
@ -7251,6 +7289,7 @@ void Image_PrintInputFormatVersions(void)
|
||||||
//if force_rgba8 then it guarentees rgba8 or rgbx8, otherwise can return l8, etc
|
//if force_rgba8 then it guarentees rgba8 or rgbx8, otherwise can return l8, etc
|
||||||
qbyte *ReadRawImageFile(qbyte *buf, int len, int *width, int *height, uploadfmt_t *format, qboolean force_rgba8, const char *fname)
|
qbyte *ReadRawImageFile(qbyte *buf, int len, int *width, int *height, uploadfmt_t *format, qboolean force_rgba8, const char *fname)
|
||||||
{
|
{
|
||||||
|
size_t l, i;
|
||||||
qbyte *data;
|
qbyte *data;
|
||||||
*format = PTI_RGBX8;
|
*format = PTI_RGBX8;
|
||||||
#ifdef IMAGEFMT_TGA
|
#ifdef IMAGEFMT_TGA
|
||||||
|
@ -7344,6 +7383,58 @@ qbyte *ReadRawImageFile(qbyte *buf, int len, int *width, int *height, uploadfmt_
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
for (l = 0; l < imageloader_count; l++)
|
||||||
|
{
|
||||||
|
struct pendingtextureinfo *mips = imageloader[l].funcs->ReadImageFile(0, fname, buf, len);
|
||||||
|
if (mips)
|
||||||
|
{
|
||||||
|
if (mips->extrafree != buf)
|
||||||
|
Sys_Error("Image loader did weird extrafree things.");
|
||||||
|
mips->extrafree = NULL;
|
||||||
|
|
||||||
|
//free any excess mips
|
||||||
|
while (mips->mipcount > 1)
|
||||||
|
if (mips->mip[--mips->mipcount].needfree)
|
||||||
|
BZ_Free(mips->mip[mips->mipcount].data);
|
||||||
|
|
||||||
|
if (mips->mipcount > 0 && mips->type == PTI_2D)
|
||||||
|
{
|
||||||
|
if (force_rgba8)
|
||||||
|
{
|
||||||
|
qboolean rgbx8only[PTI_MAX] = {0};
|
||||||
|
rgbx8only[PTI_RGBX8] = true;
|
||||||
|
rgbx8only[PTI_RGBA8] = true;
|
||||||
|
Image_ChangeFormat(mips, rgbx8only, mips->encoding, fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mips->mip[0].needfree)
|
||||||
|
{
|
||||||
|
data = mips->mip[0].data;
|
||||||
|
mips->mip[0].data = NULL;
|
||||||
|
mips->mip[0].needfree = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data = BZ_Malloc(mips->mip[0].datasize);
|
||||||
|
memcpy(data, mips->mip[0].data, mips->mip[0].datasize);
|
||||||
|
}
|
||||||
|
*width = mips->mip[0].width;
|
||||||
|
*height = mips->mip[0].height;
|
||||||
|
*format = mips->encoding;
|
||||||
|
}
|
||||||
|
for (i = 0; i < mips->mipcount; i++)
|
||||||
|
if (mips->mip[i].needfree)
|
||||||
|
BZ_Free(mips->mip[i].data);
|
||||||
|
|
||||||
|
if (mips->extrafree && mips->extrafree)
|
||||||
|
BZ_Free(mips->extrafree);
|
||||||
|
BZ_Free(mips);
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef IMAGEFMT_LMP
|
#ifdef IMAGEFMT_LMP
|
||||||
if (len >= 8) //.lmp has no magic id. guess at it.
|
if (len >= 8) //.lmp has no magic id. guess at it.
|
||||||
{
|
{
|
||||||
|
@ -13154,6 +13245,7 @@ struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char *iname
|
||||||
qbyte *rgbadata;
|
qbyte *rgbadata;
|
||||||
|
|
||||||
int imgwidth, imgheight;
|
int imgwidth, imgheight;
|
||||||
|
size_t l;
|
||||||
|
|
||||||
struct pendingtextureinfo *mips = NULL;
|
struct pendingtextureinfo *mips = NULL;
|
||||||
|
|
||||||
|
@ -13174,6 +13266,8 @@ struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char *iname
|
||||||
if (!mips && filedata[0] == 'B' && filedata[1] == 'L' && filedata[2] == 'P' && filedata[3] == '2')
|
if (!mips && filedata[0] == 'B' && filedata[1] == 'L' && filedata[2] == 'P' && filedata[3] == '2')
|
||||||
mips = Image_ReadBLPFile(flags, fname, filedata, filesize);
|
mips = Image_ReadBLPFile(flags, fname, filedata, filesize);
|
||||||
#endif
|
#endif
|
||||||
|
for (l = 0; !mips && l < imageloader_count; l++)
|
||||||
|
mips = imageloader[l].funcs->ReadImageFile(flags, fname, filedata, filesize);
|
||||||
#ifdef IMAGEFMT_ASTC
|
#ifdef IMAGEFMT_ASTC
|
||||||
if (!mips && filesize>= 16 && filedata[0] == 0x13 && filedata[1] == 0xab && filedata[2] == 0xa1 && filedata[3] == 0x5c)
|
if (!mips && filesize>= 16 && filedata[0] == 0x13 && filedata[1] == 0xab && filedata[2] == 0xa1 && filedata[3] == 0x5c)
|
||||||
mips = Image_ReadASTCFile(flags, fname, filedata, filesize);
|
mips = Image_ReadASTCFile(flags, fname, filedata, filesize);
|
||||||
|
@ -13692,6 +13786,8 @@ qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, char *be
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
s = COM_SkipPath(nicename);
|
s = COM_SkipPath(nicename);
|
||||||
|
if (!*s)
|
||||||
|
continue;
|
||||||
n = basename;
|
n = basename;
|
||||||
while (*s && (*s != '.'||exactext) && n < basename+sizeof(basename)-5)
|
while (*s && (*s != '.'||exactext) && n < basename+sizeof(basename)-5)
|
||||||
*n++ = *s++;
|
*n++ = *s++;
|
||||||
|
@ -13837,7 +13933,7 @@ static void Image_LoadHiResTextureWorker(void *ctx, void *data, size_t a, size_t
|
||||||
unsigned int locflags = 0;
|
unsigned int locflags = 0;
|
||||||
|
|
||||||
vfsfile_t *f;
|
vfsfile_t *f;
|
||||||
size_t fsize;
|
size_t fsize, l;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
int i, j;
|
int i, j;
|
||||||
|
@ -13919,6 +14015,12 @@ static void Image_LoadHiResTextureWorker(void *ctx, void *data, size_t a, size_t
|
||||||
if (!mips)
|
if (!mips)
|
||||||
mips = Image_ReadDDSFile(tex->flags, altname, buf, fsize);
|
mips = Image_ReadDDSFile(tex->flags, altname, buf, fsize);
|
||||||
#endif
|
#endif
|
||||||
|
for (l = 0; !mips && l < imageloader_count; l++)
|
||||||
|
{
|
||||||
|
if (!imageloader[l].funcs->canloadcubemaps)
|
||||||
|
continue;
|
||||||
|
mips = imageloader[l].funcs->ReadImageFile(tex->flags, altname, buf, fsize);
|
||||||
|
}
|
||||||
if (!mips)
|
if (!mips)
|
||||||
BZ_Free(buf);
|
BZ_Free(buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,6 +500,16 @@ void Image_ChangeFormat(struct pendingtextureinfo *mips, qboolean *allowedformat
|
||||||
void Image_Premultiply(struct pendingtextureinfo *mips);
|
void Image_Premultiply(struct pendingtextureinfo *mips);
|
||||||
void *Image_FlipImage(const void *inbuffer, void *outbuffer, int *inoutwidth, int *inoutheight, int pixelbytes, qboolean flipx, qboolean flipy, qboolean flipd);
|
void *Image_FlipImage(const void *inbuffer, void *outbuffer, int *inoutwidth, int *inoutheight, int pixelbytes, qboolean flipx, qboolean flipy, qboolean flipd);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char *loadername;
|
||||||
|
size_t pendingtextureinfosize;
|
||||||
|
qboolean canloadcubemaps;
|
||||||
|
struct pendingtextureinfo *(*ReadImageFile)(unsigned int imgflags, const char *fname, qbyte *filedata, size_t filesize);
|
||||||
|
#define plugimageloaderfuncs_name "ImageLoader"
|
||||||
|
} plugimageloaderfuncs_t;
|
||||||
|
qboolean Image_RegisterLoader(void *module, plugimageloaderfuncs_t *loader);
|
||||||
|
|
||||||
#ifdef D3D8QUAKE
|
#ifdef D3D8QUAKE
|
||||||
void D3D8_Set2D (void);
|
void D3D8_Set2D (void);
|
||||||
void D3D8_UpdateFiltering (image_t *imagelist, int filtermip[3], int filterpic[3], int mipcap[2], float anis);
|
void D3D8_UpdateFiltering (image_t *imagelist, int filtermip[3], int filterpic[3], int mipcap[2], float anis);
|
||||||
|
|
|
@ -406,6 +406,8 @@ static qboolean QDECL PlugBI_ExportInterface(const char *name, void *interfacept
|
||||||
#ifdef HAVE_CLIENT
|
#ifdef HAVE_CLIENT
|
||||||
if (!strcmp(name, plugvrfuncs_name))
|
if (!strcmp(name, plugvrfuncs_name))
|
||||||
return R_RegisterVRDriver(currentplug, interfaceptr);
|
return R_RegisterVRDriver(currentplug, interfaceptr);
|
||||||
|
if (!strcmp(name, plugimageloaderfuncs_name))
|
||||||
|
return Image_RegisterLoader(currentplug, interfaceptr);
|
||||||
#endif
|
#endif
|
||||||
#ifdef PACKAGEMANAGER
|
#ifdef PACKAGEMANAGER
|
||||||
if (!strcmp(name, plugupdatesourcefuncs_name))
|
if (!strcmp(name, plugupdatesourcefuncs_name))
|
||||||
|
@ -1533,6 +1535,7 @@ void Plug_Close(plugin_t *plug)
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_CLIENT
|
#ifdef HAVE_CLIENT
|
||||||
S_UnregisterSoundInputModule(plug);
|
S_UnregisterSoundInputModule(plug);
|
||||||
|
Image_RegisterLoader(plug, NULL);
|
||||||
#endif
|
#endif
|
||||||
NET_RegisterCrypto(plug, NULL);
|
NET_RegisterCrypto(plug, NULL);
|
||||||
#ifdef PACKAGEMANAGER
|
#ifdef PACKAGEMANAGER
|
||||||
|
@ -1783,6 +1786,12 @@ plugcorefuncs_t plugcorefuncs =
|
||||||
Sys_LoadLibrary,
|
Sys_LoadLibrary,
|
||||||
Sys_GetAddressForName,
|
Sys_GetAddressForName,
|
||||||
Sys_CloseLibrary,
|
Sys_CloseLibrary,
|
||||||
|
|
||||||
|
Z_Malloc,
|
||||||
|
BZ_Realloc,
|
||||||
|
Z_Free,
|
||||||
|
ZG_Malloc,
|
||||||
|
ZG_FreeGroup,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t structsize)
|
static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t structsize)
|
||||||
|
@ -1989,6 +1998,16 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
|
||||||
if (structsize == sizeof(funcs))
|
if (structsize == sizeof(funcs))
|
||||||
return &funcs;
|
return &funcs;
|
||||||
}
|
}
|
||||||
|
if (!strcmp(interfacename, plugimagefuncs_name))
|
||||||
|
{
|
||||||
|
static plugimagefuncs_t funcs =
|
||||||
|
{
|
||||||
|
Image_BlockSizeForEncoding,
|
||||||
|
Image_FormatName,
|
||||||
|
};
|
||||||
|
if (structsize == sizeof(funcs))
|
||||||
|
return &funcs;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SUPPORT_ICE
|
#ifdef SUPPORT_ICE
|
||||||
|
|
|
@ -197,6 +197,15 @@ typedef struct //core stuff
|
||||||
F(dllhandle_t*,LoadDLL, (const char *modulename, struct dllfunction_s *funcs));
|
F(dllhandle_t*,LoadDLL, (const char *modulename, struct dllfunction_s *funcs));
|
||||||
F(void*, GetDLLSymbol, (dllhandle_t *handle, const char *symbolname));
|
F(void*, GetDLLSymbol, (dllhandle_t *handle, const char *symbolname));
|
||||||
F(void, CloseDLL, (dllhandle_t *handle)); //not guarenteed to actually do anything, of course.
|
F(void, CloseDLL, (dllhandle_t *handle)); //not guarenteed to actually do anything, of course.
|
||||||
|
|
||||||
|
//general memory (mallocs and frees over dll boundaries is not usable on windows)
|
||||||
|
F(void*, Malloc, (size_t size));
|
||||||
|
F(void*, Realloc, (void *memptr, size_t size)); //doesn't zero-fill, so faster (when memptr is NULL).
|
||||||
|
F(void, Free, (void *memptr));
|
||||||
|
|
||||||
|
//for lazy mallocs
|
||||||
|
F(void*, GMalloc, (struct zonegroup_s *ctx, size_t size));
|
||||||
|
F(void, GFreeAll, (struct zonegroup_s *ctx));
|
||||||
#define plugcorefuncs_name "Core"
|
#define plugcorefuncs_name "Core"
|
||||||
} plugcorefuncs_t;
|
} plugcorefuncs_t;
|
||||||
|
|
||||||
|
@ -254,6 +263,13 @@ typedef struct
|
||||||
#define plugaudiofuncs_name "Audio"
|
#define plugaudiofuncs_name "Audio"
|
||||||
} plugaudiofuncs_t;
|
} plugaudiofuncs_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
F(void, BlockSizeForEncoding,(uploadfmt_t encoding, unsigned int *blockbytes, unsigned int *blockwidth, unsigned int *blockheight, unsigned int *blockdepth));
|
||||||
|
F(const char *,FormatName, (uploadfmt_t encoding));
|
||||||
|
#define plugimagefuncs_name "Image"
|
||||||
|
} plugimagefuncs_t;
|
||||||
|
|
||||||
typedef struct //q1 client/network info
|
typedef struct //q1 client/network info
|
||||||
{
|
{
|
||||||
F(int, GetStats, (int seat, unsigned int *stats, int maxstats));
|
F(int, GetStats, (int seat, unsigned int *stats, int maxstats));
|
||||||
|
|
Loading…
Reference in a new issue