Implement reading 16 and 32-bit color-mapped TGA images
Currently only 24-bit color-mapped images can be read. Closes #18966. Co-authored-by: Muster128 <Muster128@trac.wxwidgets.org>
This commit is contained in:
@@ -192,6 +192,22 @@ void Palette_GetRGB(const unsigned char *palette, unsigned int paletteCount,
|
||||
*blue = palette[(paletteCount * 2) + index];
|
||||
}
|
||||
|
||||
static
|
||||
void Palette_GetRGBA(const unsigned char *palette, unsigned int paletteCount,
|
||||
unsigned int index,
|
||||
unsigned char *red, unsigned char *green, unsigned char *blue, unsigned char* alpha)
|
||||
{
|
||||
if (index >= paletteCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
*red = palette[index];
|
||||
*green = palette[(paletteCount * 1) + index];
|
||||
*blue = palette[(paletteCount * 2) + index];
|
||||
*alpha = palette[(paletteCount * 3) + index];
|
||||
}
|
||||
|
||||
static
|
||||
void Palette_SetRGB(unsigned char *palette, unsigned int paletteCount,
|
||||
unsigned int index,
|
||||
@@ -202,6 +218,17 @@ void Palette_SetRGB(unsigned char *palette, unsigned int paletteCount,
|
||||
palette[(paletteCount * 2) + index] = blue;
|
||||
}
|
||||
|
||||
static
|
||||
void Palette_SetRGBA(unsigned char *palette, unsigned int paletteCount,
|
||||
unsigned int index,
|
||||
unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha)
|
||||
{
|
||||
palette[index] = red;
|
||||
palette[(paletteCount * 1) + index] = green;
|
||||
palette[(paletteCount * 2) + index] = blue;
|
||||
palette[(paletteCount * 3) + index] = alpha;
|
||||
}
|
||||
|
||||
static
|
||||
int ReadTGA(wxImage* image, wxInputStream& stream)
|
||||
{
|
||||
@@ -214,6 +241,8 @@ int ReadTGA(wxImage* image, wxInputStream& stream)
|
||||
short imageType = hdr[HDR_IMAGETYPE];
|
||||
unsigned int paletteLength = hdr[HDR_PALETTELENGTH]
|
||||
+ 256 * hdr[HDR_PALETTELENGTH + 1];
|
||||
unsigned int paletteStart = hdr[HDR_PALETTESTART]
|
||||
+ 256 * hdr[HDR_PALETTESTART + 1];
|
||||
int width = (hdr[HDR_WIDTH] + 256 * hdr[HDR_WIDTH + 1]) -
|
||||
(hdr[HDR_XORIGIN] + 256 * hdr[HDR_XORIGIN + 1]);
|
||||
int height = (hdr[HDR_HEIGHT] + 256 * hdr[HDR_HEIGHT + 1]) -
|
||||
@@ -241,8 +270,15 @@ int ReadTGA(wxImage* image, wxInputStream& stream)
|
||||
|
||||
unsigned char *dst = image->GetData();
|
||||
|
||||
short palettebpp = hdr[HDR_PALETTEBITS];
|
||||
if (colorType == wxTGA_MAPPED && !(palettebpp == 15 || palettebpp == 16 || palettebpp == 24 || palettebpp == 32))
|
||||
{
|
||||
return wxTGA_INVFORMAT;
|
||||
}
|
||||
|
||||
unsigned char* alpha = NULL;
|
||||
if (bpp == 16 || bpp == 32)
|
||||
if ((colorType != wxTGA_MAPPED && (bpp == 16 || bpp == 32)) ||
|
||||
(colorType == wxTGA_MAPPED && (palettebpp == 16 || palettebpp == 32)))
|
||||
{
|
||||
image->SetAlpha();
|
||||
|
||||
@@ -253,22 +289,54 @@ int ReadTGA(wxImage* image, wxInputStream& stream)
|
||||
if (stream.SeekI(offset, wxFromStart) == wxInvalidOffset)
|
||||
return wxTGA_INVFORMAT;
|
||||
|
||||
|
||||
wxScopedArray<unsigned char> palette;
|
||||
// Load a palette if we have one.
|
||||
if (colorType == wxTGA_MAPPED)
|
||||
{
|
||||
{
|
||||
wxScopedArray<unsigned char> paletteTmp(paletteLength*3);
|
||||
int palEntrySize = (palettebpp == 15 || palettebpp == 24) ? 3 : 4;
|
||||
wxScopedArray<unsigned char> paletteTmp(paletteLength*palEntrySize);
|
||||
palette.swap(paletteTmp);
|
||||
}
|
||||
|
||||
unsigned char buf[3];
|
||||
|
||||
for (unsigned int i = 0; i < paletteLength; i++)
|
||||
{
|
||||
stream.Read(buf, 3);
|
||||
unsigned char buf[4];
|
||||
stream.Read(buf, (palettebpp == 15) ? 2 : palettebpp/8);
|
||||
|
||||
Palette_SetRGB(palette.get(), paletteLength, i, buf[2], buf[1], buf[0]);
|
||||
switch(palettebpp)
|
||||
{
|
||||
case 15:
|
||||
{
|
||||
unsigned char r = (buf[1] & 0x7C) << 1;
|
||||
r |= r >> 5;
|
||||
unsigned char g = ((buf[1] & 0x03) << 6) | ((buf[0] & 0xE0) >> 2);
|
||||
g |= g >> 5;
|
||||
unsigned char b = (buf[0] & 0x1F) << 3;
|
||||
b |= b >> 5;
|
||||
Palette_SetRGB(palette.get(), paletteLength, paletteStart+i, r, g, b);
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
{
|
||||
unsigned char a = (buf[1] & 0x80) ? 0 : 255;
|
||||
unsigned char r = (buf[1] & 0x7C) << 1;
|
||||
r |= r >> 5;
|
||||
unsigned char g = ((buf[1] & 0x03) << 6) | ((buf[0] & 0xE0) >> 2);
|
||||
g |= g >> 5;
|
||||
unsigned char b = (buf[0] & 0x1F) << 3;
|
||||
b |= b >> 5;
|
||||
Palette_SetRGBA(palette.get(), paletteLength, paletteStart+i, r, g, b, a);
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
Palette_SetRGB(palette.get(), paletteLength, paletteStart+i, buf[2], buf[1], buf[0]);
|
||||
break;
|
||||
case 32:
|
||||
Palette_SetRGBA(palette.get(), paletteLength, paletteStart+i, buf[2], buf[1], buf[0], buf[3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if wxUSE_PALETTE
|
||||
@@ -313,12 +381,24 @@ int ReadTGA(wxImage* image, wxInputStream& stream)
|
||||
{
|
||||
for (unsigned long index = 0; index < imageSize; index += pixelSize)
|
||||
{
|
||||
Palette_GetRGB(palette.get(), paletteLength,
|
||||
imageData[index], &r, &g, &b);
|
||||
|
||||
*(dst++) = r;
|
||||
*(dst++) = g;
|
||||
*(dst++) = b;
|
||||
if ( alpha )
|
||||
{
|
||||
unsigned char a;
|
||||
Palette_GetRGBA(palette.get(), paletteLength,
|
||||
imageData[index], &r, &g, &b, &a);
|
||||
*dst++ = r;
|
||||
*dst++ = g;
|
||||
*dst++ = b;
|
||||
*alpha++ = a;
|
||||
}
|
||||
else
|
||||
{
|
||||
Palette_GetRGB(palette.get(), paletteLength,
|
||||
imageData[index], &r, &g, &b);
|
||||
*dst++ = r;
|
||||
*dst++ = g;
|
||||
*dst++ = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -508,12 +588,24 @@ int ReadTGA(wxImage* image, wxInputStream& stream)
|
||||
{
|
||||
for (unsigned long index = 0; index < imageSize; index += pixelSize)
|
||||
{
|
||||
Palette_GetRGB(palette.get(), paletteLength,
|
||||
imageData[index], &r, &g, &b);
|
||||
|
||||
*(dst++) = r;
|
||||
*(dst++) = g;
|
||||
*(dst++) = b;
|
||||
if ( alpha )
|
||||
{
|
||||
unsigned char a;
|
||||
Palette_GetRGBA(palette.get(), paletteLength,
|
||||
imageData[index], &r, &g, &b, &a);
|
||||
*dst++ = r;
|
||||
*dst++ = g;
|
||||
*dst++ = b;
|
||||
*alpha++ = a;
|
||||
}
|
||||
else
|
||||
{
|
||||
Palette_GetRGB(palette.get(), paletteLength,
|
||||
imageData[index], &r, &g, &b);
|
||||
*dst++ = r;
|
||||
*dst++ = g;
|
||||
*dst++ = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
Reference in New Issue
Block a user