mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2025-02-10 09:41:09 +00:00
Image_LoadImage: read pixel data in 1K chunks instead of calling getc in a loop
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@957 af15c1b1-3010-417e-b628-4374ebc0bcbd
This commit is contained in:
parent
d9f78442fe
commit
a0f475ebcd
1 changed files with 66 additions and 24 deletions
|
@ -24,6 +24,39 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
static char loadfilename[MAX_OSPATH]; //file scope so that error messages can use it
|
static char loadfilename[MAX_OSPATH]; //file scope so that error messages can use it
|
||||||
|
|
||||||
|
typedef struct stdio_buffer_s {
|
||||||
|
FILE *f;
|
||||||
|
unsigned char buffer[1024];
|
||||||
|
int size;
|
||||||
|
int pos;
|
||||||
|
} stdio_buffer_t;
|
||||||
|
|
||||||
|
static stdio_buffer_t *Buf_Alloc(FILE *f)
|
||||||
|
{
|
||||||
|
stdio_buffer_t *buf = calloc(1, sizeof(stdio_buffer_t));
|
||||||
|
buf->f = f;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Buf_Free(stdio_buffer_t *buf)
|
||||||
|
{
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int Buf_GetC(stdio_buffer_t *buf)
|
||||||
|
{
|
||||||
|
if (buf->pos >= buf->size)
|
||||||
|
{
|
||||||
|
buf->size = fread(buf->buffer, 1, sizeof(buf->buffer), buf->f);
|
||||||
|
buf->pos = 0;
|
||||||
|
|
||||||
|
if (buf->size == 0)
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf->buffer[buf->pos++];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
============
|
============
|
||||||
Image_LoadImage
|
Image_LoadImage
|
||||||
|
@ -151,6 +184,7 @@ byte *Image_LoadTGA (FILE *fin, int *width, int *height)
|
||||||
byte *targa_rgba;
|
byte *targa_rgba;
|
||||||
int realrow; //johnfitz -- fix for upside-down targas
|
int realrow; //johnfitz -- fix for upside-down targas
|
||||||
qboolean upside_down; //johnfitz -- fix for upside-down targas
|
qboolean upside_down; //johnfitz -- fix for upside-down targas
|
||||||
|
stdio_buffer_t *buf;
|
||||||
|
|
||||||
targa_header.id_length = fgetc(fin);
|
targa_header.id_length = fgetc(fin);
|
||||||
targa_header.colormap_type = fgetc(fin);
|
targa_header.colormap_type = fgetc(fin);
|
||||||
|
@ -182,6 +216,8 @@ byte *Image_LoadTGA (FILE *fin, int *width, int *height)
|
||||||
if (targa_header.id_length != 0)
|
if (targa_header.id_length != 0)
|
||||||
fseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment
|
fseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment
|
||||||
|
|
||||||
|
buf = Buf_Alloc(fin);
|
||||||
|
|
||||||
if (targa_header.image_type==2) // Uncompressed, RGB images
|
if (targa_header.image_type==2) // Uncompressed, RGB images
|
||||||
{
|
{
|
||||||
for(row=rows-1; row>=0; row--)
|
for(row=rows-1; row>=0; row--)
|
||||||
|
@ -196,19 +232,19 @@ byte *Image_LoadTGA (FILE *fin, int *width, int *height)
|
||||||
switch (targa_header.pixel_size)
|
switch (targa_header.pixel_size)
|
||||||
{
|
{
|
||||||
case 24:
|
case 24:
|
||||||
blue = getc(fin);
|
blue = Buf_GetC(buf);
|
||||||
green = getc(fin);
|
green = Buf_GetC(buf);
|
||||||
red = getc(fin);
|
red = Buf_GetC(buf);
|
||||||
*pixbuf++ = red;
|
*pixbuf++ = red;
|
||||||
*pixbuf++ = green;
|
*pixbuf++ = green;
|
||||||
*pixbuf++ = blue;
|
*pixbuf++ = blue;
|
||||||
*pixbuf++ = 255;
|
*pixbuf++ = 255;
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
blue = getc(fin);
|
blue = Buf_GetC(buf);
|
||||||
green = getc(fin);
|
green = Buf_GetC(buf);
|
||||||
red = getc(fin);
|
red = Buf_GetC(buf);
|
||||||
alphabyte = getc(fin);
|
alphabyte = Buf_GetC(buf);
|
||||||
*pixbuf++ = red;
|
*pixbuf++ = red;
|
||||||
*pixbuf++ = green;
|
*pixbuf++ = green;
|
||||||
*pixbuf++ = blue;
|
*pixbuf++ = blue;
|
||||||
|
@ -229,23 +265,23 @@ byte *Image_LoadTGA (FILE *fin, int *width, int *height)
|
||||||
//johnfitz
|
//johnfitz
|
||||||
for(column=0; column<columns; )
|
for(column=0; column<columns; )
|
||||||
{
|
{
|
||||||
packetHeader=getc(fin);
|
packetHeader=Buf_GetC(buf);
|
||||||
packetSize = 1 + (packetHeader & 0x7f);
|
packetSize = 1 + (packetHeader & 0x7f);
|
||||||
if (packetHeader & 0x80) // run-length packet
|
if (packetHeader & 0x80) // run-length packet
|
||||||
{
|
{
|
||||||
switch (targa_header.pixel_size)
|
switch (targa_header.pixel_size)
|
||||||
{
|
{
|
||||||
case 24:
|
case 24:
|
||||||
blue = getc(fin);
|
blue = Buf_GetC(buf);
|
||||||
green = getc(fin);
|
green = Buf_GetC(buf);
|
||||||
red = getc(fin);
|
red = Buf_GetC(buf);
|
||||||
alphabyte = 255;
|
alphabyte = 255;
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
blue = getc(fin);
|
blue = Buf_GetC(buf);
|
||||||
green = getc(fin);
|
green = Buf_GetC(buf);
|
||||||
red = getc(fin);
|
red = Buf_GetC(buf);
|
||||||
alphabyte = getc(fin);
|
alphabyte = Buf_GetC(buf);
|
||||||
break;
|
break;
|
||||||
default: /* avoid compiler warnings */
|
default: /* avoid compiler warnings */
|
||||||
blue = red = green = alphabyte = 0;
|
blue = red = green = alphabyte = 0;
|
||||||
|
@ -279,19 +315,19 @@ byte *Image_LoadTGA (FILE *fin, int *width, int *height)
|
||||||
switch (targa_header.pixel_size)
|
switch (targa_header.pixel_size)
|
||||||
{
|
{
|
||||||
case 24:
|
case 24:
|
||||||
blue = getc(fin);
|
blue = Buf_GetC(buf);
|
||||||
green = getc(fin);
|
green = Buf_GetC(buf);
|
||||||
red = getc(fin);
|
red = Buf_GetC(buf);
|
||||||
*pixbuf++ = red;
|
*pixbuf++ = red;
|
||||||
*pixbuf++ = green;
|
*pixbuf++ = green;
|
||||||
*pixbuf++ = blue;
|
*pixbuf++ = blue;
|
||||||
*pixbuf++ = 255;
|
*pixbuf++ = 255;
|
||||||
break;
|
break;
|
||||||
case 32:
|
case 32:
|
||||||
blue = getc(fin);
|
blue = Buf_GetC(buf);
|
||||||
green = getc(fin);
|
green = Buf_GetC(buf);
|
||||||
red = getc(fin);
|
red = Buf_GetC(buf);
|
||||||
alphabyte = getc(fin);
|
alphabyte = Buf_GetC(buf);
|
||||||
*pixbuf++ = red;
|
*pixbuf++ = red;
|
||||||
*pixbuf++ = green;
|
*pixbuf++ = green;
|
||||||
*pixbuf++ = blue;
|
*pixbuf++ = blue;
|
||||||
|
@ -320,6 +356,7 @@ byte *Image_LoadTGA (FILE *fin, int *width, int *height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Buf_Free(buf);
|
||||||
fclose(fin);
|
fclose(fin);
|
||||||
|
|
||||||
*width = (int)(targa_header.width);
|
*width = (int)(targa_header.width);
|
||||||
|
@ -360,6 +397,7 @@ byte *Image_LoadPCX (FILE *f, int *width, int *height)
|
||||||
int x, y, w, h, readbyte, runlength, start;
|
int x, y, w, h, readbyte, runlength, start;
|
||||||
byte *p, *data;
|
byte *p, *data;
|
||||||
byte palette[768];
|
byte palette[768];
|
||||||
|
stdio_buffer_t *buf;
|
||||||
|
|
||||||
start = ftell (f); //save start of file (since we might be inside a pak file, SEEK_SET might not be the start of the pcx)
|
start = ftell (f); //save start of file (since we might be inside a pak file, SEEK_SET might not be the start of the pcx)
|
||||||
|
|
||||||
|
@ -391,18 +429,20 @@ byte *Image_LoadPCX (FILE *f, int *width, int *height)
|
||||||
//back to start of image data
|
//back to start of image data
|
||||||
fseek (f, start + sizeof(pcx), SEEK_SET);
|
fseek (f, start + sizeof(pcx), SEEK_SET);
|
||||||
|
|
||||||
|
buf = Buf_Alloc(f);
|
||||||
|
|
||||||
for (y=0; y<h; y++)
|
for (y=0; y<h; y++)
|
||||||
{
|
{
|
||||||
p = data + y * w * 4;
|
p = data + y * w * 4;
|
||||||
|
|
||||||
for (x=0; x<(pcx.bytes_per_line); ) //read the extra padding byte if necessary
|
for (x=0; x<(pcx.bytes_per_line); ) //read the extra padding byte if necessary
|
||||||
{
|
{
|
||||||
readbyte = fgetc(f);
|
readbyte = Buf_GetC(buf);
|
||||||
|
|
||||||
if(readbyte >= 0xC0)
|
if(readbyte >= 0xC0)
|
||||||
{
|
{
|
||||||
runlength = readbyte & 0x3F;
|
runlength = readbyte & 0x3F;
|
||||||
readbyte = fgetc(f);
|
readbyte = Buf_GetC(buf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
runlength = 1;
|
runlength = 1;
|
||||||
|
@ -419,6 +459,8 @@ byte *Image_LoadPCX (FILE *f, int *width, int *height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Buf_Free(buf);
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
*width = w;
|
*width = w;
|
||||||
|
|
Loading…
Reference in a new issue