Cleanup TGA header interpretation
* Read the colour map `First Entry Index` field. If non-zero, error out as the format specification is vague as to what it does and different readers interpret it differently. * Rename the variable that holds the colour map entry size as the existing name could be misinterpreted as the size of the pointer, not the thing pointed to. * Handle images reporting themselves as 15 bits per pixel in the same way as Truevision's example code.
This commit is contained in:
parent
f97ea3577d
commit
47ec2c7951
@ -273,8 +273,9 @@ int *numComponents_ret)
|
|||||||
int flags;
|
int flags;
|
||||||
int format;
|
int format;
|
||||||
unsigned char *colormap;
|
unsigned char *colormap;
|
||||||
|
int colormapFirst = 0;
|
||||||
int colormapLen = 0;
|
int colormapLen = 0;
|
||||||
int indexsize = 0;
|
int colormapDepth = 0;
|
||||||
int rleIsCompressed;
|
int rleIsCompressed;
|
||||||
int rleRemaining;
|
int rleRemaining;
|
||||||
int rleEntrySize;
|
int rleEntrySize;
|
||||||
@ -283,6 +284,7 @@ int *numComponents_ret)
|
|||||||
unsigned char *dest;
|
unsigned char *dest;
|
||||||
int bpr;
|
int bpr;
|
||||||
unsigned char *linebuf;
|
unsigned char *linebuf;
|
||||||
|
int alphaBPP;
|
||||||
|
|
||||||
tgaerror = ERR_NO_ERROR; /* clear error */
|
tgaerror = ERR_NO_ERROR; /* clear error */
|
||||||
|
|
||||||
@ -296,8 +298,10 @@ int *numComponents_ret)
|
|||||||
type = header[2];
|
type = header[2];
|
||||||
width = getInt16(&header[12]);
|
width = getInt16(&header[12]);
|
||||||
height = getInt16(&header[14]);
|
height = getInt16(&header[14]);
|
||||||
depth = header[16] >> 3;
|
// Add 7 as R5G5B5 images with no alpha data take up two bytes per pixel, but only 15 bits
|
||||||
|
depth = (header[16] + 7) >> 3;
|
||||||
flags = header[17];
|
flags = header[17];
|
||||||
|
alphaBPP = flags & 0x0F;
|
||||||
|
|
||||||
/* check for reasonable values in case this is not a tga file */
|
/* check for reasonable values in case this is not a tga file */
|
||||||
if ((type != 1 && type != 2 && type != 10) ||
|
if ((type != 1 && type != 2 && type != 10) ||
|
||||||
@ -315,18 +319,25 @@ int *numComponents_ret)
|
|||||||
colormap = NULL;
|
colormap = NULL;
|
||||||
if (header[1] == 1) /* there is a colormap */
|
if (header[1] == 1) /* there is a colormap */
|
||||||
{
|
{
|
||||||
colormapLen = getInt16(&header[5]);
|
colormapFirst = getInt16(&header[3]);
|
||||||
indexsize = header[7]>>3;
|
if (colormapFirst != 0)
|
||||||
colormap = new unsigned char [colormapLen*indexsize];
|
|
||||||
fin.read((char*)colormap,colormapLen*indexsize);
|
|
||||||
|
|
||||||
if (indexsize == 2) /* 16 bits */
|
|
||||||
{
|
{
|
||||||
if (flags & 1) format = 4;
|
// Error on non-zero colormapFirst as it's unclear from the specification what it actually does
|
||||||
|
tgaerror = ERR_UNSUPPORTED;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
colormapLen = getInt16(&header[5]);
|
||||||
|
colormapDepth = (header[7] + 7) >> 3;
|
||||||
|
colormap = new unsigned char[colormapLen*colormapDepth];
|
||||||
|
fin.read((char*)colormap, colormapLen*colormapDepth);
|
||||||
|
|
||||||
|
if (colormapDepth == 2) /* 16 bits */
|
||||||
|
{
|
||||||
|
if (alphaBPP == 1) format = 4;
|
||||||
else format = 3;
|
else format = 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
format = indexsize;
|
format = colormapDepth;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -360,7 +371,7 @@ int *numComponents_ret)
|
|||||||
{
|
{
|
||||||
case 1: /* colormap, uncompressed */
|
case 1: /* colormap, uncompressed */
|
||||||
{
|
{
|
||||||
if (colormapLen == 0 || indexsize == 0)
|
if (colormapLen == 0 || colormapDepth == 0)
|
||||||
{
|
{
|
||||||
tgaerror = ERR_UNSUPPORTED; /* colormap missing or empty */
|
tgaerror = ERR_UNSUPPORTED; /* colormap missing or empty */
|
||||||
|
|
||||||
@ -373,7 +384,7 @@ int *numComponents_ret)
|
|||||||
unsigned char * formattedMap = new unsigned char[colormapLen * format];
|
unsigned char * formattedMap = new unsigned char[colormapLen * format];
|
||||||
for (int i = 0; i < colormapLen; i++)
|
for (int i = 0; i < colormapLen; i++)
|
||||||
{
|
{
|
||||||
convert_data(colormap, formattedMap, i, indexsize, format);
|
convert_data(colormap, formattedMap, i, colormapDepth, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
Loading…
Reference in New Issue
Block a user