mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
Fix handling of all non-RLE-compressed tga formats we supposedly support. Now
we work even if the first pixel isn't in lower left. ;) Handling the RLE-compressed oddball cases would require a lot more code duplication, will brute force that later if nobody beats me to it with a clean solution.
This commit is contained in:
parent
fe8161c036
commit
59c4290563
1 changed files with 121 additions and 12 deletions
131
libs/util/tga.c
131
libs/util/tga.c
|
@ -74,6 +74,31 @@ blit_rgba (byte *buf, int count, byte red, byte green, byte blue, byte alpha)
|
|||
return buf;
|
||||
}
|
||||
|
||||
static inline byte *
|
||||
reverse_blit_rgb (byte *buf, int count, byte red, byte green, byte blue)
|
||||
{
|
||||
while (count--) {
|
||||
*buf-- = 255;
|
||||
*buf-- = blue;
|
||||
*buf-- = green;
|
||||
*buf-- = red;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline byte *
|
||||
reverse_blit_rgba (byte *buf, int count, byte red, byte green, byte blue,
|
||||
byte alpha)
|
||||
{
|
||||
while (count--) {
|
||||
*buf-- = alpha;
|
||||
*buf-- = blue;
|
||||
*buf-- = green;
|
||||
*buf-- = red;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline byte *
|
||||
read_bgr (byte *buf, int count, byte **data)
|
||||
{
|
||||
|
@ -84,16 +109,6 @@ read_bgr (byte *buf, int count, byte **data)
|
|||
return blit_rgb (buf, count, red, green, blue);
|
||||
}
|
||||
|
||||
static inline byte *
|
||||
read_rgb (byte *buf, int count, byte **data)
|
||||
{
|
||||
byte red = *(*data)++;
|
||||
byte green = *(*data)++;
|
||||
byte blue = *(*data)++;
|
||||
|
||||
return blit_rgb (buf, count, red, green, blue);
|
||||
}
|
||||
|
||||
static inline byte *
|
||||
read_bgra (byte *buf, int count, byte **data)
|
||||
{
|
||||
|
@ -105,6 +120,16 @@ read_bgra (byte *buf, int count, byte **data)
|
|||
return blit_rgba (buf, count, red, green, blue, alpha);
|
||||
}
|
||||
|
||||
static inline byte *
|
||||
read_rgb (byte *buf, int count, byte **data)
|
||||
{
|
||||
byte red = *(*data)++;
|
||||
byte green = *(*data)++;
|
||||
byte blue = *(*data)++;
|
||||
|
||||
return blit_rgb (buf, count, red, green, blue);
|
||||
}
|
||||
|
||||
static inline byte *
|
||||
read_rgba (byte *buf, int count, byte **data)
|
||||
{
|
||||
|
@ -116,6 +141,27 @@ read_rgba (byte *buf, int count, byte **data)
|
|||
return blit_rgba (buf, count, red, green, blue, alpha);
|
||||
}
|
||||
|
||||
static inline byte *
|
||||
reverse_read_bgr (byte *buf, int count, byte **data)
|
||||
{
|
||||
byte blue = *(*data)++;
|
||||
byte green = *(*data)++;
|
||||
byte red = *(*data)++;
|
||||
|
||||
return reverse_blit_rgb (buf, count, red, green, blue);
|
||||
}
|
||||
|
||||
static inline byte *
|
||||
reverse_read_bgra (byte *buf, int count, byte **data)
|
||||
{
|
||||
byte blue = *(*data)++;
|
||||
byte green = *(*data)++;
|
||||
byte red = *(*data)++;
|
||||
byte alpha = *(*data)++;
|
||||
|
||||
return reverse_blit_rgba (buf, count, red, green, blue, alpha);
|
||||
}
|
||||
|
||||
struct tex_s *
|
||||
LoadTGA (QFile *fin)
|
||||
{
|
||||
|
@ -168,9 +214,11 @@ LoadTGA (QFile *fin)
|
|||
dataByte += targa->id_length;
|
||||
|
||||
span = columns * 4; // tex->format
|
||||
pixrow = tex->data + (rows - 1) * span;
|
||||
|
||||
if (targa->image_type == 2) { // Uncompressed image
|
||||
switch (targa->attributes & 48) {
|
||||
case 0: // Origin at bottom left
|
||||
pixrow = tex->data + (rows - 1) * span;
|
||||
switch (targa->pixel_size) {
|
||||
case 24:
|
||||
for (row = rows - 1; row >= 0; row--, pixrow -= span) {
|
||||
|
@ -187,11 +235,72 @@ LoadTGA (QFile *fin)
|
|||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 16: // Origin at bottom right
|
||||
pixrow = tex->data + rows * span - 4;
|
||||
switch (targa->pixel_size) {
|
||||
case 24:
|
||||
for (row = rows - 1; row >= 0; row--, pixrow -= span) {
|
||||
pixcol = pixrow;
|
||||
for (column = columns - 1; column >= 0; column--)
|
||||
pixcol = reverse_read_bgr (pixcol, 1, &dataByte);
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
for (row = rows - 1; row >= 0; row--, pixrow -= span) {
|
||||
pixcol = pixrow;
|
||||
for (column = columns - 1; column >= 0; column--)
|
||||
pixcol = reverse_read_bgra (pixcol, 1, &dataByte);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 32: // Origin at top left
|
||||
pixrow = tex->data;
|
||||
switch (targa->pixel_size) {
|
||||
case 24:
|
||||
for (row = 0; row < rows; row++, pixrow += span) {
|
||||
pixcol = pixrow;
|
||||
for (column = 0; column < columns; column++)
|
||||
pixcol = read_bgr (pixcol, 1, &dataByte);
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
for (row = 0; row < rows; row++, pixrow += span) {
|
||||
pixcol = pixrow;
|
||||
for (column = 0; column < columns; column++)
|
||||
pixcol = read_bgra (pixcol, 1, &dataByte);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 48: // Origin at top right
|
||||
pixrow = tex->data + span - 4;
|
||||
switch (targa->pixel_size) {
|
||||
case 24:
|
||||
for (row = 0; row < rows; row++, pixrow += span) {
|
||||
pixcol = pixrow;
|
||||
for (column = columns - 1; column >= 0; column--)
|
||||
pixcol = reverse_read_bgr (pixcol, 1, &dataByte);
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
for (row = 0; row < rows; row++, pixrow += span) {
|
||||
pixcol = pixrow;
|
||||
for (column = columns - 1; column >= 0; column--)
|
||||
pixcol = reverse_read_bgra (pixcol, 1, &dataByte);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (targa->image_type == 10) { // RLE compressed image
|
||||
unsigned char packetHeader, packetSize;
|
||||
|
||||
byte *(*expand) (byte *buf, int count, byte **data);
|
||||
|
||||
pixrow = tex->data + (rows - 1) * span;
|
||||
|
||||
if (targa->pixel_size == 24)
|
||||
expand = read_bgr;
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue