[image] Add parameter to load only the header

I want to be able to calculate texture sizes without actually loading
the images.
This commit is contained in:
Bill Currie 2021-01-19 10:15:57 +09:00
parent 9b53d7d4e2
commit e50430e00c
22 changed files with 116 additions and 82 deletions

View file

@ -45,11 +45,11 @@ typedef struct tex_s {
int width;
int height;
QFFormat format;
byte *palette; // 0 = 32 bit, otherwise 8
byte data[4]; // variable length
int loaded; // 0 if size info only, otherwise data loaded
byte *palette; // 0 = 32 bit, otherwise 8
byte data[4]; // variable length
} tex_t;
tex_t *LoadImage (const char *imageFile);
tex_t *LoadImage (const char *imageFile, int load);
#endif//__QF_image_h

View file

@ -71,10 +71,11 @@ pcx_t *EncodePCX (byte *data, int width, int height, int rowbytes,
\param f The file to read the texture from
\param convert If true, the texture is converted to RGB on load
\param pal The palette to apply during conversion
\param load If false, only the format and size info is loaded
\return A pointer to the texture.
\warning Uses Hunk_TempAlloc() to allocate the texture.
*/
struct tex_s *LoadPCX (QFile *f, qboolean convert, byte *pal);
struct tex_s *LoadPCX (QFile *f, qboolean convert, byte *pal, int load);
#endif//__QF_pcx_h

View file

@ -33,7 +33,7 @@
#include "QF/quakefs.h"
struct tex_s *LoadPNG (QFile *infile);
struct tex_s *LoadPNG (QFile *infile, int load);
void WritePNG (const char *fileName, const byte *data, int width, int height);
void WritePNGqfs (const char *fileName, const byte *data,
int width, int height);

View file

@ -67,7 +67,7 @@ typedef struct _TargaHeader {
# endif
#endif
struct tex_s *LoadTGA (QFile *fin);
struct tex_s *LoadTGA (QFile *fin, int load);
void WriteTGAfile (const char *tganame, byte *data, int width, int height);
#endif//__QF_tga_h

View file

@ -43,7 +43,7 @@
#include "QF/tga.h"
VISIBLE tex_t *
LoadImage (const char *imageFile)
LoadImage (const char *imageFile, int load)
{
int tmp;
dstring_t *tmpFile;
@ -64,7 +64,7 @@ LoadImage (const char *imageFile)
dstring_replace (tmpFile, tmp, tmpFile->size, ".png", 5);
fp = QFS_FOpenFile (tmpFile->str);
if (fp) {
tex = LoadPNG (fp);
tex = LoadPNG (fp, load);
Qclose (fp);
dstring_delete (tmpFile);
return (tex);
@ -74,7 +74,7 @@ LoadImage (const char *imageFile)
dstring_replace (tmpFile, tmp, tmpFile->size, ".tga", 5);
fp = QFS_FOpenFile (tmpFile->str);
if (fp) {
tex = LoadTGA (fp);
tex = LoadTGA (fp, load);
Qclose (fp);
dstring_delete (tmpFile);
return (tex);
@ -85,7 +85,7 @@ LoadImage (const char *imageFile)
dstring_replace (tmpFile, tmp, tmpFile->size, ".jpg", 5);
fp = QFS_FOpenFile (tmpFile->str);
if (fp) {
tex = LoadJPG (fp);
tex = LoadJPG (fp, load);
Qclose (fp);
dstring_delete (tmpFile);
return (tex);
@ -96,7 +96,8 @@ LoadImage (const char *imageFile)
dstring_replace (tmpFile, tmp, tmpFile->size, ".pcx", 5);
fp = QFS_FOpenFile (tmpFile->str);
if (fp) {
tex = LoadPCX (fp, 1, NULL); // Convert, some users don't grok paletted
// Convert, some users don't grok paletted
tex = LoadPCX (fp, 1, NULL, load);
Qclose (fp);
dstring_delete (tmpFile);
return (tex);

View file

@ -47,7 +47,7 @@
VISIBLE tex_t *
LoadPCX (QFile *f, qboolean convert, byte *pal)
LoadPCX (QFile *f, qboolean convert, byte *pal, int load)
{
pcx_t *pcx;
int pcx_mark;
@ -58,8 +58,11 @@ LoadPCX (QFile *f, qboolean convert, byte *pal)
int runLength = 1;
int count;
tex_t *tex;
int fsize = Qfilesize(f);
int fsize = sizeof (pcx_t);
if (load) {
fsize = Qfilesize(f);
}
// parse the PCX file
pcx_mark = Hunk_LowMark ();
pcx = Hunk_AllocName (fsize, "PCX");
@ -79,14 +82,16 @@ LoadPCX (QFile *f, qboolean convert, byte *pal)
|| pcx->encoding != 1
|| pcx->bits_per_pixel != 8) {
Sys_Printf ("Bad pcx file: %x %d %d %d\n",
pcx->manufacturer, pcx->version, pcx->encoding, pcx->bits_per_pixel);
pcx->manufacturer, pcx->version, pcx->encoding,
pcx->bits_per_pixel);
Hunk_FreeToLowMark (pcx_mark);
return 0;
}
end = palette = ((byte *) pcx) + fsize - 768;
dataByte = (byte *) &pcx[1];
count = (pcx->xmax + 1) * (pcx->ymax + 1);
count = load ? (pcx->xmax + 1) * (pcx->ymax + 1) : 0;
if (convert) {
tex = Hunk_TempAlloc (field_offset (tex_t, data[count * 3]));
tex->format = tex_rgb;
@ -101,6 +106,11 @@ LoadPCX (QFile *f, qboolean convert, byte *pal)
}
tex->width = pcx->xmax + 1;
tex->height = pcx->ymax + 1;
tex->loaded = load;
if (!load) {
Hunk_FreeToLowMark (pcx_mark);
return tex;
}
pix = tex->data;
while (count) {

View file

@ -115,7 +115,7 @@ readpng_init (QFile *infile, png_structp *png_ptr, png_infop *info_ptr)
/* Load the png file and return a texture */
VISIBLE tex_t *
LoadPNG (QFile *infile)
LoadPNG (QFile *infile, int load)
{
double gamma;
png_structp png_ptr = NULL;
@ -131,37 +131,41 @@ LoadPNG (QFile *infile)
png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
NULL, NULL, NULL);
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_expand (png_ptr);
if (load) {
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_expand (png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand (png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand (png_ptr);
if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_expand (png_ptr);
if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_expand (png_ptr);
if (bit_depth == 16)
png_set_strip_16 (png_ptr);
if (bit_depth == 16)
png_set_strip_16 (png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb (png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb (png_ptr);
/* NOTE: gamma support? */
/* unlike the example in the libpng documentation, we have *no* idea where
* this file may have come from--so if it doesn't have a file gamma, don't
* do any correction ("do no harm")
*/
if (png_get_gAMA(png_ptr, info_ptr, &gamma))
png_set_gamma (png_ptr, 1.0, gamma);
/* NOTE: gamma support? */
/* unlike the example in the libpng documentation, we have *no* idea
* wherethis file may have come from--so if it doesn't have a file
* gamma, don't do any correction ("do no harm")
*/
if (png_get_gAMA(png_ptr, info_ptr, &gamma))
png_set_gamma (png_ptr, 1.0, gamma);
/* All transformations have been registered, now update the info_ptr
* structure */
png_read_update_info (png_ptr, info_ptr);
/* All transformations have been registered, now update the info_ptr
* structure */
png_read_update_info (png_ptr, info_ptr);
/* Allocate tex_t structure */
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
tex = Hunk_TempAlloc (field_offset (tex_t, data[height * rowbytes]));
/* Allocate tex_t structure */
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
tex = Hunk_TempAlloc (field_offset (tex_t, data[height * rowbytes]));
} else {
tex = Hunk_TempAlloc (field_offset (tex_t, data[0]));
}
tex->width = width;
tex->height = height;
@ -170,6 +174,12 @@ LoadPNG (QFile *infile)
else
tex->format = tex_rgb;
tex->palette = NULL;
tex->loaded = load;
if (!load) {
png_read_end (png_ptr, NULL);
return tex;
}
if ((row_pointers = (png_bytepp) malloc (height * sizeof (png_bytep)))
== NULL) {

View file

@ -620,15 +620,18 @@ static decoder_t decoder_functions[] = {
/ sizeof (decoder_functions[0]))
struct tex_s *
LoadTGA (QFile *fin)
LoadTGA (QFile *fin, int load)
{
byte *dataByte;
decoder_t decode;
int fsize = Qfilesize (fin);
int fsize = sizeof (TargaHeader);
int numPixels, targa_mark;
TargaHeader *targa;
tex_t *tex;
if (load) {
fsize = Qfilesize (fin);
}
targa_mark = Hunk_LowMark ();
targa = Hunk_AllocName (fsize, "TGA");
Qread (fin, targa, fsize);
@ -641,20 +644,30 @@ LoadTGA (QFile *fin)
targa->height = LittleShort (targa->height);
if (targa->image_type >= NUM_DECODERS
|| !(decode = decoder_functions[targa->image_type]))
Sys_Error ("LoadTGA: Unsupported targa type");
|| !(decode = decoder_functions[targa->image_type])) {
Sys_Printf ("LoadTGA: Unsupported targa type");
Hunk_FreeToLowMark (targa_mark);
return 0;
}
numPixels = targa->width * targa->height;
if (load) {
numPixels = targa->width * targa->height;
} else {
numPixels = 0;
}
tex = Hunk_TempAlloc (field_offset (tex_t, data[numPixels * 4]));
tex->width = targa->width;
tex->height = targa->height;
tex->palette = 0;
tex->loaded = load;
// skip TARGA image comment
dataByte = (byte *) (targa + 1);
dataByte += targa->id_length;
if (load) {
// skip TARGA image comment
dataByte = (byte *) (targa + 1);
dataByte += targa->id_length;
decode (targa, tex, dataByte);
decode (targa, tex, dataByte);
}
Hunk_FreeToLowMark (targa_mark);
return tex;

View file

@ -120,9 +120,9 @@ Mod_LoadExternalSkin (maliasskindesc_t *pskindesc, char *filename)
if (!ptr)
ptr = filename;
tex = LoadImage (filename);
tex = LoadImage (filename, 1);
if (!tex)
tex = LoadImage (va ("textures/%s", ptr + 1));
tex = LoadImage (va ("textures/%s", ptr + 1), 1);
if (tex) {
pskindesc->texnum = GL_LoadTexture (filename, tex->width, tex->height,
tex->data, true, false,
@ -130,13 +130,13 @@ Mod_LoadExternalSkin (maliasskindesc_t *pskindesc, char *filename)
pskindesc->fb_texnum = 0;
glow = LoadImage (va ("%s_luma", filename));
glow = LoadImage (va ("%s_luma", filename), 1);
if (!glow)
glow = LoadImage (va ("%s_glow", filename));
glow = LoadImage (va ("%s_glow", filename), 1);
if (!glow)
glow = LoadImage (va ("textures/%s_luma", ptr + 1));
glow = LoadImage (va ("textures/%s_luma", ptr + 1), 1);
if (!glow)
glow = LoadImage (va ("textures/%s_glow", ptr + 1));
glow = LoadImage (va ("textures/%s_glow", ptr + 1), 1);
if (glow)
pskindesc->fb_texnum =
GL_LoadTexture (va ("fb_%s", filename), glow->width,

View file

@ -68,7 +68,7 @@ gl_Mod_ProcessTexture (texture_t *tx)
}
static tex_t *
Mod_LoadAnExternalTexture (char * tname, char *mname)
Mod_LoadAnExternalTexture (char *tname, char *mname)
{
char rname[32];
tex_t *image;
@ -78,17 +78,16 @@ Mod_LoadAnExternalTexture (char * tname, char *mname)
if (rname[0] == '*') rname[0] = '#';
image = LoadImage (va ("textures/%.*s/%s", (int) strlen (mname + 5) - 4,
mname + 5, rname));
mname + 5, rname), 1);
if (!image)
image = LoadImage (va ("maps/%.*s/%s",
(int) strlen (mname + 5) - 4,
mname + 5, rname));
image = LoadImage (va ("maps/%.*s/%s", (int) strlen (mname + 5) - 4,
mname + 5, rname), 1);
// if (!image)
// image = LoadImage (va ("textures/bmodels/%s", rname));
if (!image)
image = LoadImage (va ("textures/%s", rname));
image = LoadImage (va ("textures/%s", rname), 1);
if (!image)
image = LoadImage (va ("maps/%s", rname));
image = LoadImage (va ("maps/%s", rname), 1);
return image;
}

View file

@ -135,7 +135,7 @@ glsl_Mod_ProcessTexture (texture_t *tx)
void
glsl_Mod_LoadLighting (bsp_t *bsp)
{
// a big hacky, but it's as good a place as any
// a bit hacky, but it's as good a place as any
loadmodel->clear = glsl_brush_clear;
mod_lightmap_bytes = 1;
if (!bsp->lightdatasize) {

View file

@ -80,7 +80,7 @@ gl_iqm_load_textures (iqm_t *iqm)
for (i = 0; i < iqm->num_meshes; i++) {
dstring_copystr (str, iqm->text + iqm->meshes[i].material);
QFS_StripExtension (str->str, str->str);
if ((tex = LoadImage (va ("textures/%s", str->str))))
if ((tex = LoadImage (va ("textures/%s", str->str), 1)))
gl->textures[i] = GL_LoadTexture (str->str, tex->width,
tex->height, tex->data, true,
false,

View file

@ -102,12 +102,12 @@ glsl_iqm_load_textures (iqm_t *iqm)
for (i = 0; i < iqm->num_meshes; i++) {
dstring_copystr (str, iqm->text + iqm->meshes[i].material);
QFS_StripExtension (str->str, str->str);
if ((tex = LoadImage (va ("textures/%s", str->str))))
if ((tex = LoadImage (va ("textures/%s", str->str), 1)))
glsl->textures[i] = GLSL_LoadRGBATexture (str->str, tex->width,
tex->height, tex->data);
else
glsl->textures[i] = GLSL_LoadRGBATexture ("", 2, 2, null_texture);
if ((tex = LoadImage (va ("textures/%s_norm", str->str))))
if ((tex = LoadImage (va ("textures/%s_norm", str->str), 1)))
glsl->normmaps[i] = GLSL_LoadRGBATexture (str->str, tex->width,
tex->height, tex->data);
else

View file

@ -54,7 +54,7 @@
#include "r_internal.h"
static tex_t null_texture = {
2, 2, tex_palette, 0, {15, 15, 15, 15}
2, 2, tex_palette, 1, 0, {15, 15, 15, 15}
};
static void
@ -165,7 +165,7 @@ sw_iqm_load_textures (iqm_t *iqm)
continue;
dstring_copystr (str, iqm->text + iqm->meshes[i].material);
QFS_StripExtension (str->str, str->str);
if ((tex = LoadImage (va ("textures/%s", str->str))))
if ((tex = LoadImage (va ("textures/%s", str->str), 1)))
tex = sw->skins[i] = convert_tex (tex);
else
tex = sw->skins[i] = &null_texture;

View file

@ -184,7 +184,7 @@ Skin_SetSkin (skin_t *skin, int cmap, const char *skinname)
name = 0;
break;
}
tex = LoadPCX (file, 0, r_data->vid->palette);
tex = LoadPCX (file, 0, r_data->vid->palette, 1);
Qclose (file);
if (!tex || tex->width > 320 || tex->height > 200) {
Sys_Printf ("Bad skin %s\n", name);

View file

@ -49,7 +49,7 @@ gl_Mod_SpriteLoadTexture (mspriteframe_t *pspriteframe, int framenum)
tex_t *targa;
const char *name;
targa = LoadImage (name = va ("%s_%i", loadmodel->name, framenum));
targa = LoadImage (name = va ("%s_%i", loadmodel->name, framenum), 1);
if (targa) {
if (targa->format < 4)
pspriteframe->gl_texturenum = GL_LoadTexture (name,

View file

@ -175,7 +175,7 @@ gl_Draw_PicFromWad (const char *name)
tex_t *targa;
pic = W_GetLumpName (name);
targa = LoadImage (name);
targa = LoadImage (name, 1);
if (targa) {
p = malloc (sizeof (qpic_t) + sizeof (glpic_t));
p->width = pic->width;
@ -236,7 +236,7 @@ gl_Draw_CachePic (const char *path, qboolean alpha)
// Adjust for endian..
SwapPic (dat);
// Check for a .tga first
targa = LoadImage (path);
targa = LoadImage (path, 1);
if (targa) {
if (targa->format < 4) {
gl->texnum = GL_LoadTexture ("", targa->width, targa->height,
@ -353,7 +353,7 @@ gl_Draw_Init (void)
// write the version string into the background before turning it into a
// texture
image = LoadImage ("gfx/conchars");
image = LoadImage ("gfx/conchars", 1);
if (image) {
if (image->format < 4) {
char_texture = GL_LoadTexture ("charset", image->width,

View file

@ -131,11 +131,11 @@ gl_R_LoadSkys (const char *skyname)
qfglBindTexture (GL_TEXTURE_2D, SKY_TEX + i);
targa = LoadImage (name = va ("env/%s%s", skyname, suf[i]));
targa = LoadImage (name = va ("env/%s%s", skyname, suf[i]), 1);
if (!targa || targa->format < 3) { // FIXME Can't do PCX right now
Sys_MaskPrintf (SYS_DEV, "Couldn't load %s\n", name);
// also look in gfx/env, where Darkplaces looks for skies
targa = LoadImage (name = va ("gfx/env/%s%s", skyname, suf[i]));
targa = LoadImage (name = va ("gfx/env/%s%s", skyname, suf[i]), 1);
if (!targa) {
Sys_MaskPrintf (SYS_DEV, "Couldn't load %s\n", name);
gl_skyloaded = false;

View file

@ -1399,7 +1399,7 @@ glsl_R_LoadSkys (const char *sky)
//blender envmap
// bk rt ft
// dn up lt
tex = LoadImage (name = va ("env/%s_map", sky));
tex = LoadImage (name = va ("env/%s_map", sky), 1);
if (tex && tex->format >= 3 && tex->height * 3 == tex->width * 2
&& is_pow2 (tex->height)) {
tex_t *sub;
@ -1426,12 +1426,12 @@ glsl_R_LoadSkys (const char *sky)
} else {
skybox_loaded = true;
for (i = 0; i < 6; i++) {
tex = LoadImage (name = va ("env/%s%s", sky, sky_suffix[i]));
tex = LoadImage (name = va ("env/%s%s", sky, sky_suffix[i]), 1);
if (!tex || tex->format < 3) { // FIXME pcx support
Sys_MaskPrintf (SYS_GLSL, "Couldn't load %s\n", name);
// also look in gfx/env, where Darkplaces looks for skies
tex = LoadImage (name = va ("gfx/env/%s%s", sky,
sky_suffix[i]));
sky_suffix[i]), 1);
if (!tex || tex->format < 3) { // FIXME pcx support
Sys_MaskPrintf (SYS_GLSL, "Couldn't load %s\n", name);
skybox_loaded = false;

View file

@ -213,7 +213,7 @@ importFile (const char *inpath)
if (options.verbosity > 1)
Sys_Printf ("PCX file size: %d\n", fsize);
lmp = LoadPCX (infile, false, NULL);
lmp = LoadPCX (infile, false, NULL, 1);
if (!lmp) {
Sys_Printf ("%s: Failed to load %s as texture.\n",

View file

@ -190,7 +190,7 @@ LoadScreen (const char *name)
file = Qopen (name, "rb");
if (!file)
Sys_Error ("could not open");
image = LoadPCX (file, false, 0);
image = LoadPCX (file, false, 0, 1);
}

View file

@ -92,7 +92,7 @@ load_image (const char *name)
if (!(file = Qopen (name, "rb")))
Sys_Error ("couldn't open %s. %s", name, strerror(errno));
if (!(tex = LoadPNG (file)))
if (!(tex = LoadPNG (file, 1)))
Sys_Error ("couldn't read %s as PNG", name);
pixels = tex->width * tex->height;