zopfli 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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