some readability (and speed?) improvments for LoadTGA

This commit is contained in:
Bill Currie 2001-12-21 05:29:33 +00:00
parent 010ca032a5
commit b4de52eb5c

View file

@ -74,15 +74,81 @@ fgetLittleLong (VFile *f)
} }
*/ */
static inline byte *
blit_rgb (byte *buf, int count, byte red, byte green, byte blue)
{
while (count--) {
buf[0] = red;
buf[1] = green;
buf[2] = blue;
buf += 3;
}
return buf;
}
static inline byte *
blit_rgba (byte *buf, int count, byte red, byte green, byte blue, byte alpha)
{
while (count--) {
buf[0] = red;
buf[1] = green;
buf[2] = blue;
buf[3] = alpha;
buf += 4;
}
return buf;
}
static inline byte *
read_bgr (byte *buf, int count, VFile *f)
{
byte blue = Qgetc (f);
byte green = Qgetc (f);
byte red = Qgetc (f);
return blit_rgb(buf, count, red, green, blue);
}
static inline byte *
read_rgb (byte *buf, int count, VFile *f)
{
byte red = Qgetc (f);
byte green = Qgetc (f);
byte blue = Qgetc (f);
return blit_rgb(buf, count, red, green, blue);
}
static inline byte *
read_bgra (byte *buf, int count, VFile *f)
{
byte blue = Qgetc (f);
byte green = Qgetc (f);
byte red = Qgetc (f);
byte alpha = Qgetc (f);
return blit_rgba (buf, count, red, green, blue, alpha);
}
static inline byte *
read_rgba (byte *buf, int count, VFile *f)
{
byte red = Qgetc (f);
byte green = Qgetc (f);
byte blue = Qgetc (f);
byte alpha = Qgetc (f);
return blit_rgba (buf, count, red, green, blue, alpha);
}
struct tex_s * struct tex_s *
LoadTGA (VFile *fin) LoadTGA (VFile *fin)
{ {
byte *pixbuf; byte *pixcol, *pixrow;
byte red = 0, green = 0, blue = 0, alphabyte = 0; int column, row, columns, rows, numPixels, span;
int column, row, columns, rows, numPixels;
TargaHeader targa_header; TargaHeader targa_header;
tex_t *targa_data; tex_t *targa_data;
targa_header.id_length = Qgetc (fin); targa_header.id_length = Qgetc (fin);
targa_header.colormap_type = Qgetc (fin); targa_header.colormap_type = Qgetc (fin);
@ -135,118 +201,66 @@ LoadTGA (VFile *fin)
if (targa_header.id_length != 0) if (targa_header.id_length != 0)
Qseek (fin, targa_header.id_length, SEEK_CUR); // skip TARGA image Qseek (fin, targa_header.id_length, SEEK_CUR); // skip TARGA image
// comment // comment
span = columns * targa_data->format;
pixrow = targa_data->data + (rows - 1) * span;
if (targa_header.image_type == 2) { // Uncompressed image if (targa_header.image_type == 2) { // Uncompressed image
switch (targa_header.pixel_size) { switch (targa_header.pixel_size) {
case 24: case 24:
for (row = rows - 1; row >= 0; row--) { for (row = rows - 1; row >= 0; row--, pixrow -= span) {
pixbuf = targa_data->data + row * columns * pixcol = pixrow;
targa_data->format; for (column = 0; column < columns; column++)
for (column = 0; column < columns; column++) { pixcol = read_bgr (pixcol, 1, fin);
blue = Qgetc (fin);
green = Qgetc (fin);
red = Qgetc (fin);
*pixbuf++ = red;
*pixbuf++ = green;
*pixbuf++ = blue;
}
} }
break; break;
case 32: case 32:
for (row = rows - 1; row >= 0; row--) { for (row = rows - 1; row >= 0; row--, pixrow -= span) {
pixbuf = targa_data->data + row * columns * pixcol = pixrow;
targa_data->format; for (column = 0; column < columns; column++)
for (column = 0; column < columns; column++) { pixcol = read_bgra (pixcol, 1, fin);
blue = Qgetc (fin);
green = Qgetc (fin);
red = Qgetc (fin);
alphabyte = Qgetc (fin);
*pixbuf++ = red;
*pixbuf++ = green;
*pixbuf++ = blue;
*pixbuf++ = alphabyte;
}
} }
break; break;
} }
} else if (targa_header.image_type == 10) { // RLE compressed image } else if (targa_header.image_type == 10) { // RLE compressed image
unsigned char packetHeader, packetSize, j; unsigned char packetHeader, packetSize;
for (row = rows - 1; row >= 0; row--) { byte *(*expand)(byte *buf, int count, VFile *f);
pixbuf = targa_data->data + row * columns * targa_data->format;
if (targa_header.pixel_size == 24)
expand = read_bgr;
else
expand = read_bgra;
for (row = rows - 1; row >= 0; row--, pixrow -= span) {
pixcol = pixrow;
for (column = 0; column < columns;) { for (column = 0; column < columns;) {
packetHeader = Qgetc (fin); packetHeader = Qgetc (fin);
packetSize = 1 + (packetHeader & 0x7f); packetSize = 1 + (packetHeader & 0x7f);
if (packetHeader & 0x80) { // run-length packet while (packetSize > columns - column) {
switch (targa_header.pixel_size) { int count = columns - column;
case 24:
blue = Qgetc (fin);
green = Qgetc (fin);
red = Qgetc (fin);
break;
case 32:
blue = Qgetc (fin);
green = Qgetc (fin);
red = Qgetc (fin);
alphabyte = Qgetc (fin);
break;
}
for (j = 0; j < packetSize; j++) { packetSize -= count;
*pixbuf++ = red; if (packetHeader & 0x80) { // run-length packet
*pixbuf++ = green; expand (pixcol, count, fin);
*pixbuf++ = blue; } else { // non run-length packet
if (targa_header.pixel_size > 24) while (count--)
*pixbuf++ = alphabyte; expand (pixcol, 1, fin);
column++;
if (column == columns) { // run spans across rows
column = 0;
if (row > 0)
row--;
else
goto breakOut;
pixbuf = targa_data->data + row * columns *
targa_data->format;
}
} }
column = 0;
pixcol = (pixrow -= span);
if (--row < 0)
goto done;
}
column += packetSize;
if (packetHeader & 0x80) { // run-length packet
pixcol = expand (pixcol, packetSize, fin);
} else { // non run-length packet } else { // non run-length packet
for (j = 0; j < packetSize; j++) { while (packetSize--)
switch (targa_header.pixel_size) { pixcol = expand (pixcol, 1, fin);
case 24:
blue = Qgetc (fin);
green = Qgetc (fin);
red = Qgetc (fin);
*pixbuf++ = red;
*pixbuf++ = green;
*pixbuf++ = blue;
break;
case 32:
blue = Qgetc (fin);
green = Qgetc (fin);
red = Qgetc (fin);
alphabyte = Qgetc (fin);
*pixbuf++ = red;
*pixbuf++ = green;
*pixbuf++ = blue;
*pixbuf++ = alphabyte;
break;
}
column++;
if (column == columns) { // pixel packet run spans
// across rows
column = 0;
if (row > 0)
row--;
else
goto breakOut;
pixbuf = targa_data->data + row * columns *
targa_data->format;
}
}
} }
} }
breakOut:;
} }
done:
} }
Qclose (fin); Qclose (fin);