Home | History | Annotate | Download | only in lodepng
      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 #include "lodepng_util.h"
     27 #include <iostream>
     28 
     29 namespace lodepng
     30 {
     31 
     32 LodePNGInfo getPNGHeaderInfo(const std::vector<unsigned char>& png)
     33 {
     34   unsigned w, h;
     35   lodepng::State state;
     36   lodepng_inspect(&w, &h, &state, &png[0], png.size());
     37   return state.info_png;
     38 }
     39 
     40 unsigned getChunkInfo(std::vector<std::string>& names, std::vector<size_t>& sizes,
     41                       const std::vector<unsigned char>& png)
     42 {
     43   // Listing chunks is based on the original file, not the decoded png info.
     44   const unsigned char *chunk, *begin, *end;
     45   end = &png.back() + 1;
     46   begin = chunk = &png.front() + 8;
     47 
     48   while(chunk + 8 < end && chunk >= begin)
     49   {
     50     char type[5];
     51     lodepng_chunk_type(type, chunk);
     52     if(std::string(type).size() != 4) return 1;
     53 
     54     names.push_back(type);
     55     sizes.push_back(lodepng_chunk_length(chunk));
     56 
     57     chunk = lodepng_chunk_next_const(chunk);
     58   }
     59   return 0;
     60 }
     61 
     62 unsigned getChunks(std::vector<std::string> names[3],
     63                    std::vector<std::vector<unsigned char> > chunks[3],
     64                    const std::vector<unsigned char>& png)
     65 {
     66   const unsigned char *chunk, *next, *begin, *end;
     67   end = &png.back() + 1;
     68   begin = chunk = &png.front() + 8;
     69 
     70   int location = 0;
     71 
     72   while(chunk + 8 < end && chunk >= begin)
     73   {
     74     char type[5];
     75     lodepng_chunk_type(type, chunk);
     76     std::string name(type);
     77     if(name.size() != 4) return 1;
     78 
     79     next = lodepng_chunk_next_const(chunk);
     80 
     81     if(name == "IHDR")
     82     {
     83       location = 0;
     84     }
     85     else if(name == "PLTE")
     86     {
     87       location = 1;
     88     }
     89     else if(name == "IDAT")
     90     {
     91       location = 2;
     92     }
     93     else if(name != "IEND")
     94     {
     95       names[location].push_back(name);
     96       chunks[location].push_back(std::vector<unsigned char>(chunk, next));
     97     }
     98 
     99     chunk = next;
    100   }
    101   return 0;
    102 }
    103 
    104 
    105 unsigned insertChunks(std::vector<unsigned char>& png,
    106                       const std::vector<std::vector<unsigned char> > chunks[3])
    107 {
    108   const unsigned char *chunk, *next, *begin, *end;
    109   end = &png.back() + 1;
    110   begin = chunk = &png.front() + 8;
    111 
    112   size_t l0 = 0; //location 0: IHDR-l0-PLTE (or IHDR-l0-l1-IDAT)
    113   size_t l1 = 0; //location 1: PLTE-l1-IDAT (or IHDR-l0-l1-IDAT)
    114   size_t l2 = 0; //location 2: IDAT-l2-IEND
    115 
    116   while(chunk + 8 < end && chunk >= begin)
    117   {
    118     char type[5];
    119     lodepng_chunk_type(type, chunk);
    120     std::string name(type);
    121     if(name.size() != 4) return 1;
    122 
    123     next = lodepng_chunk_next_const(chunk);
    124 
    125     if(name == "PLTE")
    126     {
    127       if(l0 == 0) l0 = chunk - begin + 8;
    128     }
    129     else if(name == "IDAT")
    130     {
    131       if(l0 == 0) l0 = chunk - begin + 8;
    132       if(l1 == 0) l1 = chunk - begin + 8;
    133     }
    134     else if(name == "IEND")
    135     {
    136       if(l2 == 0) l2 = chunk - begin + 8;
    137     }
    138 
    139     chunk = next;
    140   }
    141 
    142   std::vector<unsigned char> result;
    143   result.insert(result.end(), png.begin(), png.begin() + l0);
    144   for(size_t i = 0; i < chunks[0].size(); i++) result.insert(result.end(), chunks[0][i].begin(), chunks[0][i].end());
    145   result.insert(result.end(), png.begin() + l0, png.begin() + l1);
    146   for(size_t i = 0; i < chunks[1].size(); i++) result.insert(result.end(), chunks[1][i].begin(), chunks[1][i].end());
    147   result.insert(result.end(), png.begin() + l1, png.begin() + l2);
    148   for(size_t i = 0; i < chunks[2].size(); i++) result.insert(result.end(), chunks[2][i].begin(), chunks[2][i].end());
    149   result.insert(result.end(), png.begin() + l2, png.end());
    150 
    151   png = result;
    152   return 0;
    153 }
    154 
    155 unsigned getFilterTypesInterlaced(std::vector<std::vector<unsigned char> >& filterTypes,
    156                                   const std::vector<unsigned char>& png)
    157 {
    158   //Get color type and interlace type
    159   lodepng::State state;
    160   unsigned w, h;
    161   unsigned error;
    162   error = lodepng_inspect(&w, &h, &state, &png[0], png.size());
    163 
    164   if(error) return 1;
    165 
    166   //Read literal data from all IDAT chunks
    167   const unsigned char *chunk, *begin, *end;
    168   end = &png.back() + 1;
    169   begin = chunk = &png.front() + 8;
    170 
    171   std::vector<unsigned char> zdata;
    172 
    173   while(chunk + 8 < end && chunk >= begin)
    174   {
    175     char type[5];
    176     lodepng_chunk_type(type, chunk);
    177     if(std::string(type).size() != 4) return 1; //Probably not a PNG file
    178 
    179     if(std::string(type) == "IDAT")
    180     {
    181       const unsigned char* cdata = lodepng_chunk_data_const(chunk);
    182       unsigned clength = lodepng_chunk_length(chunk);
    183 
    184       for(unsigned i = 0; i < clength; i++)
    185       {
    186         zdata.push_back(cdata[i]);
    187       }
    188     }
    189 
    190     chunk = lodepng_chunk_next_const(chunk);
    191   }
    192 
    193   //Decompress all IDAT data
    194   std::vector<unsigned char> data;
    195   error = lodepng::decompress(data, &zdata[0], zdata.size());
    196 
    197   if(error) return 1;
    198 
    199   if(state.info_png.interlace_method == 0)
    200   {
    201     filterTypes.resize(1);
    202 
    203     //A line is 1 filter byte + all pixels
    204     size_t linebytes = 1 + lodepng_get_raw_size(w, 1, &state.info_png.color);
    205 
    206     for(size_t i = 0; i < data.size(); i += linebytes)
    207     {
    208       filterTypes[0].push_back(data[i]);
    209     }
    210   }
    211   else
    212   {
    213     //Interlaced
    214     filterTypes.resize(7);
    215     static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/
    216     static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/
    217     static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/
    218     static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/
    219     size_t pos = 0;
    220     for(int j = 0; j < 7; j++)
    221     {
    222       unsigned w2 = (w - ADAM7_IX[j] + ADAM7_DX[j] - 1) / ADAM7_DX[j];
    223       unsigned h2 = (h - ADAM7_IY[j] + ADAM7_DY[j] - 1) / ADAM7_DY[j];
    224       if(ADAM7_IX[j] >= w || ADAM7_IY[j] >= h) w2 = h2 = 0;
    225       size_t linebytes = 1 + lodepng_get_raw_size(w2, 1, &state.info_png.color);
    226       for(size_t i = 0; i < h2; i++)
    227       {
    228         filterTypes[j].push_back(data[pos]);
    229         pos += linebytes;
    230       }
    231     }
    232   }
    233   return 0; /* OK */
    234 }
    235 
    236 
    237 unsigned getFilterTypes(std::vector<unsigned char>& filterTypes, const std::vector<unsigned char>& png)
    238 {
    239   std::vector<std::vector<unsigned char> > passes;
    240   unsigned error = getFilterTypesInterlaced(passes, png);
    241   if(error) return error;
    242 
    243   if(passes.size() == 1)
    244   {
    245     filterTypes.swap(passes[0]);
    246   }
    247   else
    248   {
    249     lodepng::State state;
    250     unsigned w, h;
    251     lodepng_inspect(&w, &h, &state, &png[0], png.size());
    252     /*
    253     Interlaced. Simplify it: put pass 6 and 7 alternating in the one vector so
    254     that one filter per scanline of the uninterlaced image is given, with that
    255     filter corresponding the closest to what it would be for non-interlaced
    256     image.
    257     */
    258     for(size_t i = 0; i < h; i++)
    259     {
    260       filterTypes.push_back(i % 2 == 0 ? passes[5][i / 2] : passes[6][i / 2]);
    261     }
    262   }
    263   return 0; /* OK */
    264 }
    265 
    266 int getPaletteValue(const unsigned char* data, size_t i, int bits)
    267 {
    268   if(bits == 8) return data[i];
    269   else if(bits == 4) return (data[i / 2] >> ((i % 2) * 4)) & 15;
    270   else if(bits == 2) return (data[i / 4] >> ((i % 4) * 2)) & 3;
    271   else if(bits == 1) return (data[i / 8] >> (i % 8)) & 1;
    272   else return 0;
    273 }
    274 
    275 //This uses a stripped down version of picoPNG to extract detailed zlib information while decompressing.
    276 static const unsigned long LENBASE[29] =
    277     {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258};
    278 static const unsigned long LENEXTRA[29] =
    279     {0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,  4,  5,  5,  5,  5,  0};
    280 static const unsigned long DISTBASE[30] =
    281     {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
    282 static const unsigned long DISTEXTRA[30] =
    283     {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5,  6,  6,  7,  7,  8,  8,   9,   9,  10,  10,  11,  11,  12,   12,   13,   13};
    284 static const unsigned long CLCL[19] =
    285     {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; //code length code lengths
    286 
    287 struct ExtractZlib // Zlib decompression and information extraction
    288 {
    289   std::vector<ZlibBlockInfo>* zlibinfo;
    290   int error;
    291 
    292   ExtractZlib(std::vector<ZlibBlockInfo>* output) : zlibinfo(output) {};
    293 
    294   unsigned long readBitFromStream(size_t& bitp, const unsigned char* bits)
    295   {
    296     unsigned long result = (bits[bitp >> 3] >> (bitp & 0x7)) & 1;
    297     bitp++;
    298     return result;
    299   }
    300 
    301   unsigned long readBitsFromStream(size_t& bitp, const unsigned char* bits, size_t nbits)
    302   {
    303     unsigned long result = 0;
    304     for(size_t i = 0; i < nbits; i++) result += (readBitFromStream(bitp, bits)) << i;
    305     return result;
    306   }
    307 
    308   struct HuffmanTree
    309   {
    310     int makeFromLengths(const std::vector<unsigned long>& bitlen, unsigned long maxbitlen)
    311     { //make tree given the lengths
    312       unsigned long numcodes = (unsigned long)(bitlen.size()), treepos = 0, nodefilled = 0;
    313       std::vector<unsigned long> tree1d(numcodes), blcount(maxbitlen + 1, 0), nextcode(maxbitlen + 1, 0);
    314       //count number of instances of each code length
    315       for(unsigned long bits = 0; bits < numcodes; bits++) blcount[bitlen[bits]]++;
    316       for(unsigned long bits = 1; bits <= maxbitlen; bits++)
    317       {
    318         nextcode[bits] = (nextcode[bits - 1] + blcount[bits - 1]) << 1;
    319       }
    320       //generate all the codes
    321       for(unsigned long n = 0; n < numcodes; n++) if(bitlen[n] != 0) tree1d[n] = nextcode[bitlen[n]]++;
    322       tree2d.clear(); tree2d.resize(numcodes * 2, 32767); //32767 here means the tree2d isn't filled there yet
    323       for(unsigned long n = 0; n < numcodes; n++) //the codes
    324       for(unsigned long i = 0; i < bitlen[n]; i++) //the bits for this code
    325       {
    326         unsigned long bit = (tree1d[n] >> (bitlen[n] - i - 1)) & 1;
    327         if(treepos > numcodes - 2) return 55;
    328         if(tree2d[2 * treepos + bit] == 32767) //not yet filled in
    329         {
    330           if(i + 1 == bitlen[n])
    331           {
    332             //last bit
    333             tree2d[2 * treepos + bit] = n;
    334             treepos = 0;
    335           }
    336           else
    337           {
    338             //addresses are encoded as values > numcodes
    339             tree2d[2 * treepos + bit] = ++nodefilled + numcodes;
    340             treepos = nodefilled;
    341           }
    342         }
    343         else treepos = tree2d[2 * treepos + bit] - numcodes; //subtract numcodes from address to get address value
    344       }
    345       return 0;
    346     }
    347     int decode(bool& decoded, unsigned long& result, size_t& treepos, unsigned long bit) const
    348     { //Decodes a symbol from the tree
    349       unsigned long numcodes = (unsigned long)tree2d.size() / 2;
    350       if(treepos >= numcodes) return 11; //error: you appeared outside the codetree
    351       result = tree2d[2 * treepos + bit];
    352       decoded = (result < numcodes);
    353       treepos = decoded ? 0 : result - numcodes;
    354       return 0;
    355     }
    356     //2D representation of a huffman tree: one dimension is "0" or "1", the other contains all nodes and leaves.
    357     std::vector<unsigned long> tree2d;
    358   };
    359 
    360   void inflate(std::vector<unsigned char>& out, const std::vector<unsigned char>& in, size_t inpos = 0)
    361   {
    362     size_t bp = 0, pos = 0; //bit pointer and byte pointer
    363     error = 0;
    364     unsigned long BFINAL = 0;
    365     while(!BFINAL && !error)
    366     {
    367       size_t uncomprblockstart = pos;
    368       size_t bpstart = bp;
    369       if(bp >> 3 >= in.size()) { error = 52; return; } //error, bit pointer will jump past memory
    370       BFINAL = readBitFromStream(bp, &in[inpos]);
    371       unsigned long BTYPE = readBitFromStream(bp, &in[inpos]); BTYPE += 2 * readBitFromStream(bp, &in[inpos]);
    372       zlibinfo->resize(zlibinfo->size() + 1);
    373       zlibinfo->back().btype = BTYPE;
    374       if(BTYPE == 3) { error = 20; return; } //error: invalid BTYPE
    375       else if(BTYPE == 0) inflateNoCompression(out, &in[inpos], bp, pos, in.size());
    376       else inflateHuffmanBlock(out, &in[inpos], bp, pos, in.size(), BTYPE);
    377       size_t uncomprblocksize = pos - uncomprblockstart;
    378       zlibinfo->back().compressedbits = bp - bpstart;
    379       zlibinfo->back().uncompressedbytes = uncomprblocksize;
    380     }
    381   }
    382 
    383   void generateFixedTrees(HuffmanTree& tree, HuffmanTree& treeD) //get the tree of a deflated block with fixed tree
    384   {
    385     std::vector<unsigned long> bitlen(288, 8), bitlenD(32, 5);;
    386     for(size_t i = 144; i <= 255; i++) bitlen[i] = 9;
    387     for(size_t i = 256; i <= 279; i++) bitlen[i] = 7;
    388     tree.makeFromLengths(bitlen, 15);
    389     treeD.makeFromLengths(bitlenD, 15);
    390   }
    391 
    392   //the code tree for Huffman codes, dist codes, and code length codes
    393   HuffmanTree codetree, codetreeD, codelengthcodetree;
    394   unsigned long huffmanDecodeSymbol(const unsigned char* in, size_t& bp, const HuffmanTree& codetree, size_t inlength)
    395   {
    396     //decode a single symbol from given list of bits with given code tree. return value is the symbol
    397     bool decoded; unsigned long ct;
    398     for(size_t treepos = 0;;)
    399     {
    400       if((bp & 0x07) == 0 && (bp >> 3) > inlength) { error = 10; return 0; } //error: end reached without endcode
    401       error = codetree.decode(decoded, ct, treepos, readBitFromStream(bp, in));
    402       if(error) return 0; //stop, an error happened
    403       if(decoded) return ct;
    404     }
    405   }
    406 
    407   void getTreeInflateDynamic(HuffmanTree& tree, HuffmanTree& treeD,
    408                              const unsigned char* in, size_t& bp, size_t inlength)
    409   {
    410     size_t bpstart = bp;
    411     //get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree
    412     std::vector<unsigned long> bitlen(288, 0), bitlenD(32, 0);
    413     if(bp >> 3 >= inlength - 2) { error = 49; return; } //the bit pointer is or will go past the memory
    414     size_t HLIT =  readBitsFromStream(bp, in, 5) + 257; //number of literal/length codes + 257
    415     size_t HDIST = readBitsFromStream(bp, in, 5) + 1; //number of dist codes + 1
    416     size_t HCLEN = readBitsFromStream(bp, in, 4) + 4; //number of code length codes + 4
    417     zlibinfo->back().hlit = HLIT - 257;
    418     zlibinfo->back().hdist = HDIST - 1;
    419     zlibinfo->back().hclen = HCLEN - 4;
    420     std::vector<unsigned long> codelengthcode(19); //lengths of tree to decode the lengths of the dynamic tree
    421     for(size_t i = 0; i < 19; i++) codelengthcode[CLCL[i]] = (i < HCLEN) ? readBitsFromStream(bp, in, 3) : 0;
    422     //code length code lengths
    423     for(size_t i = 0; i < codelengthcode.size(); i++) zlibinfo->back().clcl.push_back(codelengthcode[i]);
    424     error = codelengthcodetree.makeFromLengths(codelengthcode, 7); if(error) return;
    425     size_t i = 0, replength;
    426     while(i < HLIT + HDIST)
    427     {
    428       unsigned long code = huffmanDecodeSymbol(in, bp, codelengthcodetree, inlength); if(error) return;
    429       zlibinfo->back().treecodes.push_back(code); //tree symbol code
    430       if(code <= 15)  { if(i < HLIT) bitlen[i++] = code; else bitlenD[i++ - HLIT] = code; } //a length code
    431       else if(code == 16) //repeat previous
    432       {
    433         if(bp >> 3 >= inlength) { error = 50; return; } //error, bit pointer jumps past memory
    434         replength = 3 + readBitsFromStream(bp, in, 2);
    435         unsigned long value; //set value to the previous code
    436         if((i - 1) < HLIT) value = bitlen[i - 1];
    437         else value = bitlenD[i - HLIT - 1];
    438         for(size_t n = 0; n < replength; n++) //repeat this value in the next lengths
    439         {
    440           if(i >= HLIT + HDIST) { error = 13; return; } //error: i is larger than the amount of codes
    441           if(i < HLIT) bitlen[i++] = value; else bitlenD[i++ - HLIT] = value;
    442         }
    443       }
    444       else if(code == 17) //repeat "0" 3-10 times
    445       {
    446         if(bp >> 3 >= inlength) { error = 50; return; } //error, bit pointer jumps past memory
    447         replength = 3 + readBitsFromStream(bp, in, 3);
    448         zlibinfo->back().treecodes.push_back(replength); //tree symbol code repetitions
    449         for(size_t n = 0; n < replength; n++) //repeat this value in the next lengths
    450         {
    451           if(i >= HLIT + HDIST) { error = 14; return; } //error: i is larger than the amount of codes
    452           if(i < HLIT) bitlen[i++] = 0; else bitlenD[i++ - HLIT] = 0;
    453         }
    454       }
    455       else if(code == 18) //repeat "0" 11-138 times
    456       {
    457         if(bp >> 3 >= inlength) { error = 50; return; } //error, bit pointer jumps past memory
    458         replength = 11 + readBitsFromStream(bp, in, 7);
    459         zlibinfo->back().treecodes.push_back(replength); //tree symbol code repetitions
    460         for(size_t n = 0; n < replength; n++) //repeat this value in the next lengths
    461         {
    462           if(i >= HLIT + HDIST) { error = 15; return; } //error: i is larger than the amount of codes
    463           if(i < HLIT) bitlen[i++] = 0; else bitlenD[i++ - HLIT] = 0;
    464         }
    465       }
    466       else { error = 16; return; } //error: somehow an unexisting code appeared. This can never happen.
    467     }
    468     if(bitlen[256] == 0) { error = 64; return; } //the length of the end code 256 must be larger than 0
    469     error = tree.makeFromLengths(bitlen, 15);
    470     if(error) return; //now we've finally got HLIT and HDIST, so generate the code trees, and the function is done
    471     error = treeD.makeFromLengths(bitlenD, 15);
    472     if(error) return;
    473     zlibinfo->back().treebits = bp - bpstart;
    474     //lit/len/end symbol lengths
    475     for(size_t i = 0; i < bitlen.size(); i++) zlibinfo->back().litlenlengths.push_back(bitlen[i]);
    476     //dist lengths
    477     for(size_t i = 0; i < bitlenD.size(); i++) zlibinfo->back().distlengths.push_back(bitlenD[i]);
    478   }
    479 
    480   void inflateHuffmanBlock(std::vector<unsigned char>& out,
    481                            const unsigned char* in, size_t& bp, size_t& pos, size_t inlength, unsigned long btype)
    482   {
    483     size_t numcodes = 0, numlit = 0, numlen = 0; //for logging
    484     if(btype == 1) { generateFixedTrees(codetree, codetreeD); }
    485     else if(btype == 2) { getTreeInflateDynamic(codetree, codetreeD, in, bp, inlength); if(error) return; }
    486     for(;;)
    487     {
    488       unsigned long code = huffmanDecodeSymbol(in, bp, codetree, inlength); if(error) return;
    489       numcodes++;
    490       zlibinfo->back().lz77_lcode.push_back(code); //output code
    491       zlibinfo->back().lz77_dcode.push_back(0);
    492       zlibinfo->back().lz77_lbits.push_back(0);
    493       zlibinfo->back().lz77_dbits.push_back(0);
    494       zlibinfo->back().lz77_lvalue.push_back(0);
    495       zlibinfo->back().lz77_dvalue.push_back(0);
    496 
    497       if(code == 256) break; //end code
    498       else if(code <= 255) //literal symbol
    499       {
    500         out.push_back((unsigned char)(code));
    501         pos++;
    502         numlit++;
    503       }
    504       else if(code >= 257 && code <= 285) //length code
    505       {
    506         size_t length = LENBASE[code - 257], numextrabits = LENEXTRA[code - 257];
    507         if((bp >> 3) >= inlength) { error = 51; return; } //error, bit pointer will jump past memory
    508         length += readBitsFromStream(bp, in, numextrabits);
    509         unsigned long codeD = huffmanDecodeSymbol(in, bp, codetreeD, inlength); if(error) return;
    510         if(codeD > 29) { error = 18; return; } //error: invalid dist code (30-31 are never used)
    511         unsigned long dist = DISTBASE[codeD], numextrabitsD = DISTEXTRA[codeD];
    512         if((bp >> 3) >= inlength) { error = 51; return; } //error, bit pointer will jump past memory
    513         dist += readBitsFromStream(bp, in, numextrabitsD);
    514         size_t start = pos, back = start - dist; //backwards
    515         for(size_t i = 0; i < length; i++)
    516         {
    517           out.push_back(out[back++]);
    518           pos++;
    519           if(back >= start) back = start - dist;
    520         }
    521         numlen++;
    522         zlibinfo->back().lz77_dcode.back() = codeD; //output distance code
    523         zlibinfo->back().lz77_lbits.back() = numextrabits; //output length extra bits
    524         zlibinfo->back().lz77_dbits.back() = numextrabitsD; //output dist extra bits
    525         zlibinfo->back().lz77_lvalue.back() = length; //output length
    526         zlibinfo->back().lz77_dvalue.back() = dist; //output dist
    527       }
    528     }
    529     zlibinfo->back().numlit = numlit; //output number of literal symbols
    530     zlibinfo->back().numlen = numlen; //output number of length symbols
    531   }
    532 
    533   void inflateNoCompression(std::vector<unsigned char>& out,
    534                             const unsigned char* in, size_t& bp, size_t& pos, size_t inlength)
    535   {
    536     while((bp & 0x7) != 0) bp++; //go to first boundary of byte
    537     size_t p = bp / 8;
    538     if(p >= inlength - 4) { error = 52; return; } //error, bit pointer will jump past memory
    539     unsigned long LEN = in[p] + 256 * in[p + 1], NLEN = in[p + 2] + 256 * in[p + 3]; p += 4;
    540     if(LEN + NLEN != 65535) { error = 21; return; } //error: NLEN is not one's complement of LEN
    541     if(p + LEN > inlength) { error = 23; return; } //error: reading outside of in buffer
    542     for(unsigned long n = 0; n < LEN; n++)
    543     {
    544       out.push_back(in[p++]); //read LEN bytes of literal data
    545       pos++;
    546     }
    547     bp = p * 8;
    548   }
    549 
    550   int decompress(std::vector<unsigned char>& out, const std::vector<unsigned char>& in) //returns error value
    551   {
    552     if(in.size() < 2) { return 53; } //error, size of zlib data too small
    553     //error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way
    554     if((in[0] * 256 + in[1]) % 31 != 0) { return 24; }
    555     unsigned long CM = in[0] & 15, CINFO = (in[0] >> 4) & 15, FDICT = (in[1] >> 5) & 1;
    556     //error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec
    557     if(CM != 8 || CINFO > 7) { return 25; }
    558     //error: the PNG spec says about the zlib stream: "The additional flags shall not specify a preset dictionary."
    559     if(FDICT != 0) { return 26; }
    560     inflate(out, in, 2);
    561     return error; //note: adler32 checksum was skipped and ignored
    562   }
    563 };
    564 
    565 struct ExtractPNG //PNG decoding and information extraction
    566 {
    567   std::vector<ZlibBlockInfo>* zlibinfo;
    568   int error;
    569 
    570   ExtractPNG(std::vector<ZlibBlockInfo>* output) : zlibinfo(output) {};
    571 
    572   void decode(const unsigned char* in, size_t size)
    573   {
    574     error = 0;
    575     if(size == 0 || in == 0) { error = 48; return; } //the given data is empty
    576     readPngHeader(&in[0], size); if(error) return;
    577     size_t pos = 33; //first byte of the first chunk after the header
    578     std::vector<unsigned char> idat; //the data from idat chunks
    579     bool IEND = false;
    580     //loop through the chunks, ignoring unknown chunks and stopping at IEND chunk.
    581     //IDAT data is put at the start of the in buffer
    582     while(!IEND)
    583     {
    584       //error: size of the in buffer too small to contain next chunk
    585       if(pos + 8 >= size) { error = 30; return; }
    586       size_t chunkLength = read32bitInt(&in[pos]); pos += 4;
    587       if(chunkLength > 2147483647) { error = 63; return; }
    588       //error: size of the in buffer too small to contain next chunk
    589       if(pos + chunkLength >= size) { error = 35; return; }
    590       //IDAT chunk, containing compressed image data
    591       if(in[pos + 0] == 'I' && in[pos + 1] == 'D' && in[pos + 2] == 'A' && in[pos + 3] == 'T')
    592       {
    593         idat.insert(idat.end(), &in[pos + 4], &in[pos + 4 + chunkLength]);
    594         pos += (4 + chunkLength);
    595       }
    596       else if(in[pos + 0] == 'I' && in[pos + 1] == 'E' && in[pos + 2] == 'N' && in[pos + 3] == 'D')
    597       {
    598           pos += 4;
    599           IEND = true;
    600       }
    601       else //it's not an implemented chunk type, so ignore it: skip over the data
    602       {
    603         pos += (chunkLength + 4); //skip 4 letters and uninterpreted data of unimplemented chunk
    604       }
    605       pos += 4; //step over CRC (which is ignored)
    606     }
    607     std::vector<unsigned char> out; //now the out buffer will be filled
    608     ExtractZlib zlib(zlibinfo); //decompress with the Zlib decompressor
    609     error = zlib.decompress(out, idat);
    610     if(error) return; //stop if the zlib decompressor returned an error
    611   }
    612 
    613   //read the information from the header and store it in the Info
    614   void readPngHeader(const unsigned char* in, size_t inlength)
    615   {
    616     if(inlength < 29) { error = 27; return; } //error: the data length is smaller than the length of the header
    617     if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71
    618     || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) { error = 28; return; } //no PNG signature
    619     //error: it doesn't start with a IHDR chunk!
    620     if(in[12] != 'I' || in[13] != 'H' || in[14] != 'D' || in[15] != 'R') { error = 29; return; }
    621   }
    622 
    623   unsigned long readBitFromReversedStream(size_t& bitp, const unsigned char* bits)
    624   {
    625     unsigned long result = (bits[bitp >> 3] >> (7 - (bitp & 0x7))) & 1;
    626     bitp++;
    627     return result;
    628   }
    629 
    630   unsigned long readBitsFromReversedStream(size_t& bitp, const unsigned char* bits, unsigned long nbits)
    631   {
    632     unsigned long result = 0;
    633     for(size_t i = nbits - 1; i < nbits; i--) result += ((readBitFromReversedStream(bitp, bits)) << i);
    634     return result;
    635   }
    636 
    637   void setBitOfReversedStream(size_t& bitp, unsigned char* bits, unsigned long bit)
    638   {
    639     bits[bitp >> 3] |=  (bit << (7 - (bitp & 0x7))); bitp++;
    640   }
    641 
    642   unsigned long read32bitInt(const unsigned char* buffer)
    643   {
    644     return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
    645   }
    646 };
    647 
    648 void extractZlibInfo(std::vector<ZlibBlockInfo>& zlibinfo, const std::vector<unsigned char>& in)
    649 {
    650   ExtractPNG decoder(&zlibinfo);
    651   decoder.decode(&in[0], in.size());
    652 
    653   if(decoder.error) std::cout << "extract error: " << decoder.error << std::endl;
    654 }
    655 
    656 } // namespace lodepng
    657