Fix some rare PNG tRNS chunk cases
- For grayscale images drawn with the paletted renderer, the value here was treated as always full range [0,65535]. The max value is actually determined by the bit depth. - For RGB images drawn with the paletted renderer, the tRNS chunk was ignored. - For grayscale images drawn with the RGB renderer, having a tRNS chunk present resulted in undefined behavior. - For RGB images drawn with the RGB renderer, the tRNS chunk was ignored.
This commit is contained in:
parent
61d033328b
commit
0fc40cff0a
3 changed files with 90 additions and 34 deletions
|
|
@ -70,6 +70,8 @@ protected:
|
|||
BYTE BitDepth;
|
||||
BYTE ColorType;
|
||||
BYTE Interlace;
|
||||
bool HaveTrans;
|
||||
WORD NonPaletteTrans[3];
|
||||
|
||||
BYTE *PaletteMap;
|
||||
int PaletteSize;
|
||||
|
|
@ -195,7 +197,7 @@ FTexture *PNGTexture_CreateFromFile(PNGHandle *png, const FString &filename)
|
|||
FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height,
|
||||
BYTE depth, BYTE colortype, BYTE interlace)
|
||||
: FTexture(NULL, lumpnum), SourceFile(filename), Pixels(0), Spans(0),
|
||||
BitDepth(depth), ColorType(colortype), Interlace(interlace),
|
||||
BitDepth(depth), ColorType(colortype), Interlace(interlace), HaveTrans(false),
|
||||
PaletteMap(0), PaletteSize(0), StartOfIDAT(0)
|
||||
{
|
||||
union
|
||||
|
|
@ -204,7 +206,6 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
|
|||
BYTE pngpal[256][3];
|
||||
} p;
|
||||
BYTE trans[256];
|
||||
bool havetRNS = false;
|
||||
DWORD len, id;
|
||||
int i;
|
||||
|
||||
|
|
@ -273,7 +274,11 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
|
|||
|
||||
case MAKE_ID('t','R','N','S'):
|
||||
lump.Read (trans, len);
|
||||
havetRNS = true;
|
||||
HaveTrans = true;
|
||||
// Save for colortype 2
|
||||
NonPaletteTrans[0] = BigShort(((WORD *)trans)[0]);
|
||||
NonPaletteTrans[1] = BigShort(((WORD *)trans)[1]);
|
||||
NonPaletteTrans[2] = BigShort(((WORD *)trans)[2]);
|
||||
break;
|
||||
|
||||
case MAKE_ID('a','l','P','h'):
|
||||
|
|
@ -297,13 +302,13 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
|
|||
case 0: // Grayscale
|
||||
if (!bAlphaTexture)
|
||||
{
|
||||
if (colortype == 0 && havetRNS && trans[0] != 0)
|
||||
if (colortype == 0 && HaveTrans && NonPaletteTrans[0] != 0 && NonPaletteTrans[0] < 256)
|
||||
{
|
||||
bMasked = true;
|
||||
PaletteSize = 256;
|
||||
PaletteMap = new BYTE[256];
|
||||
memcpy (PaletteMap, GrayMap, 256);
|
||||
PaletteMap[trans[0]] = 0;
|
||||
PaletteMap[NonPaletteTrans[0]] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -328,6 +333,10 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
|
|||
case 6: // RGB + Alpha
|
||||
bMasked = true;
|
||||
break;
|
||||
|
||||
case 2: // RGB
|
||||
bMasked = HaveTrans;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -521,7 +530,23 @@ void FPNGTexture::MakeTexture ()
|
|||
{
|
||||
for (y = Height; y > 0; --y)
|
||||
{
|
||||
*out++ = RGB32k.RGB[in[0]>>3][in[1]>>3][in[2]>>3];
|
||||
if (!HaveTrans)
|
||||
{
|
||||
*out++ = RGB32k.RGB[in[0]>>3][in[1]>>3][in[2]>>3];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in[0] == NonPaletteTrans[0] &&
|
||||
in[1] == NonPaletteTrans[1] &&
|
||||
in[2] == NonPaletteTrans[2])
|
||||
{
|
||||
*out++ = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out++ = RGB32k.RGB[in[0]>>3][in[1]>>3][in[2]>>3];
|
||||
}
|
||||
}
|
||||
in += pitch;
|
||||
}
|
||||
in -= backstep;
|
||||
|
|
@ -625,11 +650,14 @@ int FPNGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
|||
break;
|
||||
|
||||
case MAKE_ID('t','R','N','S'):
|
||||
for(DWORD i = 0; i < len; i++)
|
||||
if (ColorType == 3)
|
||||
{
|
||||
(*lump) >> pe[i].a;
|
||||
if (pe[i].a != 0 && pe[i].a != 255)
|
||||
transpal = true;
|
||||
for(DWORD i = 0; i < len; i++)
|
||||
{
|
||||
(*lump) >> pe[i].a;
|
||||
if (pe[i].a != 0 && pe[i].a != 255)
|
||||
transpal = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -639,6 +667,12 @@ int FPNGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
|||
lump->Read(&id, 4);
|
||||
}
|
||||
|
||||
if (ColorType == 0 && HaveTrans && NonPaletteTrans[0] < 256)
|
||||
{
|
||||
pe[NonPaletteTrans[0]].a = 0;
|
||||
transpal = true;
|
||||
}
|
||||
|
||||
BYTE * Pixels = new BYTE[pixwidth * Height];
|
||||
|
||||
lump->Seek (StartOfIDAT, SEEK_SET);
|
||||
|
|
@ -655,7 +689,15 @@ int FPNGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
|||
break;
|
||||
|
||||
case 2:
|
||||
bmp->CopyPixelDataRGB(x, y, Pixels, Width, Height, 3, pixwidth, rotate, CF_RGB, inf);
|
||||
if (!HaveTrans)
|
||||
{
|
||||
bmp->CopyPixelDataRGB(x, y, Pixels, Width, Height, 3, pixwidth, rotate, CF_RGB, inf);
|
||||
}
|
||||
else
|
||||
{
|
||||
bmp->CopyPixelDataRGB(x, y, Pixels, Width, Height, 3, pixwidth, rotate, CF_RGBT, inf,
|
||||
NonPaletteTrans[0], NonPaletteTrans[1], NonPaletteTrans[2]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue