public static List <PngDataChunk> GetChunks(byte[] imageBytes) { // Check for the eight-byte PNG signature byte[] pngHeader = { 137, 80, 78, 71, 13, 10, 26, 10, }; for (int i = 0; i < 8; i++) { if (pngHeader[i] != imageBytes[i]) { throw new ArgumentException("No PNG signature found"); } } List <PngDataChunk> chunks = new List <PngDataChunk>(); int k = 8; while (true) { // get the data UInt32 chunkLength = ByteUtils.ToUInt32(imageBytes, k); k += 4; ChunkType chunkType = new ChunkType(imageBytes, k); k += 4; byte[] chunkData = new byte[chunkLength]; for (int i = 0; i < chunkLength; i++, k++) { chunkData[i] = imageBytes[k]; } UInt32 chunkCRC = ByteUtils.ToUInt32(imageBytes, k); k += 4; // create chunk from data and add it to list PngDataChunk dataChunk = new PngDataChunk(chunkLength, chunkType, chunkData, chunkCRC); chunks.Add(dataChunk); // stop once we hit the IEND if (chunkType.ToString() == "IEND") { break; } // TODO: proper error handling if IEND is never found } return(chunks); }
/// <summary> /// short description of given chunk type (if known) /// </summary> /// <param name="chunkType">chunk type to describe</param> /// <returns>human-readable description, as string</returns> public static string Description(ChunkType chunkType) { switch (chunkType.ToString()) { // critical chunks case "IHDR": return("image header, the first chunk in a PNG datastream"); case "PLTE": return("palette table"); case "IDAT": return("image data chunk"); case "IEND": return("image trailer, the last chunk in a PNG datastream"); // ancillary chunks case "tRNS": return("transparency information"); case "cHRM": return("primary chromaticities and white point"); case "gAMA": return("image gamma"); case "iCCP": return("embedded ICC profile"); case "sBIT": return("significant bits"); case "sRGB": return("standard RGB color space"); case "tEXt": return("textual data"); case "zTXt": return("compressed textual data"); case "iTXt": return("international textual data"); case "bKGD": return("background color"); case "hIST": return("image histogram"); case "pHYs": return("physical pixel dimensions"); case "sPLT": return("suggested palette"); case "tIME": return("image last-modification time"); // ??? default: return("unknown chunk"); } }