zopfli 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,10 +33,13 @@ compression.
33
33
 
34
34
  /*
35
35
  Stores lit/length and dist pairs for LZ77.
36
- litlens: Contains the literal symbols or length values.
37
- dists: Indicates the distance, or 0 to indicate that there is no distance and
38
- litlens contains a literal instead of a length.
39
- litlens and dists both have the same size.
36
+ Parameter litlens: Contains the literal symbols or length values.
37
+ Parameter dists: Contains the distances. A value is 0 to indicate that there is
38
+ no dist and the corresponding litlens value is a literal instead of a length.
39
+ Parameter size: The size of both the litlens and dists arrays.
40
+ The memory can best be managed by using ZopfliInitLZ77Store to initialize it,
41
+ ZopfliCleanLZ77Store to destroy it, and ZopfliStoreLitLenDist to append values.
42
+
40
43
  */
41
44
  typedef struct ZopfliLZ77Store {
42
45
  unsigned short* litlens; /* Lit or len. */
@@ -1,5 +1,5 @@
1
1
  /*
2
- LodePNG version 20130415
2
+ LodePNG version 20131222
3
3
 
4
4
  Copyright (c) 2005-2013 Lode Vandevenne
5
5
 
@@ -37,7 +37,7 @@ Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for
37
37
  #include <fstream>
38
38
  #endif /*LODEPNG_COMPILE_CPP*/
39
39
 
40
- #define VERSION_STRING "20130415"
40
+ #define VERSION_STRING "20131222"
41
41
 
42
42
  /*
43
43
  This source file is built up in the following large parts. The code sections
@@ -190,15 +190,6 @@ static unsigned uivector_copy(uivector* p, const uivector* q)
190
190
  for(i = 0; i < q->size; i++) p->data[i] = q->data[i];
191
191
  return 1;
192
192
  }
193
-
194
- static void uivector_swap(uivector* p, uivector* q)
195
- {
196
- size_t tmp;
197
- unsigned* tmpp;
198
- tmp = p->size; p->size = q->size; q->size = tmp;
199
- tmp = p->allocsize; p->allocsize = q->allocsize; q->allocsize = tmp;
200
- tmpp = p->data; p->data = q->data; q->data = tmpp;
201
- }
202
193
  #endif /*LODEPNG_COMPILE_ENCODER*/
203
194
  #endif /*LODEPNG_COMPILE_ZLIB*/
204
195
 
@@ -404,13 +395,13 @@ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const
404
395
  #ifdef LODEPNG_COMPILE_ZLIB
405
396
  #ifdef LODEPNG_COMPILE_ENCODER
406
397
  /*TODO: this ignores potential out of memory errors*/
407
- static void addBitToStream(size_t* bitpointer, ucvector* bitstream, unsigned char bit)
408
- {
409
- /*add a new byte at the end*/
410
- if((*bitpointer) % 8 == 0) ucvector_push_back(bitstream, (unsigned char)0);
411
- /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/
412
- (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7));
413
- (*bitpointer)++;
398
+ #define addBitToStream(/*size_t**/ bitpointer, /*ucvector**/ bitstream, /*unsigned char*/ bit)\
399
+ {\
400
+ /*add a new byte at the end*/\
401
+ if(((*bitpointer) & 7) == 0) ucvector_push_back(bitstream, (unsigned char)0);\
402
+ /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/\
403
+ (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7));\
404
+ (*bitpointer)++;\
414
405
  }
415
406
 
416
407
  static void addBitsToStream(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits)
@@ -580,7 +571,7 @@ static unsigned HuffmanTree_make2DTree(HuffmanTree* tree)
580
571
  }
581
572
  }
582
573
 
583
- for(n = 0; n < tree->numcodes * 2; n++)
574
+ for(n = 0; n < tree->numcodes * 2; n++)
584
575
  {
585
576
  if(tree->tree2d[n] == 32767) tree->tree2d[n] = 0; /*remove possible remaining 32767's*/
586
577
  }
@@ -698,32 +689,10 @@ static void cleanup_coins(Coin* coins, size_t num)
698
689
  for(i = 0; i < num; i++) coin_cleanup(&coins[i]);
699
690
  }
700
691
 
701
- /*
702
- This uses a simple combsort to sort the data. This function is not critical for
703
- overall encoding speed and the data amount isn't that large.
704
- */
705
- static void sort_coins(Coin* data, size_t amount)
706
- {
707
- size_t gap = amount;
708
- unsigned char swapped = 0;
709
- while((gap > 1) || swapped)
710
- {
711
- size_t i;
712
- gap = (gap * 10) / 13; /*shrink factor 1.3*/
713
- if(gap == 9 || gap == 10) gap = 11; /*combsort11*/
714
- if(gap < 1) gap = 1;
715
- swapped = 0;
716
- for(i = 0; i < amount - gap; i++)
717
- {
718
- size_t j = i + gap;
719
- if(data[j].weight < data[i].weight)
720
- {
721
- float temp = data[j].weight; data[j].weight = data[i].weight; data[i].weight = temp;
722
- uivector_swap(&data[i].symbols, &data[j].symbols);
723
- swapped = 1;
724
- }
725
- }
726
- }
692
+ static int coin_compare(const void* a, const void* b) {
693
+ float wa = ((const Coin*)a)->weight;
694
+ float wb = ((const Coin*)b)->weight;
695
+ return wa > wb ? 1 : wa < wb ? -1 : 0;
727
696
  }
728
697
 
729
698
  static unsigned append_symbol_coins(Coin* coins, const unsigned* frequencies, unsigned numcodes, size_t sum)
@@ -795,14 +764,19 @@ unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequen
795
764
  coinmem = numpresent * 2; /*max amount of coins needed with the current algo*/
796
765
  coins = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem);
797
766
  prev_row = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem);
798
- if(!coins || !prev_row) return 83; /*alloc fail*/
767
+ if(!coins || !prev_row)
768
+ {
769
+ lodepng_free(coins);
770
+ lodepng_free(prev_row);
771
+ return 83; /*alloc fail*/
772
+ }
799
773
  init_coins(coins, coinmem);
800
774
  init_coins(prev_row, coinmem);
801
775
 
802
776
  /*first row, lowest denominator*/
803
777
  error = append_symbol_coins(coins, frequencies, numcodes, sum);
804
778
  numcoins = numpresent;
805
- sort_coins(coins, numcoins);
779
+ qsort(coins, numcoins, sizeof(Coin), coin_compare);
806
780
  if(!error)
807
781
  {
808
782
  unsigned numprev = 0;
@@ -833,7 +807,7 @@ unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequen
833
807
  error = append_symbol_coins(coins + numcoins, frequencies, numcodes, sum);
834
808
  numcoins += numpresent;
835
809
  }
836
- sort_coins(coins, numcoins);
810
+ qsort(coins, numcoins, sizeof(Coin), coin_compare);
837
811
  }
838
812
  }
839
813
 
@@ -1356,6 +1330,7 @@ static void addLengthDistance(uivector* values, size_t length, size_t distance)
1356
1330
  uivector_push_back(values, extra_distance);
1357
1331
  }
1358
1332
 
1333
+ static const unsigned HASH_BIT_MASK = 65535;
1359
1334
  static const unsigned HASH_NUM_VALUES = 65536;
1360
1335
  static const unsigned HASH_NUM_CHARACTERS = 3;
1361
1336
  static const unsigned HASH_SHIFT = 2;
@@ -1411,12 +1386,18 @@ static void hash_cleanup(Hash* hash)
1411
1386
  static unsigned getHash(const unsigned char* data, size_t size, size_t pos)
1412
1387
  {
1413
1388
  unsigned result = 0;
1414
- size_t amount, i;
1415
- if(pos >= size) return 0;
1416
- amount = HASH_NUM_CHARACTERS;
1417
- if(pos + amount >= size) amount = size - pos;
1418
- for(i = 0; i < amount; i++) result ^= (data[pos + i] << (i * HASH_SHIFT));
1419
- return result % HASH_NUM_VALUES;
1389
+ if (HASH_NUM_CHARACTERS == 3 && pos + 2 < size) {
1390
+ result ^= (data[pos + 0] << (0 * HASH_SHIFT));
1391
+ result ^= (data[pos + 1] << (1 * HASH_SHIFT));
1392
+ result ^= (data[pos + 2] << (2 * HASH_SHIFT));
1393
+ } else {
1394
+ size_t amount, i;
1395
+ if(pos >= size) return 0;
1396
+ amount = HASH_NUM_CHARACTERS;
1397
+ if(pos + amount >= size) amount = size - pos;
1398
+ for(i = 0; i < amount; i++) result ^= (data[pos + i] << (i * HASH_SHIFT));
1399
+ }
1400
+ return result & HASH_BIT_MASK;
1420
1401
  }
1421
1402
 
1422
1403
  static unsigned countZeros(const unsigned char* data, size_t size, size_t pos)
@@ -1430,9 +1411,9 @@ static unsigned countZeros(const unsigned char* data, size_t size, size_t pos)
1430
1411
  return (unsigned)(data - start);
1431
1412
  }
1432
1413
 
1433
- static void updateHashChain(Hash* hash, size_t pos, int hashval, unsigned windowsize)
1414
+ /*wpos = pos & (windowsize - 1)*/
1415
+ static void updateHashChain(Hash* hash, size_t wpos, int hashval)
1434
1416
  {
1435
- unsigned wpos = pos % windowsize;
1436
1417
  hash->val[wpos] = hashval;
1437
1418
  if(hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval];
1438
1419
  hash->head[hashval] = wpos;
@@ -1451,154 +1432,165 @@ static unsigned encodeLZ77(uivector* out, Hash* hash,
1451
1432
  const unsigned char* in, size_t inpos, size_t insize, unsigned windowsize,
1452
1433
  unsigned minmatch, unsigned nicematch, unsigned lazymatching)
1453
1434
  {
1454
- unsigned short numzeros = 0;
1455
- int usezeros = windowsize >= 8192; /*for small window size, the 'max chain length' optimization does a better job*/
1456
1435
  unsigned pos, i, error = 0;
1457
1436
  /*for large window lengths, assume the user wants no compression loss. Otherwise, max hash chain length speedup.*/
1458
1437
  unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8;
1459
1438
  unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64;
1460
1439
 
1461
- if(!error)
1462
- {
1463
- unsigned offset; /*the offset represents the distance in LZ77 terminology*/
1464
- unsigned length;
1465
- unsigned lazy = 0;
1466
- unsigned lazylength = 0, lazyoffset = 0;
1467
- unsigned hashval;
1468
- unsigned current_offset, current_length;
1469
- const unsigned char *lastptr, *foreptr, *backptr;
1470
- unsigned short hashpos, prevpos;
1471
-
1472
- for(pos = inpos; pos < insize; pos++)
1473
- {
1474
- size_t wpos = pos % windowsize; /*position for in 'circular' hash buffers*/
1440
+ unsigned usezeros = 1; /*not sure if setting it to false for windowsize < 8192 is better or worse*/
1441
+ unsigned numzeros = 0;
1475
1442
 
1476
- hashval = getHash(in, insize, pos);
1477
- updateHashChain(hash, pos, hashval, windowsize);
1443
+ unsigned offset; /*the offset represents the distance in LZ77 terminology*/
1444
+ unsigned length;
1445
+ unsigned lazy = 0;
1446
+ unsigned lazylength = 0, lazyoffset = 0;
1447
+ unsigned hashval;
1448
+ unsigned current_offset, current_length;
1449
+ const unsigned char *lastptr, *foreptr, *backptr;
1450
+ unsigned hashpos, prevpos;
1478
1451
 
1479
- if(usezeros && hashval == 0)
1480
- {
1481
- numzeros = countZeros(in, insize, pos);
1482
- hash->zeros[wpos] = numzeros;
1483
- }
1452
+ if(windowsize <= 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/
1453
+ if((windowsize & (windowsize - 1)) != 0) return 90; /*error: must be power of two*/
1484
1454
 
1485
- /*the length and offset found for the current position*/
1486
- length = 0;
1487
- offset = 0;
1455
+ if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH;
1488
1456
 
1489
- prevpos = hash->head[hashval];
1490
- hashpos = hash->chain[prevpos];
1457
+ for(pos = inpos; pos < insize; pos++)
1458
+ {
1459
+ size_t wpos = pos & (windowsize - 1); /*position for in 'circular' hash buffers*/
1460
+ unsigned chainlength = 0;
1491
1461
 
1492
- lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH];
1462
+ hashval = getHash(in, insize, pos);
1463
+ updateHashChain(hash, wpos, hashval);
1493
1464
 
1494
- /*search for the longest string*/
1495
- if(hash->val[wpos] == (int)hashval)
1496
- {
1497
- unsigned chainlength = 0;
1498
- for(;;)
1499
- {
1500
- /*stop when went completely around the circular buffer*/
1501
- if(prevpos < wpos && hashpos > prevpos && hashpos <= wpos) break;
1502
- if(prevpos > wpos && (hashpos <= wpos || hashpos > prevpos)) break;
1503
- if(chainlength++ >= maxchainlength) break;
1465
+ if(usezeros && hashval == 0)
1466
+ {
1467
+ if (numzeros == 0) numzeros = countZeros(in, insize, pos);
1468
+ else if (pos + numzeros >= insize || in[pos + numzeros - 1] != 0) numzeros--;
1469
+ hash->zeros[wpos] = numzeros;
1470
+ }
1471
+ else
1472
+ {
1473
+ numzeros = 0;
1474
+ }
1504
1475
 
1505
- current_offset = hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize;
1506
- if(current_offset > 0)
1507
- {
1508
- /*test the next characters*/
1509
- foreptr = &in[pos];
1510
- backptr = &in[pos - current_offset];
1476
+ /*the length and offset found for the current position*/
1477
+ length = 0;
1478
+ offset = 0;
1511
1479
 
1512
- /*common case in PNGs is lots of zeros. Quickly skip over them as a speedup*/
1513
- if(usezeros && hashval == 0 && hash->val[hashpos] == 0 /*hashval[hashpos] may be out of date*/)
1514
- {
1515
- unsigned short skip = hash->zeros[hashpos];
1516
- if(skip > numzeros) skip = numzeros;
1517
- backptr += skip;
1518
- foreptr += skip;
1519
- }
1480
+ prevpos = hash->head[hashval];
1481
+ hashpos = hash->chain[prevpos];
1520
1482
 
1521
- /* multiple checks at once per array bounds check */
1522
- while(foreptr != lastptr && *backptr == *foreptr) /*maximum supported length by deflate is max length*/
1523
- {
1524
- ++backptr;
1525
- ++foreptr;
1526
- }
1527
- current_length = (unsigned)(foreptr - &in[pos]);
1483
+ lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH];
1528
1484
 
1529
- if(current_length > length)
1530
- {
1531
- length = current_length; /*the longest length*/
1532
- offset = current_offset; /*the offset that is related to this longest length*/
1533
- /*jump out once a length of max length is found (speed gain)*/
1534
- if(current_length >= nicematch || current_length == MAX_SUPPORTED_DEFLATE_LENGTH) break;
1535
- }
1536
- }
1485
+ /*search for the longest string*/
1486
+ for(;;)
1487
+ {
1488
+ /*stop when went completely around the circular buffer*/
1489
+ if(prevpos < wpos && hashpos > prevpos && hashpos <= wpos) break;
1490
+ if(prevpos > wpos && (hashpos <= wpos || hashpos > prevpos)) break;
1491
+ if(chainlength++ >= maxchainlength) break;
1537
1492
 
1538
- if(hashpos == hash->chain[hashpos]) break;
1493
+ current_offset = hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize;
1494
+ if(current_offset > 0)
1495
+ {
1496
+ /*test the next characters*/
1497
+ foreptr = &in[pos];
1498
+ backptr = &in[pos - current_offset];
1539
1499
 
1540
- prevpos = hashpos;
1541
- hashpos = hash->chain[hashpos];
1500
+ /*common case in PNGs is lots of zeros. Quickly skip over them as a speedup*/
1501
+ if(usezeros && hashval == 0 && hash->val[hashpos] == 0 /*hashval[hashpos] may be out of date*/)
1502
+ {
1503
+ unsigned skip = hash->zeros[hashpos];
1504
+ if(skip > numzeros) skip = numzeros;
1505
+ backptr += skip;
1506
+ foreptr += skip;
1542
1507
  }
1543
- }
1544
1508
 
1545
- if(lazymatching)
1546
- {
1547
- if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH)
1509
+ while(foreptr != lastptr && *backptr == *foreptr) /*maximum supported length by deflate is max length*/
1548
1510
  {
1549
- lazy = 1;
1550
- lazylength = length;
1551
- lazyoffset = offset;
1552
- continue; /*try the next byte*/
1511
+ ++backptr;
1512
+ ++foreptr;
1553
1513
  }
1554
- if(lazy)
1514
+ current_length = (unsigned)(foreptr - &in[pos]);
1515
+
1516
+ if(current_length > length)
1555
1517
  {
1556
- lazy = 0;
1557
- if(pos == 0) ERROR_BREAK(81);
1558
- if(length > lazylength + 1)
1559
- {
1560
- /*push the previous character as literal*/
1561
- if(!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 /*alloc fail*/);
1562
- }
1563
- else
1564
- {
1565
- length = lazylength;
1566
- offset = lazyoffset;
1567
- hash->head[hashval] = -1; /*the same hashchain update will be done, this ensures no wrong alteration*/
1568
- pos--;
1569
- }
1518
+ length = current_length; /*the longest length*/
1519
+ offset = current_offset; /*the offset that is related to this longest length*/
1520
+ /*jump out once a length of max length is found (speed gain). This also jumps
1521
+ out if length is MAX_SUPPORTED_DEFLATE_LENGTH*/
1522
+ if(current_length >= nicematch) break;
1570
1523
  }
1571
1524
  }
1572
- if(length >= 3 && offset > windowsize) ERROR_BREAK(86 /*too big (or overflown negative) offset*/);
1573
1525
 
1574
- /**encode it as length/distance pair or literal value**/
1575
- if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/
1526
+ if(hashpos == hash->chain[hashpos]) break;
1527
+
1528
+ prevpos = hashpos;
1529
+ hashpos = hash->chain[hashpos];
1530
+ }
1531
+
1532
+ if(lazymatching)
1533
+ {
1534
+ if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH)
1576
1535
  {
1577
- if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/);
1536
+ lazy = 1;
1537
+ lazylength = length;
1538
+ lazyoffset = offset;
1539
+ continue; /*try the next byte*/
1578
1540
  }
1579
- else if(length < minmatch || (length == 3 && offset > 4096))
1541
+ if(lazy)
1580
1542
  {
1581
- /*compensate for the fact that longer offsets have more extra bits, a
1582
- length of only 3 may be not worth it then*/
1583
- if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/);
1543
+ lazy = 0;
1544
+ if(pos == 0) ERROR_BREAK(81);
1545
+ if(length > lazylength + 1)
1546
+ {
1547
+ /*push the previous character as literal*/
1548
+ if(!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 /*alloc fail*/);
1549
+ }
1550
+ else
1551
+ {
1552
+ length = lazylength;
1553
+ offset = lazyoffset;
1554
+ hash->head[hashval] = -1; /*the same hashchain update will be done, this ensures no wrong alteration*/
1555
+ pos--;
1556
+ }
1584
1557
  }
1585
- else
1558
+ }
1559
+ if(length >= 3 && offset > windowsize) ERROR_BREAK(86 /*too big (or overflown negative) offset*/);
1560
+
1561
+ /*encode it as length/distance pair or literal value*/
1562
+ if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/
1563
+ {
1564
+ if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/);
1565
+ }
1566
+ else if(length < minmatch || (length == 3 && offset > 4096))
1567
+ {
1568
+ /*compensate for the fact that longer offsets have more extra bits, a
1569
+ length of only 3 may be not worth it then*/
1570
+ if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/);
1571
+ }
1572
+ else
1573
+ {
1574
+ addLengthDistance(out, length, offset);
1575
+ for(i = 1; i < length; i++)
1586
1576
  {
1587
- addLengthDistance(out, length, offset);
1588
- for(i = 1; i < length; i++)
1577
+ pos++;
1578
+ wpos = pos & (windowsize - 1);
1579
+ hashval = getHash(in, insize, pos);
1580
+ updateHashChain(hash, wpos, hashval);
1581
+ if(usezeros && hashval == 0)
1589
1582
  {
1590
- pos++;
1591
- hashval = getHash(in, insize, pos);
1592
- updateHashChain(hash, pos, hashval, windowsize);
1593
- if(usezeros && hashval == 0)
1594
- {
1595
- hash->zeros[pos % windowsize] = countZeros(in, insize, pos);
1596
- }
1583
+ if (numzeros == 0) numzeros = countZeros(in, insize, pos);
1584
+ else if (pos + numzeros >= insize || in[pos + numzeros - 1] != 0) numzeros--;
1585
+ hash->zeros[wpos] = numzeros;
1586
+ }
1587
+ else
1588
+ {
1589
+ numzeros = 0;
1597
1590
  }
1598
1591
  }
1599
-
1600
- } /*end of the loop through each character of input*/
1601
- } /*end of "if(!error)"*/
1592
+ }
1593
+ } /*end of the loop through each character of input*/
1602
1594
 
1603
1595
  return error;
1604
1596
  }
@@ -2125,9 +2117,13 @@ static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsi
2125
2117
  size_t insize, const LodePNGDecompressSettings* settings)
2126
2118
  {
2127
2119
  if(settings->custom_zlib)
2120
+ {
2128
2121
  return settings->custom_zlib(out, outsize, in, insize, settings);
2122
+ }
2129
2123
  else
2124
+ {
2130
2125
  return lodepng_zlib_decompress(out, outsize, in, insize, settings);
2126
+ }
2131
2127
  }
2132
2128
 
2133
2129
  #endif /*LODEPNG_COMPILE_DECODER*/
@@ -2267,46 +2263,53 @@ const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0,
2267
2263
  /* / CRC32 / */
2268
2264
  /* ////////////////////////////////////////////////////////////////////////// */
2269
2265
 
2270
- static unsigned Crc32_crc_table_computed = 0;
2271
- static unsigned Crc32_crc_table[256];
2272
-
2273
- /*Make the table for a fast CRC.*/
2274
- static void Crc32_make_crc_table(void)
2275
- {
2276
- unsigned c, k, n;
2277
- for(n = 0; n < 256; n++)
2278
- {
2279
- c = n;
2280
- for(k = 0; k < 8; k++)
2281
- {
2282
- if(c & 1) c = 0xedb88320L ^ (c >> 1);
2283
- else c = c >> 1;
2284
- }
2285
- Crc32_crc_table[n] = c;
2286
- }
2287
- Crc32_crc_table_computed = 1;
2288
- }
2266
+ /* CRC polynomial: 0xedb88320 */
2267
+ static unsigned lodepng_crc32_table[256] = {
2268
+ 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u,
2269
+ 249268274u, 2044508324u, 3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u,
2270
+ 498536548u, 1789927666u, 4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u,
2271
+ 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u, 4195302755u, 2366115317u,
2272
+ 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u,
2273
+ 901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u,
2274
+ 651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u,
2275
+ 671266974u, 1594198024u, 3322730930u, 2970347812u, 795835527u, 1483230225u, 3244367275u, 3060149565u,
2276
+ 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u,
2277
+ 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u,
2278
+ 1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u,
2279
+ 1706088902u, 314042704u, 2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u,
2280
+ 1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u,
2281
+ 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u, 2852801631u, 3708648649u,
2282
+ 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u,
2283
+ 1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u,
2284
+ 3988292384u, 2596254646u, 62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u,
2285
+ 3814918930u, 2489596804u, 225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u,
2286
+ 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u, 426522225u, 1852507879u,
2287
+ 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u,
2288
+ 3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u,
2289
+ 3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u,
2290
+ 3412177804u, 3160834842u, 628085408u, 1382605366u, 3423369109u, 3138078467u, 570562233u, 1426400815u,
2291
+ 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u,
2292
+ 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u,
2293
+ 2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u,
2294
+ 2262029012u, 4057260610u, 1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u,
2295
+ 2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u, 1634467795u, 376229701u,
2296
+ 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u,
2297
+ 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u,
2298
+ 3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u,
2299
+ 3009837614u, 3294710456u, 1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u
2300
+ };
2289
2301
 
2290
- /*Update a running CRC with the bytes buf[0..len-1]--the CRC should be
2291
- initialized to all 1's, and the transmitted value is the 1's complement of the
2292
- final running CRC (see the crc() routine below).*/
2293
- static unsigned Crc32_update_crc(const unsigned char* buf, unsigned crc, size_t len)
2302
+ /*Return the CRC of the bytes buf[0..len-1].*/
2303
+ unsigned lodepng_crc32(const unsigned char* buf, size_t len)
2294
2304
  {
2295
- unsigned c = crc;
2305
+ unsigned c = 0xffffffffL;
2296
2306
  size_t n;
2297
2307
 
2298
- if(!Crc32_crc_table_computed) Crc32_make_crc_table();
2299
2308
  for(n = 0; n < len; n++)
2300
2309
  {
2301
- c = Crc32_crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
2310
+ c = lodepng_crc32_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
2302
2311
  }
2303
- return c;
2304
- }
2305
-
2306
- /*Return the CRC of the bytes buf[0..len-1].*/
2307
- unsigned lodepng_crc32(const unsigned char* buf, size_t len)
2308
- {
2309
- return Crc32_update_crc(buf, 0xffffffffL, len) ^ 0xffffffffL;
2312
+ return c ^ 0xffffffffL;
2310
2313
  }
2311
2314
 
2312
2315
  /* ////////////////////////////////////////////////////////////////////////// */
@@ -2890,13 +2893,14 @@ void lodepng_info_swap(LodePNGInfo* a, LodePNGInfo* b)
2890
2893
 
2891
2894
  /* ////////////////////////////////////////////////////////////////////////// */
2892
2895
 
2893
- /*index: bitgroup index, bits: bitgroup size(1, 2 or 4, in: bitgroup value, out: octet array to add bits to*/
2896
+ /*index: bitgroup index, bits: bitgroup size(1, 2 or 4), in: bitgroup value, out: octet array to add bits to*/
2894
2897
  static void addColorBits(unsigned char* out, size_t index, unsigned bits, unsigned in)
2895
2898
  {
2899
+ unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1; /*8 / bits - 1*/
2896
2900
  /*p = the partial index in the byte, e.g. with 4 palettebits it is 0 for first half or 1 for second half*/
2897
- unsigned p = index % (8 / bits);
2901
+ unsigned p = index & m;
2898
2902
  in &= (1 << bits) - 1; /*filter out any other bits of the input value*/
2899
- in = in << (bits * (8 / bits - p - 1));
2903
+ in = in << (bits * (m - p));
2900
2904
  if(p == 0) out[index * bits / 8] = in;
2901
2905
  else out[index * bits / 8] |= in;
2902
2906
  }
@@ -3387,7 +3391,7 @@ the out buffer must have (w * h * bpp + 7) / 8 bytes, where bpp is the bits per
3387
3391
  (lodepng_get_bpp) for < 8 bpp images, there may _not_ be padding bits at the end of scanlines.
3388
3392
  */
3389
3393
  unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
3390
- LodePNGColorMode* mode_out, LodePNGColorMode* mode_in,
3394
+ LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in,
3391
3395
  unsigned w, unsigned h, unsigned fix_png)
3392
3396
  {
3393
3397
  unsigned error = 0;
@@ -3482,7 +3486,7 @@ typedef struct ColorProfile
3482
3486
 
3483
3487
  } ColorProfile;
3484
3488
 
3485
- static void color_profile_init(ColorProfile* profile, LodePNGColorMode* mode)
3489
+ static void color_profile_init(ColorProfile* profile, const LodePNGColorMode* mode)
3486
3490
  {
3487
3491
  profile->sixteenbit = 0;
3488
3492
  profile->sixteenbit_done = mode->bitdepth == 16 ? 0 : 1;
@@ -3547,8 +3551,9 @@ unsigned getValueRequiredBits(unsigned short value)
3547
3551
  /*profile must already have been inited with mode.
3548
3552
  It's ok to set some parameters of profile to done already.*/
3549
3553
  static unsigned get_color_profile(ColorProfile* profile,
3550
- const unsigned char* in, size_t numpixels,
3551
- LodePNGColorMode* mode,
3554
+ const unsigned char* in,
3555
+ size_t numpixels /*must be full image size, for certain filesize based choices*/,
3556
+ const LodePNGColorMode* mode,
3552
3557
  unsigned fix_png)
3553
3558
  {
3554
3559
  unsigned error = 0;
@@ -3584,9 +3589,10 @@ static unsigned get_color_profile(ColorProfile* profile,
3584
3589
 
3585
3590
  if(!profile->alpha_done && a != 65535)
3586
3591
  {
3587
- if(a == 0 && !(profile->key && (r != profile->key_r || g != profile->key_g || b != profile->key_b)))
3592
+ /*only use color key if numpixels large enough to justify tRNS chunk size*/
3593
+ if(a == 0 && numpixels > 16 && !(profile->key && (r != profile->key_r || g != profile->key_g || b != profile->key_b)))
3588
3594
  {
3589
- if(!profile->key)
3595
+ if(!profile->alpha && !profile->key)
3590
3596
  {
3591
3597
  profile->key = 1;
3592
3598
  profile->key_r = r;
@@ -3748,9 +3754,10 @@ static void setColorKeyFrom16bit(LodePNGColorMode* mode_out, unsigned r, unsigne
3748
3754
 
3749
3755
  /*updates values of mode with a potentially smaller color model. mode_out should
3750
3756
  contain the user chosen color model, but will be overwritten with the new chosen one.*/
3751
- static unsigned doAutoChooseColor(LodePNGColorMode* mode_out,
3752
- const unsigned char* image, unsigned w, unsigned h, LodePNGColorMode* mode_in,
3753
- LodePNGAutoConvert auto_convert)
3757
+ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out,
3758
+ const unsigned char* image, unsigned w, unsigned h,
3759
+ const LodePNGColorMode* mode_in,
3760
+ LodePNGAutoConvert auto_convert)
3754
3761
  {
3755
3762
  ColorProfile profile;
3756
3763
  unsigned error = 0;
@@ -3807,9 +3814,9 @@ static unsigned doAutoChooseColor(LodePNGColorMode* mode_out,
3807
3814
  {
3808
3815
  if(!palette_ok || (grey_ok && profile.greybits <= palettebits))
3809
3816
  {
3817
+ unsigned grey = profile.key_r;
3810
3818
  mode_out->colortype = LCT_GREY;
3811
3819
  mode_out->bitdepth = profile.greybits;
3812
- unsigned grey = profile.key_r;
3813
3820
  if(profile.key) setColorKeyFrom16bit(mode_out, grey, grey, grey, mode_out->bitdepth);
3814
3821
  }
3815
3822
  else
@@ -4560,6 +4567,7 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
4560
4567
  const unsigned char* chunk;
4561
4568
  size_t i;
4562
4569
  ucvector idat; /*the data from idat chunks*/
4570
+ ucvector scanlines;
4563
4571
 
4564
4572
  /*for unknown chunk order*/
4565
4573
  unsigned unknown = 0;
@@ -4697,36 +4705,33 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
4697
4705
  if(!IEND) chunk = lodepng_chunk_next_const(chunk);
4698
4706
  }
4699
4707
 
4708
+ ucvector_init(&scanlines);
4700
4709
  if(!state->error)
4701
4710
  {
4702
- ucvector scanlines;
4703
- ucvector_init(&scanlines);
4704
-
4705
4711
  /*maximum final image length is already reserved in the vector's length - this is not really necessary*/
4706
4712
  if(!ucvector_resize(&scanlines, lodepng_get_raw_size(*w, *h, &state->info_png.color) + *h))
4707
4713
  {
4708
4714
  state->error = 83; /*alloc fail*/
4709
4715
  }
4710
- if(!state->error)
4711
- {
4712
- /*decompress with the Zlib decompressor*/
4713
- state->error = zlib_decompress(&scanlines.data, &scanlines.size, idat.data,
4714
- idat.size, &state->decoder.zlibsettings);
4715
- }
4716
-
4717
- if(!state->error)
4718
- {
4719
- ucvector outv;
4720
- ucvector_init(&outv);
4721
- if(!ucvector_resizev(&outv,
4722
- lodepng_get_raw_size(*w, *h, &state->info_png.color), 0)) state->error = 83; /*alloc fail*/
4723
- if(!state->error) state->error = postProcessScanlines(outv.data, scanlines.data, *w, *h, &state->info_png);
4724
- *out = outv.data;
4725
- }
4726
- ucvector_cleanup(&scanlines);
4727
4716
  }
4728
-
4717
+ if(!state->error)
4718
+ {
4719
+ /*decompress with the Zlib decompressor*/
4720
+ state->error = zlib_decompress(&scanlines.data, &scanlines.size, idat.data,
4721
+ idat.size, &state->decoder.zlibsettings);
4722
+ }
4729
4723
  ucvector_cleanup(&idat);
4724
+
4725
+ if(!state->error)
4726
+ {
4727
+ ucvector outv;
4728
+ ucvector_init(&outv);
4729
+ if(!ucvector_resizev(&outv,
4730
+ lodepng_get_raw_size(*w, *h, &state->info_png.color), 0)) state->error = 83; /*alloc fail*/
4731
+ if(!state->error) state->error = postProcessScanlines(outv.data, scanlines.data, *w, *h, &state->info_png);
4732
+ *out = outv.data;
4733
+ }
4734
+ ucvector_cleanup(&scanlines);
4730
4735
  }
4731
4736
 
4732
4737
  unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h,
@@ -5679,15 +5684,11 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize,
5679
5684
 
5680
5685
  if(state->encoder.auto_convert != LAC_NO)
5681
5686
  {
5682
- state->error = doAutoChooseColor(&info.color, image, w, h, &state->info_raw,
5683
- state->encoder.auto_convert);
5687
+ state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw,
5688
+ state->encoder.auto_convert);
5684
5689
  }
5685
5690
  if(state->error) return state->error;
5686
5691
 
5687
- if(state->encoder.zlibsettings.windowsize > 32768)
5688
- {
5689
- CERROR_RETURN_ERROR(state->error, 60); /*error: windowsize larger than allowed*/
5690
- }
5691
5692
  if(state->encoder.zlibsettings.btype > 2)
5692
5693
  {
5693
5694
  CERROR_RETURN_ERROR(state->error, 61); /*error: unexisting btype*/
@@ -5787,9 +5788,13 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize,
5787
5788
  break;
5788
5789
  }
5789
5790
  if(state->encoder.text_compression)
5791
+ {
5790
5792
  addChunk_zTXt(&outv, info.text_keys[i], info.text_strings[i], &state->encoder.zlibsettings);
5793
+ }
5791
5794
  else
5795
+ {
5792
5796
  addChunk_tEXt(&outv, info.text_keys[i], info.text_strings[i]);
5797
+ }
5793
5798
  }
5794
5799
  /*LodePNG version id in text chunk*/
5795
5800
  if(state->encoder.add_id)
@@ -5804,7 +5809,9 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize,
5804
5809
  }
5805
5810
  }
5806
5811
  if(alread_added_id_text == 0)
5812
+ {
5807
5813
  addChunk_tEXt(&outv, "LodePNG", VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/
5814
+ }
5808
5815
  }
5809
5816
  /*iTXt*/
5810
5817
  for(i = 0; i < info.itext_num; i++)
@@ -5831,7 +5838,6 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize,
5831
5838
  if(state->error) break;
5832
5839
  }
5833
5840
  #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5834
- /*IEND*/
5835
5841
  addChunk_IEND(&outv);
5836
5842
 
5837
5843
  break; /*this isn't really a while loop; no error happened so break out now!*/
@@ -6014,6 +6020,8 @@ const char* lodepng_error_text(unsigned code)
6014
6020
  case 87: return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined";
6015
6021
  case 88: return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy";
6016
6022
  case 89: return "text chunk keyword too short or long: must have size 1-79";
6023
+ /*the windowsize in the LodePNGCompressSettings. Requiring POT(==> & instead of %) makes encoding 12% faster.*/
6024
+ case 90: return "windowsize must be a power of two";
6017
6025
  }
6018
6026
  return "unknown error code";
6019
6027
  }
@@ -6025,7 +6033,6 @@ const char* lodepng_error_text(unsigned code)
6025
6033
  /* ////////////////////////////////////////////////////////////////////////// */
6026
6034
  /* ////////////////////////////////////////////////////////////////////////// */
6027
6035
 
6028
-
6029
6036
  #ifdef LODEPNG_COMPILE_CPP
6030
6037
  namespace lodepng
6031
6038
  {
@@ -6153,14 +6160,14 @@ unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
6153
6160
  State& state,
6154
6161
  const unsigned char* in, size_t insize)
6155
6162
  {
6156
- unsigned char* buffer;
6163
+ unsigned char* buffer = NULL;
6157
6164
  unsigned error = lodepng_decode(&buffer, &w, &h, &state, in, insize);
6158
6165
  if(buffer && !error)
6159
6166
  {
6160
6167
  size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw);
6161
6168
  out.insert(out.end(), &buffer[0], &buffer[buffersize]);
6162
- lodepng_free(buffer);
6163
6169
  }
6170
+ lodepng_free(buffer);
6164
6171
  return error;
6165
6172
  }
6166
6173