Compress-Zopfli

 view release on metacpan or  search on metacpan

zopflib/src/zopflipng/lodepng/lodepng.cpp  view on Meta::CPAN

933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
  unsigned treepos = 0, ct;
  for(;;)
  {
    if(*bp >= inbitlength) return (unsigned)(-1); /*error: end of input memory reached without endcode*/
    /*
    decode the symbol from the tree. The "readBitFromStream" code is inlined in
    the expression below because this is the biggest bottleneck while decoding
    */
    ct = codetree->tree2d[(treepos << 1) + READBIT(*bp, in)];
    ++(*bp);
    if(ct < codetree->numcodes) return ct; /*the symbol is decoded, return it*/
    else treepos = ct - codetree->numcodes; /*symbol not yet decoded, instead move tree position*/
 
    if(treepos >= codetree->numcodes) return (unsigned)(-1); /*error: it appeared outside the codetree*/
  }
}
#endif /*LODEPNG_COMPILE_DECODER*/
 
#ifdef LODEPNG_COMPILE_DECODER
 
/* ////////////////////////////////////////////////////////////////////////// */
/* / Inflator (Decompressor)                                                / */

zopflib/src/zopflipng/lodepng/lodepng.cpp  view on Meta::CPAN

4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
/*compressed text chunk (zTXt)*/
static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings,
                               const unsigned char* data, size_t chunkLength)
{
  unsigned error = 0;
  unsigned i;
 
  unsigned length, string2_begin;
  char *key = 0;
  ucvector decoded;
 
  ucvector_init(&decoded);
 
  while(!error) /*not really a while loop, only used to break on error*/
  {
    for(length = 0; length < chunkLength && data[length] != 0; ++length) ;
    if(length + 2 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/
    if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/
 
    key = (char*)lodepng_malloc(length + 1);
    if(!key) CERROR_BREAK(error, 83); /*alloc fail*/
 
    key[length] = 0;
    for(i = 0; i != length; ++i) key[i] = (char)data[i];
 
    if(data[length + 1] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/
 
    string2_begin = length + 2;
    if(string2_begin > chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/
 
    length = chunkLength - string2_begin;
    /*will fail if zlib error, e.g. if length is too small*/
    error = zlib_decompress(&decoded.data, &decoded.size,
                            (unsigned char*)(&data[string2_begin]),
                            length, zlibsettings);
    if(error) break;
    ucvector_push_back(&decoded, 0);
 
    error = lodepng_add_text(info, key, (char*)decoded.data);
 
    break;
  }
 
  lodepng_free(key);
  ucvector_cleanup(&decoded);
 
  return error;
}
 
/*international text chunk (iTXt)*/
static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings,
                               const unsigned char* data, size_t chunkLength)
{
  unsigned error = 0;
  unsigned i;
 
  unsigned length, begin, compressed;
  char *key = 0, *langtag = 0, *transkey = 0;
  ucvector decoded;
  ucvector_init(&decoded);
 
  while(!error) /*not really a while loop, only used to break on error*/
  {
    /*Quick check if the chunk length isn't too small. Even without check
    it'd still fail with other error checks below if it's too short. This just gives a different error code.*/
    if(chunkLength < 5) CERROR_BREAK(error, 30); /*iTXt chunk too short*/
 
    /*read the key*/
    for(length = 0; length < chunkLength && data[length] != 0; ++length) ;
    if(length + 3 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination char, corrupt?*/

zopflib/src/zopflipng/lodepng/lodepng.cpp  view on Meta::CPAN

4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
    for(i = 0; i != length; ++i) transkey[i] = (char)data[begin + i];
 
    /*read the actual text*/
    begin += length + 1;
 
    length = chunkLength < begin ? 0 : chunkLength - begin;
 
    if(compressed)
    {
      /*will fail if zlib error, e.g. if length is too small*/
      error = zlib_decompress(&decoded.data, &decoded.size,
                              (unsigned char*)(&data[begin]),
                              length, zlibsettings);
      if(error) break;
      if(decoded.allocsize < decoded.size) decoded.allocsize = decoded.size;
      ucvector_push_back(&decoded, 0);
    }
    else
    {
      if(!ucvector_resize(&decoded, length + 1)) CERROR_BREAK(error, 83 /*alloc fail*/);
 
      decoded.data[length] = 0;
      for(i = 0; i != length; ++i) decoded.data[i] = data[begin + i];
    }
 
    error = lodepng_add_itext(info, key, langtag, transkey, (char*)decoded.data);
 
    break;
  }
 
  lodepng_free(key);
  lodepng_free(langtag);
  lodepng_free(transkey);
  ucvector_cleanup(&decoded);
 
  return error;
}
 
static unsigned readChunk_tIME(LodePNGInfo* info, const unsigned char* data, size_t chunkLength)
{
  if(chunkLength != 7) return 73; /*invalid tIME chunk size*/
 
  info->time_defined = 1;
  info->time.year = 256u * data[0] + data[1];

zopflib/src/zopflipng/lodepng/lodepng.h  view on Meta::CPAN

1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
A quick reference of some settings to set on the LodePNGState
 
For decoding:
 
state.decoder.zlibsettings.ignore_adler32: ignore ADLER32 checksums
state.decoder.zlibsettings.custom_...: use custom inflate function
state.decoder.ignore_crc: ignore CRC checksums
state.decoder.color_convert: convert internal PNG color to chosen one
state.decoder.read_text_chunks: whether to read in text metadata chunks
state.decoder.remember_unknown_chunks: whether to read in unknown chunks
state.info_raw.colortype: desired color type for decoded image
state.info_raw.bitdepth: desired bit depth for decoded image
state.info_raw....: more color settings, see struct LodePNGColorMode
state.info_png....: no settings for decoder but ouput, see struct LodePNGInfo
 
For encoding:
 
state.encoder.zlibsettings.btype: disable compression by setting it to 0
state.encoder.zlibsettings.use_lz77: use LZ77 in compression
state.encoder.zlibsettings.windowsize: tweak LZ77 windowsize
state.encoder.zlibsettings.minmatch: tweak min LZ77 length to match
state.encoder.zlibsettings.nicematch: tweak LZ77 match where to stop searching

zopflib/src/zopflipng/lodepng/lodepng_util.cpp  view on Meta::CPAN

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
{
  unsigned w, h;
  lodepng::State state;
  lodepng_inspect(&w, &h, &state, &png[0], png.size());
  return state.info_png;
}
 
unsigned getChunkInfo(std::vector<std::string>& names, std::vector<size_t>& sizes,
                      const std::vector<unsigned char>& png)
{
  // Listing chunks is based on the original file, not the decoded png info.
  const unsigned char *chunk, *begin, *end, *next;
  end = &png.back() + 1;
  begin = chunk = &png.front() + 8;
 
  while(chunk + 8 < end && chunk >= begin)
  {
    char type[5];
    lodepng_chunk_type(type, chunk);
    if(std::string(type).size() != 4) return 1;

zopflib/src/zopflipng/lodepng/lodepng_util.cpp  view on Meta::CPAN

354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
        {
          //addresses are encoded as values > numcodes
          tree2d[2 * treepos + bit] = ++nodefilled + numcodes;
          treepos = nodefilled;
        }
      }
      else treepos = tree2d[2 * treepos + bit] - numcodes; //subtract numcodes from address to get address value
    }
    return 0;
  }
  int decode(bool& decoded, unsigned long& result, size_t& treepos, unsigned long bit) const
  { //Decodes a symbol from the tree
    unsigned long numcodes = (unsigned long)tree2d.size() / 2;
    if(treepos >= numcodes) return 11; //error: you appeared outside the codetree
    result = tree2d[2 * treepos + bit];
    decoded = (result < numcodes);
    treepos = decoded ? 0 : result - numcodes;
    return 0;
  }
  //2D representation of a huffman tree: one dimension is "0" or "1", the other contains all nodes and leaves.
  std::vector<unsigned long> tree2d;
};
 
void inflate(std::vector<unsigned char>& out, const std::vector<unsigned char>& in, size_t inpos = 0)
{
  size_t bp = 0, pos = 0; //bit pointer and byte pointer
  error = 0;

zopflib/src/zopflipng/lodepng/lodepng_util.cpp  view on Meta::CPAN

404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
  for(size_t i = 256; i <= 279; i++) bitlen[i] = 7;
  tree.makeFromLengths(bitlen, 15);
  treeD.makeFromLengths(bitlenD, 15);
}
 
//the code tree for Huffman codes, dist codes, and code length codes
HuffmanTree codetree, codetreeD, codelengthcodetree;
unsigned long huffmanDecodeSymbol(const unsigned char* in, size_t& bp, const HuffmanTree& tree, size_t inlength)
{
  //decode a single symbol from given list of bits with given code tree. return value is the symbol
  bool decoded; unsigned long ct;
  for(size_t treepos = 0;;)
  {
    if((bp & 0x07) == 0 && (bp >> 3) > inlength) { error = 10; return 0; } //error: end reached without endcode
    error = tree.decode(decoded, ct, treepos, readBitFromStream(bp, in));
    if(error) return 0; //stop, an error happened
    if(decoded) return ct;
  }
}
 
void getTreeInflateDynamic(HuffmanTree& tree, HuffmanTree& treeD,
                           const unsigned char* in, size_t& bp, size_t inlength)
{
  size_t bpstart = bp;
  //get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree
  std::vector<unsigned long> bitlen(288, 0), bitlenD(32, 0);
  if(bp >> 3 >= inlength - 2) { error = 49; return; } //the bit pointer is or will go past the memory



( run in 0.292 second using v1.01-cache-2.11-cpan-bf8d7bb2d05 )