1/* 2LodePNG Utils 3 4Copyright (c) 2005-2012 Lode Vandevenne 5 6This software is provided 'as-is', without any express or implied 7warranty. In no event will the authors be held liable for any damages 8arising from the use of this software. 9 10Permission is granted to anyone to use this software for any purpose, 11including commercial applications, and to alter it and redistribute it 12freely, 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/* 27Extra C++ utilities for LodePNG, for convenience. 28*/ 29 30#include <string> 31#include <vector> 32#include "lodepng.h" 33 34#pragma once 35 36namespace lodepng 37{ 38 39/* 40Returns info from the header of the PNG by value, purely for convenience. 41Does NOT check for errors. Returns bogus info if the PNG has an error. 42Does not require cleanup of allocated memory because no palette or text chunk 43info is in the LodePNGInfo object after checking only the header of the PNG. 44*/ 45LodePNGInfo getPNGHeaderInfo(const std::vector<unsigned char>& png); 46 47/* 48Get the names and sizes of all chunks in the PNG file. 49Returns 0 if ok, non-0 if error happened. 50*/ 51unsigned getChunkInfo(std::vector<std::string>& names, std::vector<size_t>& sizes, 52 const std::vector<unsigned char>& png); 53 54/* 55Returns the names and full chunks (including the name and everything else that 56makes up the chunk) for all chunks except IHDR, PLTE, IDAT and IEND. 57It separates the chunks into 3 separate lists, representing the chunks between 58certain critical chunks: 0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND 59Returns 0 if ok, non-0 if error happened. 60*/ 61unsigned 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/* 66Inserts chunks into the given png file. The chunks must be fully encoded, 67including length, type, content and CRC. 68The array index determines where it goes: 690: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND. 70They're appended at the end of those locations within the PNG. 71Returns 0 if ok, non-0 if error happened. 72*/ 73unsigned insertChunks(std::vector<unsigned char>& png, 74 const std::vector<std::vector<unsigned char> > chunks[3]); 75 76/* 77Get the filtertypes of each scanline in this PNG file. 78Returns 0 if ok, 1 if PNG decoding error happened. 79 80For a non-interlaced PNG, it returns one filtertype per scanline, in order. 81 82For interlaced PNGs, it returns a result as if it's not interlaced. It returns 83one filtertype per scanline, in order. The values match pass 6 and 7 of the 84Adam7 interlacing, alternating between the two, so that the values correspond 85the most to their scanlines. 86*/ 87unsigned getFilterTypes(std::vector<unsigned char>& filterTypes, const std::vector<unsigned char>& png); 88 89/* 90Get the filtertypes of each scanline in every interlace pass this PNG file. 91Returns 0 if ok, 1 if PNG decoding error happened. 92 93For a non-interlaced PNG, it returns one filtertype per scanline, in order, in 94a single std::vector in filterTypes. 95 96For an interlaced PNG, it returns 7 std::vectors in filterTypes, one for each 97Adam7 pass. The amount of values per pass can be calculated as follows, where 98w and h are the size of the image and all divisions are integer divisions: 99pass 1: (h + 7) / 8 100pass 2: w <= 4 ? 0 : (h + 7) / 8 101pass 3: h <= 4 ? 0 : (h + 7) / 8 102pass 4: w <= 2 ? 0 : (h + 3) / 4 103pass 5: h <= 2 ? 0 : (h + 3) / 4 104pass 6: w <= 1 ? 0 : (h + 1) / 2 105pass 7: h <= 1 ? 0 : (h + 1) / 2 106*/ 107unsigned getFilterTypesInterlaced(std::vector<std::vector<unsigned char> >& filterTypes, 108 const std::vector<unsigned char>& png); 109 110/* 111Returns the value of the i-th pixel in an image with 1, 2, 4 or 8-bit color. 112E.g. if bits is 4 and i is 5, it returns the 5th nibble (4-bit group), which 113is the second half of the 3th byte, in big endian (PNG's endian order). 114*/ 115int getPaletteValue(const unsigned char* data, size_t i, int bits); 116 117/* 118The information for extractZlibInfo. 119*/ 120struct 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. 149void extractZlibInfo(std::vector<ZlibBlockInfo>& zlibinfo, const std::vector<unsigned char>& in); 150 151} // namespace lodepng 152