33#ifdef LODEPNG_COMPILE_DISK
38#ifdef LODEPNG_COMPILE_ALLOCATORS
42#if defined(_MSC_VER) && (_MSC_VER >= 1310)
43#pragma warning( disable : 4244 )
44#pragma warning( disable : 4996 )
73#ifdef LODEPNG_COMPILE_ALLOCATORS
74static void* lodepng_malloc(
size_t size) {
75#ifdef LODEPNG_MAX_ALLOC
76 if(
size > LODEPNG_MAX_ALLOC)
return 0;
82static void* lodepng_realloc(
void* ptr,
size_t new_size) {
83#ifdef LODEPNG_MAX_ALLOC
84 if(new_size > LODEPNG_MAX_ALLOC)
return 0;
86 return realloc(ptr, new_size);
89static void lodepng_free(
void* ptr) {
94void* lodepng_malloc(
size_t size);
95void* lodepng_realloc(
void* ptr,
size_t new_size);
96void lodepng_free(
void* ptr);
101#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined(__cplusplus) && (__cplusplus >= 199711L))
102#define LODEPNG_INLINE inline
104#define LODEPNG_INLINE
108#if (defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) ||\
109 (defined(_MSC_VER) && (_MSC_VER >= 1400)) || \
110 (defined(__WATCOMC__) && (__WATCOMC__ >= 1250) && !defined(__cplusplus))
111#define LODEPNG_RESTRICT __restrict
113#define LODEPNG_RESTRICT
124#define LODEPNG_MAX_ALLOC ((size_t)256*1024*1024)
126void* lodepng_malloc(
size_t size) {
127 if (
size > LODEPNG_MAX_ALLOC) {
131 return AllocatePool(
size);
134void lodepng_free(
void* ptr) {
140static void* lodepng_reallocate(
void* ptr,
size_t old_size,
size_t new_size) {
142 return ReallocatePool (old_size, new_size, ptr);
151 int value,
size_t num) {
157static void* lodepng_reallocate(
void* ptr,
size_t old_size,
size_t new_size) {
159 return lodepng_realloc(ptr, new_size);
165 for(i = 0; i <
size; i++) ((
char*)dst)[i] = ((
const char*)src)[i];
169 int value,
size_t num) {
171 for(i = 0; i < num; i++) ((
char*)dst)[i] = (char)
value;
177static size_t lodepng_strlen(
const char* a) {
178 const char* orig = a;
180 (void)(&lodepng_strlen);
182 return (
size_t)(a - orig);
185#define LODEPNG_MAX(a, b) (((a) > (b)) ? (a) : (b))
186#define LODEPNG_MIN(a, b) (((a) < (b)) ? (a) : (b))
188#if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_DECODER)
191static int lodepng_addofl(
size_t a,
size_t b,
size_t* result) {
197#ifdef LODEPNG_COMPILE_DECODER
200static int lodepng_mulofl(
size_t a,
size_t b,
size_t* result) {
202 return (a != 0 && *result / a != b);
205#ifdef LODEPNG_COMPILE_ZLIB
207static int lodepng_gtofl(
size_t a,
size_t b,
size_t c) {
209 if(lodepng_addofl(a, b, &d))
return 1;
223#define CERROR_BREAK(errorvar, code){\
229#define ERROR_BREAK(code) CERROR_BREAK(error, code)
232#define CERROR_RETURN_ERROR(errorvar, code){\
238#define CERROR_TRY_RETURN(call){\
239 unsigned error = call;\
240 if(error) return error;\
244#define CERROR_RETURN(errorvar, code){\
258#ifdef LODEPNG_COMPILE_ZLIB
259#ifdef LODEPNG_COMPILE_ENCODER
267static void uivector_cleanup(
void* p) {
274static unsigned uivector_resize(
uivector* p,
size_t size) {
275 size_t allocsize =
size *
sizeof(unsigned);
277 size_t newsize = allocsize + (p->
allocsize >> 1u);
279 void* data = lodepng_reallocate(p->
data, p->
allocsize, newsize);
282 p->
data = (
unsigned*)data;
290static void uivector_init(
uivector* p) {
296static unsigned uivector_push_back(
uivector* p,
unsigned c) {
297 if(!uivector_resize(p, p->
size + 1))
return 0;
314static unsigned ucvector_reserve(
ucvector* p,
size_t size) {
318 void* data = lodepng_reallocate(p->
data, p->
allocsize, newsize);
321 p->
data = (
unsigned char*)data;
329static unsigned ucvector_resize(
ucvector* p,
size_t size) {
331 return ucvector_reserve(p,
size);
334static ucvector ucvector_init(
unsigned char* buffer,
size_t size) {
343#ifdef LODEPNG_COMPILE_PNG
344#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
347static void string_cleanup(
char** out) {
353static char* alloc_string_sized(
const char* in,
size_t insize) {
354 char* out = (
char*)lodepng_malloc(insize + 1);
356 lodepng_memcpy(out, in, insize);
363static char* alloc_string(
const char* in) {
364 return alloc_string_sized(in, lodepng_strlen(in));
371#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_PNG)
372static unsigned lodepng_read32bitInt(
const unsigned char* buffer) {
373 return (((
unsigned)buffer[0] << 24u) | ((
unsigned)buffer[1] << 16u) |
374 ((
unsigned)buffer[2] << 8u) | (
unsigned)buffer[3]);
378#if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)
380static void lodepng_set32bitInt(
unsigned char* buffer,
unsigned value) {
381 buffer[0] = (
unsigned char)((
value >> 24) & 0xff);
382 buffer[1] = (
unsigned char)((
value >> 16) & 0xff);
383 buffer[2] = (
unsigned char)((
value >> 8) & 0xff);
384 buffer[3] = (
unsigned char)((
value ) & 0xff);
392#ifdef LODEPNG_COMPILE_DISK
395static long lodepng_filesize(
const char* filename) {
398 file = fopen(filename,
"rb");
401 if(fseek(file, 0, SEEK_END) != 0) {
415static unsigned lodepng_buffer_file(
unsigned char* out,
size_t size,
const char* filename) {
418 file = fopen(filename,
"rb");
421 readsize = fread(out, 1,
size, file);
424 if(readsize !=
size)
return 78;
429 long size = lodepng_filesize(filename);
430 if(
size < 0)
return 78;
433 *out = (
unsigned char*)lodepng_malloc((
size_t)
size);
434 if(!(*out) &&
size > 0)
return 83;
436 return lodepng_buffer_file(*out, (
size_t)
size, filename);
440unsigned lodepng_save_file(
const unsigned char* buffer,
size_t buffersize,
const char* filename) {
442 file = fopen(filename,
"wb" );
444 fwrite(buffer, 1, buffersize, file);
457#ifdef LODEPNG_COMPILE_ZLIB
458#ifdef LODEPNG_COMPILE_ENCODER
471#define WRITEBIT(writer, bit){\
473 if(((writer->bp) & 7u) == 0) {\
474 if(!ucvector_resize(writer->data, writer->data->size + 1)) return;\
475 writer->data->data[writer->data->size - 1] = 0;\
477 (writer->data->data[writer->data->size - 1]) |= (bit << ((writer->bp) & 7u));\
488 for(i = 0; i != nbits; ++i) {
497 for(i = 0; i != nbits; ++i) {
499 WRITEBIT(writer, (
unsigned char)((
value >> (nbits - 1u - i)) & 1u));
504#ifdef LODEPNG_COMPILE_DECODER
515static unsigned LodePNGBitReader_init(
LodePNGBitReader* reader,
const unsigned char* data,
size_t size) {
520 if(lodepng_mulofl(
size, 8u, &reader->
bitsize))
return 105;
523 if(lodepng_addofl(reader->
bitsize, 64u, &temp))
return 105;
539 size_t start = reader->
bp >> 3u;
541 if(start + 1u <
size) {
542 reader->
buffer = (unsigned)reader->
data[start + 0] | ((
unsigned)reader->
data[start + 1] << 8u);
543 reader->
buffer >>= (reader->
bp & 7u);
547 reader->
buffer >>= (reader->
bp & 7u);
554 size_t start = reader->
bp >> 3u;
556 if(start + 2u <
size) {
557 reader->
buffer = (unsigned)reader->
data[start + 0] | ((
unsigned)reader->
data[start + 1] << 8u) |
558 ((unsigned)reader->
data[start + 2] << 16u);
559 reader->
buffer >>= (reader->
bp & 7u);
563 if(start + 1u <
size) reader->
buffer |= ((unsigned)reader->
data[start + 1] << 8u);
564 reader->
buffer >>= (reader->
bp & 7u);
571 size_t start = reader->
bp >> 3u;
573 if(start + 3u <
size) {
574 reader->
buffer = (unsigned)reader->
data[start + 0] | ((
unsigned)reader->
data[start + 1] << 8u) |
575 ((unsigned)reader->
data[start + 2] << 16u) | ((
unsigned)reader->
data[start + 3] << 24u);
576 reader->
buffer >>= (reader->
bp & 7u);
580 if(start + 1u <
size) reader->
buffer |= ((unsigned)reader->
data[start + 1] << 8u);
581 if(start + 2u <
size) reader->
buffer |= ((unsigned)reader->
data[start + 2] << 16u);
582 reader->
buffer >>= (reader->
bp & 7u);
589 size_t start = reader->
bp >> 3u;
591 if(start + 4u <
size) {
592 reader->
buffer = (unsigned)reader->
data[start + 0] | ((
unsigned)reader->
data[start + 1] << 8u) |
593 ((unsigned)reader->
data[start + 2] << 16u) | ((
unsigned)reader->
data[start + 3] << 24u);
594 reader->
buffer >>= (reader->
bp & 7u);
595 reader->
buffer |= (((unsigned)reader->
data[start + 4] << 24u) << (8u - (reader->
bp & 7u)));
599 if(start + 1u <
size) reader->
buffer |= ((unsigned)reader->
data[start + 1] << 8u);
600 if(start + 2u <
size) reader->
buffer |= ((unsigned)reader->
data[start + 2] << 16u);
601 if(start + 3u <
size) reader->
buffer |= ((unsigned)reader->
data[start + 3] << 24u);
602 reader->
buffer >>= (reader->
bp & 7u);
610 return reader->
buffer & ((1u << nbits) - 1u);
621 unsigned result = peekBits(reader, nbits);
622 advanceBits(reader, nbits);
627static unsigned reverseBits(
unsigned bits,
unsigned num) {
629 unsigned i, result = 0;
630 for(i = 0; i < num; i++) result |= ((bits >> (num - i - 1u)) & 1u) << i;
638#define FIRST_LENGTH_CODE_INDEX 257
639#define LAST_LENGTH_CODE_INDEX 285
641#define NUM_DEFLATE_CODE_SYMBOLS 288
643#define NUM_DISTANCE_SYMBOLS 32
645#define NUM_CODE_LENGTH_CODES 19
648static const unsigned LENGTHBASE[29]
649 = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
650 67, 83, 99, 115, 131, 163, 195, 227, 258};
653static const unsigned LENGTHEXTRA[29]
654 = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
655 4, 4, 4, 4, 5, 5, 5, 5, 0};
658static const unsigned DISTANCEBASE[30]
659 = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513,
660 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
663static const unsigned DISTANCEEXTRA[30]
664 = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
665 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
670 = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
694static void HuffmanTree_cleanup(
HuffmanTree* tree) {
695 lodepng_free(tree->
codes);
707#define INVALIDSYMBOL 65535u
710static unsigned HuffmanTree_makeTable(
HuffmanTree* tree) {
711 static const unsigned headsize = 1u <<
FIRSTBITS;
712 static const unsigned mask = (1u <<
FIRSTBITS) - 1u;
713 size_t i, numpresent, pointer,
size;
714 unsigned* maxlens = (
unsigned*)lodepng_malloc(headsize *
sizeof(
unsigned));
715 if(!maxlens)
return 83;
718 lodepng_memset(maxlens, 0, headsize *
sizeof(*maxlens));
719 for(i = 0; i < tree->
numcodes; i++) {
720 unsigned symbol = tree->
codes[i];
730 for(i = 0; i < headsize; ++i) {
731 unsigned l = maxlens[i];
737 lodepng_free(maxlens);
746 for(i = 0; i < headsize; ++i) {
747 unsigned l = maxlens[i];
753 lodepng_free(maxlens);
757 for(i = 0; i < tree->
numcodes; ++i) {
759 unsigned symbol, reverse;
761 symbol = tree->
codes[i];
763 reverse = reverseBits(symbol, l);
770 for(j = 0; j < num; ++j) {
772 unsigned index = reverse | (j << l);
773 if(tree->
table_len[index] != 16)
return 55;
780 unsigned index = reverse & mask;
781 unsigned maxlen = tree->
table_len[index];
785 unsigned num = 1u << (tablelen - (l -
FIRSTBITS));
787 if(maxlen < l)
return 55;
788 for(j = 0; j < num; ++j) {
789 unsigned reverse2 = reverse >>
FIRSTBITS;
790 unsigned index2 = start + (reverse2 | (j << (l -
FIRSTBITS)));
804 for(i = 0; i <
size; ++i) {
818 for(i = 0; i <
size; ++i) {
831static unsigned HuffmanTree_makeFromLengths2(
HuffmanTree* tree) {
837 tree->
codes = (
unsigned*)lodepng_malloc(tree->
numcodes *
sizeof(
unsigned));
838 blcount = (
unsigned*)lodepng_malloc((tree->
maxbitlen + 1) *
sizeof(
unsigned));
839 nextcode = (
unsigned*)lodepng_malloc((tree->
maxbitlen + 1) *
sizeof(
unsigned));
840 if(!tree->
codes || !blcount || !nextcode) error = 83;
843 for(n = 0; n != tree->
maxbitlen + 1; n++) blcount[n] = nextcode[n] = 0;
845 for(bits = 0; bits != tree->
numcodes; ++bits) ++blcount[tree->
lengths[bits]];
847 for(bits = 1; bits <= tree->
maxbitlen; ++bits) {
848 nextcode[bits] = (nextcode[bits - 1] + blcount[bits - 1]) << 1u;
851 for(n = 0; n != tree->
numcodes; ++n) {
860 lodepng_free(blcount);
861 lodepng_free(nextcode);
863 if(!error) error = HuffmanTree_makeTable(tree);
872static unsigned HuffmanTree_makeFromLengths(
HuffmanTree* tree,
const unsigned* bitlen,
873 size_t numcodes,
unsigned maxbitlen) {
875 tree->
lengths = (
unsigned*)lodepng_malloc(numcodes *
sizeof(
unsigned));
877 for(i = 0; i != numcodes; ++i) tree->
lengths[i] = bitlen[i];
878 tree->
numcodes = (unsigned)numcodes;
880 return HuffmanTree_makeFromLengths2(tree);
883#ifdef LODEPNG_COMPILE_ENCODER
919 for(i = 0; i != lists->
listsize; ++i) {
926 for(i = 0; i != lists->
memsize; ++i) {
934 result->
index = index;
940static void bpmnode_sort(
BPMNode* leaves,
size_t num) {
942 size_t width, counter = 0;
944 BPMNode* a = (counter & 1) ? mem : leaves;
945 BPMNode* b = (counter & 1) ? leaves : mem;
947 for(p = 0; p < num; p += 2 *
width) {
948 size_t q = (p +
width > num) ? num : (p +
width);
949 size_t r = (p + 2 *
width > num) ? num : (p + 2 *
width);
950 size_t i = p, j = q, k;
951 for(k = p; k < r; k++) {
952 if(i < q && (j >= r || a[i].weight <= a[j].weight)) b[k] = a[i++];
958 if(counter & 1) lodepng_memcpy(leaves, mem,
sizeof(*leaves) * num);
963static void boundaryPM(
BPMLists* lists,
BPMNode* leaves,
size_t numpresent,
int c,
int num) {
967 if(lastindex >= numpresent)
return;
969 lists->
chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, 0);
974 if(lastindex < numpresent && sum > leaves[lastindex].weight) {
975 lists->
chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, lists->
chains1[c]->
tail);
978 lists->
chains1[c] = bpmnode_create(lists, sum, lastindex, lists->
chains1[c - 1]);
981 if(num + 1 < (
int)(2 * numpresent - 2)) {
982 boundaryPM(lists, leaves, numpresent, c - 1, num);
983 boundaryPM(lists, leaves, numpresent, c - 1, num);
989 size_t numcodes,
unsigned maxbitlen) {
992 size_t numpresent = 0;
995 if(numcodes == 0)
return 80;
996 if((1u << maxbitlen) < (
unsigned)numcodes)
return 80;
998 leaves = (
BPMNode*)lodepng_malloc(numcodes *
sizeof(*leaves));
999 if(!leaves)
return 83;
1001 for(i = 0; i != numcodes; ++i) {
1002 if(frequencies[i] > 0) {
1003 leaves[numpresent].
weight = (int)frequencies[i];
1004 leaves[numpresent].
index = i;
1009 lodepng_memset(lengths, 0, numcodes *
sizeof(*lengths));
1016 if(numpresent == 0) {
1017 lengths[0] = lengths[1] = 1;
1018 }
else if(numpresent == 1) {
1019 lengths[leaves[0].
index] = 1;
1020 lengths[leaves[0].index == 0 ? 1 : 0] = 1;
1025 bpmnode_sort(leaves, numpresent);
1028 lists.
memsize = 2 * maxbitlen * (maxbitlen + 1);
1040 bpmnode_create(&lists, leaves[0].weight, 1, 0);
1041 bpmnode_create(&lists, leaves[1].weight, 2, 0);
1043 for(i = 0; i != lists.
listsize; ++i) {
1049 for(i = 2; i != 2 * numpresent - 2; ++i) boundaryPM(&lists, leaves, numpresent, (
int)maxbitlen - 1, (
int)i);
1051 for(node = lists.
chains1[maxbitlen - 1]; node; node = node->
tail) {
1052 for(i = 0; i != node->
index; ++i) ++lengths[leaves[i].index];
1056 lodepng_free(lists.
memory);
1062 lodepng_free(leaves);
1067static unsigned HuffmanTree_makeFromFrequencies(
HuffmanTree* tree,
const unsigned* frequencies,
1068 size_t mincodes,
size_t numcodes,
unsigned maxbitlen) {
1070 while(!frequencies[numcodes - 1] && numcodes > mincodes) --numcodes;
1071 tree->
lengths = (
unsigned*)lodepng_malloc(numcodes *
sizeof(
unsigned));
1074 tree->
numcodes = (unsigned)numcodes;
1077 if(!error) error = HuffmanTree_makeFromLengths2(tree);
1083static unsigned generateFixedLitLenTree(
HuffmanTree* tree) {
1084 unsigned i, error = 0;
1086 if(!bitlen)
return 83;
1089 for(i = 0; i <= 143; ++i) bitlen[i] = 8;
1090 for(i = 144; i <= 255; ++i) bitlen[i] = 9;
1091 for(i = 256; i <= 279; ++i) bitlen[i] = 7;
1092 for(i = 280; i <= 287; ++i) bitlen[i] = 8;
1096 lodepng_free(bitlen);
1101static unsigned generateFixedDistanceTree(
HuffmanTree* tree) {
1102 unsigned i, error = 0;
1104 if(!bitlen)
return 83;
1110 lodepng_free(bitlen);
1114#ifdef LODEPNG_COMPILE_DECODER
1124 advanceBits(reader, l);
1135#ifdef LODEPNG_COMPILE_DECODER
1144 unsigned error = generateFixedLitLenTree(tree_ll);
1145 if(error)
return error;
1146 return generateFixedDistanceTree(tree_d);
1154 unsigned n, HLIT, HDIST, HCLEN, i;
1157 unsigned* bitlen_ll = 0;
1158 unsigned* bitlen_d = 0;
1160 unsigned* bitlen_cl = 0;
1163 if(reader->
bitsize - reader->
bp < 14)
return 49;
1164 ensureBits17(reader, 14);
1167 HLIT = readBits(reader, 5) + 257;
1169 HDIST = readBits(reader, 5) + 1;
1171 HCLEN = readBits(reader, 4) + 4;
1174 if(!bitlen_cl)
return 83 ;
1176 HuffmanTree_init(&tree_cl);
1180 if(lodepng_gtofl(reader->
bp, HCLEN * 3, reader->
bitsize)) {
1183 for(i = 0; i != HCLEN; ++i) {
1184 ensureBits9(reader, 3);
1185 bitlen_cl[CLCL_ORDER[i]] = readBits(reader, 3);
1188 bitlen_cl[CLCL_ORDER[i]] = 0;
1203 while(i < HLIT + HDIST) {
1205 ensureBits25(reader, 22);
1206 code = huffmanDecodeSymbol(reader, &tree_cl);
1208 if(i < HLIT) bitlen_ll[i] =
code;
1209 else bitlen_d[i - HLIT] =
code;
1211 }
else if(
code == 16) {
1212 unsigned replength = 3;
1217 replength += readBits(reader, 2);
1219 if(i < HLIT + 1)
value = bitlen_ll[i - 1];
1220 else value = bitlen_d[i - HLIT - 1];
1222 for(n = 0; n < replength; ++n) {
1224 if(i < HLIT) bitlen_ll[i] =
value;
1225 else bitlen_d[i - HLIT] =
value;
1228 }
else if(
code == 17) {
1229 unsigned replength = 3;
1230 replength += readBits(reader, 3);
1233 for(n = 0; n < replength; ++n) {
1236 if(i < HLIT) bitlen_ll[i] = 0;
1237 else bitlen_d[i - HLIT] = 0;
1240 }
else if(
code == 18) {
1241 unsigned replength = 11;
1242 replength += readBits(reader, 7);
1245 for(n = 0; n < replength; ++n) {
1248 if(i < HLIT) bitlen_ll[i] = 0;
1249 else bitlen_d[i - HLIT] = 0;
1275 lodepng_free(bitlen_cl);
1276 lodepng_free(bitlen_ll);
1277 lodepng_free(bitlen_d);
1278 HuffmanTree_cleanup(&tree_cl);
1285 unsigned btype,
size_t max_output_size) {
1289 const size_t reserved_size = 260;
1292 if(!ucvector_reserve(out, out->
size + reserved_size))
return 83;
1294 HuffmanTree_init(&tree_ll);
1295 HuffmanTree_init(&tree_d);
1297 if(btype == 1) error = getTreeInflateFixed(&tree_ll, &tree_d);
1298 else error = getTreeInflateDynamic(&tree_ll, &tree_d, reader);
1301 while(!error && !done) {
1306 ensureBits32(reader, 30);
1307 code_ll = huffmanDecodeSymbol(reader, &tree_ll);
1308 if(code_ll <= 255) {
1310 out->
data[out->
size++] = (
unsigned char)code_ll;
1311 code_ll = huffmanDecodeSymbol(reader, &tree_ll);
1313 if(code_ll <= 255) {
1314 out->
data[out->
size++] = (
unsigned char)code_ll;
1316 unsigned code_d, distance;
1317 unsigned numextrabits_l, numextrabits_d;
1318 size_t start, backward, length;
1325 if(numextrabits_l != 0) {
1327 ensureBits25(reader, 5);
1328 length += readBits(reader, numextrabits_l);
1332 ensureBits32(reader, 28);
1333 code_d = huffmanDecodeSymbol(reader, &tree_d);
1341 distance = DISTANCEBASE[code_d];
1344 numextrabits_d = DISTANCEEXTRA[code_d];
1345 if(numextrabits_d != 0) {
1347 distance += readBits(reader, numextrabits_d);
1353 backward = start - distance;
1355 out->
size += length;
1356 if(distance < length) {
1358 lodepng_memcpy(out->
data + start, out->
data + backward, distance);
1360 for(forward = distance; forward < length; ++forward) {
1361 out->
data[start++] = out->
data[backward++];
1364 lodepng_memcpy(out->
data + start, out->
data + backward, length);
1366 }
else if(code_ll == 256) {
1372 if(!ucvector_reserve(out, out->
size + reserved_size))
ERROR_BREAK(83);
1381 if(max_output_size && out->
size > max_output_size) {
1386 HuffmanTree_cleanup(&tree_ll);
1387 HuffmanTree_cleanup(&tree_d);
1396 unsigned LEN, NLEN, error = 0;
1399 bytepos = (reader->
bp + 7u) >> 3u;
1402 if(bytepos + 4 >=
size)
return 52;
1403 LEN = (unsigned)reader->
data[bytepos] + ((
unsigned)reader->
data[bytepos + 1] << 8u); bytepos += 2;
1404 NLEN = (unsigned)reader->
data[bytepos] + ((
unsigned)reader->
data[bytepos + 1] << 8u); bytepos += 2;
1411 if(!ucvector_resize(out, out->
size +
LEN))
return 83;
1414 if(bytepos +
LEN >
size)
return 23;
1422 reader->
bp = bytepos << 3u;
1427static unsigned lodepng_inflatev(
ucvector* out,
1428 const unsigned char* in,
size_t insize,
1430 unsigned BFINAL = 0;
1432 unsigned error = LodePNGBitReader_init(&reader, in, insize);
1434 if(error)
return error;
1438 if(reader.
bitsize - reader.
bp < 3)
return 52;
1439 ensureBits9(&reader, 3);
1440 BFINAL = readBits(&reader, 1);
1441 BTYPE = readBits(&reader, 2);
1443 if(BTYPE == 3)
return 20;
1444 else if(BTYPE == 0) error = inflateNoCompression(out, &reader, settings);
1445 else error = inflateHuffmanBlock(out, &reader, BTYPE, settings->
max_output_size);
1454 const unsigned char* in,
size_t insize,
1456 ucvector v = ucvector_init(*out, *outsize);
1457 unsigned error = lodepng_inflatev(&v, in, insize, settings);
1463static unsigned inflatev(
ucvector* out,
const unsigned char* in,
size_t insize,
1476 return lodepng_inflatev(out, in, insize, settings);
1482#ifdef LODEPNG_COMPILE_ENCODER
1488static const unsigned MAX_SUPPORTED_DEFLATE_LENGTH = 258;
1492static size_t searchCodeIndex(
const unsigned* array,
size_t array_size,
size_t value) {
1495 size_t right = array_size - 1;
1497 while(left <= right) {
1498 size_t mid = (left + right) >> 1;
1499 if(array[mid] >=
value) right = mid - 1;
1500 else left = mid + 1;
1502 if(left >= array_size || array[left] >
value) left--;
1506static void addLengthDistance(
uivector* values,
size_t length,
size_t distance) {
1513 unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length);
1514 unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]);
1515 unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance);
1516 unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]);
1518 size_t pos = values->
size;
1520 unsigned ok = uivector_resize(values, values->
size + 4);
1523 values->
data[pos + 1] = extra_length;
1524 values->
data[pos + 2] = dist_code;
1525 values->
data[pos + 3] = extra_distance;
1531static const unsigned HASH_NUM_VALUES = 65536;
1532static const unsigned HASH_BIT_MASK = 65535;
1547static unsigned hash_init(
Hash* hash,
unsigned windowsize) {
1549 hash->
head = (
int*)lodepng_malloc(
sizeof(
int) * HASH_NUM_VALUES);
1550 hash->
val = (
int*)lodepng_malloc(
sizeof(
int) * windowsize);
1551 hash->
chain = (
unsigned short*)lodepng_malloc(
sizeof(
unsigned short) * windowsize);
1553 hash->
zeros = (
unsigned short*)lodepng_malloc(
sizeof(
unsigned short) * windowsize);
1554 hash->
headz = (
int*)lodepng_malloc(
sizeof(
int) * (MAX_SUPPORTED_DEFLATE_LENGTH + 1));
1555 hash->
chainz = (
unsigned short*)lodepng_malloc(
sizeof(
unsigned short) * windowsize);
1562 for(i = 0; i != HASH_NUM_VALUES; ++i) hash->
head[i] = -1;
1563 for(i = 0; i != windowsize; ++i) hash->
val[i] = -1;
1564 for(i = 0; i != windowsize; ++i) hash->
chain[i] = i;
1566 for(i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; ++i) hash->
headz[i] = -1;
1567 for(i = 0; i != windowsize; ++i) hash->
chainz[i] = i;
1572static void hash_cleanup(
Hash* hash) {
1573 lodepng_free(hash->
head);
1574 lodepng_free(hash->
val);
1575 lodepng_free(hash->
chain);
1577 lodepng_free(hash->
zeros);
1578 lodepng_free(hash->
headz);
1579 lodepng_free(hash->
chainz);
1584static unsigned getHash(
const unsigned char* data,
size_t size,
size_t pos) {
1585 unsigned result = 0;
1586 if(pos + 2 <
size) {
1591 result ^= ((unsigned)data[pos + 0] << 0u);
1592 result ^= ((unsigned)data[pos + 1] << 4u);
1593 result ^= ((unsigned)data[pos + 2] << 8u);
1596 if(pos >=
size)
return 0;
1598 for(i = 0; i !=
amount; ++i) result ^= ((
unsigned)data[pos + i] << (i * 8u));
1600 return result & HASH_BIT_MASK;
1603static unsigned countZeros(
const unsigned char* data,
size_t size,
size_t pos) {
1604 const unsigned char* start = data + pos;
1605 const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH;
1606 if(end > data +
size) end = data +
size;
1608 while(data != end && *data == 0) ++data;
1610 return (
unsigned)(data - start);
1614static void updateHashChain(
Hash* hash,
size_t wpos,
unsigned hashval,
unsigned short numzeros) {
1615 hash->
val[wpos] = (int)hashval;
1616 if(hash->
head[hashval] != -1) hash->
chain[wpos] = hash->
head[hashval];
1617 hash->
head[hashval] = (int)wpos;
1619 hash->
zeros[wpos] = numzeros;
1620 if(hash->
headz[numzeros] != -1) hash->
chainz[wpos] = hash->
headz[numzeros];
1621 hash->
headz[numzeros] = (int)wpos;
1634 const unsigned char* in,
size_t inpos,
size_t insize,
unsigned windowsize,
1635 unsigned minmatch,
unsigned nicematch,
unsigned lazymatching) {
1637 unsigned i, error = 0;
1639 unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8u;
1640 unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64;
1642 unsigned usezeros = 1;
1643 unsigned numzeros = 0;
1648 unsigned lazylength = 0, lazyoffset = 0;
1650 unsigned current_offset, current_length;
1651 unsigned prev_offset;
1652 const unsigned char *lastptr, *foreptr, *backptr;
1655 if(windowsize == 0 || windowsize > 32768)
return 60;
1656 if((windowsize & (windowsize - 1)) != 0)
return 90;
1658 if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH;
1660 for(pos = inpos; pos < insize; ++pos) {
1661 size_t wpos = pos & (windowsize - 1);
1662 unsigned chainlength = 0;
1664 hashval = getHash(in, insize, pos);
1666 if(usezeros && hashval == 0) {
1667 if(numzeros == 0) numzeros = countZeros(in, insize, pos);
1668 else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros;
1673 updateHashChain(hash, wpos, hashval, numzeros);
1679 hashpos = hash->
chain[wpos];
1681 lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH];
1686 if(chainlength++ >= maxchainlength)
break;
1687 current_offset = (unsigned)(hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize);
1689 if(current_offset < prev_offset)
break;
1690 prev_offset = current_offset;
1691 if(current_offset > 0) {
1694 backptr = &in[pos - current_offset];
1698 unsigned skip = hash->
zeros[hashpos];
1699 if(skip > numzeros) skip = numzeros;
1704 while(foreptr != lastptr && *backptr == *foreptr) {
1708 current_length = (unsigned)(foreptr - &in[pos]);
1710 if(current_length > length) {
1711 length = current_length;
1712 offset = current_offset;
1715 if(current_length >= nicematch)
break;
1719 if(hashpos == hash->
chain[hashpos])
break;
1721 if(numzeros >= 3 && length > numzeros) {
1722 hashpos = hash->
chainz[hashpos];
1723 if(hash->
zeros[hashpos] != numzeros)
break;
1725 hashpos = hash->
chain[hashpos];
1727 if(hash->
val[hashpos] != (
int)hashval)
break;
1732 if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH) {
1734 lazylength = length;
1735 lazyoffset = offset;
1741 if(length > lazylength + 1) {
1743 if(!uivector_push_back(out, in[pos - 1]))
ERROR_BREAK(83 );
1745 length = lazylength;
1746 offset = lazyoffset;
1747 hash->
head[hashval] = -1;
1748 hash->
headz[numzeros] = -1;
1753 if(length >= 3 && offset > windowsize)
ERROR_BREAK(86 );
1757 if(!uivector_push_back(out, in[pos]))
ERROR_BREAK(83 );
1758 }
else if(length < minmatch || (length == 3 && offset > 4096)) {
1761 if(!uivector_push_back(out, in[pos]))
ERROR_BREAK(83 );
1763 addLengthDistance(out, length, offset);
1764 for(i = 1; i < length; ++i) {
1766 wpos = pos & (windowsize - 1);
1767 hashval = getHash(in, insize, pos);
1768 if(usezeros && hashval == 0) {
1769 if(numzeros == 0) numzeros = countZeros(in, insize, pos);
1770 else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros;
1774 updateHashChain(hash, wpos, hashval, numzeros);
1784static unsigned deflateNoCompression(
ucvector* out,
const unsigned char* data,
size_t datasize) {
1788 size_t i, numdeflateblocks = (datasize + 65534u) / 65535u;
1789 unsigned datapos = 0;
1790 for(i = 0; i != numdeflateblocks; ++i) {
1791 unsigned BFINAL, BTYPE,
LEN, NLEN;
1792 unsigned char firstbyte;
1793 size_t pos = out->
size;
1795 BFINAL = (i == numdeflateblocks - 1);
1799 if(datasize - datapos < 65535u)
LEN = (unsigned)datasize - datapos;
1802 if(!ucvector_resize(out, out->
size +
LEN + 5))
return 83;
1804 firstbyte = (
unsigned char)(BFINAL + ((BTYPE & 1u) << 1u) + ((BTYPE & 2u) << 1u));
1805 out->
data[pos + 0] = firstbyte;
1806 out->
data[pos + 1] = (
unsigned char)(
LEN & 255);
1807 out->
data[pos + 2] = (
unsigned char)(
LEN >> 8u);
1808 out->
data[pos + 3] = (
unsigned char)(NLEN & 255);
1809 out->
data[pos + 4] = (
unsigned char)(NLEN >> 8u);
1810 lodepng_memcpy(out->
data + pos + 5, data + datapos,
LEN);
1825 for(i = 0; i != lz77_encoded->
size; ++i) {
1826 unsigned val = lz77_encoded->
data[i];
1827 writeBitsReversed(writer, tree_ll->
codes[val], tree_ll->
lengths[val]);
1830 unsigned n_length_extra_bits = LENGTHEXTRA[length_index];
1831 unsigned length_extra_bits = lz77_encoded->
data[++i];
1833 unsigned distance_code = lz77_encoded->
data[++i];
1835 unsigned distance_index = distance_code;
1836 unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index];
1837 unsigned distance_extra_bits = lz77_encoded->
data[++i];
1839 writeBits(writer, length_extra_bits, n_length_extra_bits);
1840 writeBitsReversed(writer, tree_d->
codes[distance_code], tree_d->
lengths[distance_code]);
1841 writeBits(writer, distance_extra_bits, n_distance_extra_bits);
1848 const unsigned char* data,
size_t datapos,
size_t dataend,
1868 unsigned* frequencies_ll = 0;
1869 unsigned* frequencies_d = 0;
1870 unsigned* frequencies_cl = 0;
1871 unsigned* bitlen_lld = 0;
1872 unsigned* bitlen_lld_e = 0;
1873 size_t datasize = dataend - datapos;
1884 unsigned BFINAL =
final;
1886 size_t numcodes_ll, numcodes_d, numcodes_lld, numcodes_lld_e, numcodes_cl;
1887 unsigned HLIT, HDIST, HCLEN;
1889 uivector_init(&lz77_encoded);
1890 HuffmanTree_init(&tree_ll);
1891 HuffmanTree_init(&tree_d);
1892 HuffmanTree_init(&tree_cl);
1894 frequencies_ll = (
unsigned*)lodepng_malloc(286 *
sizeof(*frequencies_ll));
1895 frequencies_d = (
unsigned*)lodepng_malloc(30 *
sizeof(*frequencies_d));
1898 if(!frequencies_ll || !frequencies_d || !frequencies_cl) error = 83;
1903 lodepng_memset(frequencies_ll, 0, 286 *
sizeof(*frequencies_ll));
1904 lodepng_memset(frequencies_d, 0, 30 *
sizeof(*frequencies_d));
1908 error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->
windowsize,
1912 if(!uivector_resize(&lz77_encoded, datasize))
ERROR_BREAK(83 );
1913 for(i = datapos; i < dataend; ++i) lz77_encoded.
data[i - datapos] = data[i];
1917 for(i = 0; i != lz77_encoded.
size; ++i) {
1918 unsigned symbol = lz77_encoded.
data[i];
1919 ++frequencies_ll[symbol];
1921 unsigned dist = lz77_encoded.
data[i + 2];
1922 ++frequencies_d[dist];
1926 frequencies_ll[256] = 1;
1929 error = HuffmanTree_makeFromFrequencies(&tree_ll, frequencies_ll, 257, 286, 15);
1932 error = HuffmanTree_makeFromFrequencies(&tree_d, frequencies_d, 2, 30, 15);
1938 numcodes_lld = numcodes_ll + numcodes_d;
1939 bitlen_lld = (
unsigned*)lodepng_malloc(numcodes_lld *
sizeof(*bitlen_lld));
1941 bitlen_lld_e = (
unsigned*)lodepng_malloc(numcodes_lld *
sizeof(*bitlen_lld_e));
1945 for(i = 0; i != numcodes_ll; ++i) bitlen_lld[i] = tree_ll.
lengths[i];
1946 for(i = 0; i != numcodes_d; ++i) bitlen_lld[numcodes_ll + i] = tree_d.
lengths[i];
1950 for(i = 0; i != numcodes_lld; ++i) {
1952 while(i + j + 1 < numcodes_lld && bitlen_lld[i + j + 1] == bitlen_lld[i]) ++j;
1954 if(bitlen_lld[i] == 0 && j >= 2) {
1957 bitlen_lld_e[numcodes_lld_e++] = 17;
1958 bitlen_lld_e[numcodes_lld_e++] = j - 3;
1960 if(j > 138) j = 138;
1961 bitlen_lld_e[numcodes_lld_e++] = 18;
1962 bitlen_lld_e[numcodes_lld_e++] = j - 11;
1967 unsigned num = j / 6u, rest = j % 6u;
1968 bitlen_lld_e[numcodes_lld_e++] = bitlen_lld[i];
1969 for(k = 0; k < num; ++k) {
1970 bitlen_lld_e[numcodes_lld_e++] = 16;
1971 bitlen_lld_e[numcodes_lld_e++] = 6 - 3;
1974 bitlen_lld_e[numcodes_lld_e++] = 16;
1975 bitlen_lld_e[numcodes_lld_e++] = rest - 3;
1980 bitlen_lld_e[numcodes_lld_e++] = bitlen_lld[i];
1985 for(i = 0; i != numcodes_lld_e; ++i) {
1986 ++frequencies_cl[bitlen_lld_e[i]];
1989 if(bitlen_lld_e[i] >= 16) ++i;
1992 error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl,
1999 while(numcodes_cl > 4u && tree_cl.
lengths[CLCL_ORDER[numcodes_cl - 1u]] == 0) {
2018 writeBits(writer, BFINAL, 1);
2019 writeBits(writer, 0, 1);
2020 writeBits(writer, 1, 1);
2025 HLIT = (unsigned)(numcodes_ll - 257);
2026 HDIST = (unsigned)(numcodes_d - 1);
2027 HCLEN = (unsigned)(numcodes_cl - 4);
2028 writeBits(writer, HLIT, 5);
2029 writeBits(writer, HDIST, 5);
2030 writeBits(writer, HCLEN, 4);
2033 for(i = 0; i != numcodes_cl; ++i) writeBits(writer, tree_cl.
lengths[CLCL_ORDER[i]], 3);
2036 for(i = 0; i != numcodes_lld_e; ++i) {
2037 writeBitsReversed(writer, tree_cl.
codes[bitlen_lld_e[i]], tree_cl.
lengths[bitlen_lld_e[i]]);
2039 if(bitlen_lld_e[i] == 16) writeBits(writer, bitlen_lld_e[++i], 2);
2040 else if(bitlen_lld_e[i] == 17) writeBits(writer, bitlen_lld_e[++i], 3);
2041 else if(bitlen_lld_e[i] == 18) writeBits(writer, bitlen_lld_e[++i], 7);
2045 writeLZ77data(writer, &lz77_encoded, &tree_ll, &tree_d);
2050 writeBitsReversed(writer, tree_ll.
codes[256], tree_ll.
lengths[256]);
2056 uivector_cleanup(&lz77_encoded);
2057 HuffmanTree_cleanup(&tree_ll);
2058 HuffmanTree_cleanup(&tree_d);
2059 HuffmanTree_cleanup(&tree_cl);
2060 lodepng_free(frequencies_ll);
2061 lodepng_free(frequencies_d);
2062 lodepng_free(frequencies_cl);
2063 lodepng_free(bitlen_lld);
2064 lodepng_free(bitlen_lld_e);
2070 const unsigned char* data,
2071 size_t datapos,
size_t dataend,
2076 unsigned BFINAL =
final;
2080 HuffmanTree_init(&tree_ll);
2081 HuffmanTree_init(&tree_d);
2083 error = generateFixedLitLenTree(&tree_ll);
2084 if(!error) error = generateFixedDistanceTree(&tree_d);
2087 writeBits(writer, BFINAL, 1);
2088 writeBits(writer, 1, 1);
2089 writeBits(writer, 0, 1);
2093 uivector_init(&lz77_encoded);
2094 error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->
windowsize,
2096 if(!error) writeLZ77data(writer, &lz77_encoded, &tree_ll, &tree_d);
2097 uivector_cleanup(&lz77_encoded);
2099 for(i = datapos; i < dataend; ++i) {
2100 writeBitsReversed(writer, tree_ll.
codes[data[i]], tree_ll.
lengths[data[i]]);
2104 if(!error) writeBitsReversed(writer,tree_ll.
codes[256], tree_ll.
lengths[256]);
2108 HuffmanTree_cleanup(&tree_ll);
2109 HuffmanTree_cleanup(&tree_d);
2114static unsigned lodepng_deflatev(
ucvector* out,
const unsigned char* in,
size_t insize,
2117 size_t i, blocksize, numdeflateblocks;
2121 LodePNGBitWriter_init(&writer, out);
2123 if(settings->
btype > 2)
return 61;
2124 else if(settings->
btype == 0)
return deflateNoCompression(out, in, insize);
2125 else if(settings->
btype == 1) blocksize = insize;
2128 blocksize = insize / 8u + 8;
2129 if(blocksize < 65536) blocksize = 65536;
2130 if(blocksize > 262144) blocksize = 262144;
2133 numdeflateblocks = (insize + blocksize - 1) / blocksize;
2134 if(numdeflateblocks == 0) numdeflateblocks = 1;
2136 error = hash_init(&hash, settings->
windowsize);
2139 for(i = 0; i != numdeflateblocks && !error; ++i) {
2140 unsigned final = (i == numdeflateblocks - 1);
2141 size_t start = i * blocksize;
2142 size_t end = start + blocksize;
2143 if(end > insize) end = insize;
2145 if(settings->
btype == 1) error = deflateFixed(&writer, &hash, in, start, end, settings,
final);
2146 else if(settings->
btype == 2) error = deflateDynamic(&writer, &hash, in, start, end, settings,
final);
2150 hash_cleanup(&hash);
2156 const unsigned char* in,
size_t insize,
2158 ucvector v = ucvector_init(*out, *outsize);
2159 unsigned error = lodepng_deflatev(&v, in, insize, settings);
2165static unsigned deflate(
unsigned char** out,
size_t* outsize,
2166 const unsigned char* in,
size_t insize,
2169 unsigned error = settings->
custom_deflate(out, outsize, in, insize, settings);
2171 return error ? 111 : 0;
2183static unsigned update_adler32(
unsigned adler,
const unsigned char* data,
unsigned len) {
2184 unsigned s1 = adler & 0xffffu;
2185 unsigned s2 = (adler >> 16u) & 0xffffu;
2190 unsigned amount = len > 5552u ? 5552u : len;
2192 for(i = 0; i !=
amount; ++i) {
2200 return (s2 << 16u) | s1;
2204static unsigned adler32(
const unsigned char* data,
unsigned len) {
2205 return update_adler32(1u, data, len);
2212#ifdef LODEPNG_COMPILE_DECODER
2214static unsigned lodepng_zlib_decompressv(
ucvector* out,
2215 const unsigned char* in,
size_t insize,
2218 unsigned CM, CINFO, FDICT;
2220 if(insize < 2)
return 53;
2222 if((in[0] * 256 + in[1]) % 31 != 0) {
2228 CINFO = (in[0] >> 4) & 15;
2230 FDICT = (in[1] >> 5) & 1;
2233 if(CM != 8 || CINFO > 7) {
2243 error = inflatev(out, in + 2, insize - 2, settings);
2244 if(error)
return error;
2247 unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]);
2249 if(checksum != ADLER32)
return 58;
2258 ucvector v = ucvector_init(*out, *outsize);
2259 unsigned error = lodepng_zlib_decompressv(&v, in, insize, settings);
2266static unsigned zlib_decompress(
unsigned char** out,
size_t* outsize,
size_t expected_size,
2270 error = settings->
custom_zlib(out, outsize, in, insize, settings);
2278 ucvector v = ucvector_init(*out, *outsize);
2281 ucvector_resize(&v, *outsize + expected_size);
2284 error = lodepng_zlib_decompressv(&v, in, insize, settings);
2293#ifdef LODEPNG_COMPILE_ENCODER
2299 unsigned char* deflatedata = 0;
2300 size_t deflatesize = 0;
2302 error =
deflate(&deflatedata, &deflatesize, in, insize, settings);
2307 *outsize = deflatesize + 6;
2308 *out = (
unsigned char*)lodepng_malloc(*outsize);
2309 if(!*out) error = 83;
2313 unsigned ADLER32 =
adler32(in, (
unsigned)insize);
2316 unsigned FLEVEL = 0;
2318 unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64;
2319 unsigned FCHECK = 31 - CMFFLG % 31;
2322 (*out)[0] = (
unsigned char)(CMFFLG >> 8);
2323 (*out)[1] = (
unsigned char)(CMFFLG & 255);
2324 for(i = 0; i != deflatesize; ++i) (*out)[i + 2] = deflatedata[i];
2325 lodepng_set32bitInt(&(*out)[*outsize - 4], ADLER32);
2328 lodepng_free(deflatedata);
2333static unsigned zlib_compress(
unsigned char** out,
size_t* outsize,
const unsigned char* in,
2336 unsigned error = settings->
custom_zlib(out, outsize, in, insize, settings);
2338 return error ? 111 : 0;
2348#ifdef LODEPNG_COMPILE_DECODER
2349static unsigned zlib_decompress(
unsigned char** out,
size_t* outsize,
size_t expected_size,
2352 (void)expected_size;
2353 return settings->
custom_zlib(out, outsize, in, insize, settings);
2356#ifdef LODEPNG_COMPILE_ENCODER
2357static unsigned zlib_compress(
unsigned char** out,
size_t* outsize,
const unsigned char* in,
2360 return settings->
custom_zlib(out, outsize, in, insize, settings);
2368#ifdef LODEPNG_COMPILE_ENCODER
2371#define DEFAULT_WINDOWSIZE 2048
2375 settings->
btype = 2;
2392#ifdef LODEPNG_COMPILE_DECODER
2414#ifdef LODEPNG_COMPILE_PNG
2421#ifdef LODEPNG_COMPILE_CRC
2423static const unsigned lodepng_crc32_table0[256] = {
2424 0x00000000u, 0x77073096u, 0xee0e612cu, 0x990951bau, 0x076dc419u, 0x706af48fu, 0xe963a535u, 0x9e6495a3u,
2425 0x0edb8832u, 0x79dcb8a4u, 0xe0d5e91eu, 0x97d2d988u, 0x09b64c2bu, 0x7eb17cbdu, 0xe7b82d07u, 0x90bf1d91u,
2426 0x1db71064u, 0x6ab020f2u, 0xf3b97148u, 0x84be41deu, 0x1adad47du, 0x6ddde4ebu, 0xf4d4b551u, 0x83d385c7u,
2427 0x136c9856u, 0x646ba8c0u, 0xfd62f97au, 0x8a65c9ecu, 0x14015c4fu, 0x63066cd9u, 0xfa0f3d63u, 0x8d080df5u,
2428 0x3b6e20c8u, 0x4c69105eu, 0xd56041e4u, 0xa2677172u, 0x3c03e4d1u, 0x4b04d447u, 0xd20d85fdu, 0xa50ab56bu,
2429 0x35b5a8fau, 0x42b2986cu, 0xdbbbc9d6u, 0xacbcf940u, 0x32d86ce3u, 0x45df5c75u, 0xdcd60dcfu, 0xabd13d59u,
2430 0x26d930acu, 0x51de003au, 0xc8d75180u, 0xbfd06116u, 0x21b4f4b5u, 0x56b3c423u, 0xcfba9599u, 0xb8bda50fu,
2431 0x2802b89eu, 0x5f058808u, 0xc60cd9b2u, 0xb10be924u, 0x2f6f7c87u, 0x58684c11u, 0xc1611dabu, 0xb6662d3du,
2432 0x76dc4190u, 0x01db7106u, 0x98d220bcu, 0xefd5102au, 0x71b18589u, 0x06b6b51fu, 0x9fbfe4a5u, 0xe8b8d433u,
2433 0x7807c9a2u, 0x0f00f934u, 0x9609a88eu, 0xe10e9818u, 0x7f6a0dbbu, 0x086d3d2du, 0x91646c97u, 0xe6635c01u,
2434 0x6b6b51f4u, 0x1c6c6162u, 0x856530d8u, 0xf262004eu, 0x6c0695edu, 0x1b01a57bu, 0x8208f4c1u, 0xf50fc457u,
2435 0x65b0d9c6u, 0x12b7e950u, 0x8bbeb8eau, 0xfcb9887cu, 0x62dd1ddfu, 0x15da2d49u, 0x8cd37cf3u, 0xfbd44c65u,
2436 0x4db26158u, 0x3ab551ceu, 0xa3bc0074u, 0xd4bb30e2u, 0x4adfa541u, 0x3dd895d7u, 0xa4d1c46du, 0xd3d6f4fbu,
2437 0x4369e96au, 0x346ed9fcu, 0xad678846u, 0xda60b8d0u, 0x44042d73u, 0x33031de5u, 0xaa0a4c5fu, 0xdd0d7cc9u,
2438 0x5005713cu, 0x270241aau, 0xbe0b1010u, 0xc90c2086u, 0x5768b525u, 0x206f85b3u, 0xb966d409u, 0xce61e49fu,
2439 0x5edef90eu, 0x29d9c998u, 0xb0d09822u, 0xc7d7a8b4u, 0x59b33d17u, 0x2eb40d81u, 0xb7bd5c3bu, 0xc0ba6cadu,
2440 0xedb88320u, 0x9abfb3b6u, 0x03b6e20cu, 0x74b1d29au, 0xead54739u, 0x9dd277afu, 0x04db2615u, 0x73dc1683u,
2441 0xe3630b12u, 0x94643b84u, 0x0d6d6a3eu, 0x7a6a5aa8u, 0xe40ecf0bu, 0x9309ff9du, 0x0a00ae27u, 0x7d079eb1u,
2442 0xf00f9344u, 0x8708a3d2u, 0x1e01f268u, 0x6906c2feu, 0xf762575du, 0x806567cbu, 0x196c3671u, 0x6e6b06e7u,
2443 0xfed41b76u, 0x89d32be0u, 0x10da7a5au, 0x67dd4accu, 0xf9b9df6fu, 0x8ebeeff9u, 0x17b7be43u, 0x60b08ed5u,
2444 0xd6d6a3e8u, 0xa1d1937eu, 0x38d8c2c4u, 0x4fdff252u, 0xd1bb67f1u, 0xa6bc5767u, 0x3fb506ddu, 0x48b2364bu,
2445 0xd80d2bdau, 0xaf0a1b4cu, 0x36034af6u, 0x41047a60u, 0xdf60efc3u, 0xa867df55u, 0x316e8eefu, 0x4669be79u,
2446 0xcb61b38cu, 0xbc66831au, 0x256fd2a0u, 0x5268e236u, 0xcc0c7795u, 0xbb0b4703u, 0x220216b9u, 0x5505262fu,
2447 0xc5ba3bbeu, 0xb2bd0b28u, 0x2bb45a92u, 0x5cb36a04u, 0xc2d7ffa7u, 0xb5d0cf31u, 0x2cd99e8bu, 0x5bdeae1du,
2448 0x9b64c2b0u, 0xec63f226u, 0x756aa39cu, 0x026d930au, 0x9c0906a9u, 0xeb0e363fu, 0x72076785u, 0x05005713u,
2449 0x95bf4a82u, 0xe2b87a14u, 0x7bb12baeu, 0x0cb61b38u, 0x92d28e9bu, 0xe5d5be0du, 0x7cdcefb7u, 0x0bdbdf21u,
2450 0x86d3d2d4u, 0xf1d4e242u, 0x68ddb3f8u, 0x1fda836eu, 0x81be16cdu, 0xf6b9265bu, 0x6fb077e1u, 0x18b74777u,
2451 0x88085ae6u, 0xff0f6a70u, 0x66063bcau, 0x11010b5cu, 0x8f659effu, 0xf862ae69u, 0x616bffd3u, 0x166ccf45u,
2452 0xa00ae278u, 0xd70dd2eeu, 0x4e048354u, 0x3903b3c2u, 0xa7672661u, 0xd06016f7u, 0x4969474du, 0x3e6e77dbu,
2453 0xaed16a4au, 0xd9d65adcu, 0x40df0b66u, 0x37d83bf0u, 0xa9bcae53u, 0xdebb9ec5u, 0x47b2cf7fu, 0x30b5ffe9u,
2454 0xbdbdf21cu, 0xcabac28au, 0x53b39330u, 0x24b4a3a6u, 0xbad03605u, 0xcdd70693u, 0x54de5729u, 0x23d967bfu,
2455 0xb3667a2eu, 0xc4614ab8u, 0x5d681b02u, 0x2a6f2b94u, 0xb40bbe37u, 0xc30c8ea1u, 0x5a05df1bu, 0x2d02ef8du
2458static const unsigned lodepng_crc32_table1[256] = {
2459 0x00000000u, 0x191b3141u, 0x32366282u, 0x2b2d53c3u, 0x646cc504u, 0x7d77f445u, 0x565aa786u, 0x4f4196c7u,
2460 0xc8d98a08u, 0xd1c2bb49u, 0xfaefe88au, 0xe3f4d9cbu, 0xacb54f0cu, 0xb5ae7e4du, 0x9e832d8eu, 0x87981ccfu,
2461 0x4ac21251u, 0x53d92310u, 0x78f470d3u, 0x61ef4192u, 0x2eaed755u, 0x37b5e614u, 0x1c98b5d7u, 0x05838496u,
2462 0x821b9859u, 0x9b00a918u, 0xb02dfadbu, 0xa936cb9au, 0xe6775d5du, 0xff6c6c1cu, 0xd4413fdfu, 0xcd5a0e9eu,
2463 0x958424a2u, 0x8c9f15e3u, 0xa7b24620u, 0xbea97761u, 0xf1e8e1a6u, 0xe8f3d0e7u, 0xc3de8324u, 0xdac5b265u,
2464 0x5d5daeaau, 0x44469febu, 0x6f6bcc28u, 0x7670fd69u, 0x39316baeu, 0x202a5aefu, 0x0b07092cu, 0x121c386du,
2465 0xdf4636f3u, 0xc65d07b2u, 0xed705471u, 0xf46b6530u, 0xbb2af3f7u, 0xa231c2b6u, 0x891c9175u, 0x9007a034u,
2466 0x179fbcfbu, 0x0e848dbau, 0x25a9de79u, 0x3cb2ef38u, 0x73f379ffu, 0x6ae848beu, 0x41c51b7du, 0x58de2a3cu,
2467 0xf0794f05u, 0xe9627e44u, 0xc24f2d87u, 0xdb541cc6u, 0x94158a01u, 0x8d0ebb40u, 0xa623e883u, 0xbf38d9c2u,
2468 0x38a0c50du, 0x21bbf44cu, 0x0a96a78fu, 0x138d96ceu, 0x5ccc0009u, 0x45d73148u, 0x6efa628bu, 0x77e153cau,
2469 0xbabb5d54u, 0xa3a06c15u, 0x888d3fd6u, 0x91960e97u, 0xded79850u, 0xc7cca911u, 0xece1fad2u, 0xf5facb93u,
2470 0x7262d75cu, 0x6b79e61du, 0x4054b5deu, 0x594f849fu, 0x160e1258u, 0x0f152319u, 0x243870dau, 0x3d23419bu,
2471 0x65fd6ba7u, 0x7ce65ae6u, 0x57cb0925u, 0x4ed03864u, 0x0191aea3u, 0x188a9fe2u, 0x33a7cc21u, 0x2abcfd60u,
2472 0xad24e1afu, 0xb43fd0eeu, 0x9f12832du, 0x8609b26cu, 0xc94824abu, 0xd05315eau, 0xfb7e4629u, 0xe2657768u,
2473 0x2f3f79f6u, 0x362448b7u, 0x1d091b74u, 0x04122a35u, 0x4b53bcf2u, 0x52488db3u, 0x7965de70u, 0x607eef31u,
2474 0xe7e6f3feu, 0xfefdc2bfu, 0xd5d0917cu, 0xcccba03du, 0x838a36fau, 0x9a9107bbu, 0xb1bc5478u, 0xa8a76539u,
2475 0x3b83984bu, 0x2298a90au, 0x09b5fac9u, 0x10aecb88u, 0x5fef5d4fu, 0x46f46c0eu, 0x6dd93fcdu, 0x74c20e8cu,
2476 0xf35a1243u, 0xea412302u, 0xc16c70c1u, 0xd8774180u, 0x9736d747u, 0x8e2de606u, 0xa500b5c5u, 0xbc1b8484u,
2477 0x71418a1au, 0x685abb5bu, 0x4377e898u, 0x5a6cd9d9u, 0x152d4f1eu, 0x0c367e5fu, 0x271b2d9cu, 0x3e001cddu,
2478 0xb9980012u, 0xa0833153u, 0x8bae6290u, 0x92b553d1u, 0xddf4c516u, 0xc4eff457u, 0xefc2a794u, 0xf6d996d5u,
2479 0xae07bce9u, 0xb71c8da8u, 0x9c31de6bu, 0x852aef2au, 0xca6b79edu, 0xd37048acu, 0xf85d1b6fu, 0xe1462a2eu,
2480 0x66de36e1u, 0x7fc507a0u, 0x54e85463u, 0x4df36522u, 0x02b2f3e5u, 0x1ba9c2a4u, 0x30849167u, 0x299fa026u,
2481 0xe4c5aeb8u, 0xfdde9ff9u, 0xd6f3cc3au, 0xcfe8fd7bu, 0x80a96bbcu, 0x99b25afdu, 0xb29f093eu, 0xab84387fu,
2482 0x2c1c24b0u, 0x350715f1u, 0x1e2a4632u, 0x07317773u, 0x4870e1b4u, 0x516bd0f5u, 0x7a468336u, 0x635db277u,
2483 0xcbfad74eu, 0xd2e1e60fu, 0xf9ccb5ccu, 0xe0d7848du, 0xaf96124au, 0xb68d230bu, 0x9da070c8u, 0x84bb4189u,
2484 0x03235d46u, 0x1a386c07u, 0x31153fc4u, 0x280e0e85u, 0x674f9842u, 0x7e54a903u, 0x5579fac0u, 0x4c62cb81u,
2485 0x8138c51fu, 0x9823f45eu, 0xb30ea79du, 0xaa1596dcu, 0xe554001bu, 0xfc4f315au, 0xd7626299u, 0xce7953d8u,
2486 0x49e14f17u, 0x50fa7e56u, 0x7bd72d95u, 0x62cc1cd4u, 0x2d8d8a13u, 0x3496bb52u, 0x1fbbe891u, 0x06a0d9d0u,
2487 0x5e7ef3ecu, 0x4765c2adu, 0x6c48916eu, 0x7553a02fu, 0x3a1236e8u, 0x230907a9u, 0x0824546au, 0x113f652bu,
2488 0x96a779e4u, 0x8fbc48a5u, 0xa4911b66u, 0xbd8a2a27u, 0xf2cbbce0u, 0xebd08da1u, 0xc0fdde62u, 0xd9e6ef23u,
2489 0x14bce1bdu, 0x0da7d0fcu, 0x268a833fu, 0x3f91b27eu, 0x70d024b9u, 0x69cb15f8u, 0x42e6463bu, 0x5bfd777au,
2490 0xdc656bb5u, 0xc57e5af4u, 0xee530937u, 0xf7483876u, 0xb809aeb1u, 0xa1129ff0u, 0x8a3fcc33u, 0x9324fd72u
2493static const unsigned lodepng_crc32_table2[256] = {
2494 0x00000000u, 0x01c26a37u, 0x0384d46eu, 0x0246be59u, 0x0709a8dcu, 0x06cbc2ebu, 0x048d7cb2u, 0x054f1685u,
2495 0x0e1351b8u, 0x0fd13b8fu, 0x0d9785d6u, 0x0c55efe1u, 0x091af964u, 0x08d89353u, 0x0a9e2d0au, 0x0b5c473du,
2496 0x1c26a370u, 0x1de4c947u, 0x1fa2771eu, 0x1e601d29u, 0x1b2f0bacu, 0x1aed619bu, 0x18abdfc2u, 0x1969b5f5u,
2497 0x1235f2c8u, 0x13f798ffu, 0x11b126a6u, 0x10734c91u, 0x153c5a14u, 0x14fe3023u, 0x16b88e7au, 0x177ae44du,
2498 0x384d46e0u, 0x398f2cd7u, 0x3bc9928eu, 0x3a0bf8b9u, 0x3f44ee3cu, 0x3e86840bu, 0x3cc03a52u, 0x3d025065u,
2499 0x365e1758u, 0x379c7d6fu, 0x35dac336u, 0x3418a901u, 0x3157bf84u, 0x3095d5b3u, 0x32d36beau, 0x331101ddu,
2500 0x246be590u, 0x25a98fa7u, 0x27ef31feu, 0x262d5bc9u, 0x23624d4cu, 0x22a0277bu, 0x20e69922u, 0x2124f315u,
2501 0x2a78b428u, 0x2bbade1fu, 0x29fc6046u, 0x283e0a71u, 0x2d711cf4u, 0x2cb376c3u, 0x2ef5c89au, 0x2f37a2adu,
2502 0x709a8dc0u, 0x7158e7f7u, 0x731e59aeu, 0x72dc3399u, 0x7793251cu, 0x76514f2bu, 0x7417f172u, 0x75d59b45u,
2503 0x7e89dc78u, 0x7f4bb64fu, 0x7d0d0816u, 0x7ccf6221u, 0x798074a4u, 0x78421e93u, 0x7a04a0cau, 0x7bc6cafdu,
2504 0x6cbc2eb0u, 0x6d7e4487u, 0x6f38fadeu, 0x6efa90e9u, 0x6bb5866cu, 0x6a77ec5bu, 0x68315202u, 0x69f33835u,
2505 0x62af7f08u, 0x636d153fu, 0x612bab66u, 0x60e9c151u, 0x65a6d7d4u, 0x6464bde3u, 0x662203bau, 0x67e0698du,
2506 0x48d7cb20u, 0x4915a117u, 0x4b531f4eu, 0x4a917579u, 0x4fde63fcu, 0x4e1c09cbu, 0x4c5ab792u, 0x4d98dda5u,
2507 0x46c49a98u, 0x4706f0afu, 0x45404ef6u, 0x448224c1u, 0x41cd3244u, 0x400f5873u, 0x4249e62au, 0x438b8c1du,
2508 0x54f16850u, 0x55330267u, 0x5775bc3eu, 0x56b7d609u, 0x53f8c08cu, 0x523aaabbu, 0x507c14e2u, 0x51be7ed5u,
2509 0x5ae239e8u, 0x5b2053dfu, 0x5966ed86u, 0x58a487b1u, 0x5deb9134u, 0x5c29fb03u, 0x5e6f455au, 0x5fad2f6du,
2510 0xe1351b80u, 0xe0f771b7u, 0xe2b1cfeeu, 0xe373a5d9u, 0xe63cb35cu, 0xe7fed96bu, 0xe5b86732u, 0xe47a0d05u,
2511 0xef264a38u, 0xeee4200fu, 0xeca29e56u, 0xed60f461u, 0xe82fe2e4u, 0xe9ed88d3u, 0xebab368au, 0xea695cbdu,
2512 0xfd13b8f0u, 0xfcd1d2c7u, 0xfe976c9eu, 0xff5506a9u, 0xfa1a102cu, 0xfbd87a1bu, 0xf99ec442u, 0xf85cae75u,
2513 0xf300e948u, 0xf2c2837fu, 0xf0843d26u, 0xf1465711u, 0xf4094194u, 0xf5cb2ba3u, 0xf78d95fau, 0xf64fffcdu,
2514 0xd9785d60u, 0xd8ba3757u, 0xdafc890eu, 0xdb3ee339u, 0xde71f5bcu, 0xdfb39f8bu, 0xddf521d2u, 0xdc374be5u,
2515 0xd76b0cd8u, 0xd6a966efu, 0xd4efd8b6u, 0xd52db281u, 0xd062a404u, 0xd1a0ce33u, 0xd3e6706au, 0xd2241a5du,
2516 0xc55efe10u, 0xc49c9427u, 0xc6da2a7eu, 0xc7184049u, 0xc25756ccu, 0xc3953cfbu, 0xc1d382a2u, 0xc011e895u,
2517 0xcb4dafa8u, 0xca8fc59fu, 0xc8c97bc6u, 0xc90b11f1u, 0xcc440774u, 0xcd866d43u, 0xcfc0d31au, 0xce02b92du,
2518 0x91af9640u, 0x906dfc77u, 0x922b422eu, 0x93e92819u, 0x96a63e9cu, 0x976454abu, 0x9522eaf2u, 0x94e080c5u,
2519 0x9fbcc7f8u, 0x9e7eadcfu, 0x9c381396u, 0x9dfa79a1u, 0x98b56f24u, 0x99770513u, 0x9b31bb4au, 0x9af3d17du,
2520 0x8d893530u, 0x8c4b5f07u, 0x8e0de15eu, 0x8fcf8b69u, 0x8a809decu, 0x8b42f7dbu, 0x89044982u, 0x88c623b5u,
2521 0x839a6488u, 0x82580ebfu, 0x801eb0e6u, 0x81dcdad1u, 0x8493cc54u, 0x8551a663u, 0x8717183au, 0x86d5720du,
2522 0xa9e2d0a0u, 0xa820ba97u, 0xaa6604ceu, 0xaba46ef9u, 0xaeeb787cu, 0xaf29124bu, 0xad6fac12u, 0xacadc625u,
2523 0xa7f18118u, 0xa633eb2fu, 0xa4755576u, 0xa5b73f41u, 0xa0f829c4u, 0xa13a43f3u, 0xa37cfdaau, 0xa2be979du,
2524 0xb5c473d0u, 0xb40619e7u, 0xb640a7beu, 0xb782cd89u, 0xb2cddb0cu, 0xb30fb13bu, 0xb1490f62u, 0xb08b6555u,
2525 0xbbd72268u, 0xba15485fu, 0xb853f606u, 0xb9919c31u, 0xbcde8ab4u, 0xbd1ce083u, 0xbf5a5edau, 0xbe9834edu
2528static const unsigned lodepng_crc32_table3[256] = {
2529 0x00000000u, 0xb8bc6765u, 0xaa09c88bu, 0x12b5afeeu, 0x8f629757u, 0x37def032u, 0x256b5fdcu, 0x9dd738b9u,
2530 0xc5b428efu, 0x7d084f8au, 0x6fbde064u, 0xd7018701u, 0x4ad6bfb8u, 0xf26ad8ddu, 0xe0df7733u, 0x58631056u,
2531 0x5019579fu, 0xe8a530fau, 0xfa109f14u, 0x42acf871u, 0xdf7bc0c8u, 0x67c7a7adu, 0x75720843u, 0xcdce6f26u,
2532 0x95ad7f70u, 0x2d111815u, 0x3fa4b7fbu, 0x8718d09eu, 0x1acfe827u, 0xa2738f42u, 0xb0c620acu, 0x087a47c9u,
2533 0xa032af3eu, 0x188ec85bu, 0x0a3b67b5u, 0xb28700d0u, 0x2f503869u, 0x97ec5f0cu, 0x8559f0e2u, 0x3de59787u,
2534 0x658687d1u, 0xdd3ae0b4u, 0xcf8f4f5au, 0x7733283fu, 0xeae41086u, 0x525877e3u, 0x40edd80du, 0xf851bf68u,
2535 0xf02bf8a1u, 0x48979fc4u, 0x5a22302au, 0xe29e574fu, 0x7f496ff6u, 0xc7f50893u, 0xd540a77du, 0x6dfcc018u,
2536 0x359fd04eu, 0x8d23b72bu, 0x9f9618c5u, 0x272a7fa0u, 0xbafd4719u, 0x0241207cu, 0x10f48f92u, 0xa848e8f7u,
2537 0x9b14583du, 0x23a83f58u, 0x311d90b6u, 0x89a1f7d3u, 0x1476cf6au, 0xaccaa80fu, 0xbe7f07e1u, 0x06c36084u,
2538 0x5ea070d2u, 0xe61c17b7u, 0xf4a9b859u, 0x4c15df3cu, 0xd1c2e785u, 0x697e80e0u, 0x7bcb2f0eu, 0xc377486bu,
2539 0xcb0d0fa2u, 0x73b168c7u, 0x6104c729u, 0xd9b8a04cu, 0x446f98f5u, 0xfcd3ff90u, 0xee66507eu, 0x56da371bu,
2540 0x0eb9274du, 0xb6054028u, 0xa4b0efc6u, 0x1c0c88a3u, 0x81dbb01au, 0x3967d77fu, 0x2bd27891u, 0x936e1ff4u,
2541 0x3b26f703u, 0x839a9066u, 0x912f3f88u, 0x299358edu, 0xb4446054u, 0x0cf80731u, 0x1e4da8dfu, 0xa6f1cfbau,
2542 0xfe92dfecu, 0x462eb889u, 0x549b1767u, 0xec277002u, 0x71f048bbu, 0xc94c2fdeu, 0xdbf98030u, 0x6345e755u,
2543 0x6b3fa09cu, 0xd383c7f9u, 0xc1366817u, 0x798a0f72u, 0xe45d37cbu, 0x5ce150aeu, 0x4e54ff40u, 0xf6e89825u,
2544 0xae8b8873u, 0x1637ef16u, 0x048240f8u, 0xbc3e279du, 0x21e91f24u, 0x99557841u, 0x8be0d7afu, 0x335cb0cau,
2545 0xed59b63bu, 0x55e5d15eu, 0x47507eb0u, 0xffec19d5u, 0x623b216cu, 0xda874609u, 0xc832e9e7u, 0x708e8e82u,
2546 0x28ed9ed4u, 0x9051f9b1u, 0x82e4565fu, 0x3a58313au, 0xa78f0983u, 0x1f336ee6u, 0x0d86c108u, 0xb53aa66du,
2547 0xbd40e1a4u, 0x05fc86c1u, 0x1749292fu, 0xaff54e4au, 0x322276f3u, 0x8a9e1196u, 0x982bbe78u, 0x2097d91du,
2548 0x78f4c94bu, 0xc048ae2eu, 0xd2fd01c0u, 0x6a4166a5u, 0xf7965e1cu, 0x4f2a3979u, 0x5d9f9697u, 0xe523f1f2u,
2549 0x4d6b1905u, 0xf5d77e60u, 0xe762d18eu, 0x5fdeb6ebu, 0xc2098e52u, 0x7ab5e937u, 0x680046d9u, 0xd0bc21bcu,
2550 0x88df31eau, 0x3063568fu, 0x22d6f961u, 0x9a6a9e04u, 0x07bda6bdu, 0xbf01c1d8u, 0xadb46e36u, 0x15080953u,
2551 0x1d724e9au, 0xa5ce29ffu, 0xb77b8611u, 0x0fc7e174u, 0x9210d9cdu, 0x2aacbea8u, 0x38191146u, 0x80a57623u,
2552 0xd8c66675u, 0x607a0110u, 0x72cfaefeu, 0xca73c99bu, 0x57a4f122u, 0xef189647u, 0xfdad39a9u, 0x45115eccu,
2553 0x764dee06u, 0xcef18963u, 0xdc44268du, 0x64f841e8u, 0xf92f7951u, 0x41931e34u, 0x5326b1dau, 0xeb9ad6bfu,
2554 0xb3f9c6e9u, 0x0b45a18cu, 0x19f00e62u, 0xa14c6907u, 0x3c9b51beu, 0x842736dbu, 0x96929935u, 0x2e2efe50u,
2555 0x2654b999u, 0x9ee8defcu, 0x8c5d7112u, 0x34e11677u, 0xa9362eceu, 0x118a49abu, 0x033fe645u, 0xbb838120u,
2556 0xe3e09176u, 0x5b5cf613u, 0x49e959fdu, 0xf1553e98u, 0x6c820621u, 0xd43e6144u, 0xc68bceaau, 0x7e37a9cfu,
2557 0xd67f4138u, 0x6ec3265du, 0x7c7689b3u, 0xc4caeed6u, 0x591dd66fu, 0xe1a1b10au, 0xf3141ee4u, 0x4ba87981u,
2558 0x13cb69d7u, 0xab770eb2u, 0xb9c2a15cu, 0x017ec639u, 0x9ca9fe80u, 0x241599e5u, 0x36a0360bu, 0x8e1c516eu,
2559 0x866616a7u, 0x3eda71c2u, 0x2c6fde2cu, 0x94d3b949u, 0x090481f0u, 0xb1b8e695u, 0xa30d497bu, 0x1bb12e1eu,
2560 0x43d23e48u, 0xfb6e592du, 0xe9dbf6c3u, 0x516791a6u, 0xccb0a91fu, 0x740cce7au, 0x66b96194u, 0xde0506f1u
2563static const unsigned lodepng_crc32_table4[256] = {
2564 0x00000000u, 0x3d6029b0u, 0x7ac05360u, 0x47a07ad0u, 0xf580a6c0u, 0xc8e08f70u, 0x8f40f5a0u, 0xb220dc10u,
2565 0x30704bc1u, 0x0d106271u, 0x4ab018a1u, 0x77d03111u, 0xc5f0ed01u, 0xf890c4b1u, 0xbf30be61u, 0x825097d1u,
2566 0x60e09782u, 0x5d80be32u, 0x1a20c4e2u, 0x2740ed52u, 0x95603142u, 0xa80018f2u, 0xefa06222u, 0xd2c04b92u,
2567 0x5090dc43u, 0x6df0f5f3u, 0x2a508f23u, 0x1730a693u, 0xa5107a83u, 0x98705333u, 0xdfd029e3u, 0xe2b00053u,
2568 0xc1c12f04u, 0xfca106b4u, 0xbb017c64u, 0x866155d4u, 0x344189c4u, 0x0921a074u, 0x4e81daa4u, 0x73e1f314u,
2569 0xf1b164c5u, 0xccd14d75u, 0x8b7137a5u, 0xb6111e15u, 0x0431c205u, 0x3951ebb5u, 0x7ef19165u, 0x4391b8d5u,
2570 0xa121b886u, 0x9c419136u, 0xdbe1ebe6u, 0xe681c256u, 0x54a11e46u, 0x69c137f6u, 0x2e614d26u, 0x13016496u,
2571 0x9151f347u, 0xac31daf7u, 0xeb91a027u, 0xd6f18997u, 0x64d15587u, 0x59b17c37u, 0x1e1106e7u, 0x23712f57u,
2572 0x58f35849u, 0x659371f9u, 0x22330b29u, 0x1f532299u, 0xad73fe89u, 0x9013d739u, 0xd7b3ade9u, 0xead38459u,
2573 0x68831388u, 0x55e33a38u, 0x124340e8u, 0x2f236958u, 0x9d03b548u, 0xa0639cf8u, 0xe7c3e628u, 0xdaa3cf98u,
2574 0x3813cfcbu, 0x0573e67bu, 0x42d39cabu, 0x7fb3b51bu, 0xcd93690bu, 0xf0f340bbu, 0xb7533a6bu, 0x8a3313dbu,
2575 0x0863840au, 0x3503adbau, 0x72a3d76au, 0x4fc3fedau, 0xfde322cau, 0xc0830b7au, 0x872371aau, 0xba43581au,
2576 0x9932774du, 0xa4525efdu, 0xe3f2242du, 0xde920d9du, 0x6cb2d18du, 0x51d2f83du, 0x167282edu, 0x2b12ab5du,
2577 0xa9423c8cu, 0x9422153cu, 0xd3826fecu, 0xeee2465cu, 0x5cc29a4cu, 0x61a2b3fcu, 0x2602c92cu, 0x1b62e09cu,
2578 0xf9d2e0cfu, 0xc4b2c97fu, 0x8312b3afu, 0xbe729a1fu, 0x0c52460fu, 0x31326fbfu, 0x7692156fu, 0x4bf23cdfu,
2579 0xc9a2ab0eu, 0xf4c282beu, 0xb362f86eu, 0x8e02d1deu, 0x3c220dceu, 0x0142247eu, 0x46e25eaeu, 0x7b82771eu,
2580 0xb1e6b092u, 0x8c869922u, 0xcb26e3f2u, 0xf646ca42u, 0x44661652u, 0x79063fe2u, 0x3ea64532u, 0x03c66c82u,
2581 0x8196fb53u, 0xbcf6d2e3u, 0xfb56a833u, 0xc6368183u, 0x74165d93u, 0x49767423u, 0x0ed60ef3u, 0x33b62743u,
2582 0xd1062710u, 0xec660ea0u, 0xabc67470u, 0x96a65dc0u, 0x248681d0u, 0x19e6a860u, 0x5e46d2b0u, 0x6326fb00u,
2583 0xe1766cd1u, 0xdc164561u, 0x9bb63fb1u, 0xa6d61601u, 0x14f6ca11u, 0x2996e3a1u, 0x6e369971u, 0x5356b0c1u,
2584 0x70279f96u, 0x4d47b626u, 0x0ae7ccf6u, 0x3787e546u, 0x85a73956u, 0xb8c710e6u, 0xff676a36u, 0xc2074386u,
2585 0x4057d457u, 0x7d37fde7u, 0x3a978737u, 0x07f7ae87u, 0xb5d77297u, 0x88b75b27u, 0xcf1721f7u, 0xf2770847u,
2586 0x10c70814u, 0x2da721a4u, 0x6a075b74u, 0x576772c4u, 0xe547aed4u, 0xd8278764u, 0x9f87fdb4u, 0xa2e7d404u,
2587 0x20b743d5u, 0x1dd76a65u, 0x5a7710b5u, 0x67173905u, 0xd537e515u, 0xe857cca5u, 0xaff7b675u, 0x92979fc5u,
2588 0xe915e8dbu, 0xd475c16bu, 0x93d5bbbbu, 0xaeb5920bu, 0x1c954e1bu, 0x21f567abu, 0x66551d7bu, 0x5b3534cbu,
2589 0xd965a31au, 0xe4058aaau, 0xa3a5f07au, 0x9ec5d9cau, 0x2ce505dau, 0x11852c6au, 0x562556bau, 0x6b457f0au,
2590 0x89f57f59u, 0xb49556e9u, 0xf3352c39u, 0xce550589u, 0x7c75d999u, 0x4115f029u, 0x06b58af9u, 0x3bd5a349u,
2591 0xb9853498u, 0x84e51d28u, 0xc34567f8u, 0xfe254e48u, 0x4c059258u, 0x7165bbe8u, 0x36c5c138u, 0x0ba5e888u,
2592 0x28d4c7dfu, 0x15b4ee6fu, 0x521494bfu, 0x6f74bd0fu, 0xdd54611fu, 0xe03448afu, 0xa794327fu, 0x9af41bcfu,
2593 0x18a48c1eu, 0x25c4a5aeu, 0x6264df7eu, 0x5f04f6ceu, 0xed242adeu, 0xd044036eu, 0x97e479beu, 0xaa84500eu,
2594 0x4834505du, 0x755479edu, 0x32f4033du, 0x0f942a8du, 0xbdb4f69du, 0x80d4df2du, 0xc774a5fdu, 0xfa148c4du,
2595 0x78441b9cu, 0x4524322cu, 0x028448fcu, 0x3fe4614cu, 0x8dc4bd5cu, 0xb0a494ecu, 0xf704ee3cu, 0xca64c78cu
2598static const unsigned lodepng_crc32_table5[256] = {
2599 0x00000000u, 0xcb5cd3a5u, 0x4dc8a10bu, 0x869472aeu, 0x9b914216u, 0x50cd91b3u, 0xd659e31du, 0x1d0530b8u,
2600 0xec53826du, 0x270f51c8u, 0xa19b2366u, 0x6ac7f0c3u, 0x77c2c07bu, 0xbc9e13deu, 0x3a0a6170u, 0xf156b2d5u,
2601 0x03d6029bu, 0xc88ad13eu, 0x4e1ea390u, 0x85427035u, 0x9847408du, 0x531b9328u, 0xd58fe186u, 0x1ed33223u,
2602 0xef8580f6u, 0x24d95353u, 0xa24d21fdu, 0x6911f258u, 0x7414c2e0u, 0xbf481145u, 0x39dc63ebu, 0xf280b04eu,
2603 0x07ac0536u, 0xccf0d693u, 0x4a64a43du, 0x81387798u, 0x9c3d4720u, 0x57619485u, 0xd1f5e62bu, 0x1aa9358eu,
2604 0xebff875bu, 0x20a354feu, 0xa6372650u, 0x6d6bf5f5u, 0x706ec54du, 0xbb3216e8u, 0x3da66446u, 0xf6fab7e3u,
2605 0x047a07adu, 0xcf26d408u, 0x49b2a6a6u, 0x82ee7503u, 0x9feb45bbu, 0x54b7961eu, 0xd223e4b0u, 0x197f3715u,
2606 0xe82985c0u, 0x23755665u, 0xa5e124cbu, 0x6ebdf76eu, 0x73b8c7d6u, 0xb8e41473u, 0x3e7066ddu, 0xf52cb578u,
2607 0x0f580a6cu, 0xc404d9c9u, 0x4290ab67u, 0x89cc78c2u, 0x94c9487au, 0x5f959bdfu, 0xd901e971u, 0x125d3ad4u,
2608 0xe30b8801u, 0x28575ba4u, 0xaec3290au, 0x659ffaafu, 0x789aca17u, 0xb3c619b2u, 0x35526b1cu, 0xfe0eb8b9u,
2609 0x0c8e08f7u, 0xc7d2db52u, 0x4146a9fcu, 0x8a1a7a59u, 0x971f4ae1u, 0x5c439944u, 0xdad7ebeau, 0x118b384fu,
2610 0xe0dd8a9au, 0x2b81593fu, 0xad152b91u, 0x6649f834u, 0x7b4cc88cu, 0xb0101b29u, 0x36846987u, 0xfdd8ba22u,
2611 0x08f40f5au, 0xc3a8dcffu, 0x453cae51u, 0x8e607df4u, 0x93654d4cu, 0x58399ee9u, 0xdeadec47u, 0x15f13fe2u,
2612 0xe4a78d37u, 0x2ffb5e92u, 0xa96f2c3cu, 0x6233ff99u, 0x7f36cf21u, 0xb46a1c84u, 0x32fe6e2au, 0xf9a2bd8fu,
2613 0x0b220dc1u, 0xc07ede64u, 0x46eaaccau, 0x8db67f6fu, 0x90b34fd7u, 0x5bef9c72u, 0xdd7beedcu, 0x16273d79u,
2614 0xe7718facu, 0x2c2d5c09u, 0xaab92ea7u, 0x61e5fd02u, 0x7ce0cdbau, 0xb7bc1e1fu, 0x31286cb1u, 0xfa74bf14u,
2615 0x1eb014d8u, 0xd5ecc77du, 0x5378b5d3u, 0x98246676u, 0x852156ceu, 0x4e7d856bu, 0xc8e9f7c5u, 0x03b52460u,
2616 0xf2e396b5u, 0x39bf4510u, 0xbf2b37beu, 0x7477e41bu, 0x6972d4a3u, 0xa22e0706u, 0x24ba75a8u, 0xefe6a60du,
2617 0x1d661643u, 0xd63ac5e6u, 0x50aeb748u, 0x9bf264edu, 0x86f75455u, 0x4dab87f0u, 0xcb3ff55eu, 0x006326fbu,
2618 0xf135942eu, 0x3a69478bu, 0xbcfd3525u, 0x77a1e680u, 0x6aa4d638u, 0xa1f8059du, 0x276c7733u, 0xec30a496u,
2619 0x191c11eeu, 0xd240c24bu, 0x54d4b0e5u, 0x9f886340u, 0x828d53f8u, 0x49d1805du, 0xcf45f2f3u, 0x04192156u,
2620 0xf54f9383u, 0x3e134026u, 0xb8873288u, 0x73dbe12du, 0x6eded195u, 0xa5820230u, 0x2316709eu, 0xe84aa33bu,
2621 0x1aca1375u, 0xd196c0d0u, 0x5702b27eu, 0x9c5e61dbu, 0x815b5163u, 0x4a0782c6u, 0xcc93f068u, 0x07cf23cdu,
2622 0xf6999118u, 0x3dc542bdu, 0xbb513013u, 0x700de3b6u, 0x6d08d30eu, 0xa65400abu, 0x20c07205u, 0xeb9ca1a0u,
2623 0x11e81eb4u, 0xdab4cd11u, 0x5c20bfbfu, 0x977c6c1au, 0x8a795ca2u, 0x41258f07u, 0xc7b1fda9u, 0x0ced2e0cu,
2624 0xfdbb9cd9u, 0x36e74f7cu, 0xb0733dd2u, 0x7b2fee77u, 0x662adecfu, 0xad760d6au, 0x2be27fc4u, 0xe0beac61u,
2625 0x123e1c2fu, 0xd962cf8au, 0x5ff6bd24u, 0x94aa6e81u, 0x89af5e39u, 0x42f38d9cu, 0xc467ff32u, 0x0f3b2c97u,
2626 0xfe6d9e42u, 0x35314de7u, 0xb3a53f49u, 0x78f9ececu, 0x65fcdc54u, 0xaea00ff1u, 0x28347d5fu, 0xe368aefau,
2627 0x16441b82u, 0xdd18c827u, 0x5b8cba89u, 0x90d0692cu, 0x8dd55994u, 0x46898a31u, 0xc01df89fu, 0x0b412b3au,
2628 0xfa1799efu, 0x314b4a4au, 0xb7df38e4u, 0x7c83eb41u, 0x6186dbf9u, 0xaada085cu, 0x2c4e7af2u, 0xe712a957u,
2629 0x15921919u, 0xdececabcu, 0x585ab812u, 0x93066bb7u, 0x8e035b0fu, 0x455f88aau, 0xc3cbfa04u, 0x089729a1u,
2630 0xf9c19b74u, 0x329d48d1u, 0xb4093a7fu, 0x7f55e9dau, 0x6250d962u, 0xa90c0ac7u, 0x2f987869u, 0xe4c4abccu
2633static const unsigned lodepng_crc32_table6[256] = {
2634 0x00000000u, 0xa6770bb4u, 0x979f1129u, 0x31e81a9du, 0xf44f2413u, 0x52382fa7u, 0x63d0353au, 0xc5a73e8eu,
2635 0x33ef4e67u, 0x959845d3u, 0xa4705f4eu, 0x020754fau, 0xc7a06a74u, 0x61d761c0u, 0x503f7b5du, 0xf64870e9u,
2636 0x67de9cceu, 0xc1a9977au, 0xf0418de7u, 0x56368653u, 0x9391b8ddu, 0x35e6b369u, 0x040ea9f4u, 0xa279a240u,
2637 0x5431d2a9u, 0xf246d91du, 0xc3aec380u, 0x65d9c834u, 0xa07ef6bau, 0x0609fd0eu, 0x37e1e793u, 0x9196ec27u,
2638 0xcfbd399cu, 0x69ca3228u, 0x582228b5u, 0xfe552301u, 0x3bf21d8fu, 0x9d85163bu, 0xac6d0ca6u, 0x0a1a0712u,
2639 0xfc5277fbu, 0x5a257c4fu, 0x6bcd66d2u, 0xcdba6d66u, 0x081d53e8u, 0xae6a585cu, 0x9f8242c1u, 0x39f54975u,
2640 0xa863a552u, 0x0e14aee6u, 0x3ffcb47bu, 0x998bbfcfu, 0x5c2c8141u, 0xfa5b8af5u, 0xcbb39068u, 0x6dc49bdcu,
2641 0x9b8ceb35u, 0x3dfbe081u, 0x0c13fa1cu, 0xaa64f1a8u, 0x6fc3cf26u, 0xc9b4c492u, 0xf85cde0fu, 0x5e2bd5bbu,
2642 0x440b7579u, 0xe27c7ecdu, 0xd3946450u, 0x75e36fe4u, 0xb044516au, 0x16335adeu, 0x27db4043u, 0x81ac4bf7u,
2643 0x77e43b1eu, 0xd19330aau, 0xe07b2a37u, 0x460c2183u, 0x83ab1f0du, 0x25dc14b9u, 0x14340e24u, 0xb2430590u,
2644 0x23d5e9b7u, 0x85a2e203u, 0xb44af89eu, 0x123df32au, 0xd79acda4u, 0x71edc610u, 0x4005dc8du, 0xe672d739u,
2645 0x103aa7d0u, 0xb64dac64u, 0x87a5b6f9u, 0x21d2bd4du, 0xe47583c3u, 0x42028877u, 0x73ea92eau, 0xd59d995eu,
2646 0x8bb64ce5u, 0x2dc14751u, 0x1c295dccu, 0xba5e5678u, 0x7ff968f6u, 0xd98e6342u, 0xe86679dfu, 0x4e11726bu,
2647 0xb8590282u, 0x1e2e0936u, 0x2fc613abu, 0x89b1181fu, 0x4c162691u, 0xea612d25u, 0xdb8937b8u, 0x7dfe3c0cu,
2648 0xec68d02bu, 0x4a1fdb9fu, 0x7bf7c102u, 0xdd80cab6u, 0x1827f438u, 0xbe50ff8cu, 0x8fb8e511u, 0x29cfeea5u,
2649 0xdf879e4cu, 0x79f095f8u, 0x48188f65u, 0xee6f84d1u, 0x2bc8ba5fu, 0x8dbfb1ebu, 0xbc57ab76u, 0x1a20a0c2u,
2650 0x8816eaf2u, 0x2e61e146u, 0x1f89fbdbu, 0xb9fef06fu, 0x7c59cee1u, 0xda2ec555u, 0xebc6dfc8u, 0x4db1d47cu,
2651 0xbbf9a495u, 0x1d8eaf21u, 0x2c66b5bcu, 0x8a11be08u, 0x4fb68086u, 0xe9c18b32u, 0xd82991afu, 0x7e5e9a1bu,
2652 0xefc8763cu, 0x49bf7d88u, 0x78576715u, 0xde206ca1u, 0x1b87522fu, 0xbdf0599bu, 0x8c184306u, 0x2a6f48b2u,
2653 0xdc27385bu, 0x7a5033efu, 0x4bb82972u, 0xedcf22c6u, 0x28681c48u, 0x8e1f17fcu, 0xbff70d61u, 0x198006d5u,
2654 0x47abd36eu, 0xe1dcd8dau, 0xd034c247u, 0x7643c9f3u, 0xb3e4f77du, 0x1593fcc9u, 0x247be654u, 0x820cede0u,
2655 0x74449d09u, 0xd23396bdu, 0xe3db8c20u, 0x45ac8794u, 0x800bb91au, 0x267cb2aeu, 0x1794a833u, 0xb1e3a387u,
2656 0x20754fa0u, 0x86024414u, 0xb7ea5e89u, 0x119d553du, 0xd43a6bb3u, 0x724d6007u, 0x43a57a9au, 0xe5d2712eu,
2657 0x139a01c7u, 0xb5ed0a73u, 0x840510eeu, 0x22721b5au, 0xe7d525d4u, 0x41a22e60u, 0x704a34fdu, 0xd63d3f49u,
2658 0xcc1d9f8bu, 0x6a6a943fu, 0x5b828ea2u, 0xfdf58516u, 0x3852bb98u, 0x9e25b02cu, 0xafcdaab1u, 0x09baa105u,
2659 0xfff2d1ecu, 0x5985da58u, 0x686dc0c5u, 0xce1acb71u, 0x0bbdf5ffu, 0xadcafe4bu, 0x9c22e4d6u, 0x3a55ef62u,
2660 0xabc30345u, 0x0db408f1u, 0x3c5c126cu, 0x9a2b19d8u, 0x5f8c2756u, 0xf9fb2ce2u, 0xc813367fu, 0x6e643dcbu,
2661 0x982c4d22u, 0x3e5b4696u, 0x0fb35c0bu, 0xa9c457bfu, 0x6c636931u, 0xca146285u, 0xfbfc7818u, 0x5d8b73acu,
2662 0x03a0a617u, 0xa5d7ada3u, 0x943fb73eu, 0x3248bc8au, 0xf7ef8204u, 0x519889b0u, 0x6070932du, 0xc6079899u,
2663 0x304fe870u, 0x9638e3c4u, 0xa7d0f959u, 0x01a7f2edu, 0xc400cc63u, 0x6277c7d7u, 0x539fdd4au, 0xf5e8d6feu,
2664 0x647e3ad9u, 0xc209316du, 0xf3e12bf0u, 0x55962044u, 0x90311ecau, 0x3646157eu, 0x07ae0fe3u, 0xa1d90457u,
2665 0x579174beu, 0xf1e67f0au, 0xc00e6597u, 0x66796e23u, 0xa3de50adu, 0x05a95b19u, 0x34414184u, 0x92364a30u
2668static const unsigned lodepng_crc32_table7[256] = {
2669 0x00000000u, 0xccaa009eu, 0x4225077du, 0x8e8f07e3u, 0x844a0efau, 0x48e00e64u, 0xc66f0987u, 0x0ac50919u,
2670 0xd3e51bb5u, 0x1f4f1b2bu, 0x91c01cc8u, 0x5d6a1c56u, 0x57af154fu, 0x9b0515d1u, 0x158a1232u, 0xd92012acu,
2671 0x7cbb312bu, 0xb01131b5u, 0x3e9e3656u, 0xf23436c8u, 0xf8f13fd1u, 0x345b3f4fu, 0xbad438acu, 0x767e3832u,
2672 0xaf5e2a9eu, 0x63f42a00u, 0xed7b2de3u, 0x21d12d7du, 0x2b142464u, 0xe7be24fau, 0x69312319u, 0xa59b2387u,
2673 0xf9766256u, 0x35dc62c8u, 0xbb53652bu, 0x77f965b5u, 0x7d3c6cacu, 0xb1966c32u, 0x3f196bd1u, 0xf3b36b4fu,
2674 0x2a9379e3u, 0xe639797du, 0x68b67e9eu, 0xa41c7e00u, 0xaed97719u, 0x62737787u, 0xecfc7064u, 0x205670fau,
2675 0x85cd537du, 0x496753e3u, 0xc7e85400u, 0x0b42549eu, 0x01875d87u, 0xcd2d5d19u, 0x43a25afau, 0x8f085a64u,
2676 0x562848c8u, 0x9a824856u, 0x140d4fb5u, 0xd8a74f2bu, 0xd2624632u, 0x1ec846acu, 0x9047414fu, 0x5ced41d1u,
2677 0x299dc2edu, 0xe537c273u, 0x6bb8c590u, 0xa712c50eu, 0xadd7cc17u, 0x617dcc89u, 0xeff2cb6au, 0x2358cbf4u,
2678 0xfa78d958u, 0x36d2d9c6u, 0xb85dde25u, 0x74f7debbu, 0x7e32d7a2u, 0xb298d73cu, 0x3c17d0dfu, 0xf0bdd041u,
2679 0x5526f3c6u, 0x998cf358u, 0x1703f4bbu, 0xdba9f425u, 0xd16cfd3cu, 0x1dc6fda2u, 0x9349fa41u, 0x5fe3fadfu,
2680 0x86c3e873u, 0x4a69e8edu, 0xc4e6ef0eu, 0x084cef90u, 0x0289e689u, 0xce23e617u, 0x40ace1f4u, 0x8c06e16au,
2681 0xd0eba0bbu, 0x1c41a025u, 0x92cea7c6u, 0x5e64a758u, 0x54a1ae41u, 0x980baedfu, 0x1684a93cu, 0xda2ea9a2u,
2682 0x030ebb0eu, 0xcfa4bb90u, 0x412bbc73u, 0x8d81bcedu, 0x8744b5f4u, 0x4beeb56au, 0xc561b289u, 0x09cbb217u,
2683 0xac509190u, 0x60fa910eu, 0xee7596edu, 0x22df9673u, 0x281a9f6au, 0xe4b09ff4u, 0x6a3f9817u, 0xa6959889u,
2684 0x7fb58a25u, 0xb31f8abbu, 0x3d908d58u, 0xf13a8dc6u, 0xfbff84dfu, 0x37558441u, 0xb9da83a2u, 0x7570833cu,
2685 0x533b85dau, 0x9f918544u, 0x111e82a7u, 0xddb48239u, 0xd7718b20u, 0x1bdb8bbeu, 0x95548c5du, 0x59fe8cc3u,
2686 0x80de9e6fu, 0x4c749ef1u, 0xc2fb9912u, 0x0e51998cu, 0x04949095u, 0xc83e900bu, 0x46b197e8u, 0x8a1b9776u,
2687 0x2f80b4f1u, 0xe32ab46fu, 0x6da5b38cu, 0xa10fb312u, 0xabcaba0bu, 0x6760ba95u, 0xe9efbd76u, 0x2545bde8u,
2688 0xfc65af44u, 0x30cfafdau, 0xbe40a839u, 0x72eaa8a7u, 0x782fa1beu, 0xb485a120u, 0x3a0aa6c3u, 0xf6a0a65du,
2689 0xaa4de78cu, 0x66e7e712u, 0xe868e0f1u, 0x24c2e06fu, 0x2e07e976u, 0xe2ade9e8u, 0x6c22ee0bu, 0xa088ee95u,
2690 0x79a8fc39u, 0xb502fca7u, 0x3b8dfb44u, 0xf727fbdau, 0xfde2f2c3u, 0x3148f25du, 0xbfc7f5beu, 0x736df520u,
2691 0xd6f6d6a7u, 0x1a5cd639u, 0x94d3d1dau, 0x5879d144u, 0x52bcd85du, 0x9e16d8c3u, 0x1099df20u, 0xdc33dfbeu,
2692 0x0513cd12u, 0xc9b9cd8cu, 0x4736ca6fu, 0x8b9ccaf1u, 0x8159c3e8u, 0x4df3c376u, 0xc37cc495u, 0x0fd6c40bu,
2693 0x7aa64737u, 0xb60c47a9u, 0x3883404au, 0xf42940d4u, 0xfeec49cdu, 0x32464953u, 0xbcc94eb0u, 0x70634e2eu,
2694 0xa9435c82u, 0x65e95c1cu, 0xeb665bffu, 0x27cc5b61u, 0x2d095278u, 0xe1a352e6u, 0x6f2c5505u, 0xa386559bu,
2695 0x061d761cu, 0xcab77682u, 0x44387161u, 0x889271ffu, 0x825778e6u, 0x4efd7878u, 0xc0727f9bu, 0x0cd87f05u,
2696 0xd5f86da9u, 0x19526d37u, 0x97dd6ad4u, 0x5b776a4au, 0x51b26353u, 0x9d1863cdu, 0x1397642eu, 0xdf3d64b0u,
2697 0x83d02561u, 0x4f7a25ffu, 0xc1f5221cu, 0x0d5f2282u, 0x079a2b9bu, 0xcb302b05u, 0x45bf2ce6u, 0x89152c78u,
2698 0x50353ed4u, 0x9c9f3e4au, 0x121039a9u, 0xdeba3937u, 0xd47f302eu, 0x18d530b0u, 0x965a3753u, 0x5af037cdu,
2699 0xff6b144au, 0x33c114d4u, 0xbd4e1337u, 0x71e413a9u, 0x7b211ab0u, 0xb78b1a2eu, 0x39041dcdu, 0xf5ae1d53u,
2700 0x2c8e0fffu, 0xe0240f61u, 0x6eab0882u, 0xa201081cu, 0xa8c40105u, 0x646e019bu, 0xeae10678u, 0x264b06e6u
2706 unsigned r = 0xffffffffu;
2707 while(length >= 8) {
2708 r = lodepng_crc32_table7[(data[0] ^ (r & 0xffu))] ^
2709 lodepng_crc32_table6[(data[1] ^ ((r >> 8) & 0xffu))] ^
2710 lodepng_crc32_table5[(data[2] ^ ((r >> 16) & 0xffu))] ^
2711 lodepng_crc32_table4[(data[3] ^ ((r >> 24) & 0xffu))] ^
2712 lodepng_crc32_table3[data[4]] ^
2713 lodepng_crc32_table2[data[5]] ^
2714 lodepng_crc32_table1[data[6]] ^
2715 lodepng_crc32_table0[data[7]];
2720 r = lodepng_crc32_table0[(r ^ *data++) & 0xffu] ^ (r >> 8);
2722 return r ^ 0xffffffffu;
2744unsigned lodepng_crc32(
const unsigned char* data,
size_t length);
2754static unsigned char readBitFromReversedStream(
size_t* bitpointer,
const unsigned char* bitstream) {
2755 unsigned char result = (
unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1);
2761static unsigned readBitsFromReversedStream(
size_t* bitpointer,
const unsigned char* bitstream,
size_t nbits) {
2762 unsigned result = 0;
2764 for(i = 0 ; i < nbits; ++i) {
2766 result |= (unsigned)readBitFromReversedStream(bitpointer, bitstream);
2771static void setBitOfReversedStream(
size_t* bitpointer,
unsigned char* bitstream,
unsigned char bit) {
2773 if(bit == 0) bitstream[(*bitpointer) >> 3u] &= (
unsigned char)(~(1u << (7u - ((*bitpointer) & 7u))));
2774 else bitstream[(*bitpointer) >> 3u] |= (1u << (7u - ((*bitpointer) & 7u)));
2783 return lodepng_read32bitInt(chunk);
2788 for(i = 0; i != 4; ++i)
type[i] = (
char)chunk[4 + i];
2793 if(lodepng_strlen(
type) != 4)
return 0;
2794 return (chunk[4] ==
type[0] && chunk[5] ==
type[1] && chunk[6] ==
type[2] && chunk[7] ==
type[3]);
2798 return((chunk[4] & 32) != 0);
2802 return((chunk[6] & 32) != 0);
2806 return((chunk[7] & 32) != 0);
2819 unsigned CRC = lodepng_read32bitInt(&chunk[length + 8]);
2822 if(CRC != checksum)
return 1;
2829 lodepng_set32bitInt(chunk + 8 + length, CRC);
2833 size_t available_size = (
size_t)(end - chunk);
2834 if(chunk >= end || available_size < 12)
return end;
2835 if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47
2836 && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) {
2840 size_t total_chunk_length;
2842 if(total_chunk_length > available_size)
return end;
2843 return chunk + total_chunk_length;
2848 size_t available_size = (
size_t)(end - chunk);
2849 if(chunk >= end || available_size < 12)
return end;
2850 if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47
2851 && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) {
2855 size_t total_chunk_length;
2857 if(total_chunk_length > available_size)
return end;
2858 return chunk + total_chunk_length;
2864 if(chunk >= end || end - chunk < 12)
return 0;
2872 if(chunk >= end || end - chunk < 12)
return 0;
2880 size_t total_chunk_length, new_length;
2881 unsigned char *chunk_start, *new_buffer;
2884 if(lodepng_addofl(*outsize, total_chunk_length, &new_length))
return 77;
2887 new_buffer = (
unsigned char*)lodepng_reallocate(*out, *outsize, new_length);
2888 if(!new_buffer)
return 83;
2889 (*out) = new_buffer;
2890 (*outsize) = new_length;
2891 chunk_start = &(*out)[new_length - total_chunk_length];
2893 for(i = 0; i != total_chunk_length; ++i) chunk_start[i] = chunk[i];
2902static unsigned lodepng_chunk_init(
unsigned char** chunk,
2904 size_t length,
const char*
type) {
2905 size_t new_length = out->
size;
2906 if(lodepng_addofl(new_length, length, &new_length))
return 77;
2907 if(lodepng_addofl(new_length, 12, &new_length))
return 77;
2908 if(!ucvector_resize(out, new_length))
return 83;
2909 *chunk = out->
data + new_length - length - 12u;
2912 lodepng_set32bitInt(*chunk, (
unsigned)length);
2915 lodepng_memcpy(*chunk + 4,
type, 4);
2921static unsigned lodepng_chunk_createv(
ucvector* out,
2922 size_t length,
const char*
type,
const unsigned char* data) {
2923 unsigned char* chunk;
2927 lodepng_memcpy(chunk + 8, data, length);
2936 size_t length,
const char*
type,
const unsigned char* data) {
2937 ucvector v = ucvector_init(*out, *outsize);
2938 unsigned error = lodepng_chunk_createv(&v, length,
type, data);
2950static unsigned checkColorValidity(
LodePNGColorType colortype,
unsigned bd) {
2952 case LCT_GREY:
if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16))
return 37;
break;
2953 case LCT_RGB:
if(!( bd == 8 || bd == 16))
return 37;
break;
2954 case LCT_PALETTE:
if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 ))
return 37;
break;
2955 case LCT_GREY_ALPHA:
if(!( bd == 8 || bd == 16))
return 37;
break;
2956 case LCT_RGBA:
if(!( bd == 8 || bd == 16))
return 37;
break;
2975static unsigned lodepng_get_bpp_lct(
LodePNGColorType colortype,
unsigned bitdepth) {
2977 return getNumColorChannels(colortype) * bitdepth;
2996 if(!info->
palette) info->
palette = (
unsigned char*)lodepng_malloc(1024);
2998 for(i = 0; i != 256; ++i) {
3005 info->
palette[i * 4 + 3] = 255;
3017 dest->
palette = (
unsigned char*)lodepng_malloc(1024);
3056 unsigned char r,
unsigned char g,
unsigned char b,
unsigned char a) {
3058 lodepng_color_mode_alloc_palette(info);
3078 return getNumColorChannels(info->
colortype);
3096 if(info->
palette[i * 4 + 3] < 255)
return 1;
3107static size_t lodepng_get_raw_size_lct(
unsigned w,
unsigned h,
LodePNGColorType colortype,
unsigned bitdepth) {
3108 size_t bpp = lodepng_get_bpp_lct(colortype, bitdepth);
3109 size_t n = (
size_t)w * (
size_t)h;
3110 return ((n / 8u) * bpp) + ((n & 7u) * bpp + 7u) / 8u;
3118#ifdef LODEPNG_COMPILE_PNG
3123static size_t lodepng_get_raw_size_idat(
unsigned w,
unsigned h,
unsigned bpp) {
3126 size_t line = ((
size_t)(w / 8u) * bpp) + 1u + ((w & 7u) * bpp + 7u) / 8u;
3127 return (
size_t)h * line;
3130#ifdef LODEPNG_COMPILE_DECODER
3139static int lodepng_pixel_overflow(
unsigned w,
unsigned h,
3142 size_t numpixels, total;
3145 if(lodepng_mulofl((
size_t)w, (
size_t)h, &numpixels))
return 1;
3146 if(lodepng_mulofl(numpixels, 8, &total))
return 1;
3149 if(lodepng_mulofl((
size_t)(w / 8u), bpp, &line))
return 1;
3150 if(lodepng_addofl(line, ((w & 7u) * bpp + 7u) / 8u, &line))
return 1;
3152 if(lodepng_addofl(line, 5, &line))
return 1;
3153 if(lodepng_mulofl(line, h, &total))
return 1;
3160#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
3162static void LodePNGUnknownChunks_init(
LodePNGInfo* info) {
3168static void LodePNGUnknownChunks_cleanup(
LodePNGInfo* info) {
3176 LodePNGUnknownChunks_cleanup(dest);
3178 for(i = 0; i != 3; ++i) {
3199static void LodePNGText_cleanup(
LodePNGInfo* info) {
3201 for(i = 0; i != info->
text_num; ++i) {
3214 for(i = 0; i != source->
text_num; ++i) {
3220static unsigned lodepng_add_text_sized(
LodePNGInfo* info,
const char* key,
const char* str,
size_t size) {
3222 char** new_keys = (
char**)(lodepng_reallocate(info->
text_keys,
sizeof(
char*) * info->
text_num,
sizeof(
char*) * (info->
text_num + 1)));
3223 char** new_strings = (
char**)(lodepng_reallocate(info->
text_strings,
sizeof(
char*) * info->
text_num,
sizeof(
char*) * (info->
text_num + 1)));
3225 if(new_keys) info->
text_keys = new_keys;
3228 if(!new_keys || !new_strings)
return 83;
3239 return lodepng_add_text_sized(info, key, str, lodepng_strlen(str));
3243 LodePNGText_cleanup(info);
3256static void LodePNGIText_cleanup(
LodePNGInfo* info) {
3277 for(i = 0; i != source->
itext_num; ++i) {
3285 LodePNGIText_cleanup(info);
3288static unsigned lodepng_add_itext_sized(
LodePNGInfo* info,
const char* key,
const char* langtag,
3289 const char* transkey,
const char* str,
size_t size) {
3291 char** new_keys = (
char**)(lodepng_reallocate(info->
itext_keys,
sizeof(
char*) * info->
itext_num,
sizeof(
char*) * (info->
itext_num + 1)));
3301 if(!new_keys || !new_langtags || !new_transkeys || !new_strings)
return 83;
3314 const char* transkey,
const char* str) {
3315 return lodepng_add_itext_sized(info, key, langtag, transkey, str, lodepng_strlen(str));
3319static unsigned lodepng_assign_icc(
LodePNGInfo* info,
const char* name,
const unsigned char* profile,
unsigned profile_size) {
3320 if(profile_size == 0)
return 100;
3323 info->
iccp_profile = (
unsigned char*)lodepng_malloc(profile_size);
3327 lodepng_memcpy(info->
iccp_profile, profile, profile_size);
3337 return lodepng_assign_icc(info, name, profile, profile_size);
3354#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
3358 LodePNGText_init(info);
3359 LodePNGIText_init(info);
3374 LodePNGUnknownChunks_init(info);
3380#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
3381 LodePNGText_cleanup(info);
3382 LodePNGIText_cleanup(info);
3386 LodePNGUnknownChunks_cleanup(info);
3392 lodepng_memcpy(dest, source,
sizeof(
LodePNGInfo));
3396#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
3403 LodePNGUnknownChunks_init(dest);
3412static void addColorBits(
unsigned char* out,
size_t index,
unsigned bits,
unsigned in) {
3413 unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1;
3415 unsigned p = index & m;
3416 in &= (1u << bits) - 1u;
3417 in = in << (bits * (m - p));
3418 if(p == 0) out[index * bits / 8u] = in;
3419 else out[index * bits / 8u] |= in;
3435static void color_tree_init(
ColorTree* tree) {
3440static void color_tree_cleanup(
ColorTree* tree) {
3442 for(i = 0; i != 16; ++i) {
3444 color_tree_cleanup(tree->
children[i]);
3451static int color_tree_get(
ColorTree* tree,
unsigned char r,
unsigned char g,
unsigned char b,
unsigned char a) {
3453 for(bit = 0; bit < 8; ++bit) {
3454 int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1);
3458 return tree ? tree->
index : -1;
3461#ifdef LODEPNG_COMPILE_ENCODER
3462static int color_tree_has(
ColorTree* tree,
unsigned char r,
unsigned char g,
unsigned char b,
unsigned char a) {
3463 return color_tree_get(tree, r, g, b, a) >= 0;
3470static unsigned color_tree_add(
ColorTree* tree,
3471 unsigned char r,
unsigned char g,
unsigned char b,
unsigned char a,
unsigned index) {
3473 for(bit = 0; bit < 8; ++bit) {
3474 int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1);
3478 color_tree_init(tree->
children[i]);
3482 tree->
index = (int)index;
3487static unsigned rgba8ToPixel(
unsigned char* out,
size_t i,
3489 unsigned char r,
unsigned char g,
unsigned char b,
unsigned char a) {
3491 unsigned char gray = r;
3492 if(mode->
bitdepth == 8) out[i] = gray;
3493 else if(mode->
bitdepth == 16) out[i * 2 + 0] = out[i * 2 + 1] = gray;
3496 gray = ((unsigned)gray >> (8u - mode->
bitdepth)) & ((1u << mode->
bitdepth) - 1u);
3497 addColorBits(out, i, mode->
bitdepth, gray);
3505 out[i * 6 + 0] = out[i * 6 + 1] = r;
3506 out[i * 6 + 2] = out[i * 6 + 3] = g;
3507 out[i * 6 + 4] = out[i * 6 + 5] = b;
3510 int index = color_tree_get(tree, r, g, b, a);
3511 if(index < 0)
return 82;
3512 if(mode->
bitdepth == 8) out[i] = index;
3513 else addColorBits(out, i, mode->
bitdepth, (
unsigned)index);
3515 unsigned char gray = r;
3517 out[i * 2 + 0] = gray;
3520 out[i * 4 + 0] = out[i * 4 + 1] = gray;
3521 out[i * 4 + 2] = out[i * 4 + 3] = a;
3530 out[i * 8 + 0] = out[i * 8 + 1] = r;
3531 out[i * 8 + 2] = out[i * 8 + 3] = g;
3532 out[i * 8 + 4] = out[i * 8 + 5] = b;
3533 out[i * 8 + 6] = out[i * 8 + 7] = a;
3541static void rgba16ToPixel(
unsigned char* out,
size_t i,
3543 unsigned short r,
unsigned short g,
unsigned short b,
unsigned short a) {
3545 unsigned short gray = r;
3546 out[i * 2 + 0] = (gray >> 8) & 255;
3547 out[i * 2 + 1] = gray & 255;
3549 out[i * 6 + 0] = (r >> 8) & 255;
3550 out[i * 6 + 1] = r & 255;
3551 out[i * 6 + 2] = (g >> 8) & 255;
3552 out[i * 6 + 3] = g & 255;
3553 out[i * 6 + 4] = (b >> 8) & 255;
3554 out[i * 6 + 5] = b & 255;
3556 unsigned short gray = r;
3557 out[i * 4 + 0] = (gray >> 8) & 255;
3558 out[i * 4 + 1] = gray & 255;
3559 out[i * 4 + 2] = (a >> 8) & 255;
3560 out[i * 4 + 3] = a & 255;
3562 out[i * 8 + 0] = (r >> 8) & 255;
3563 out[i * 8 + 1] = r & 255;
3564 out[i * 8 + 2] = (g >> 8) & 255;
3565 out[i * 8 + 3] = g & 255;
3566 out[i * 8 + 4] = (b >> 8) & 255;
3567 out[i * 8 + 5] = b & 255;
3568 out[i * 8 + 6] = (a >> 8) & 255;
3569 out[i * 8 + 7] = a & 255;
3574static void getPixelColorRGBA8(
unsigned char* r,
unsigned char* g,
3575 unsigned char* b,
unsigned char* a,
3576 const unsigned char* in,
size_t i,
3580 *r = *g = *b = in[i];
3584 *r = *g = *b = in[i * 2 + 0];
3585 if(mode->
key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->
key_r) *a = 0;
3588 unsigned highest = ((1U << mode->
bitdepth) - 1U);
3590 unsigned value = readBitsFromReversedStream(&j, in, mode->
bitdepth);
3591 *r = *g = *b = (
value * 255) / highest;
3597 *r = in[i * 3 + 0]; *g = in[i * 3 + 1]; *b = in[i * 3 + 2];
3604 if(mode->
key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->
key_r
3605 && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->
key_g
3606 && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->
key_b) *a = 0;
3611 if(mode->
bitdepth == 8) index = in[i];
3614 index = readBitsFromReversedStream(&j, in, mode->
bitdepth);
3617 *r = mode->
palette[index * 4 + 0];
3618 *g = mode->
palette[index * 4 + 1];
3619 *b = mode->
palette[index * 4 + 2];
3620 *a = mode->
palette[index * 4 + 3];
3623 *r = *g = *b = in[i * 2 + 0];
3626 *r = *g = *b = in[i * 4 + 0];
3648static void getPixelColorsRGBA8(
unsigned char*
LODEPNG_RESTRICT buffer,
size_t numpixels,
3651 unsigned num_channels = 4;
3655 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3656 buffer[0] = buffer[1] = buffer[2] = in[i];
3660 buffer -= numpixels * num_channels;
3661 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3662 if(buffer[0] == mode->
key_r) buffer[3] = 0;
3666 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3667 buffer[0] = buffer[1] = buffer[2] = in[i * 2];
3668 buffer[3] = mode->
key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->
key_r ? 0 : 255;
3671 unsigned highest = ((1U << mode->
bitdepth) - 1U);
3673 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3674 unsigned value = readBitsFromReversedStream(&j, in, mode->
bitdepth);
3675 buffer[0] = buffer[1] = buffer[2] = (
value * 255) / highest;
3681 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3682 lodepng_memcpy(buffer, &in[i * 3], 3);
3686 buffer -= numpixels * num_channels;
3687 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3688 if(buffer[0] == mode->
key_r && buffer[1]== mode->
key_g && buffer[2] == mode->
key_b) buffer[3] = 0;
3692 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3693 buffer[0] = in[i * 6 + 0];
3694 buffer[1] = in[i * 6 + 2];
3695 buffer[2] = in[i * 6 + 4];
3697 && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->
key_r
3698 && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->
key_g
3699 && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->
key_b ? 0 : 255;
3704 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3705 unsigned index = in[i];
3707 lodepng_memcpy(buffer, &mode->
palette[index * 4], 4);
3711 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3712 unsigned index = readBitsFromReversedStream(&j, in, mode->
bitdepth);
3714 lodepng_memcpy(buffer, &mode->
palette[index * 4], 4);
3719 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3720 buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0];
3721 buffer[3] = in[i * 2 + 1];
3724 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3725 buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0];
3726 buffer[3] = in[i * 4 + 2];
3731 lodepng_memcpy(buffer, in, numpixels * 4);
3733 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3734 buffer[0] = in[i * 8 + 0];
3735 buffer[1] = in[i * 8 + 2];
3736 buffer[2] = in[i * 8 + 4];
3737 buffer[3] = in[i * 8 + 6];
3744static void getPixelColorsRGB8(
unsigned char*
LODEPNG_RESTRICT buffer,
size_t numpixels,
3747 const unsigned num_channels = 3;
3751 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3752 buffer[0] = buffer[1] = buffer[2] = in[i];
3755 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3756 buffer[0] = buffer[1] = buffer[2] = in[i * 2];
3759 unsigned highest = ((1U << mode->
bitdepth) - 1U);
3761 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3762 unsigned value = readBitsFromReversedStream(&j, in, mode->
bitdepth);
3763 buffer[0] = buffer[1] = buffer[2] = (
value * 255) / highest;
3768 lodepng_memcpy(buffer, in, numpixels * 3);
3770 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3771 buffer[0] = in[i * 6 + 0];
3772 buffer[1] = in[i * 6 + 2];
3773 buffer[2] = in[i * 6 + 4];
3778 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3779 unsigned index = in[i];
3781 lodepng_memcpy(buffer, &mode->
palette[index * 4], 3);
3785 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3786 unsigned index = readBitsFromReversedStream(&j, in, mode->
bitdepth);
3788 lodepng_memcpy(buffer, &mode->
palette[index * 4], 3);
3793 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3794 buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0];
3797 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3798 buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0];
3803 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3804 lodepng_memcpy(buffer, &in[i * 4], 3);
3807 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3808 buffer[0] = in[i * 8 + 0];
3809 buffer[1] = in[i * 8 + 2];
3810 buffer[2] = in[i * 8 + 4];
3818static void getPixelColorRGBA16(
unsigned short* r,
unsigned short* g,
unsigned short* b,
unsigned short* a,
3821 *r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1];
3822 if(mode->
key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->
key_r) *a = 0;
3825 *r = 256u * in[i * 6 + 0] + in[i * 6 + 1];
3826 *g = 256u * in[i * 6 + 2] + in[i * 6 + 3];
3827 *b = 256u * in[i * 6 + 4] + in[i * 6 + 5];
3829 && 256u * in[i * 6 + 0] + in[i * 6 + 1] == mode->
key_r
3830 && 256u * in[i * 6 + 2] + in[i * 6 + 3] == mode->
key_g
3831 && 256u * in[i * 6 + 4] + in[i * 6 + 5] == mode->
key_b) *a = 0;
3834 *r = *g = *b = 256u * in[i * 4 + 0] + in[i * 4 + 1];
3835 *a = 256u * in[i * 4 + 2] + in[i * 4 + 3];
3837 *r = 256u * in[i * 8 + 0] + in[i * 8 + 1];
3838 *g = 256u * in[i * 8 + 2] + in[i * 8 + 3];
3839 *b = 256u * in[i * 8 + 4] + in[i * 8 + 5];
3840 *a = 256u * in[i * 8 + 6] + in[i * 8 + 7];
3846 unsigned w,
unsigned h) {
3849 size_t numpixels = (
size_t)w * (
size_t)h;
3856 if(lodepng_color_mode_equal(mode_out, mode_in)) {
3858 lodepng_memcpy(out, in, numbytes);
3864 const unsigned char* palette = mode_out->
palette;
3869 if(palettesize == 0) {
3877 lodepng_memcpy(out, in, numbytes);
3881 if(palettesize < palsize) palsize = palettesize;
3882 color_tree_init(&tree);
3883 for(i = 0; i != palsize; ++i) {
3884 const unsigned char* p = &palette[i * 4];
3885 error = color_tree_add(&tree, p[0], p[1], p[2], p[3], (
unsigned)i);
3892 for(i = 0; i != numpixels; ++i) {
3893 unsigned short r = 0, g = 0, b = 0, a = 0;
3894 getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
3895 rgba16ToPixel(out, i, mode_out, r, g, b, a);
3898 getPixelColorsRGBA8(out, numpixels, in, mode_in);
3900 getPixelColorsRGB8(out, numpixels, in, mode_in);
3902 unsigned char r = 0, g = 0, b = 0, a = 0;
3903 for(i = 0; i != numpixels; ++i) {
3904 getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in);
3905 error = rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a);
3912 color_tree_cleanup(&tree);
3926 unsigned* r_out,
unsigned* g_out,
unsigned* b_out,
3927 unsigned r_in,
unsigned g_in,
unsigned b_in,
3929 unsigned r = 0, g = 0, b = 0;
3930 unsigned mul = 65535 / ((1u << mode_in->
bitdepth) - 1u);
3931 unsigned shift = 16 - mode_out->
bitdepth;
3934 r = g = b = r_in * mul;
3941 r = mode_in->
palette[r_in * 4 + 0] * 257u;
3942 g = mode_in->
palette[r_in * 4 + 1] * 257u;
3943 b = mode_in->
palette[r_in * 4 + 2] * 257u;
3950 *r_out = r >> shift ;
3952 *r_out = r >> shift ;
3953 *g_out = g >> shift ;
3954 *b_out = b >> shift ;
3958 if((r >> 8) != (r & 255) || (g >> 8) != (g & 255) || (b >> 8) != (b & 255))
return 82;
3961 if((r >> 8) == mode_out->
palette[j + 0] && (g >> 8) == mode_out->
palette[j + 1] &&
3962 (b >> 8) == mode_out->
palette[j + 2]) {
3975#ifdef LODEPNG_COMPILE_ENCODER
4004static unsigned getValueRequiredBits(
unsigned char value) {
4007 if(
value % 17 == 0)
return value % 85 == 0 ? 2 : 4;
4013 const unsigned char* in,
unsigned w,
unsigned h,
4017 size_t numpixels = (
size_t)w * (
size_t)h;
4023 unsigned numcolors_done = 0;
4025 unsigned bits_done = (stats->
bits == 1 && bpp == 1) ? 1 : 0;
4026 unsigned sixteen = 0;
4027 unsigned maxnumcolors = 257;
4035 color_tree_init(&tree);
4039 if(stats->
alpha) alpha_done = 1;
4040 if(stats->
colored) colored_done = 1;
4041 if(stats->
bits == 16) numcolors_done = 1;
4042 if(stats->
bits >= bpp) bits_done = 1;
4043 if(stats->
numcolors >= maxnumcolors) numcolors_done = 1;
4045 if(!numcolors_done) {
4047 const unsigned char* color = &stats->
palette[i * 4];
4048 error = color_tree_add(&tree, color[0], color[1], color[2], color[3], (
unsigned)i);
4049 if(error)
goto cleanup;
4054 if(mode_in->
bitdepth == 16 && !sixteen) {
4055 unsigned short r = 0, g = 0, b = 0, a = 0;
4056 for(i = 0; i != numpixels; ++i) {
4057 getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
4058 if((r & 255) != ((r >> 8) & 255) || (g & 255) != ((g >> 8) & 255) ||
4059 (b & 255) != ((b >> 8) & 255) || (a & 255) != ((a >> 8) & 255)) {
4070 unsigned short r = 0, g = 0, b = 0, a = 0;
4072 for(i = 0; i != numpixels; ++i) {
4073 getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
4075 if(!colored_done && (r != g || r != b)) {
4081 unsigned matchkey = (r == stats->
key_r && g == stats->
key_g && b == stats->
key_b);
4082 if(a != 65535 && (a != 0 || (stats->
key && !matchkey))) {
4086 }
else if(a == 0 && !stats->
alpha && !stats->
key) {
4091 }
else if(a == 65535 && stats->
key && matchkey) {
4098 if(alpha_done && numcolors_done && colored_done && bits_done)
break;
4102 for(i = 0; i != numpixels; ++i) {
4103 getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
4104 if(a != 0 && r == stats->
key_r && g == stats->
key_g && b == stats->
key_b) {
4113 unsigned char r = 0, g = 0, b = 0, a = 0;
4114 for(i = 0; i != numpixels; ++i) {
4115 getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in);
4117 if(!bits_done && stats->
bits < 8) {
4119 unsigned bits = getValueRequiredBits(r);
4120 if(bits > stats->
bits) stats->
bits = bits;
4122 bits_done = (stats->
bits >= bpp);
4124 if(!colored_done && (r != g || r != b)) {
4127 if(stats->
bits < 8) stats->
bits = 8;
4131 unsigned matchkey = (r == stats->
key_r && g == stats->
key_g && b == stats->
key_b);
4132 if(a != 255 && (a != 0 || (stats->
key && !matchkey))) {
4136 if(stats->
bits < 8) stats->
bits = 8;
4137 }
else if(a == 0 && !stats->
alpha && !stats->
key) {
4142 }
else if(a == 255 && stats->
key && matchkey) {
4147 if(stats->
bits < 8) stats->
bits = 8;
4151 if(!numcolors_done) {
4152 if(!color_tree_has(&tree, r, g, b, a)) {
4153 error = color_tree_add(&tree, r, g, b, a, stats->
numcolors);
4154 if(error)
goto cleanup;
4156 unsigned char* p = stats->
palette;
4164 numcolors_done = stats->
numcolors >= maxnumcolors;
4168 if(alpha_done && numcolors_done && colored_done && bits_done)
break;
4172 for(i = 0; i != numpixels; ++i) {
4173 getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in);
4174 if(a != 0 && r == stats->
key_r && g == stats->
key_g && b == stats->
key_b) {
4179 if(stats->
bits < 8) stats->
bits = 8;
4191 color_tree_cleanup(&tree);
4195#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4200 unsigned r,
unsigned g,
unsigned b,
unsigned a) {
4202 unsigned char image[8];
4205 image[0] = r >> 8; image[1] = r; image[2] = g >> 8; image[3] = g;
4206 image[4] = b >> 8; image[5] = b; image[6] = a >> 8; image[7] = a;
4226 unsigned palettebits;
4229 unsigned palette_ok, gray_ok;
4231 unsigned alpha = stats->
alpha;
4232 unsigned key = stats->
key;
4233 unsigned bits = stats->
bits;
4237 if(key && numpixels <= 16) {
4240 if(bits < 8) bits = 8;
4245 if(!gray_ok && bits < 8) bits = 8;
4248 palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8));
4249 palette_ok = n <= 256 && bits <= 8 && n != 0;
4250 if(numpixels < n * 2) palette_ok = 0;
4251 if(gray_ok && !alpha && bits <= palettebits) palette_ok = 0;
4255 const unsigned char* p = stats->
palette;
4257 for(i = 0; i != stats->
numcolors; ++i) {
4258 error =
lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]);
4276 unsigned mask = (1u << mode_out->
bitdepth) - 1u;
4290static unsigned char paethPredictor(
unsigned char a,
unsigned char b,
unsigned char c) {
4293 short pa = (b - c) < 0 ? -(b - c) : (b - c);
4294 short pb = (a - c) < 0 ? -(a - c) : (a - c);
4296 short pc = (a + b - c - c) < 0 ? -(a + b - c - c) : (a + b - c - c);
4298 if(pb < pa) { a = b; pa = pb; }
4299 return (pc < pa) ? c : a;
4304static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 };
4305static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 };
4306static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 };
4307static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 };
4324static void Adam7_getpassvalues(
unsigned passw[7],
unsigned passh[7],
size_t filter_passstart[8],
4325 size_t padded_passstart[8],
size_t passstart[8],
unsigned w,
unsigned h,
unsigned bpp) {
4330 for(i = 0; i != 7; ++i) {
4331 passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i];
4332 passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i];
4333 if(passw[i] == 0) passh[i] = 0;
4334 if(passh[i] == 0) passw[i] = 0;
4337 filter_passstart[0] = padded_passstart[0] = passstart[0] = 0;
4338 for(i = 0; i != 7; ++i) {
4340 filter_passstart[i + 1] = filter_passstart[i]
4341 + ((passw[i] && passh[i]) ? passh[i] * (1u + (passw[i] * bpp + 7u) / 8u) : 0);
4343 padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7u) / 8u);
4345 passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7u) / 8u;
4349#ifdef LODEPNG_COMPILE_DECODER
4357 const unsigned char* in,
size_t insize) {
4360 if(insize == 0 || in == 0) {
4372 if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71
4373 || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) {
4384 width = lodepng_read32bitInt(&in[16]);
4385 height = lodepng_read32bitInt(&in[20]);
4410 unsigned CRC = lodepng_read32bitInt(&in[29]);
4412 if(CRC != checksum) {
4417 return state->
error;
4420static unsigned unfilterScanline(
unsigned char* recon,
const unsigned char* scanline,
const unsigned char* precon,
4421 size_t bytewidth,
unsigned char filterType,
size_t length) {
4432 switch(filterType) {
4434 for(i = 0; i != length; ++i) recon[i] = scanline[i];
4438 for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
4439 for(i = bytewidth; i != length; ++i, ++j) recon[i] = scanline[i] + recon[j];
4444 for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i];
4446 for(i = 0; i != length; ++i) recon[i] = scanline[i];
4452 for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1u);
4455 if(bytewidth >= 4) {
4456 for(; i + 3 < length; i += 4, j += 4) {
4457 unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2], s3 = scanline[i + 3];
4458 unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2], r3 = recon[j + 3];
4459 unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2], p3 = precon[i + 3];
4460 recon[i + 0] = s0 + ((r0 + p0) >> 1u);
4461 recon[i + 1] = s1 + ((r1 + p1) >> 1u);
4462 recon[i + 2] = s2 + ((r2 + p2) >> 1u);
4463 recon[i + 3] = s3 + ((r3 + p3) >> 1u);
4465 }
else if(bytewidth >= 3) {
4466 for(; i + 2 < length; i += 3, j += 3) {
4467 unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2];
4468 unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2];
4469 unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2];
4470 recon[i + 0] = s0 + ((r0 + p0) >> 1u);
4471 recon[i + 1] = s1 + ((r1 + p1) >> 1u);
4472 recon[i + 2] = s2 + ((r2 + p2) >> 1u);
4474 }
else if(bytewidth >= 2) {
4475 for(; i + 1 < length; i += 2, j += 2) {
4476 unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1];
4477 unsigned char r0 = recon[j + 0], r1 = recon[j + 1];
4478 unsigned char p0 = precon[i + 0], p1 = precon[i + 1];
4479 recon[i + 0] = s0 + ((r0 + p0) >> 1u);
4480 recon[i + 1] = s1 + ((r1 + p1) >> 1u);
4483 for(; i != length; ++i, ++j) recon[i] = scanline[i] + ((recon[j] + precon[i]) >> 1u);
4486 for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
4487 for(i = bytewidth; i != length; ++i, ++j) recon[i] = scanline[i] + (recon[j] >> 1u);
4494 if(bytewidth == 8) {
4495 unsigned char a0, b0 = 0, c0, d0 = 0, a1, b1 = 0, c1, d1 = 0;
4496 unsigned char a2, b2 = 0, c2, d2 = 0, a3, b3 = 0, c3, d3 = 0;
4497 unsigned char a4, b4 = 0, c4, d4 = 0, a5, b5 = 0, c5, d5 = 0;
4498 unsigned char a6, b6 = 0, c6, d6 = 0, a7, b7 = 0, c7, d7 = 0;
4499 for(i = 0; i + 7 < length; i += 8) {
4500 c0 = b0; c1 = b1; c2 = b2; c3 = b3;
4501 c4 = b4; c5 = b5; c6 = b6; c7 = b7;
4502 b0 = precon[i + 0]; b1 = precon[i + 1]; b2 = precon[i + 2]; b3 = precon[i + 3];
4503 b4 = precon[i + 4]; b5 = precon[i + 5]; b6 = precon[i + 6]; b7 = precon[i + 7];
4504 a0 = d0; a1 = d1; a2 = d2; a3 = d3;
4505 a4 = d4; a5 = d5; a6 = d6; a7 = d7;
4506 d0 = scanline[i + 0] + paethPredictor(a0, b0, c0);
4507 d1 = scanline[i + 1] + paethPredictor(a1, b1, c1);
4508 d2 = scanline[i + 2] + paethPredictor(a2, b2, c2);
4509 d3 = scanline[i + 3] + paethPredictor(a3, b3, c3);
4510 d4 = scanline[i + 4] + paethPredictor(a4, b4, c4);
4511 d5 = scanline[i + 5] + paethPredictor(a5, b5, c5);
4512 d6 = scanline[i + 6] + paethPredictor(a6, b6, c6);
4513 d7 = scanline[i + 7] + paethPredictor(a7, b7, c7);
4514 recon[i + 0] = d0; recon[i + 1] = d1; recon[i + 2] = d2; recon[i + 3] = d3;
4515 recon[i + 4] = d4; recon[i + 5] = d5; recon[i + 6] = d6; recon[i + 7] = d7;
4517 }
else if(bytewidth == 6) {
4518 unsigned char a0, b0 = 0, c0, d0 = 0, a1, b1 = 0, c1, d1 = 0;
4519 unsigned char a2, b2 = 0, c2, d2 = 0, a3, b3 = 0, c3, d3 = 0;
4520 unsigned char a4, b4 = 0, c4, d4 = 0, a5, b5 = 0, c5, d5 = 0;
4521 for(i = 0; i + 5 < length; i += 6) {
4522 c0 = b0; c1 = b1; c2 = b2;
4523 c3 = b3; c4 = b4; c5 = b5;
4524 b0 = precon[i + 0]; b1 = precon[i + 1]; b2 = precon[i + 2];
4525 b3 = precon[i + 3]; b4 = precon[i + 4]; b5 = precon[i + 5];
4526 a0 = d0; a1 = d1; a2 = d2;
4527 a3 = d3; a4 = d4; a5 = d5;
4528 d0 = scanline[i + 0] + paethPredictor(a0, b0, c0);
4529 d1 = scanline[i + 1] + paethPredictor(a1, b1, c1);
4530 d2 = scanline[i + 2] + paethPredictor(a2, b2, c2);
4531 d3 = scanline[i + 3] + paethPredictor(a3, b3, c3);
4532 d4 = scanline[i + 4] + paethPredictor(a4, b4, c4);
4533 d5 = scanline[i + 5] + paethPredictor(a5, b5, c5);
4534 recon[i + 0] = d0; recon[i + 1] = d1; recon[i + 2] = d2;
4535 recon[i + 3] = d3; recon[i + 4] = d4; recon[i + 5] = d5;
4537 }
else if(bytewidth == 4) {
4538 unsigned char a0, b0 = 0, c0, d0 = 0, a1, b1 = 0, c1, d1 = 0;
4539 unsigned char a2, b2 = 0, c2, d2 = 0, a3, b3 = 0, c3, d3 = 0;
4540 for(i = 0; i + 3 < length; i += 4) {
4541 c0 = b0; c1 = b1; c2 = b2; c3 = b3;
4542 b0 = precon[i + 0]; b1 = precon[i + 1]; b2 = precon[i + 2]; b3 = precon[i + 3];
4543 a0 = d0; a1 = d1; a2 = d2; a3 = d3;
4544 d0 = scanline[i + 0] + paethPredictor(a0, b0, c0);
4545 d1 = scanline[i + 1] + paethPredictor(a1, b1, c1);
4546 d2 = scanline[i + 2] + paethPredictor(a2, b2, c2);
4547 d3 = scanline[i + 3] + paethPredictor(a3, b3, c3);
4548 recon[i + 0] = d0; recon[i + 1] = d1; recon[i + 2] = d2; recon[i + 3] = d3;
4550 }
else if(bytewidth == 3) {
4551 unsigned char a0, b0 = 0, c0, d0 = 0;
4552 unsigned char a1, b1 = 0, c1, d1 = 0;
4553 unsigned char a2, b2 = 0, c2, d2 = 0;
4554 for(i = 0; i + 2 < length; i += 3) {
4555 c0 = b0; c1 = b1; c2 = b2;
4556 b0 = precon[i + 0]; b1 = precon[i + 1]; b2 = precon[i + 2];
4557 a0 = d0; a1 = d1; a2 = d2;
4558 d0 = scanline[i + 0] + paethPredictor(a0, b0, c0);
4559 d1 = scanline[i + 1] + paethPredictor(a1, b1, c1);
4560 d2 = scanline[i + 2] + paethPredictor(a2, b2, c2);
4561 recon[i + 0] = d0; recon[i + 1] = d1; recon[i + 2] = d2;
4563 }
else if(bytewidth == 2) {
4564 unsigned char a0, b0 = 0, c0, d0 = 0;
4565 unsigned char a1, b1 = 0, c1, d1 = 0;
4566 for(i = 0; i + 1 < length; i += 2) {
4571 d0 = scanline[i + 0] + paethPredictor(a0, b0, c0);
4572 d1 = scanline[i + 1] + paethPredictor(a1, b1, c1);
4576 }
else if(bytewidth == 1) {
4577 unsigned char a, b = 0, c, d = 0;
4578 for(i = 0; i != length; ++i) {
4582 d = scanline[i] + paethPredictor(a, b, c);
4587 for(i = 0; i != bytewidth; ++i) {
4588 recon[i] = (scanline[i] + precon[i]);
4592 for(; i != length; ++i) {
4593 recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
4597 for(i = 0; i != bytewidth; ++i) {
4598 recon[i] = scanline[i];
4600 for(i = bytewidth; i != length; ++i, ++j) {
4602 recon[i] = (scanline[i] + recon[j]);
4611static unsigned unfilter(
unsigned char* out,
const unsigned char* in,
unsigned w,
unsigned h,
unsigned bpp) {
4621 unsigned char* prevline = 0;
4624 size_t bytewidth = (bpp + 7u) / 8u;
4626 size_t linebytes = lodepng_get_raw_size_idat(w, 1, bpp) - 1u;
4628 for(
y = 0;
y < h; ++
y) {
4629 size_t outindex = linebytes *
y;
4630 size_t inindex = (1 + linebytes) *
y;
4631 unsigned char filterType = in[inindex];
4633 CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes));
4635 prevline = &out[outindex];
4652static void Adam7_deinterlace(
unsigned char* out,
const unsigned char* in,
unsigned w,
unsigned h,
unsigned bpp) {
4653 unsigned passw[7], passh[7];
4654 size_t filter_passstart[8], padded_passstart[8], passstart[8];
4657 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
4660 for(i = 0; i != 7; ++i) {
4662 size_t bytewidth = bpp / 8u;
4663 for(
y = 0;
y < passh[i]; ++
y)
4664 for(
x = 0;
x < passw[i]; ++
x) {
4665 size_t pixelinstart = passstart[i] + (
y * passw[i] +
x) * bytewidth;
4666 size_t pixeloutstart = ((ADAM7_IY[i] + (
size_t)
y * ADAM7_DY[i]) * (
size_t)w
4667 + ADAM7_IX[i] + (
size_t)
x * ADAM7_DX[i]) * bytewidth;
4668 for(b = 0; b < bytewidth; ++b) {
4669 out[pixeloutstart + b] = in[pixelinstart + b];
4674 for(i = 0; i != 7; ++i) {
4676 unsigned ilinebits = bpp * passw[i];
4677 unsigned olinebits = bpp * w;
4679 for(
y = 0;
y < passh[i]; ++
y)
4680 for(
x = 0;
x < passw[i]; ++
x) {
4681 ibp = (8 * passstart[i]) + (
y * ilinebits +
x * bpp);
4682 obp = (ADAM7_IY[i] + (
size_t)
y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + (
size_t)
x * ADAM7_DX[i]) * bpp;
4683 for(b = 0; b < bpp; ++b) {
4684 unsigned char bit = readBitFromReversedStream(&ibp, in);
4685 setBitOfReversedStream(&obp, out, bit);
4692static void removePaddingBits(
unsigned char* out,
const unsigned char* in,
4693 size_t olinebits,
size_t ilinebits,
unsigned h) {
4704 size_t diff = ilinebits - olinebits;
4705 size_t ibp = 0, obp = 0;
4706 for(
y = 0;
y < h; ++
y) {
4708 for(
x = 0;
x < olinebits; ++
x) {
4709 unsigned char bit = readBitFromReversedStream(&ibp, in);
4710 setBitOfReversedStream(&obp, out, bit);
4719static unsigned postProcessScanlines(
unsigned char* out,
unsigned char* in,
4720 unsigned w,
unsigned h,
const LodePNGInfo* info_png) {
4729 if(bpp == 0)
return 31;
4732 if(bpp < 8 && w * bpp != ((w * bpp + 7u) / 8u) * 8u) {
4734 removePaddingBits(out, in, w * bpp, ((w * bpp + 7u) / 8u) * 8u, h);
4739 unsigned passw[7], passh[7];
size_t filter_passstart[8], padded_passstart[8], passstart[8];
4742 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
4744 for(i = 0; i != 7; ++i) {
4745 CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp));
4751 removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp,
4752 ((passw[i] * bpp + 7u) / 8u) * 8u, passh[i]);
4756 Adam7_deinterlace(out, in, w, h, bpp);
4762static unsigned readChunk_PLTE(
LodePNGColorMode* color,
const unsigned char* data,
size_t chunkLength) {
4763 unsigned pos = 0, i;
4766 lodepng_color_mode_alloc_palette(color);
4773 color->
palette[4 * i + 0] = data[pos++];
4774 color->
palette[4 * i + 1] = data[pos++];
4775 color->
palette[4 * i + 2] = data[pos++];
4776 color->
palette[4 * i + 3] = 255;
4782static unsigned readChunk_tRNS(
LodePNGColorMode* color,
const unsigned char* data,
size_t chunkLength) {
4788 for(i = 0; i != chunkLength; ++i) color->
palette[4 * i + 3] = data[i];
4791 if(chunkLength != 2)
return 30;
4794 color->
key_r = color->
key_g = color->
key_b = 256u * data[0] + data[1];
4797 if(chunkLength != 6)
return 41;
4800 color->
key_r = 256u * data[0] + data[1];
4801 color->
key_g = 256u * data[2] + data[3];
4802 color->
key_b = 256u * data[4] + data[5];
4810#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4812static unsigned readChunk_bKGD(
LodePNGInfo* info,
const unsigned char* data,
size_t chunkLength) {
4815 if(chunkLength != 1)
return 43;
4824 if(chunkLength != 2)
return 44;
4831 if(chunkLength != 6)
return 45;
4844static unsigned readChunk_tEXt(
LodePNGInfo* info,
const unsigned char* data,
size_t chunkLength) {
4846 char *key = 0, *str = 0;
4849 unsigned length, string2_begin;
4852 while(length < chunkLength && data[length] != 0) ++length;
4857 key = (
char*)lodepng_malloc(length + 1);
4860 lodepng_memcpy(key, data, length);
4863 string2_begin = length + 1;
4865 length = (unsigned)(chunkLength < string2_begin ? 0 : chunkLength - string2_begin);
4866 str = (
char*)lodepng_malloc(length + 1);
4869 lodepng_memcpy(str, data + string2_begin, length);
4885 const unsigned char* data,
size_t chunkLength) {
4891 unsigned length, string2_begin;
4893 unsigned char* str = 0;
4897 for(length = 0; length < chunkLength && data[length] != 0; ++length) ;
4901 key = (
char*)lodepng_malloc(length + 1);
4904 lodepng_memcpy(key, data, length);
4909 string2_begin = length + 2;
4910 if(string2_begin > chunkLength)
CERROR_BREAK(error, 75);
4912 length = (unsigned)chunkLength - string2_begin;
4915 error = zlib_decompress(&str, &
size, 0, &data[string2_begin],
4916 length, &zlibsettings);
4920 error = lodepng_add_text_sized(info, key, (
char*)str,
size);
4932 const unsigned char* data,
size_t chunkLength) {
4939 unsigned length, begin, compressed;
4940 char *key = 0, *langtag = 0, *transkey = 0;
4948 for(length = 0; length < chunkLength && data[length] != 0; ++length) ;
4952 key = (
char*)lodepng_malloc(length + 1);
4955 lodepng_memcpy(key, data, length);
4959 compressed = data[length + 1];
4968 for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length;
4970 langtag = (
char*)lodepng_malloc(length + 1);
4973 lodepng_memcpy(langtag, data + begin, length);
4974 langtag[length] = 0;
4977 begin += length + 1;
4979 for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length;
4981 transkey = (
char*)lodepng_malloc(length + 1);
4984 lodepng_memcpy(transkey, data + begin, length);
4985 transkey[length] = 0;
4988 begin += length + 1;
4990 length = (unsigned)chunkLength < begin ? 0 : (unsigned)chunkLength - begin;
4993 unsigned char* str = 0;
4997 error = zlib_decompress(&str, &
size, 0, &data[begin],
4998 length, &zlibsettings);
5001 if(!error) error = lodepng_add_itext_sized(info, key, langtag, transkey, (
char*)str,
size);
5004 error = lodepng_add_itext_sized(info, key, langtag, transkey, (
char*)(data + begin), length);
5011 lodepng_free(langtag);
5012 lodepng_free(transkey);
5017static unsigned readChunk_tIME(
LodePNGInfo* info,
const unsigned char* data,
size_t chunkLength) {
5018 if(chunkLength != 7)
return 73;
5021 info->
time.
year = 256u * data[0] + data[1];
5031static unsigned readChunk_pHYs(
LodePNGInfo* info,
const unsigned char* data,
size_t chunkLength) {
5032 if(chunkLength != 9)
return 74;
5035 info->
phys_x = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3];
5036 info->
phys_y = 16777216u * data[4] + 65536u * data[5] + 256u * data[6] + data[7];
5042static unsigned readChunk_gAMA(
LodePNGInfo* info,
const unsigned char* data,
size_t chunkLength) {
5043 if(chunkLength != 4)
return 96;
5046 info->
gama_gamma = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3];
5051static unsigned readChunk_cHRM(
LodePNGInfo* info,
const unsigned char* data,
size_t chunkLength) {
5052 if(chunkLength != 32)
return 97;
5055 info->
chrm_white_x = 16777216u * data[ 0] + 65536u * data[ 1] + 256u * data[ 2] + data[ 3];
5056 info->
chrm_white_y = 16777216u * data[ 4] + 65536u * data[ 5] + 256u * data[ 6] + data[ 7];
5057 info->
chrm_red_x = 16777216u * data[ 8] + 65536u * data[ 9] + 256u * data[10] + data[11];
5058 info->
chrm_red_y = 16777216u * data[12] + 65536u * data[13] + 256u * data[14] + data[15];
5059 info->
chrm_green_x = 16777216u * data[16] + 65536u * data[17] + 256u * data[18] + data[19];
5060 info->
chrm_green_y = 16777216u * data[20] + 65536u * data[21] + 256u * data[22] + data[23];
5061 info->
chrm_blue_x = 16777216u * data[24] + 65536u * data[25] + 256u * data[26] + data[27];
5062 info->
chrm_blue_y = 16777216u * data[28] + 65536u * data[29] + 256u * data[30] + data[31];
5067static unsigned readChunk_sRGB(
LodePNGInfo* info,
const unsigned char* data,
size_t chunkLength) {
5068 if(chunkLength != 1)
return 98;
5077 const unsigned char* data,
size_t chunkLength) {
5084 unsigned length, string2_begin;
5089 for(length = 0; length < chunkLength && data[length] != 0; ++length) ;
5090 if(length + 2 >= chunkLength)
return 75;
5091 if(length < 1 || length > 79)
return 89;
5093 info->
iccp_name = (
char*)lodepng_malloc(length + 1);
5097 for(i = 0; i != length; ++i) info->
iccp_name[i] = (
char)data[i];
5099 if(data[length + 1] != 0)
return 72;
5101 string2_begin = length + 2;
5102 if(string2_begin > chunkLength)
return 75;
5104 length = (unsigned)chunkLength - string2_begin;
5107 &data[string2_begin],
5108 length, &zlibsettings);
5117static unsigned readChunk_sBIT(
LodePNGInfo* info,
const unsigned char* data,
size_t chunkLength) {
5121 if(chunkLength != 1)
return 114;
5122 if(data[0] == 0 || data[0] > bitdepth)
return 115;
5127 if(chunkLength != 3)
return 114;
5128 if(data[0] == 0 || data[1] == 0 || data[2] == 0)
return 115;
5129 if(data[0] > bitdepth || data[1] > bitdepth || data[2] > bitdepth)
return 115;
5136 if(chunkLength != 2)
return 114;
5137 if(data[0] == 0 || data[1] == 0)
return 115;
5138 if(data[0] > bitdepth || data[1] > bitdepth)
return 115;
5144 if(chunkLength != 4)
return 114;
5145 if(data[0] == 0 || data[1] == 0 || data[2] == 0 || data[3] == 0)
return 115;
5146 if(data[0] > bitdepth || data[1] > bitdepth || data[2] > bitdepth || data[3] > bitdepth)
return 115;
5159 const unsigned char* in,
size_t insize) {
5160 const unsigned char* chunk = in + pos;
5161 unsigned chunkLength;
5162 const unsigned char* data;
5163 unsigned unhandled = 0;
5166 if(pos + 4 > insize)
return 30;
5168 if(chunkLength > 2147483647)
return 63;
5170 if(chunkLength + 12 > insize - pos)
return 30;
5173 error = readChunk_PLTE(&state->
info_png.
color, data, chunkLength);
5175 error = readChunk_tRNS(&state->
info_png.
color, data, chunkLength);
5176#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5178 error = readChunk_bKGD(&state->
info_png, data, chunkLength);
5180 error = readChunk_tEXt(&state->
info_png, data, chunkLength);
5182 error = readChunk_zTXt(&state->
info_png, &state->
decoder, data, chunkLength);
5184 error = readChunk_iTXt(&state->
info_png, &state->
decoder, data, chunkLength);
5186 error = readChunk_tIME(&state->
info_png, data, chunkLength);
5188 error = readChunk_pHYs(&state->
info_png, data, chunkLength);
5190 error = readChunk_gAMA(&state->
info_png, data, chunkLength);
5192 error = readChunk_cHRM(&state->
info_png, data, chunkLength);
5194 error = readChunk_sRGB(&state->
info_png, data, chunkLength);
5196 error = readChunk_iCCP(&state->
info_png, &state->
decoder, data, chunkLength);
5198 error = readChunk_sBIT(&state->
info_png, data, chunkLength);
5213static void decodeGeneric(
unsigned char** out,
unsigned* w,
unsigned* h,
5215 const unsigned char* in,
size_t insize) {
5216 unsigned char IEND = 0;
5217 const unsigned char* chunk;
5218 unsigned char* idat;
5219 size_t idatsize = 0;
5220 unsigned char* scanlines = 0;
5221 size_t scanlines_size = 0, expected_size = 0;
5225 unsigned unknown = 0;
5226#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5227 unsigned critical_pos = 1;
5236 if(state->
error)
return;
5243 idat = (
unsigned char*)lodepng_malloc(insize);
5250 while(!IEND && !state->
error) {
5251 unsigned chunkLength;
5252 const unsigned char* data;
5253 size_t pos = (
size_t)(chunk - in);
5256 if(chunk < in || pos + 12 > insize) {
5264 if(chunkLength > 2147483647) {
5269 if(pos + (
size_t)chunkLength + 12 > insize || pos + (
size_t)chunkLength + 12 < pos) {
5280 if(lodepng_addofl(idatsize, chunkLength, &newsize))
CERROR_BREAK(state->
error, 95);
5282 lodepng_memcpy(idat + idatsize, data, chunkLength);
5283 idatsize += chunkLength;
5284#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5293 if(state->
error)
break;
5294#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5302 if(state->
error)
break;
5303#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5306 state->
error = readChunk_bKGD(&state->
info_png, data, chunkLength);
5307 if(state->
error)
break;
5311 state->
error = readChunk_tEXt(&state->
info_png, data, chunkLength);
5312 if(state->
error)
break;
5318 if(state->
error)
break;
5324 if(state->
error)
break;
5327 state->
error = readChunk_tIME(&state->
info_png, data, chunkLength);
5328 if(state->
error)
break;
5330 state->
error = readChunk_pHYs(&state->
info_png, data, chunkLength);
5331 if(state->
error)
break;
5333 state->
error = readChunk_gAMA(&state->
info_png, data, chunkLength);
5334 if(state->
error)
break;
5336 state->
error = readChunk_cHRM(&state->
info_png, data, chunkLength);
5337 if(state->
error)
break;
5339 state->
error = readChunk_sRGB(&state->
info_png, data, chunkLength);
5340 if(state->
error)
break;
5343 if(state->
error)
break;
5345 state->
error = readChunk_sBIT(&state->
info_png, data, chunkLength);
5346 if(state->
error)
break;
5355#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5359 if(state->
error)
break;
5380 expected_size = lodepng_get_raw_size_idat(*w, *h, bpp);
5385 expected_size += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, bpp);
5386 if(*w > 4) expected_size += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, bpp);
5387 expected_size += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, bpp);
5388 if(*w > 2) expected_size += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, bpp);
5389 expected_size += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, bpp);
5390 if(*w > 1) expected_size += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, bpp);
5391 expected_size += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, bpp);
5394 state->
error = zlib_decompress(&scanlines, &scanlines_size, expected_size, idat, idatsize, &state->
decoder.
zlibsettings);
5396 if(!state->
error && scanlines_size != expected_size) state->
error = 91;
5401 *out = (
unsigned char*)lodepng_malloc(outsize);
5402 if(!*out) state->
error = 83;
5405 lodepng_memset(*out, 0, outsize);
5406 state->
error = postProcessScanlines(*out, scanlines, *w, *h, &state->
info_png);
5408 lodepng_free(scanlines);
5413 const unsigned char* in,
size_t insize) {
5415 decodeGeneric(out, w, h, state, in, insize);
5426 unsigned char* data = *out;
5437 *out = (
unsigned char*)lodepng_malloc(outsize);
5445 return state->
error;
5455#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5465unsigned lodepng_decode32(
unsigned char** out,
unsigned* w,
unsigned* h,
const unsigned char* in,
size_t insize) {
5469unsigned lodepng_decode24(
unsigned char** out,
unsigned* w,
unsigned* h,
const unsigned char* in,
size_t insize) {
5473#ifdef LODEPNG_COMPILE_DISK
5476 unsigned char* buffer = 0;
5484 lodepng_free(buffer);
5499#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5513#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER)
5516#ifdef LODEPNG_COMPILE_DECODER
5519#ifdef LODEPNG_COMPILE_ENCODER
5544#ifdef LODEPNG_COMPILE_ENCODER
5551static unsigned writeSignature(
ucvector* out) {
5552 size_t pos = out->
size;
5553 const unsigned char signature[] = {137, 80, 78, 71, 13, 10, 26, 10};
5555 if(!ucvector_resize(out, out->
size + 8))
return 83;
5560static unsigned addChunk_IHDR(
ucvector* out,
unsigned w,
unsigned h,
5561 LodePNGColorType colortype,
unsigned bitdepth,
unsigned interlace_method) {
5562 unsigned char *chunk, *data;
5566 lodepng_set32bitInt(data + 0, w);
5567 lodepng_set32bitInt(data + 4, h);
5568 data[8] = (
unsigned char)bitdepth;
5569 data[9] = (
unsigned char)colortype;
5572 data[12] = interlace_method;
5580 unsigned char* chunk;
5591 chunk[j++] = info->
palette[i * 4 + 0];
5592 chunk[j++] = info->
palette[i * 4 + 1];
5593 chunk[j++] = info->
palette[i * 4 + 2];
5601 unsigned char* chunk = 0;
5607 if(info->
palette[4 * (i - 1) + 3] != 255)
break;
5613 for(i = 0; i !=
amount; ++i) chunk[8 + i] = info->
palette[4 * i + 3];
5618 chunk[8] = (
unsigned char)(info->
key_r >> 8);
5619 chunk[9] = (
unsigned char)(info->
key_r & 255);
5624 chunk[8] = (
unsigned char)(info->
key_r >> 8);
5625 chunk[9] = (
unsigned char)(info->
key_r & 255);
5626 chunk[10] = (
unsigned char)(info->
key_g >> 8);
5627 chunk[11] = (
unsigned char)(info->
key_g & 255);
5628 chunk[12] = (
unsigned char)(info->
key_b >> 8);
5629 chunk[13] = (
unsigned char)(info->
key_b & 255);
5637static unsigned addChunk_IDAT(
ucvector* out,
const unsigned char* data,
size_t datasize,
5640 unsigned char* zlib = 0;
5641 size_t zlibsize = 0;
5643 error = zlib_compress(&zlib, &zlibsize, data, datasize, zlibsettings);
5645 error = lodepng_chunk_createv(out, zlibsize,
"IDAT", zlib);
5651static unsigned addChunk_IEND(
ucvector* out) {
5652 return lodepng_chunk_createv(out, 0,
"IEND", 0);
5655#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5657static unsigned addChunk_tEXt(
ucvector* out,
const char* keyword,
const char* textstring) {
5658 unsigned char* chunk = 0;
5659 size_t keysize = lodepng_strlen(keyword), textsize = lodepng_strlen(textstring);
5660 size_t size = keysize + 1 + textsize;
5661 if(keysize < 1 || keysize > 79)
return 89;
5663 lodepng_memcpy(chunk + 8, keyword, keysize);
5664 chunk[8 + keysize] = 0;
5665 lodepng_memcpy(chunk + 9 + keysize, textstring, textsize);
5670static unsigned addChunk_zTXt(
ucvector* out,
const char* keyword,
const char* textstring,
5673 unsigned char* chunk = 0;
5674 unsigned char* compressed = 0;
5675 size_t compressedsize = 0;
5676 size_t textsize = lodepng_strlen(textstring);
5677 size_t keysize = lodepng_strlen(keyword);
5678 if(keysize < 1 || keysize > 79)
return 89;
5680 error = zlib_compress(&compressed, &compressedsize,
5681 (
const unsigned char*)textstring, textsize, zlibsettings);
5683 size_t size = keysize + 2 + compressedsize;
5684 error = lodepng_chunk_init(&chunk, out,
size,
"zTXt");
5687 lodepng_memcpy(chunk + 8, keyword, keysize);
5688 chunk[8 + keysize] = 0;
5689 chunk[9 + keysize] = 0;
5690 lodepng_memcpy(chunk + 10 + keysize, compressed, compressedsize);
5694 lodepng_free(compressed);
5698static unsigned addChunk_iTXt(
ucvector* out,
unsigned compress,
const char* keyword,
const char* langtag,
5701 unsigned char* chunk = 0;
5702 unsigned char* compressed = 0;
5703 size_t compressedsize = 0;
5704 size_t textsize = lodepng_strlen(textstring);
5705 size_t keysize = lodepng_strlen(keyword), langsize = lodepng_strlen(langtag), transsize = lodepng_strlen(transkey);
5707 if(keysize < 1 || keysize > 79)
return 89;
5710 error = zlib_compress(&compressed, &compressedsize,
5711 (
const unsigned char*)textstring, textsize, zlibsettings);
5714 size_t size = keysize + 3 + langsize + 1 + transsize + 1 + (
compress ? compressedsize : textsize);
5715 error = lodepng_chunk_init(&chunk, out,
size,
"iTXt");
5719 lodepng_memcpy(chunk + pos, keyword, keysize);
5724 lodepng_memcpy(chunk + pos, langtag, langsize);
5727 lodepng_memcpy(chunk + pos, transkey, transsize);
5731 lodepng_memcpy(chunk + pos, compressed, compressedsize);
5733 lodepng_memcpy(chunk + pos, textstring, textsize);
5738 lodepng_free(compressed);
5743 unsigned char* chunk = 0;
5765 unsigned char* chunk;
5767 chunk[8] = (
unsigned char)(time->
year >> 8);
5768 chunk[9] = (
unsigned char)(time->
year & 255);
5769 chunk[10] = (
unsigned char)time->
month;
5770 chunk[11] = (
unsigned char)time->
day;
5771 chunk[12] = (
unsigned char)time->
hour;
5772 chunk[13] = (
unsigned char)time->
minute;
5773 chunk[14] = (
unsigned char)time->second;
5779 unsigned char* chunk;
5781 lodepng_set32bitInt(chunk + 8, info->
phys_x);
5782 lodepng_set32bitInt(chunk + 12, info->
phys_y);
5789 unsigned char* chunk;
5791 lodepng_set32bitInt(chunk + 8, info->
gama_gamma);
5797 unsigned char* chunk;
5801 lodepng_set32bitInt(chunk + 16, info->
chrm_red_x);
5802 lodepng_set32bitInt(chunk + 20, info->
chrm_red_y);
5805 lodepng_set32bitInt(chunk + 32, info->
chrm_blue_x);
5806 lodepng_set32bitInt(chunk + 36, info->
chrm_blue_y);
5813 return lodepng_chunk_createv(out, 1,
"sRGB", &data);
5818 unsigned char* chunk = 0;
5819 unsigned char* compressed = 0;
5820 size_t compressedsize = 0;
5821 size_t keysize = lodepng_strlen(info->
iccp_name);
5823 if(keysize < 1 || keysize > 79)
return 89;
5824 error = zlib_compress(&compressed, &compressedsize,
5827 size_t size = keysize + 2 + compressedsize;
5828 error = lodepng_chunk_init(&chunk, out,
size,
"iCCP");
5831 lodepng_memcpy(chunk + 8, info->
iccp_name, keysize);
5832 chunk[8 + keysize] = 0;
5833 chunk[9 + keysize] = 0;
5834 lodepng_memcpy(chunk + 10 + keysize, compressed, compressedsize);
5838 lodepng_free(compressed);
5844 unsigned char* chunk = 0;
5846 if(info->
sbit_r == 0 || info->
sbit_r > bitdepth)
return 115;
5851 if(info->
sbit_r > bitdepth || info->
sbit_g > bitdepth || info->
sbit_b > bitdepth)
return 115;
5855 chunk[10] = info->
sbit_b;
5858 if(info->
sbit_r > bitdepth || info->
sbit_a > bitdepth)
return 115;
5871 chunk[10] = info->
sbit_b;
5872 chunk[11] = info->
sbit_a;
5880static void filterScanline(
unsigned char* out,
const unsigned char* scanline,
const unsigned char* prevline,
5881 size_t length,
size_t bytewidth,
unsigned char filterType) {
5883 switch(filterType) {
5885 for(i = 0; i != length; ++i) out[i] = scanline[i];
5888 for(i = 0; i != bytewidth; ++i) out[i] = scanline[i];
5889 for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth];
5893 for(i = 0; i != length; ++i) out[i] = scanline[i] - prevline[i];
5895 for(i = 0; i != length; ++i) out[i] = scanline[i];
5900 for(i = 0; i != bytewidth; ++i) out[i] = scanline[i] - (prevline[i] >> 1);
5901 for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) >> 1);
5903 for(i = 0; i != bytewidth; ++i) out[i] = scanline[i];
5904 for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - (scanline[i - bytewidth] >> 1);
5910 for(i = 0; i != bytewidth; ++i) out[i] = (scanline[i] - prevline[i]);
5911 for(i = bytewidth; i < length; ++i) {
5912 out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth]));
5915 for(i = 0; i != bytewidth; ++i) out[i] = scanline[i];
5917 for(i = bytewidth; i < length; ++i) out[i] = (scanline[i] - scanline[i - bytewidth]);
5925static size_t ilog2(
size_t i) {
5927 if(i >= 65536) { result += 16; i >>= 16; }
5928 if(i >= 256) { result += 8; i >>= 8; }
5929 if(i >= 16) { result += 4; i >>= 4; }
5930 if(i >= 4) { result += 2; i >>= 2; }
5931 if(i >= 2) { result += 1; }
5936static size_t ilog2i(
size_t i) {
5938 if(i == 0)
return 0;
5942 return i * l + ((i - (((
size_t)1) << l)) << 1u);
5945static unsigned filter(
unsigned char* out,
const unsigned char* in,
unsigned w,
unsigned h,
5955 size_t linebytes = lodepng_get_raw_size_idat(w, 1, bpp) - 1u;
5958 size_t bytewidth = (bpp + 7u) / 8u;
5959 const unsigned char* prevline = 0;
5980 if(bpp == 0)
return 31;
5983 unsigned char type = (
unsigned char)strategy;
5984 for(
y = 0;
y != h; ++
y) {
5985 size_t outindex = (1 + linebytes) *
y;
5986 size_t inindex = linebytes *
y;
5987 out[outindex] =
type;
5988 filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth,
type);
5989 prevline = &in[inindex];
5993 unsigned char* attempt[5];
5994 size_t smallest = 0;
5995 unsigned char type, bestType = 0;
5998 attempt[
type] = (
unsigned char*)lodepng_malloc(linebytes);
5999 if(!attempt[
type]) error = 83;
6003 for(
y = 0;
y != h; ++
y) {
6007 filterScanline(attempt[
type], &in[
y * linebytes], prevline, linebytes, bytewidth,
type);
6011 for(
x = 0;
x != linebytes; ++
x) sum += (
unsigned char)(attempt[
type][
x]);
6013 for(
x = 0;
x != linebytes; ++
x) {
6017 unsigned char s = attempt[
type][
x];
6018 sum += s < 128 ? s : (255U - s);
6023 if(
type == 0 || sum < smallest) {
6029 prevline = &in[
y * linebytes];
6032 out[
y * (linebytes + 1)] = bestType;
6033 for(
x = 0;
x != linebytes; ++
x) out[
y * (linebytes + 1) + 1 +
x] = attempt[bestType][
x];
6039 unsigned char* attempt[5];
6041 unsigned type, bestType = 0;
6042 unsigned count[256];
6045 attempt[
type] = (
unsigned char*)lodepng_malloc(linebytes);
6046 if(!attempt[
type]) error = 83;
6050 for(
y = 0;
y != h; ++
y) {
6054 filterScanline(attempt[
type], &in[
y * linebytes], prevline, linebytes, bytewidth,
type);
6055 lodepng_memset(count, 0, 256 *
sizeof(*count));
6056 for(
x = 0;
x != linebytes; ++
x) ++count[attempt[
type][
x]];
6058 for(
x = 0;
x != 256; ++
x) {
6059 sum += ilog2i(count[
x]);
6062 if(
type == 0 || sum > bestSum) {
6068 prevline = &in[
y * linebytes];
6071 out[
y * (linebytes + 1)] = bestType;
6072 for(
x = 0;
x != linebytes; ++
x) out[
y * (linebytes + 1) + 1 +
x] = attempt[bestType][
x];
6078 for(
y = 0;
y != h; ++
y) {
6079 size_t outindex = (1 + linebytes) *
y;
6080 size_t inindex = linebytes *
y;
6082 out[outindex] =
type;
6083 filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth,
type);
6084 prevline = &in[inindex];
6091 unsigned char* attempt[5];
6092 size_t smallest = 0;
6093 unsigned type = 0, bestType = 0;
6094 unsigned char* dummy;
6101 zlibsettings.
btype = 1;
6107 attempt[
type] = (
unsigned char*)lodepng_malloc(linebytes);
6108 if(!attempt[
type]) error = 83;
6111 for(
y = 0;
y != h; ++
y) {
6113 unsigned testsize = (unsigned)linebytes;
6116 filterScanline(attempt[
type], &in[
y * linebytes], prevline, linebytes, bytewidth,
type);
6119 zlib_compress(&dummy, &
size[
type], attempt[
type], testsize, &zlibsettings);
6120 lodepng_free(dummy);
6127 prevline = &in[
y * linebytes];
6128 out[
y * (linebytes + 1)] = bestType;
6129 for(
x = 0;
x != linebytes; ++
x) out[
y * (linebytes + 1) + 1 +
x] = attempt[bestType][
x];
6139static void addPaddingBits(
unsigned char* out,
const unsigned char* in,
6140 size_t olinebits,
size_t ilinebits,
unsigned h) {
6144 size_t diff = olinebits - ilinebits;
6145 size_t obp = 0, ibp = 0;
6146 for(
y = 0;
y != h; ++
y) {
6148 for(
x = 0;
x < ilinebits; ++
x) {
6149 unsigned char bit = readBitFromReversedStream(&ibp, in);
6150 setBitOfReversedStream(&obp, out, bit);
6154 for(
x = 0;
x != diff; ++
x) setBitOfReversedStream(&obp, out, 0);
6169static void Adam7_interlace(
unsigned char* out,
const unsigned char* in,
unsigned w,
unsigned h,
unsigned bpp) {
6170 unsigned passw[7], passh[7];
6171 size_t filter_passstart[8], padded_passstart[8], passstart[8];
6174 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
6177 for(i = 0; i != 7; ++i) {
6179 size_t bytewidth = bpp / 8u;
6180 for(
y = 0;
y < passh[i]; ++
y)
6181 for(
x = 0;
x < passw[i]; ++
x) {
6182 size_t pixelinstart = ((ADAM7_IY[i] +
y * ADAM7_DY[i]) * w + ADAM7_IX[i] +
x * ADAM7_DX[i]) * bytewidth;
6183 size_t pixeloutstart = passstart[i] + (
y * passw[i] +
x) * bytewidth;
6184 for(b = 0; b < bytewidth; ++b) {
6185 out[pixeloutstart + b] = in[pixelinstart + b];
6190 for(i = 0; i != 7; ++i) {
6192 unsigned ilinebits = bpp * passw[i];
6193 unsigned olinebits = bpp * w;
6195 for(
y = 0;
y < passh[i]; ++
y)
6196 for(
x = 0;
x < passw[i]; ++
x) {
6197 ibp = (ADAM7_IY[i] +
y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] +
x * ADAM7_DX[i]) * bpp;
6198 obp = (8 * passstart[i]) + (
y * ilinebits +
x * bpp);
6199 for(b = 0; b < bpp; ++b) {
6200 unsigned char bit = readBitFromReversedStream(&ibp, in);
6201 setBitOfReversedStream(&obp, out, bit);
6210static unsigned preProcessScanlines(
unsigned char** out,
size_t* outsize,
const unsigned char* in,
6211 unsigned w,
unsigned h,
6222 *outsize = h + (h * ((w * bpp + 7u) / 8u));
6223 *out = (
unsigned char*)lodepng_malloc(*outsize);
6224 if(!(*out) && (*outsize)) error = 83;
6228 if(bpp < 8 && w * bpp != ((w * bpp + 7u) / 8u) * 8u) {
6229 unsigned char* padded = (
unsigned char*)lodepng_malloc(h * ((w * bpp + 7u) / 8u));
6230 if(!padded) error = 83;
6232 addPaddingBits(padded, in, ((w * bpp + 7u) / 8u) * 8u, w * bpp, h);
6233 error = filter(*out, padded, w, h, &info_png->
color, settings);
6235 lodepng_free(padded);
6238 error = filter(*out, in, w, h, &info_png->
color, settings);
6242 unsigned passw[7], passh[7];
6243 size_t filter_passstart[8], padded_passstart[8], passstart[8];
6244 unsigned char* adam7;
6246 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
6248 *outsize = filter_passstart[7];
6249 *out = (
unsigned char*)lodepng_malloc(*outsize);
6250 if(!(*out)) error = 83;
6252 adam7 = (
unsigned char*)lodepng_malloc(passstart[7]);
6253 if(!adam7 && passstart[7]) error = 83;
6258 Adam7_interlace(adam7, in, w, h, bpp);
6259 for(i = 0; i != 7; ++i) {
6261 unsigned char* padded = (
unsigned char*)lodepng_malloc(padded_passstart[i + 1] - padded_passstart[i]);
6263 addPaddingBits(padded, &adam7[passstart[i]],
6264 ((passw[i] * bpp + 7u) / 8u) * 8u, passw[i] * bpp, passh[i]);
6265 error = filter(&(*out)[filter_passstart[i]], padded,
6266 passw[i], passh[i], &info_png->
color, settings);
6267 lodepng_free(padded);
6269 error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]],
6270 passw[i], passh[i], &info_png->
color, settings);
6277 lodepng_free(adam7);
6283#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6284static unsigned addUnknownChunks(
ucvector* out,
unsigned char* data,
size_t datasize) {
6285 unsigned char* inchunk = data;
6286 while((
size_t)(inchunk - data) < datasize) {
6294static unsigned isGrayICCProfile(
const unsigned char* profile,
unsigned size) {
6304 if(
size < 20)
return 0;
6305 return profile[16] ==
'G' && profile[17] ==
'R' && profile[18] ==
'A' && profile[19] ==
'Y';
6308static unsigned isRGBICCProfile(
const unsigned char* profile,
unsigned size) {
6310 if(
size < 20)
return 0;
6311 return profile[16] ==
'R' && profile[17] ==
'G' && profile[18] ==
'B' && profile[19] ==
' ';
6316 const unsigned char* image,
unsigned w,
unsigned h,
6318 unsigned char* data = 0;
6319 size_t datasize = 0;
6320 ucvector outv = ucvector_init(NULL, 0);
6352 if(state->
error)
goto cleanup;
6354 if(state->
error)
goto cleanup;
6360 unsigned allow_convert = 1;
6362#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6376 if(state->
error)
goto cleanup;
6377#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6380 unsigned r = 0, g = 0, b = 0;
6384 state->
error = lodepng_color_stats_add(&stats, r, g, b, 65535);
6385 if(state->
error)
goto cleanup;
6388 state->
error = auto_choose_color(&auto_color, &state->
info_raw, &stats);
6389 if(state->
error)
goto cleanup;
6390#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6417 info_png->
sbit_a == 8 && sbit_max <= 8) {
6450#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6462#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6467 if(!gray_icc && !rgb_icc) {
6471 if(gray_icc != gray_png) {
6479 if(!lodepng_color_mode_equal(&state->
info_raw, &info.
color)) {
6480 unsigned char* converted;
6483 converted = (
unsigned char*)lodepng_malloc(
size);
6484 if(!converted &&
size) state->
error = 83;
6489 state->
error = preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->
encoder);
6491 lodepng_free(converted);
6492 if(state->
error)
goto cleanup;
6494 state->
error = preProcessScanlines(&data, &datasize, image, w, h, &info, &state->
encoder);
6495 if(state->
error)
goto cleanup;
6499#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6503 state->
error = writeSignature(&outv);
6504 if(state->
error)
goto cleanup;
6507 if(state->
error)
goto cleanup;
6508#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6512 if(state->
error)
goto cleanup;
6517 if(state->
error)
goto cleanup;
6520 state->
error = addChunk_sRGB(&outv, &info);
6521 if(state->
error)
goto cleanup;
6524 state->
error = addChunk_gAMA(&outv, &info);
6525 if(state->
error)
goto cleanup;
6528 state->
error = addChunk_cHRM(&outv, &info);
6529 if(state->
error)
goto cleanup;
6532 state->
error = addChunk_sBIT(&outv, &info);
6533 if(state->
error)
goto cleanup;
6538 state->
error = addChunk_PLTE(&outv, &info.
color);
6539 if(state->
error)
goto cleanup;
6543 state->
error = addChunk_PLTE(&outv, &info.
color);
6544 if(state->
error)
goto cleanup;
6547 state->
error = addChunk_tRNS(&outv, &info.
color);
6548 if(state->
error)
goto cleanup;
6549#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6552 state->
error = addChunk_bKGD(&outv, &info);
6553 if(state->
error)
goto cleanup;
6557 state->
error = addChunk_pHYs(&outv, &info);
6558 if(state->
error)
goto cleanup;
6564 if(state->
error)
goto cleanup;
6569 if(state->
error)
goto cleanup;
6570#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6573 state->
error = addChunk_tIME(&outv, &info.
time);
6574 if(state->
error)
goto cleanup;
6577 for(i = 0; i != info.
text_num; ++i) {
6578 if(lodepng_strlen(info.
text_keys[i]) > 79) {
6582 if(lodepng_strlen(info.
text_keys[i]) < 1) {
6588 if(state->
error)
goto cleanup;
6591 if(state->
error)
goto cleanup;
6596 unsigned already_added_id_text = 0;
6597 for(i = 0; i != info.
text_num; ++i) {
6600 if(k[0] ==
'L' && k[1] ==
'o' && k[2] ==
'd' && k[3] ==
'e' &&
6601 k[4] ==
'P' && k[5] ==
'N' && k[6] ==
'G' && k[7] ==
'\0') {
6602 already_added_id_text = 1;
6606 if(already_added_id_text == 0) {
6608 if(state->
error)
goto cleanup;
6613 if(lodepng_strlen(info.
itext_keys[i]) > 79) {
6621 state->
error = addChunk_iTXt(
6625 if(state->
error)
goto cleanup;
6631 if(state->
error)
goto cleanup;
6634 state->
error = addChunk_IEND(&outv);
6635 if(state->
error)
goto cleanup;
6645 *outsize = outv.
size;
6647 return state->
error;
6660 error = state.
error;
6665unsigned lodepng_encode32(
unsigned char** out,
size_t* outsize,
const unsigned char* image,
unsigned w,
unsigned h) {
6669unsigned lodepng_encode24(
unsigned char** out,
size_t* outsize,
const unsigned char* image,
unsigned w,
unsigned h) {
6673#ifdef LODEPNG_COMPILE_DISK
6676 unsigned char* buffer;
6680 lodepng_free(buffer);
6700#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6709#ifdef LODEPNG_COMPILE_ERROR_TEXT
6716 case 0:
return "no error, everything went ok";
6717 case 1:
return "nothing done yet";
6718 case 10:
return "end of input memory reached without huffman end code";
6719 case 11:
return "error in code tree made it jump outside of huffman tree";
6720 case 13:
return "problem while processing dynamic deflate block";
6721 case 14:
return "problem while processing dynamic deflate block";
6722 case 15:
return "problem while processing dynamic deflate block";
6724 case 16:
return "invalid code while processing dynamic deflate block";
6725 case 17:
return "end of out buffer memory reached while inflating";
6726 case 18:
return "invalid distance code while inflating";
6727 case 19:
return "end of out buffer memory reached while inflating";
6728 case 20:
return "invalid deflate block BTYPE encountered while decoding";
6729 case 21:
return "NLEN is not ones complement of LEN in a deflate block";
6735 case 22:
return "end of out buffer memory reached while inflating";
6736 case 23:
return "end of in buffer memory reached while inflating";
6737 case 24:
return "invalid FCHECK in zlib header";
6738 case 25:
return "invalid compression method in zlib header";
6739 case 26:
return "FDICT encountered in zlib header while it's not used for PNG";
6740 case 27:
return "PNG file is smaller than a PNG header";
6742 case 28:
return "incorrect PNG signature, it's no PNG or corrupted";
6743 case 29:
return "first chunk is not the header chunk";
6744 case 30:
return "chunk length too large, chunk broken off at end of file";
6745 case 31:
return "illegal PNG color type or bpp";
6746 case 32:
return "illegal PNG compression method";
6747 case 33:
return "illegal PNG filter method";
6748 case 34:
return "illegal PNG interlace method";
6749 case 35:
return "chunk length of a chunk is too large or the chunk too small";
6750 case 36:
return "illegal PNG filter type encountered";
6751 case 37:
return "illegal bit depth for this color type given";
6752 case 38:
return "the palette is too small or too big";
6753 case 39:
return "tRNS chunk before PLTE or has more entries than palette size";
6754 case 40:
return "tRNS chunk has wrong size for grayscale image";
6755 case 41:
return "tRNS chunk has wrong size for RGB image";
6756 case 42:
return "tRNS chunk appeared while it was not allowed for this color type";
6757 case 43:
return "bKGD chunk has wrong size for palette image";
6758 case 44:
return "bKGD chunk has wrong size for grayscale image";
6759 case 45:
return "bKGD chunk has wrong size for RGB image";
6760 case 48:
return "empty input buffer given to decoder. Maybe caused by non-existing file?";
6761 case 49:
return "jumped past memory while generating dynamic huffman tree";
6762 case 50:
return "jumped past memory while generating dynamic huffman tree";
6763 case 51:
return "jumped past memory while inflating huffman block";
6764 case 52:
return "jumped past memory while inflating";
6765 case 53:
return "size of zlib data too small";
6766 case 54:
return "repeat symbol in tree while there was no value symbol yet";
6770 case 55:
return "jumped past tree while generating huffman tree";
6771 case 56:
return "given output image colortype or bitdepth not supported for color conversion";
6772 case 57:
return "invalid CRC encountered (checking CRC can be disabled)";
6773 case 58:
return "invalid ADLER32 encountered (checking ADLER32 can be disabled)";
6774 case 59:
return "requested color conversion not supported";
6775 case 60:
return "invalid window size given in the settings of the encoder (must be 0-32768)";
6776 case 61:
return "invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)";
6778 case 62:
return "conversion from color to grayscale not supported";
6780 case 63:
return "length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk";
6782 case 64:
return "the length of the END symbol 256 in the Huffman tree is 0";
6783 case 66:
return "the length of a text chunk keyword given to the encoder is longer than the maximum of 79 bytes";
6784 case 67:
return "the length of a text chunk keyword given to the encoder is smaller than the minimum of 1 byte";
6785 case 68:
return "tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors";
6786 case 69:
return "unknown chunk type with 'critical' flag encountered by the decoder";
6787 case 71:
return "invalid interlace mode given to encoder (must be 0 or 1)";
6788 case 72:
return "while decoding, invalid compression method encountering in zTXt or iTXt chunk (it must be 0)";
6789 case 73:
return "invalid tIME chunk size";
6790 case 74:
return "invalid pHYs chunk size";
6792 case 75:
return "no null termination char found while decoding text chunk";
6793 case 76:
return "iTXt chunk too short to contain required bytes";
6794 case 77:
return "integer overflow in buffer size";
6795 case 78:
return "failed to open file for reading";
6796 case 79:
return "failed to open file for writing";
6797 case 80:
return "tried creating a tree of 0 symbols";
6798 case 81:
return "lazy matching at pos 0 is impossible";
6799 case 82:
return "color conversion to palette requested while a color isn't in palette, or index out of bounds";
6800 case 83:
return "memory allocation failed";
6801 case 84:
return "given image too small to contain all pixels to be encoded";
6802 case 86:
return "impossible offset in lz77 encoding (internal bug)";
6803 case 87:
return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined";
6804 case 88:
return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy";
6805 case 89:
return "text chunk keyword too short or long: must have size 1-79";
6807 case 90:
return "windowsize must be a power of two";
6808 case 91:
return "invalid decompressed idat size";
6809 case 92:
return "integer overflow due to too many pixels";
6810 case 93:
return "zero width or height is invalid";
6811 case 94:
return "header chunk must have a size of 13 bytes";
6812 case 95:
return "integer overflow with combined idat chunk size";
6813 case 96:
return "invalid gAMA chunk size";
6814 case 97:
return "invalid cHRM chunk size";
6815 case 98:
return "invalid sRGB chunk size";
6816 case 99:
return "invalid sRGB rendering intent";
6817 case 100:
return "invalid ICC profile color type, the PNG specification only allows RGB or GRAY";
6818 case 101:
return "PNG specification does not allow RGB ICC profile on gray color types and vice versa";
6819 case 102:
return "not allowed to set grayscale ICC profile with colored pixels by PNG specification";
6820 case 103:
return "invalid palette index in bKGD chunk. Maybe it came before PLTE chunk?";
6821 case 104:
return "invalid bKGD color while encoding (e.g. palette index out of range)";
6822 case 105:
return "integer overflow of bitsize";
6823 case 106:
return "PNG file must have PLTE chunk if color type is palette";
6824 case 107:
return "color convert from palette mode requested without setting the palette data in it";
6825 case 108:
return "tried to add more than 256 values to a palette";
6827 case 109:
return "tried to decompress zlib or deflate data larger than desired max_output_size";
6828 case 110:
return "custom zlib or inflate decompression failed";
6829 case 111:
return "custom zlib or deflate compression failed";
6832 case 112:
return "compressed text unreasonably large";
6835 case 113:
return "ICC profile unreasonably large";
6836 case 114:
return "sBIT chunk has wrong size for the color type of the image";
6837 case 115:
return "sBIT value out of range";
6839 return "unknown error code";
6849#ifdef LODEPNG_COMPILE_CPP
6852#ifdef LODEPNG_COMPILE_DISK
6853unsigned load_file(std::vector<unsigned char>& buffer,
const std::string& filename) {
6854 long size = lodepng_filesize(filename.c_str());
6855 if(
size < 0)
return 78;
6856 buffer.resize((
size_t)
size);
6857 return size == 0 ? 0 : lodepng_buffer_file(&buffer[0], (
size_t)
size, filename.c_str());
6861unsigned save_file(
const std::vector<unsigned char>& buffer,
const std::string& filename) {
6862 return lodepng_save_file(buffer.empty() ? 0 : &buffer[0], buffer.size(), filename.c_str());
6866#ifdef LODEPNG_COMPILE_ZLIB
6867#ifdef LODEPNG_COMPILE_DECODER
6868unsigned decompress(std::vector<unsigned char>& out,
const unsigned char* in,
size_t insize,
6870 unsigned char* buffer = 0;
6871 size_t buffersize = 0;
6872 unsigned error = zlib_decompress(&buffer, &buffersize, 0, in, insize, &settings);
6874 out.insert(out.end(), buffer, &buffer[buffersize]);
6875 lodepng_free(buffer);
6880unsigned decompress(std::vector<unsigned char>& out,
const std::vector<unsigned char>& in,
6882 return decompress(out, in.empty() ? 0 : &in[0], in.size(), settings);
6886#ifdef LODEPNG_COMPILE_ENCODER
6887unsigned compress(std::vector<unsigned char>& out,
const unsigned char* in,
size_t insize,
6889 unsigned char* buffer = 0;
6890 size_t buffersize = 0;
6891 unsigned error = zlib_compress(&buffer, &buffersize, in, insize, &settings);
6893 out.insert(out.end(), buffer, &buffer[buffersize]);
6894 lodepng_free(buffer);
6899unsigned compress(std::vector<unsigned char>& out,
const std::vector<unsigned char>& in,
6901 return compress(out, in.empty() ? 0 : &in[0], in.size(), settings);
6907#ifdef LODEPNG_COMPILE_PNG
6913State::State(
const State& other) {
6922State& State::operator=(
const State& other) {
6927#ifdef LODEPNG_COMPILE_DECODER
6929unsigned decode(std::vector<unsigned char>& out,
unsigned& w,
unsigned& h,
const unsigned char* in,
6931 unsigned char* buffer = 0;
6933 if(buffer && !error) {
6936 state.info_raw.bitdepth = bitdepth;
6938 out.insert(out.end(), buffer, &buffer[buffersize]);
6940 lodepng_free(buffer);
6944unsigned decode(std::vector<unsigned char>& out,
unsigned& w,
unsigned& h,
6945 const std::vector<unsigned char>& in,
LodePNGColorType colortype,
unsigned bitdepth) {
6946 return decode(out, w, h, in.empty() ? 0 : &in[0], (
unsigned)in.size(), colortype, bitdepth);
6949unsigned decode(std::vector<unsigned char>& out,
unsigned& w,
unsigned& h,
6951 const unsigned char* in,
size_t insize) {
6952 unsigned char* buffer = NULL;
6953 unsigned error =
lodepng_decode(&buffer, &w, &h, &state, in, insize);
6954 if(buffer && !error) {
6956 out.insert(out.end(), buffer, &buffer[buffersize]);
6958 lodepng_free(buffer);
6962unsigned decode(std::vector<unsigned char>& out,
unsigned& w,
unsigned& h,
6964 const std::vector<unsigned char>& in) {
6965 return decode(out, w, h, state, in.empty() ? 0 : &in[0], in.size());
6968#ifdef LODEPNG_COMPILE_DISK
6969unsigned decode(std::vector<unsigned char>& out,
unsigned& w,
unsigned& h,
const std::string& filename,
6971 std::vector<unsigned char> buffer;
6974 unsigned error = load_file(buffer, filename);
6975 if(error)
return error;
6976 return decode(out, w, h, buffer, colortype, bitdepth);
6981#ifdef LODEPNG_COMPILE_ENCODER
6982unsigned encode(std::vector<unsigned char>& out,
const unsigned char* in,
unsigned w,
unsigned h,
6984 unsigned char* buffer;
6988 out.insert(out.end(), buffer, &buffer[buffersize]);
6989 lodepng_free(buffer);
6994unsigned encode(std::vector<unsigned char>& out,
6995 const std::vector<unsigned char>& in,
unsigned w,
unsigned h,
6997 if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size())
return 84;
6998 return encode(out, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth);
7001unsigned encode(std::vector<unsigned char>& out,
7002 const unsigned char* in,
unsigned w,
unsigned h,
7004 unsigned char* buffer;
7006 unsigned error =
lodepng_encode(&buffer, &buffersize, in, w, h, &state);
7008 out.insert(out.end(), buffer, &buffer[buffersize]);
7009 lodepng_free(buffer);
7014unsigned encode(std::vector<unsigned char>& out,
7015 const std::vector<unsigned char>& in,
unsigned w,
unsigned h,
7018 return encode(out, in.empty() ? 0 : &in[0], w, h, state);
7021#ifdef LODEPNG_COMPILE_DISK
7022unsigned encode(
const std::string& filename,
7023 const unsigned char* in,
unsigned w,
unsigned h,
7025 std::vector<unsigned char> buffer;
7026 unsigned error = encode(buffer, in, w, h, colortype, bitdepth);
7027 if(!error) error = save_file(buffer, filename);
7031unsigned encode(
const std::string& filename,
7032 const std::vector<unsigned char>& in,
unsigned w,
unsigned h,
7034 if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size())
return 84;
7035 return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth);
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len)
int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
int ZEXPORT deflate(z_streamp strm, int flush)
unsigned lodepng_encode_file(const char *filename, const unsigned char *image, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth)
unsigned lodepng_encode32_file(const char *filename, const unsigned char *image, unsigned w, unsigned h)
unsigned lodepng_chunk_check_crc(const unsigned char *chunk)
unsigned lodepng_inspect_chunk(LodePNGState *state, size_t pos, const unsigned char *in, size_t insize)
#define LODEPNG_MAX(a, b)
unsigned lodepng_palette_add(LodePNGColorMode *info, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
const LodePNGCompressSettings lodepng_default_compress_settings
unsigned lodepng_inspect(unsigned *w, unsigned *h, LodePNGState *state, const unsigned char *in, size_t insize)
unsigned lodepng_add_text(LodePNGInfo *info, const char *key, const char *str)
unsigned lodepng_info_copy(LodePNGInfo *dest, const LodePNGInfo *source)
void lodepng_clear_icc(LodePNGInfo *info)
unsigned char * lodepng_chunk_next(unsigned char *chunk, unsigned char *end)
unsigned char * lodepng_chunk_find(unsigned char *chunk, unsigned char *end, const char type[5])
#define CERROR_RETURN_ERROR(errorvar, code)
#define NUM_CODE_LENGTH_CODES
unsigned lodepng_chunk_create(unsigned char **out, size_t *outsize, size_t length, const char *type, const unsigned char *data)
unsigned char lodepng_chunk_private(const unsigned char *chunk)
void lodepng_palette_clear(LodePNGColorMode *info)
void lodepng_chunk_type(char type[5], const unsigned char *chunk)
unsigned char lodepng_chunk_safetocopy(const unsigned char *chunk)
struct HuffmanTree HuffmanTree
unsigned lodepng_decode32_file(unsigned char **out, unsigned *w, unsigned *h, const char *filename)
unsigned lodepng_encode24(unsigned char **out, size_t *outsize, const unsigned char *image, unsigned w, unsigned h)
LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth)
unsigned lodepng_has_palette_alpha(const LodePNGColorMode *info)
unsigned lodepng_encode24_file(const char *filename, const unsigned char *image, unsigned w, unsigned h)
unsigned char lodepng_chunk_type_equals(const unsigned char *chunk, const char *type)
void lodepng_clear_text(LodePNGInfo *info)
size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode *color)
#define NUM_DEFLATE_CODE_SYMBOLS
#define NUM_DISTANCE_SYMBOLS
const unsigned char * lodepng_chunk_data_const(const unsigned char *chunk)
void lodepng_chunk_generate_crc(unsigned char *chunk)
unsigned char * lodepng_chunk_data(unsigned char *chunk)
#define WRITEBIT(writer, bit)
unsigned lodepng_decode_memory(unsigned char **out, unsigned *w, unsigned *h, const unsigned char *in, size_t insize, LodePNGColorType colortype, unsigned bitdepth)
void lodepng_color_mode_init(LodePNGColorMode *info)
unsigned lodepng_decode32(unsigned char **out, unsigned *w, unsigned *h, const unsigned char *in, size_t insize)
#define ERROR_BREAK(code)
unsigned lodepng_convert_rgb(unsigned *r_out, unsigned *g_out, unsigned *b_out, unsigned r_in, unsigned g_in, unsigned b_in, const LodePNGColorMode *mode_out, const LodePNGColorMode *mode_in)
unsigned lodepng_decode_file(unsigned char **out, unsigned *w, unsigned *h, const char *filename, LodePNGColorType colortype, unsigned bitdepth)
unsigned lodepng_deflate(unsigned char **out, size_t *outsize, const unsigned char *in, size_t insize, const LodePNGCompressSettings *settings)
void lodepng_compress_settings_init(LodePNGCompressSettings *settings)
unsigned lodepng_decode(unsigned char **out, unsigned *w, unsigned *h, LodePNGState *state, const unsigned char *in, size_t insize)
unsigned lodepng_zlib_compress(unsigned char **out, size_t *outsize, const unsigned char *in, size_t insize, const LodePNGCompressSettings *settings)
void lodepng_state_cleanup(LodePNGState *state)
unsigned lodepng_encode32(unsigned char **out, size_t *outsize, const unsigned char *image, unsigned w, unsigned h)
unsigned lodepng_color_mode_copy(LodePNGColorMode *dest, const LodePNGColorMode *source)
void lodepng_color_stats_init(LodePNGColorStats *stats)
unsigned lodepng_huffman_code_lengths(unsigned *lengths, const unsigned *frequencies, size_t numcodes, unsigned maxbitlen)
unsigned lodepng_get_bpp(const LodePNGColorMode *info)
unsigned lodepng_save_file(const unsigned char *buffer, size_t buffersize, const char *filename)
#define CERROR_TRY_RETURN(call)
void lodepng_encoder_settings_init(LodePNGEncoderSettings *settings)
void lodepng_state_copy(LodePNGState *dest, const LodePNGState *source)
const unsigned char * lodepng_chunk_next_const(const unsigned char *chunk, const unsigned char *end)
const char * LODEPNG_VERSION_STRING
unsigned lodepng_encode(unsigned char **out, size_t *outsize, const unsigned char *image, unsigned w, unsigned h, LodePNGState *state)
unsigned lodepng_crc32(const unsigned char *data, size_t length)
void lodepng_decoder_settings_init(LodePNGDecoderSettings *settings)
unsigned lodepng_can_have_alpha(const LodePNGColorMode *info)
#define DEFAULT_WINDOWSIZE
unsigned lodepng_inflate(unsigned char **out, size_t *outsize, const unsigned char *in, size_t insize, const LodePNGDecompressSettings *settings)
unsigned lodepng_is_alpha_type(const LodePNGColorMode *info)
const LodePNGDecompressSettings lodepng_default_decompress_settings
unsigned lodepng_compute_color_stats(LodePNGColorStats *stats, const unsigned char *in, unsigned w, unsigned h, const LodePNGColorMode *mode_in)
unsigned char lodepng_chunk_ancillary(const unsigned char *chunk)
unsigned lodepng_add_itext(LodePNGInfo *info, const char *key, const char *langtag, const char *transkey, const char *str)
unsigned lodepng_decode24_file(unsigned char **out, unsigned *w, unsigned *h, const char *filename)
void lodepng_color_mode_cleanup(LodePNGColorMode *info)
void lodepng_decompress_settings_init(LodePNGDecompressSettings *settings)
unsigned lodepng_get_channels(const LodePNGColorMode *info)
unsigned lodepng_convert(unsigned char *out, const unsigned char *in, const LodePNGColorMode *mode_out, const LodePNGColorMode *mode_in, unsigned w, unsigned h)
#define CERROR_RETURN(errorvar, code)
unsigned lodepng_chunk_append(unsigned char **out, size_t *outsize, const unsigned char *chunk)
const char * lodepng_error_text(unsigned code)
#define FIRST_LENGTH_CODE_INDEX
void lodepng_info_cleanup(LodePNGInfo *info)
unsigned lodepng_chunk_length(const unsigned char *chunk)
unsigned lodepng_decode24(unsigned char **out, unsigned *w, unsigned *h, const unsigned char *in, size_t insize)
#define LODEPNG_MIN(a, b)
unsigned lodepng_is_palette_type(const LodePNGColorMode *info)
unsigned lodepng_encode_memory(unsigned char **out, size_t *outsize, const unsigned char *image, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth)
#define LAST_LENGTH_CODE_INDEX
unsigned lodepng_is_greyscale_type(const LodePNGColorMode *info)
void lodepng_state_init(LodePNGState *state)
void lodepng_info_init(LodePNGInfo *info)
unsigned lodepng_zlib_decompress(unsigned char **out, size_t *outsize, const unsigned char *in, size_t insize, const LodePNGDecompressSettings *settings)
const unsigned char * lodepng_chunk_find_const(const unsigned char *chunk, const unsigned char *end, const char type[5])
void lodepng_clear_itext(LodePNGInfo *info)
unsigned lodepng_set_icc(LodePNGInfo *info, const char *name, const unsigned char *profile, unsigned profile_size)
unsigned lodepng_load_file(unsigned char **out, size_t *outsize, const char *filename)
#define CERROR_BREAK(errorvar, code)
unsigned short * table_value
unsigned char * table_len
const unsigned char * data
LodePNGColorType colortype
unsigned char palette[1024]
unsigned(* custom_zlib)(unsigned char **, size_t *, const unsigned char *, size_t, const LodePNGCompressSettings *)
unsigned(* custom_deflate)(unsigned char **, size_t *, const unsigned char *, size_t, const LodePNGCompressSettings *)
const void * custom_context
unsigned remember_unknown_chunks
LodePNGDecompressSettings zlibsettings
unsigned read_text_chunks
unsigned(* custom_inflate)(unsigned char **, size_t *, const unsigned char *, size_t, const LodePNGDecompressSettings *)
const void * custom_context
unsigned(* custom_zlib)(unsigned char **, size_t *, const unsigned char *, size_t, const LodePNGDecompressSettings *)
unsigned filter_palette_zero
LodePNGCompressSettings zlibsettings
const unsigned char * predefined_filters
LodePNGFilterStrategy filter_strategy
unsigned text_compression
unsigned iccp_profile_size
size_t unknown_chunks_size[3]
unsigned compression_method
unsigned char * iccp_profile
unsigned interlace_method
unsigned char * unknown_chunks_data[3]
unsigned background_defined
LodePNGColorMode info_raw
LodePNGDecoderSettings decoder
LodePNGEncoderSettings encoder