diff --git a/src/textures/bitmap.cpp b/src/textures/bitmap.cpp index 94b8ce774..6c2530653 100644 --- a/src/textures/bitmap.cpp +++ b/src/textures/bitmap.cpp @@ -46,7 +46,8 @@ // //=========================================================================== template -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 fac; @@ -59,7 +60,7 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in case BLEND_NONE: for(i=0;i>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]; for(i=0;i(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; for(i=0;iblendcolor[0])>>FRACBITS; @@ -163,7 +164,7 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in for(i=0;iblendcolor[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) \ { \ iCopyColors, \ + iCopyColors, \ iCopyColors, \ iCopyColors, \ iCopyColors, \ @@ -197,7 +199,7 @@ typedef void (*CopyFunc)(BYTE *pout, const BYTE *pin, int count, int step, FCopy iCopyColors, \ iCopyColors \ } -static const CopyFunc copyfuncs[][9]={ +static const CopyFunc copyfuncs[][10]={ COPY_FUNCS(bCopy), COPY_FUNCS(bBlend), 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, - 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)) { @@ -378,7 +381,7 @@ void FBitmap::CopyPixelDataRGB(int originx, int originy, const BYTE *patch, int int op = inf==NULL? OP_COPY : inf->op; for (int y=0;yblend) { - iCopyColors((BYTE*)penew, (const BYTE*)palette, 256, 4, inf); + iCopyColors((BYTE*)penew, (const BYTE*)palette, 256, 4, inf, 0, 0, 0); palette = penew; } diff --git a/src/textures/bitmap.h b/src/textures/bitmap.h index ef57f562d..b8494efaf 100644 --- a/src/textures/bitmap.h +++ b/src/textures/bitmap.h @@ -157,7 +157,8 @@ public: 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, 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 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) { 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; } }; @@ -195,7 +205,7 @@ struct cRGBA 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) { 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; } }; @@ -204,7 +214,7 @@ struct cIA 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 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]; } }; @@ -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 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 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; } }; @@ -222,7 +232,7 @@ struct cBGR 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 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; } }; @@ -238,7 +248,7 @@ struct cBGRA 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 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; } }; @@ -254,7 +264,7 @@ struct cARGB 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 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; } }; @@ -263,7 +273,7 @@ struct cI16 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 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]; } }; @@ -272,7 +282,7 @@ struct cRGB555 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 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; } }; @@ -281,13 +291,14 @@ struct cPalEntry 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 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; } }; enum ColorType { CF_RGB, + CF_RGBT, CF_RGBA, CF_IA, CF_CMYK, diff --git a/src/textures/pngtexture.cpp b/src/textures/pngtexture.cpp index 165e730a1..7a7e4960d 100644 --- a/src/textures/pngtexture.cpp +++ b/src/textures/pngtexture.cpp @@ -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: