1 /* 2 LodePNG Utils 3 4 Copyright (c) 2005-2012 Lode Vandevenne 5 6 This software is provided 'as-is', without any express or implied 7 warranty. In no event will the authors be held liable for any damages 8 arising from the use of this software. 9 10 Permission is granted to anyone to use this software for any purpose, 11 including commercial applications, and to alter it and redistribute it 12 freely, subject to the following restrictions: 13 14 1. The origin of this software must not be misrepresented; you must not 15 claim that you wrote the original software. If you use this software 16 in a product, an acknowledgment in the product documentation would be 17 appreciated but is not required. 18 19 2. Altered source versions must be plainly marked as such, and must not be 20 misrepresented as being the original software. 21 22 3. This notice may not be removed or altered from any source 23 distribution. 24 */ 25 26 /* 27 Extra C++ utilities for LodePNG, for convenience. 28 */ 29 30 #include <string> 31 #include <vector> 32 #include "lodepng.h" 33 34 #pragma once 35 36 namespace lodepng 37 { 38 39 /* 40 Returns info from the header of the PNG by value, purely for convenience. 41 Does NOT check for errors. Returns bogus info if the PNG has an error. 42 Does not require cleanup of allocated memory because no palette or text chunk 43 info is in the LodePNGInfo object after checking only the header of the PNG. 44 */ 45 LodePNGInfo getPNGHeaderInfo(const std::vector<unsigned char>& png); 46 47 /* 48 Get the names and sizes of all chunks in the PNG file. 49 Returns 0 if ok, non-0 if error happened. 50 */ 51 unsigned getChunkInfo(std::vector<std::string>& names, std::vector<size_t>& sizes, 52 const std::vector<unsigned char>& png); 53 54 /* 55 Returns the names and full chunks (including the name and everything else that 56 makes up the chunk) for all chunks except IHDR, PLTE, IDAT and IEND. 57 It separates the chunks into 3 separate lists, representing the chunks between 58 certain critical chunks: 0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND 59 Returns 0 if ok, non-0 if error happened. 60 */ 61 unsigned getChunks(std::vector<std::string> names[3], 62 std::vector<std::vector<unsigned char> > chunks[3], 63 const std::vector<unsigned char>& png); 64 65 /* 66 Inserts chunks into the given png file. The chunks must be fully encoded, 67 including length, type, content and CRC. 68 The array index determines where it goes: 69 0: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND. 70 They're appended at the end of those locations within the PNG. 71 Returns 0 if ok, non-0 if error happened. 72 */ 73 unsigned insertChunks(std::vector<unsigned char>& png, 74 const std::vector<std::vector<unsigned char> > chunks[3]); 75 76 /* 77 Get the filtertypes of each scanline in this PNG file. 78 Returns 0 if ok, 1 if PNG decoding error happened. 79 80 For a non-interlaced PNG, it returns one filtertype per scanline, in order. 81 82 For interlaced PNGs, it returns a result as if it's not interlaced. It returns 83 one filtertype per scanline, in order. The values match pass 6 and 7 of the 84 Adam7 interlacing, alternating between the two, so that the values correspond 85 the most to their scanlines. 86 */ 87 unsigned getFilterTypes(std::vector<unsigned char>& filterTypes, const std::vector<unsigned char>& png); 88 89 /* 90 Get the filtertypes of each scanline in every interlace pass this PNG file. 91 Returns 0 if ok, 1 if PNG decoding error happened. 92 93 For a non-interlaced PNG, it returns one filtertype per scanline, in order, in 94 a single std::vector in filterTypes. 95 96 For an interlaced PNG, it returns 7 std::vectors in filterTypes, one for each 97 Adam7 pass. The amount of values per pass can be calculated as follows, where 98 w and h are the size of the image and all divisions are integer divisions: 99 pass 1: (h + 7) / 8 100 pass 2: w <= 4 ? 0 : (h + 7) / 8 101 pass 3: h <= 4 ? 0 : (h + 7) / 8 102 pass 4: w <= 2 ? 0 : (h + 3) / 4 103 pass 5: h <= 2 ? 0 : (h + 3) / 4 104 pass 6: w <= 1 ? 0 : (h + 1) / 2 105 pass 7: h <= 1 ? 0 : (h + 1) / 2 106 */ 107 unsigned getFilterTypesInterlaced(std::vector<std::vector<unsigned char> >& filterTypes, 108 const std::vector<unsigned char>& png); 109 110 /* 111 Returns the value of the i-th pixel in an image with 1, 2, 4 or 8-bit color. 112 E.g. if bits is 4 and i is 5, it returns the 5th nibble (4-bit group), which 113 is the second half of the 3th byte, in big endian (PNG's endian order). 114 */ 115 int getPaletteValue(const unsigned char* data, size_t i, int bits); 116 117 /* 118 The information for extractZlibInfo. 119 */ 120 struct ZlibBlockInfo 121 { 122 int btype; //block type (0-2) 123 size_t compressedbits; //size of compressed block in bits 124 size_t uncompressedbytes; //size of uncompressed block in bytes 125 126 // only filled in for block type 2 127 size_t treebits; //encoded tree size in bits 128 int hlit; //the HLIT value that was filled in for this tree 129 int hdist; //the HDIST value that was filled in for this tree 130 int hclen; //the HCLEN value that was filled in for this tree 131 std::vector<int> clcl; //19 code length code lengths (compressed tree's tree) 132 std::vector<int> treecodes; //N tree codes, with values 0-18. Values 17 or 18 are followed by the repetition value. 133 std::vector<int> litlenlengths; //288 code lengths for lit/len symbols 134 std::vector<int> distlengths; //32 code lengths for dist symbols 135 136 // only filled in for block types 1 or 2 137 std::vector<int> lz77_lcode; //LZ77 codes. 0-255: literals. 256: end symbol. 257-285: length code of length/dist pairs 138 // the next vectors have the same size as lz77_lcode, but an element only has meaningful value if lz77_lcode contains a length code. 139 std::vector<int> lz77_dcode; 140 std::vector<int> lz77_lbits; 141 std::vector<int> lz77_dbits; 142 std::vector<int> lz77_lvalue; 143 std::vector<int> lz77_dvalue; 144 size_t numlit; //number of lit codes in this block 145 size_t numlen; //number of len codes in this block 146 }; 147 148 //Extracts all info needed from a PNG file to reconstruct the zlib compression exactly. 149 void extractZlibInfo(std::vector<ZlibBlockInfo>& zlibinfo, const std::vector<unsigned char>& in); 150 151 } // namespace lodepng 152