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;
|
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 *
|
static inline byte *
|
||||||
read_bgr (byte *buf, int count, byte **data)
|
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);
|
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 *
|
static inline byte *
|
||||||
read_bgra (byte *buf, int count, byte **data)
|
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);
|
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 *
|
static inline byte *
|
||||||
read_rgba (byte *buf, int count, byte **data)
|
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);
|
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 *
|
struct tex_s *
|
||||||
LoadTGA (QFile *fin)
|
LoadTGA (QFile *fin)
|
||||||
{
|
{
|
||||||
|
@ -168,9 +214,11 @@ LoadTGA (QFile *fin)
|
||||||
dataByte += targa->id_length;
|
dataByte += targa->id_length;
|
||||||
|
|
||||||
span = columns * 4; // tex->format
|
span = columns * 4; // tex->format
|
||||||
pixrow = tex->data + (rows - 1) * span;
|
|
||||||
|
|
||||||
if (targa->image_type == 2) { // Uncompressed image
|
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) {
|
switch (targa->pixel_size) {
|
||||||
case 24:
|
case 24:
|
||||||
for (row = rows - 1; row >= 0; row--, pixrow -= span) {
|
for (row = rows - 1; row >= 0; row--, pixrow -= span) {
|
||||||
|
@ -187,11 +235,72 @@ LoadTGA (QFile *fin)
|
||||||
}
|
}
|
||||||
break;
|
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
|
} else if (targa->image_type == 10) { // RLE compressed image
|
||||||
unsigned char packetHeader, packetSize;
|
unsigned char packetHeader, packetSize;
|
||||||
|
|
||||||
byte *(*expand) (byte *buf, int count, byte **data);
|
byte *(*expand) (byte *buf, int count, byte **data);
|
||||||
|
|
||||||
|
pixrow = tex->data + (rows - 1) * span;
|
||||||
|
|
||||||
if (targa->pixel_size == 24)
|
if (targa->pixel_size == 24)
|
||||||
expand = read_bgr;
|
expand = read_bgr;
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue