//-------------------------------------- //--- 010 Editor v2.0.2 Binary Template // // File: PNG12Template.bt // Author: RCS // Revision: 0.1 // Purpose: Use templates on PNG images //-------------------------------------- typedef struct { WORD btPngSignature[4] ; } PNG_SIGNATURE; typedef struct { DWORD btChunkLen; SetForeColor(cYellow); SetBackColor(cBlue); CHAR btChunkType[4]; SetBackColor(cWhite); } PNG_CHUNK_HEADER; typedef enum pngColorSpaceType { GrayScale = 0, TrueColor = 2, Indexed = 3, AlphaGrayScale = 4, AlphaTrueColor = 6 } PNG_COLOR_SPACE_TYPE; // Compression Methods typedef enum pngCompressionMethod { Deflate = 0 } PNG_COMPR_METHOD; // Filter Methods typedef enum pngFilterMethod { AdaptiveFiltering = 0 } PNG_FILTER_METHOD; // Interlace Methods typedef enum pngInterlaceMethod { NoInterlace = 0, Adam7Interlace = 1 } PNG_INTERLACE_METHOD; // IHDR data typedef struct { UINT width; UINT height; BYTE bit_depth; PNG_COLOR_SPACE_TYPE color_type; PNG_COMPR_METHOD compr_method; PNG_FILTER_METHOD filter_method; PNG_INTERLACE_METHOD interlace_method; } IHDR_CHUNK_DATA; typedef struct { BYTE btRed ; BYTE btGreen ; BYTE btBlue ; } PNG_PALETTE_PIXEL; typedef struct { uint x; uint y; } PNG_POINT; typedef struct { PNG_POINT white; PNG_POINT red; PNG_POINT green; PNG_POINT blue; } PNG_CHRM_CHUNK_DATA; typedef enum { Perceptual = 0, RelativeColorimetric = 1, Saturation = 2, AbsoluteColorimetric = 3 } PNG_SRGB_CHUNK_DATA; typedef struct { string profile_name; unsigned byte red; } PNG_ICCP_CHUNK_DATA; //--------------------------------------------- // PNG is big endian BigEndian(); // Start PNG file struct PngFile { // Check the PNG signature // (89h 50h 4Eh 47h 0Dh 0Ah 1Ah 0Ah) SetForeColor(cRed); PNG_SIGNATURE sig; if (sig.btPngSignature[0] != 0x8950 || sig.btPngSignature[1] != 0x4E47 || sig.btPngSignature[2] != 0x0D0A || sig.btPngSignature[3] != 0x1A0A) { Warning( "File is not a PNG image. Template stopped." ); return -1; } // Chunks naming rules // Ancillary bit: bit 5 of first byte // Private bit: bit 5 of second byte // Reserved bit: bit 5 of third byte // Safe-to-copy bit: bit 5 of fourth byte SetForeColor(cGreen); PNG_CHUNK_HEADER ihdrChunkHdr; if (Strnicmp(ihdrChunkHdr.btChunkType, "IHDR", 4) != 0) { Warning( "PNG File does not start with IHDR chunk." ); return -2; } SetForeColor(cBlack); IHDR_CHUNK_DATA ihdrChunkData; SetForeColor(cBlue); DWORD ihdrCrc ; while (!FEof()) { // Chunks naming rules // Ancillary bit: bit 5 of first byte // Private bit: bit 5 of second byte // Reserved bit: bit 5 of third byte // Safe-to-copy bit: bit 5 of fourth byte SetForeColor(cGreen); PNG_CHUNK_HEADER chunkHdr; if (Strnicmp(chunkHdr.btChunkType, "PLTE", 4) == 0) { SetForeColor(cBlack); PNG_PALETTE_PIXEL plteChunkData[chunkHdr.btChunkLen/3]; SetForeColor(cBlue); DWORD plteCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "tRNS", 4) == 0) { SetForeColor(cBlack); BYTE trnsChunkData[chunkHdr.btChunkLen] ; SetForeColor(cBlue); DWORD trnsCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "IDAT", 4) == 0) { SetForeColor(cWhite); SetBackColor(cBlack); BYTE idatChunkData[chunkHdr.btChunkLen] ; SetForeColor(cBlack); SetBackColor(cWhite); SetForeColor(cBlue); DWORD idatCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "gAMA", 4) == 0) { SetForeColor(cBlack); BYTE gamaChunkData[chunkHdr.btChunkLen]; SetForeColor(cBlue); DWORD gamaCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "cHRM", 4) == 0) { SetForeColor(cBlack); PNG_CHRM_CHUNK_DATA chrmChunkData; SetForeColor(cBlue); DWORD chrmCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "sRGB", 4) == 0) { SetForeColor(cBlack); PNG_SRGB_CHUNK_DATA srgbChunkData; SetForeColor(cBlue); DWORD srgbCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "iEXT", 4) == 0) { SetForeColor(cBlack); string iextIdChunkData; byte iextCompressionFlag; PNG_COMPR_METHOD iextComprMethod; string iextLanguageTag; string iextTranslatedKeyword; char iextValChunkData[chunkHdr.btChunkLen - Strlen(iextIdChunkData) -1 - Strlen(iextLanguageTag) -1 - Strlen(iextTranslatedKeyword) -1 - 2]; SetForeColor(cBlue); DWORD iextCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "tEXT", 4) == 0) { SetForeColor(cBlack); string textIdChunkData; char textValChunkData[chunkHdr.btChunkLen - Strlen(textIdChunkData) -1]; SetForeColor(cBlue); DWORD textCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "zEXT", 4) == 0) { SetForeColor(cBlack); string zextIdChunkData; PNG_COMPR_METHOD comprMethod; char zextValChunkData[chunkHdr.btChunkLen - Strlen(zextIdChunkData) -2]; SetForeColor(cBlue); DWORD zextCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "tIME", 4) == 0) { SetForeColor(cBlack); short timeYear ; byte timeMonth ; byte timeDay ; byte timeHour ; byte timeMin ; byte timeSec ; SetForeColor(cBlue); DWORD zextCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "bKGD", 4) == 0) { SetForeColor(cBlack); switch (ihdrChunkData.color_type) { case 3: // Indexed unsigned byte bgColorPaletteIndex ; break; case 0: // Grayscale case 4: // Grayscale with alpha unsigned short bgGrayscalePixelValue ; break; case 2: // TrueColor case 6: // TrueColor with alpha unsigned short bgColorPixelRed ; unsigned short bgColorPixelGreen ; unsigned short bgColorPixelBlue ; break; default: Warning( "Unknown Color Model Type for background color chunk." ); return -4; } SetForeColor(cBlue); DWORD zextCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "pHYS", 4) == 0) { SetForeColor(cBlack); uint physPixelPerUnitX; uint physPixelPerUnitY; enum { UnkownUnit = 0, Meter = 1 } physUnitSpec; SetForeColor(cBlue); DWORD zextCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "sBIT", 4) == 0) { SetForeColor(cBlack); switch (ihdrChunkData.color_type) { case 3: // Indexed byte sbitRed; byte sbitGreen; byte sbitBlue; break; case 0: // Grayscale byte sbitGraySource; break; case 4: // Grayscale with alpha byte sbitGrayAlphaSource; byte sbitGrayAlphaSourceAlpha; break; case 2: // TrueColor byte sbitColorRed; byte sbitColorGreen; byte sbitColorBlue; break; case 6: // TrueColor with alpha byte sbitColorAlphaRed; byte sbitColorAlphaGreen; byte sbitColorAlphaBlue; byte sbitColorAlphaAlpha; break; default: Warning( "Unknown Color Model Type for background color chunk." ); return -4; } SetForeColor(cBlue); DWORD sbitCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "sPLT", 4) == 0) { SetForeColor(cBlue); string paletteName; byte sampleDepth; byte spltData[chunkHdr.btChunkLen - Strlen(paletteName) -2]; SetForeColor(cBlue); DWORD spltCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "hIST", 4) == 0) { SetForeColor(cBlue); DWORD iendCrc ; SetForeColor(cBlue); DWORD histCrc ; } else if (Strnicmp(chunkHdr.btChunkType, "IEND", 4) == 0) { SetForeColor(cBlue); DWORD iendCrc ; } else { SetForeColor(cBlack); BYTE genChunkData[chunkHdr.btChunkLen]; SetForeColor(cBlue); DWORD genCrc ; } } } myPngFile;