mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 06:53:58 +00:00
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
|
@ -46,7 +46,8 @@
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
template<class TSrc, class TDest, class TBlend>
|
template<class TSrc, class TDest, class TBlend>
|
||||||
void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *inf)
|
void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *inf,
|
||||||
|
BYTE tr, BYTE tg, BYTE tb)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int fac;
|
int fac;
|
||||||
|
@ -59,7 +60,7 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in
|
||||||
case BLEND_NONE:
|
case BLEND_NONE:
|
||||||
for(i=0;i<count;i++)
|
for(i=0;i<count;i++)
|
||||||
{
|
{
|
||||||
a = TSrc::A(pin);
|
a = TSrc::A(pin, tr, tg, tb);
|
||||||
if (TBlend::ProcessAlpha0() || a)
|
if (TBlend::ProcessAlpha0() || a)
|
||||||
{
|
{
|
||||||
TBlend::OpC(pout[TDest::RED], TSrc::R(pin), a, inf);
|
TBlend::OpC(pout[TDest::RED], TSrc::R(pin), a, inf);
|
||||||
|
@ -77,7 +78,7 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in
|
||||||
// Since this is done in True Color the purplish tint is fully preserved - even in Doom!
|
// Since this is done in True Color the purplish tint is fully preserved - even in Doom!
|
||||||
for(i=0;i<count;i++)
|
for(i=0;i<count;i++)
|
||||||
{
|
{
|
||||||
a = TSrc::A(pin);
|
a = TSrc::A(pin, tr, tg, tb);
|
||||||
if (TBlend::ProcessAlpha0() || a)
|
if (TBlend::ProcessAlpha0() || a)
|
||||||
{
|
{
|
||||||
int gray = TSrc::Gray(pin)>>4;
|
int gray = TSrc::Gray(pin)>>4;
|
||||||
|
@ -99,7 +100,7 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in
|
||||||
FSpecialColormap *cm = &SpecialColormaps[inf->blend - BLEND_SPECIALCOLORMAP1];
|
FSpecialColormap *cm = &SpecialColormaps[inf->blend - BLEND_SPECIALCOLORMAP1];
|
||||||
for(i=0;i<count;i++)
|
for(i=0;i<count;i++)
|
||||||
{
|
{
|
||||||
a = TSrc::A(pin);
|
a = TSrc::A(pin, tr, tg, tb);
|
||||||
if (TBlend::ProcessAlpha0() || a)
|
if (TBlend::ProcessAlpha0() || a)
|
||||||
{
|
{
|
||||||
gray = clamp<int>(TSrc::Gray(pin),0,255);
|
gray = clamp<int>(TSrc::Gray(pin),0,255);
|
||||||
|
@ -120,7 +121,7 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in
|
||||||
fac=inf->blend-BLEND_DESATURATE1+1;
|
fac=inf->blend-BLEND_DESATURATE1+1;
|
||||||
for(i=0;i<count;i++)
|
for(i=0;i<count;i++)
|
||||||
{
|
{
|
||||||
a = TSrc::A(pin);
|
a = TSrc::A(pin, tr, tg, tb);
|
||||||
if (TBlend::ProcessAlpha0() || a)
|
if (TBlend::ProcessAlpha0() || a)
|
||||||
{
|
{
|
||||||
gray = TSrc::Gray(pin);
|
gray = TSrc::Gray(pin);
|
||||||
|
@ -142,7 +143,7 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in
|
||||||
case BLEND_MODULATE:
|
case BLEND_MODULATE:
|
||||||
for(i=0;i<count;i++)
|
for(i=0;i<count;i++)
|
||||||
{
|
{
|
||||||
a = TSrc::A(pin);
|
a = TSrc::A(pin, tr, tg, tb);
|
||||||
if (TBlend::ProcessAlpha0() || a)
|
if (TBlend::ProcessAlpha0() || a)
|
||||||
{
|
{
|
||||||
r = (TSrc::R(pin)*inf->blendcolor[0])>>FRACBITS;
|
r = (TSrc::R(pin)*inf->blendcolor[0])>>FRACBITS;
|
||||||
|
@ -163,7 +164,7 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in
|
||||||
for(i=0;i<count;i++)
|
for(i=0;i<count;i++)
|
||||||
{
|
{
|
||||||
// color blend
|
// color blend
|
||||||
a = TSrc::A(pin);
|
a = TSrc::A(pin, tr, tg, tb);
|
||||||
if (TBlend::ProcessAlpha0() || a)
|
if (TBlend::ProcessAlpha0() || a)
|
||||||
{
|
{
|
||||||
r = (TSrc::R(pin)*inf->blendcolor[3] + inf->blendcolor[0]) >> FRACBITS;
|
r = (TSrc::R(pin)*inf->blendcolor[3] + inf->blendcolor[0]) >> FRACBITS;
|
||||||
|
@ -183,11 +184,12 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*CopyFunc)(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *inf);
|
typedef void (*CopyFunc)(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *inf, BYTE r, BYTE g, BYTE b);
|
||||||
|
|
||||||
#define COPY_FUNCS(op) \
|
#define COPY_FUNCS(op) \
|
||||||
{ \
|
{ \
|
||||||
iCopyColors<cRGB, cBGRA, op>, \
|
iCopyColors<cRGB, cBGRA, op>, \
|
||||||
|
iCopyColors<cRGBT, cBGRA, op>, \
|
||||||
iCopyColors<cRGBA, cBGRA, op>, \
|
iCopyColors<cRGBA, cBGRA, op>, \
|
||||||
iCopyColors<cIA, cBGRA, op>, \
|
iCopyColors<cIA, cBGRA, op>, \
|
||||||
iCopyColors<cCMYK, cBGRA, op>, \
|
iCopyColors<cCMYK, cBGRA, op>, \
|
||||||
|
@ -197,7 +199,7 @@ typedef void (*CopyFunc)(BYTE *pout, const BYTE *pin, int count, int step, FCopy
|
||||||
iCopyColors<cRGB555, cBGRA, op>, \
|
iCopyColors<cRGB555, cBGRA, op>, \
|
||||||
iCopyColors<cPalEntry, cBGRA, op> \
|
iCopyColors<cPalEntry, cBGRA, op> \
|
||||||
}
|
}
|
||||||
static const CopyFunc copyfuncs[][9]={
|
static const CopyFunc copyfuncs[][10]={
|
||||||
COPY_FUNCS(bCopy),
|
COPY_FUNCS(bCopy),
|
||||||
COPY_FUNCS(bBlend),
|
COPY_FUNCS(bBlend),
|
||||||
COPY_FUNCS(bAdd),
|
COPY_FUNCS(bAdd),
|
||||||
|
@ -370,7 +372,8 @@ bool FClipRect::Intersect(int ix, int iy, int iw, int ih)
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
void FBitmap::CopyPixelDataRGB(int originx, int originy, const BYTE *patch, int srcwidth,
|
void FBitmap::CopyPixelDataRGB(int originx, int originy, const BYTE *patch, int srcwidth,
|
||||||
int srcheight, int step_x, int step_y, int rotate, int ct, FCopyInfo *inf)
|
int srcheight, int step_x, int step_y, int rotate, int ct, FCopyInfo *inf,
|
||||||
|
int r, int g, int b)
|
||||||
{
|
{
|
||||||
if (ClipCopyPixelRect(&ClipRect, originx, originy, patch, srcwidth, srcheight, step_x, step_y, rotate))
|
if (ClipCopyPixelRect(&ClipRect, originx, originy, patch, srcwidth, srcheight, step_x, step_y, rotate))
|
||||||
{
|
{
|
||||||
|
@ -378,7 +381,7 @@ void FBitmap::CopyPixelDataRGB(int originx, int originy, const BYTE *patch, int
|
||||||
int op = inf==NULL? OP_COPY : inf->op;
|
int op = inf==NULL? OP_COPY : inf->op;
|
||||||
for (int y=0;y<srcheight;y++)
|
for (int y=0;y<srcheight;y++)
|
||||||
{
|
{
|
||||||
copyfuncs[op][ct](&buffer[y*Pitch], &patch[y*step_y], srcwidth, step_x, inf);
|
copyfuncs[op][ct](&buffer[y*Pitch], &patch[y*step_y], srcwidth, step_x, inf, r, g, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -443,7 +446,7 @@ void FBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int sr
|
||||||
memset(penew, 0, sizeof(penew));
|
memset(penew, 0, sizeof(penew));
|
||||||
if (inf && inf->blend)
|
if (inf && inf->blend)
|
||||||
{
|
{
|
||||||
iCopyColors<cPalEntry, cBGRA, bCopy>((BYTE*)penew, (const BYTE*)palette, 256, 4, inf);
|
iCopyColors<cPalEntry, cBGRA, bCopy>((BYTE*)penew, (const BYTE*)palette, 256, 4, inf, 0, 0, 0);
|
||||||
palette = penew;
|
palette = penew;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,8 @@ public:
|
||||||
|
|
||||||
|
|
||||||
virtual void CopyPixelDataRGB(int originx, int originy, const BYTE *patch, int srcwidth,
|
virtual void CopyPixelDataRGB(int originx, int originy, const BYTE *patch, int srcwidth,
|
||||||
int srcheight, int step_x, int step_y, int rotate, int ct, FCopyInfo *inf = NULL);
|
int srcheight, int step_x, int step_y, int rotate, int ct, FCopyInfo *inf = NULL,
|
||||||
|
/* for PNG tRNS */ int r=0, int g=0, int b=0);
|
||||||
virtual void CopyPixelData(int originx, int originy, const BYTE * patch, int srcwidth, int srcheight,
|
virtual void CopyPixelData(int originx, int originy, const BYTE * patch, int srcwidth, int srcheight,
|
||||||
int step_x, int step_y, int rotate, PalEntry * palette, FCopyInfo *inf = NULL);
|
int step_x, int step_y, int rotate, PalEntry * palette, FCopyInfo *inf = NULL);
|
||||||
|
|
||||||
|
@ -179,7 +180,16 @@ struct cRGB
|
||||||
static __forceinline unsigned char R(const unsigned char * p) { return p[0]; }
|
static __forceinline unsigned char R(const unsigned char * p) { return p[0]; }
|
||||||
static __forceinline unsigned char G(const unsigned char * p) { return p[1]; }
|
static __forceinline unsigned char G(const unsigned char * p) { return p[1]; }
|
||||||
static __forceinline unsigned char B(const unsigned char * p) { return p[2]; }
|
static __forceinline unsigned char B(const unsigned char * p) { return p[2]; }
|
||||||
static __forceinline unsigned char A(const unsigned char * p) { return 255; }
|
static __forceinline unsigned char A(const unsigned char * p, BYTE x, BYTE y, BYTE z) { return 255; }
|
||||||
|
static __forceinline int Gray(const unsigned char * p) { return (p[0]*77 + p[1]*143 + p[2]*36)>>8; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cRGBT
|
||||||
|
{
|
||||||
|
static __forceinline unsigned char R(const unsigned char * p) { return p[0]; }
|
||||||
|
static __forceinline unsigned char G(const unsigned char * p) { return p[1]; }
|
||||||
|
static __forceinline unsigned char B(const unsigned char * p) { return p[2]; }
|
||||||
|
static __forceinline unsigned char A(const unsigned char * p, BYTE r, BYTE g, BYTE b) { return p[0] != r || p[1] != g || p[2] != b; }
|
||||||
static __forceinline int Gray(const unsigned char * p) { return (p[0]*77 + p[1]*143 + p[2]*36)>>8; }
|
static __forceinline int Gray(const unsigned char * p) { return (p[0]*77 + p[1]*143 + p[2]*36)>>8; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -195,7 +205,7 @@ struct cRGBA
|
||||||
static __forceinline unsigned char R(const unsigned char * p) { return p[0]; }
|
static __forceinline unsigned char R(const unsigned char * p) { return p[0]; }
|
||||||
static __forceinline unsigned char G(const unsigned char * p) { return p[1]; }
|
static __forceinline unsigned char G(const unsigned char * p) { return p[1]; }
|
||||||
static __forceinline unsigned char B(const unsigned char * p) { return p[2]; }
|
static __forceinline unsigned char B(const unsigned char * p) { return p[2]; }
|
||||||
static __forceinline unsigned char A(const unsigned char * p) { return p[3]; }
|
static __forceinline unsigned char A(const unsigned char * p, BYTE x, BYTE y, BYTE z) { return p[3]; }
|
||||||
static __forceinline int Gray(const unsigned char * p) { return (p[0]*77 + p[1]*143 + p[2]*36)>>8; }
|
static __forceinline int Gray(const unsigned char * p) { return (p[0]*77 + p[1]*143 + p[2]*36)>>8; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -204,7 +214,7 @@ struct cIA
|
||||||
static __forceinline unsigned char R(const unsigned char * p) { return p[0]; }
|
static __forceinline unsigned char R(const unsigned char * p) { return p[0]; }
|
||||||
static __forceinline unsigned char G(const unsigned char * p) { return p[0]; }
|
static __forceinline unsigned char G(const unsigned char * p) { return p[0]; }
|
||||||
static __forceinline unsigned char B(const unsigned char * p) { return p[0]; }
|
static __forceinline unsigned char B(const unsigned char * p) { return p[0]; }
|
||||||
static __forceinline unsigned char A(const unsigned char * p) { return p[1]; }
|
static __forceinline unsigned char A(const unsigned char * p, BYTE x, BYTE y, BYTE z) { return p[1]; }
|
||||||
static __forceinline int Gray(const unsigned char * p) { return p[0]; }
|
static __forceinline int Gray(const unsigned char * p) { return p[0]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -213,7 +223,7 @@ struct cCMYK
|
||||||
static __forceinline unsigned char R(const unsigned char * p) { return p[3] - (((256-p[0])*p[3]) >> 8); }
|
static __forceinline unsigned char R(const unsigned char * p) { return p[3] - (((256-p[0])*p[3]) >> 8); }
|
||||||
static __forceinline unsigned char G(const unsigned char * p) { return p[3] - (((256-p[1])*p[3]) >> 8); }
|
static __forceinline unsigned char G(const unsigned char * p) { return p[3] - (((256-p[1])*p[3]) >> 8); }
|
||||||
static __forceinline unsigned char B(const unsigned char * p) { return p[3] - (((256-p[2])*p[3]) >> 8); }
|
static __forceinline unsigned char B(const unsigned char * p) { return p[3] - (((256-p[2])*p[3]) >> 8); }
|
||||||
static __forceinline unsigned char A(const unsigned char * p) { return 255; }
|
static __forceinline unsigned char A(const unsigned char * p, BYTE x, BYTE y, BYTE z) { return 255; }
|
||||||
static __forceinline int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; }
|
static __forceinline int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -222,7 +232,7 @@ struct cBGR
|
||||||
static __forceinline unsigned char R(const unsigned char * p) { return p[2]; }
|
static __forceinline unsigned char R(const unsigned char * p) { return p[2]; }
|
||||||
static __forceinline unsigned char G(const unsigned char * p) { return p[1]; }
|
static __forceinline unsigned char G(const unsigned char * p) { return p[1]; }
|
||||||
static __forceinline unsigned char B(const unsigned char * p) { return p[0]; }
|
static __forceinline unsigned char B(const unsigned char * p) { return p[0]; }
|
||||||
static __forceinline unsigned char A(const unsigned char * p) { return 255; }
|
static __forceinline unsigned char A(const unsigned char * p, BYTE x, BYTE y, BYTE z) { return 255; }
|
||||||
static __forceinline int Gray(const unsigned char * p) { return (p[2]*77 + p[1]*143 + p[0]*36)>>8; }
|
static __forceinline int Gray(const unsigned char * p) { return (p[2]*77 + p[1]*143 + p[0]*36)>>8; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -238,7 +248,7 @@ struct cBGRA
|
||||||
static __forceinline unsigned char R(const unsigned char * p) { return p[2]; }
|
static __forceinline unsigned char R(const unsigned char * p) { return p[2]; }
|
||||||
static __forceinline unsigned char G(const unsigned char * p) { return p[1]; }
|
static __forceinline unsigned char G(const unsigned char * p) { return p[1]; }
|
||||||
static __forceinline unsigned char B(const unsigned char * p) { return p[0]; }
|
static __forceinline unsigned char B(const unsigned char * p) { return p[0]; }
|
||||||
static __forceinline unsigned char A(const unsigned char * p) { return p[3]; }
|
static __forceinline unsigned char A(const unsigned char * p, BYTE x, BYTE y, BYTE z) { return p[3]; }
|
||||||
static __forceinline int Gray(const unsigned char * p) { return (p[2]*77 + p[1]*143 + p[0]*36)>>8; }
|
static __forceinline int Gray(const unsigned char * p) { return (p[2]*77 + p[1]*143 + p[0]*36)>>8; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -254,7 +264,7 @@ struct cARGB
|
||||||
static __forceinline unsigned char R(const unsigned char * p) { return p[1]; }
|
static __forceinline unsigned char R(const unsigned char * p) { return p[1]; }
|
||||||
static __forceinline unsigned char G(const unsigned char * p) { return p[2]; }
|
static __forceinline unsigned char G(const unsigned char * p) { return p[2]; }
|
||||||
static __forceinline unsigned char B(const unsigned char * p) { return p[3]; }
|
static __forceinline unsigned char B(const unsigned char * p) { return p[3]; }
|
||||||
static __forceinline unsigned char A(const unsigned char * p) { return p[0]; }
|
static __forceinline unsigned char A(const unsigned char * p, BYTE x, BYTE y, BYTE z) { return p[0]; }
|
||||||
static __forceinline int Gray(const unsigned char * p) { return (p[1]*77 + p[2]*143 + p[3]*36)>>8; }
|
static __forceinline int Gray(const unsigned char * p) { return (p[1]*77 + p[2]*143 + p[3]*36)>>8; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -263,7 +273,7 @@ struct cI16
|
||||||
static __forceinline unsigned char R(const unsigned char * p) { return p[1]; }
|
static __forceinline unsigned char R(const unsigned char * p) { return p[1]; }
|
||||||
static __forceinline unsigned char G(const unsigned char * p) { return p[1]; }
|
static __forceinline unsigned char G(const unsigned char * p) { return p[1]; }
|
||||||
static __forceinline unsigned char B(const unsigned char * p) { return p[1]; }
|
static __forceinline unsigned char B(const unsigned char * p) { return p[1]; }
|
||||||
static __forceinline unsigned char A(const unsigned char * p) { return 255; }
|
static __forceinline unsigned char A(const unsigned char * p, BYTE x, BYTE y, BYTE z) { return 255; }
|
||||||
static __forceinline int Gray(const unsigned char * p) { return p[1]; }
|
static __forceinline int Gray(const unsigned char * p) { return p[1]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -272,7 +282,7 @@ struct cRGB555
|
||||||
static __forceinline unsigned char R(const unsigned char * p) { return (((*(WORD*)p)&0x1f)<<3); }
|
static __forceinline unsigned char R(const unsigned char * p) { return (((*(WORD*)p)&0x1f)<<3); }
|
||||||
static __forceinline unsigned char G(const unsigned char * p) { return (((*(WORD*)p)&0x3e0)>>2); }
|
static __forceinline unsigned char G(const unsigned char * p) { return (((*(WORD*)p)&0x3e0)>>2); }
|
||||||
static __forceinline unsigned char B(const unsigned char * p) { return (((*(WORD*)p)&0x7c00)>>7); }
|
static __forceinline unsigned char B(const unsigned char * p) { return (((*(WORD*)p)&0x7c00)>>7); }
|
||||||
static __forceinline unsigned char A(const unsigned char * p) { return 255; }
|
static __forceinline unsigned char A(const unsigned char * p, BYTE x, BYTE y, BYTE z) { return 255; }
|
||||||
static __forceinline int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; }
|
static __forceinline int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -281,13 +291,14 @@ struct cPalEntry
|
||||||
static __forceinline unsigned char R(const unsigned char * p) { return ((PalEntry*)p)->r; }
|
static __forceinline unsigned char R(const unsigned char * p) { return ((PalEntry*)p)->r; }
|
||||||
static __forceinline unsigned char G(const unsigned char * p) { return ((PalEntry*)p)->g; }
|
static __forceinline unsigned char G(const unsigned char * p) { return ((PalEntry*)p)->g; }
|
||||||
static __forceinline unsigned char B(const unsigned char * p) { return ((PalEntry*)p)->b; }
|
static __forceinline unsigned char B(const unsigned char * p) { return ((PalEntry*)p)->b; }
|
||||||
static __forceinline unsigned char A(const unsigned char * p) { return ((PalEntry*)p)->a; }
|
static __forceinline unsigned char A(const unsigned char * p, BYTE x, BYTE y, BYTE z) { return ((PalEntry*)p)->a; }
|
||||||
static __forceinline int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; }
|
static __forceinline int Gray(const unsigned char * p) { return (R(p)*77 + G(p)*143 + B(p)*36)>>8; }
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ColorType
|
enum ColorType
|
||||||
{
|
{
|
||||||
CF_RGB,
|
CF_RGB,
|
||||||
|
CF_RGBT,
|
||||||
CF_RGBA,
|
CF_RGBA,
|
||||||
CF_IA,
|
CF_IA,
|
||||||
CF_CMYK,
|
CF_CMYK,
|
||||||
|
|
|
@ -70,6 +70,8 @@ protected:
|
||||||
BYTE BitDepth;
|
BYTE BitDepth;
|
||||||
BYTE ColorType;
|
BYTE ColorType;
|
||||||
BYTE Interlace;
|
BYTE Interlace;
|
||||||
|
bool HaveTrans;
|
||||||
|
WORD NonPaletteTrans[3];
|
||||||
|
|
||||||
BYTE *PaletteMap;
|
BYTE *PaletteMap;
|
||||||
int PaletteSize;
|
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,
|
FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height,
|
||||||
BYTE depth, BYTE colortype, BYTE interlace)
|
BYTE depth, BYTE colortype, BYTE interlace)
|
||||||
: FTexture(NULL, lumpnum), SourceFile(filename), Pixels(0), Spans(0),
|
: 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)
|
PaletteMap(0), PaletteSize(0), StartOfIDAT(0)
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
|
@ -204,7 +206,6 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
|
||||||
BYTE pngpal[256][3];
|
BYTE pngpal[256][3];
|
||||||
} p;
|
} p;
|
||||||
BYTE trans[256];
|
BYTE trans[256];
|
||||||
bool havetRNS = false;
|
|
||||||
DWORD len, id;
|
DWORD len, id;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -273,7 +274,11 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
|
||||||
|
|
||||||
case MAKE_ID('t','R','N','S'):
|
case MAKE_ID('t','R','N','S'):
|
||||||
lump.Read (trans, len);
|
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;
|
break;
|
||||||
|
|
||||||
case MAKE_ID('a','l','P','h'):
|
case MAKE_ID('a','l','P','h'):
|
||||||
|
@ -297,13 +302,13 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
|
||||||
case 0: // Grayscale
|
case 0: // Grayscale
|
||||||
if (!bAlphaTexture)
|
if (!bAlphaTexture)
|
||||||
{
|
{
|
||||||
if (colortype == 0 && havetRNS && trans[0] != 0)
|
if (colortype == 0 && HaveTrans && NonPaletteTrans[0] != 0 && NonPaletteTrans[0] < 256)
|
||||||
{
|
{
|
||||||
bMasked = true;
|
bMasked = true;
|
||||||
PaletteSize = 256;
|
PaletteSize = 256;
|
||||||
PaletteMap = new BYTE[256];
|
PaletteMap = new BYTE[256];
|
||||||
memcpy (PaletteMap, GrayMap, 256);
|
memcpy (PaletteMap, GrayMap, 256);
|
||||||
PaletteMap[trans[0]] = 0;
|
PaletteMap[NonPaletteTrans[0]] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -328,6 +333,10 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename
|
||||||
case 6: // RGB + Alpha
|
case 6: // RGB + Alpha
|
||||||
bMasked = true;
|
bMasked = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 2: // RGB
|
||||||
|
bMasked = HaveTrans;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,8 +529,24 @@ void FPNGTexture::MakeTexture ()
|
||||||
for (x = Width; x > 0; --x)
|
for (x = Width; x > 0; --x)
|
||||||
{
|
{
|
||||||
for (y = Height; y > 0; --y)
|
for (y = Height; y > 0; --y)
|
||||||
|
{
|
||||||
|
if (!HaveTrans)
|
||||||
{
|
{
|
||||||
*out++ = RGB32k.RGB[in[0]>>3][in[1]>>3][in[2]>>3];
|
*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 += pitch;
|
||||||
}
|
}
|
||||||
in -= backstep;
|
in -= backstep;
|
||||||
|
@ -625,12 +650,15 @@ int FPNGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAKE_ID('t','R','N','S'):
|
case MAKE_ID('t','R','N','S'):
|
||||||
|
if (ColorType == 3)
|
||||||
|
{
|
||||||
for(DWORD i = 0; i < len; i++)
|
for(DWORD i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
(*lump) >> pe[i].a;
|
(*lump) >> pe[i].a;
|
||||||
if (pe[i].a != 0 && pe[i].a != 255)
|
if (pe[i].a != 0 && pe[i].a != 255)
|
||||||
transpal = true;
|
transpal = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lump->Seek(4, SEEK_CUR); // Skip CRC
|
lump->Seek(4, SEEK_CUR); // Skip CRC
|
||||||
|
@ -639,6 +667,12 @@ int FPNGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
||||||
lump->Read(&id, 4);
|
lump->Read(&id, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ColorType == 0 && HaveTrans && NonPaletteTrans[0] < 256)
|
||||||
|
{
|
||||||
|
pe[NonPaletteTrans[0]].a = 0;
|
||||||
|
transpal = true;
|
||||||
|
}
|
||||||
|
|
||||||
BYTE * Pixels = new BYTE[pixwidth * Height];
|
BYTE * Pixels = new BYTE[pixwidth * Height];
|
||||||
|
|
||||||
lump->Seek (StartOfIDAT, SEEK_SET);
|
lump->Seek (StartOfIDAT, SEEK_SET);
|
||||||
|
@ -655,7 +689,15 @@ int FPNGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
if (!HaveTrans)
|
||||||
|
{
|
||||||
bmp->CopyPixelDataRGB(x, y, Pixels, Width, Height, 3, pixwidth, rotate, CF_RGB, inf);
|
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;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
|
|
Loading…
Reference in a new issue