34 #ifdef XEMU_USE_LODEPNG
41 #if defined(_MSC_VER) && (_MSC_VER >= 1310)
42 #pragma warning( disable : 4244 )
43 #pragma warning( disable : 4996 )
46 const char* LODEPNG_VERSION_STRING =
"20150418";
66 #ifdef LODEPNG_COMPILE_ALLOCATORS
67 static void* lodepng_malloc(
size_t size)
72 static void* lodepng_realloc(
void* ptr,
size_t new_size)
74 return realloc(ptr, new_size);
77 static void lodepng_free(
void* ptr)
82 void* lodepng_malloc(
size_t size);
83 void* lodepng_realloc(
void* ptr,
size_t new_size);
84 void lodepng_free(
void* ptr);
100 #define CERROR_BREAK(errorvar, code)\
107 #define ERROR_BREAK(code) CERROR_BREAK(error, code)
110 #define CERROR_RETURN_ERROR(errorvar, code)\
117 #define CERROR_TRY_RETURN(call)\
119 unsigned error = call;\
120 if(error) return error;\
124 #define CERROR_RETURN(errorvar, code)\
139 #ifdef LODEPNG_COMPILE_ZLIB
141 typedef struct uivector
148 static void uivector_cleanup(
void* p)
150 ((uivector*)p)->size = ((uivector*)p)->allocsize = 0;
151 lodepng_free(((uivector*)p)->
data);
152 ((uivector*)p)->data = NULL;
156 static unsigned uivector_reserve(uivector* p,
size_t allocsize)
158 if(allocsize > p->allocsize)
160 size_t newsize = (allocsize > p->allocsize * 2) ? allocsize : (allocsize * 3 / 2);
161 void*
data = lodepng_realloc(p->data, newsize);
164 p->allocsize = newsize;
165 p->data = (
unsigned*)
data;
173 static unsigned uivector_resize(uivector* p,
size_t size)
175 if(!uivector_reserve(p,
size *
sizeof(
unsigned)))
return 0;
181 static unsigned uivector_resizev(uivector* p,
size_t size,
unsigned value)
183 size_t oldsize = p->size, i;
184 if(!uivector_resize(p,
size))
return 0;
185 for(i = oldsize; i <
size; ++i) p->data[i] =
value;
189 static void uivector_init(uivector* p)
192 p->size = p->allocsize = 0;
195 #ifdef LODEPNG_COMPILE_ENCODER
197 static unsigned uivector_push_back(uivector* p,
unsigned c)
199 if(!uivector_resize(p, p->size + 1))
return 0;
200 p->data[p->size - 1] = c;
209 typedef struct ucvector
217 static unsigned ucvector_reserve(ucvector* p,
size_t allocsize)
219 if(allocsize > p->allocsize)
221 size_t newsize = (allocsize > p->allocsize * 2) ? allocsize : (allocsize * 3 / 2);
222 void*
data = lodepng_realloc(p->data, newsize);
225 p->allocsize = newsize;
226 p->data = (
unsigned char*)
data;
234 static unsigned ucvector_resize(ucvector* p,
size_t size)
236 if(!ucvector_reserve(p,
size *
sizeof(
unsigned char)))
return 0;
241 #ifdef LODEPNG_COMPILE_PNG
243 static void ucvector_cleanup(
void* p)
245 ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0;
246 lodepng_free(((ucvector*)p)->
data);
247 ((ucvector*)p)->data = NULL;
250 static void ucvector_init(ucvector* p)
253 p->size = p->allocsize = 0;
256 #ifdef LODEPNG_COMPILE_DECODER
258 static unsigned ucvector_resizev(ucvector* p,
size_t size,
unsigned char value)
260 size_t oldsize = p->size, i;
261 if(!ucvector_resize(p,
size))
return 0;
262 for(i = oldsize; i <
size; ++i) p->data[i] =
value;
268 #ifdef LODEPNG_COMPILE_ZLIB
271 static void ucvector_init_buffer(ucvector* p,
unsigned char* buffer,
size_t size)
274 p->allocsize = p->size =
size;
278 #if (defined(LODEPNG_COMPILE_PNG) && defined(LODEPNG_COMPILE_ANCILLARY_CHUNKS)) || defined(LODEPNG_COMPILE_ENCODER)
280 static unsigned ucvector_push_back(ucvector* p,
unsigned char c)
282 if(!ucvector_resize(p, p->size + 1))
return 0;
283 p->data[p->size - 1] = c;
291 #ifdef LODEPNG_COMPILE_PNG
292 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
294 static unsigned string_resize(
char** out,
size_t size)
296 char*
data = (
char*)lodepng_realloc(*out,
size + 1);
306 static void string_init(
char** out)
309 string_resize(out, 0);
313 static void string_cleanup(
char** out)
319 static void string_set(
char** out,
const char* in)
321 size_t insize = strlen(in), i;
322 if(string_resize(out, insize))
324 for(i = 0; i != insize; ++i)
335 unsigned lodepng_read32bitInt(
const unsigned char* buffer)
337 return (
unsigned)((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]);
340 #if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)
342 static void lodepng_set32bitInt(
unsigned char* buffer,
unsigned value)
344 buffer[0] = (
unsigned char)((
value >> 24) & 0xff);
345 buffer[1] = (
unsigned char)((
value >> 16) & 0xff);
346 buffer[2] = (
unsigned char)((
value >> 8) & 0xff);
347 buffer[3] = (
unsigned char)((
value ) & 0xff);
351 #ifdef LODEPNG_COMPILE_ENCODER
352 static void lodepng_add32bitInt(ucvector* buffer,
unsigned value)
354 ucvector_resize(buffer, buffer->size + 4);
355 lodepng_set32bitInt(&buffer->data[buffer->size - 4],
value);
363 #ifdef LODEPNG_COMPILE_DISK
365 unsigned lodepng_load_file(
unsigned char** out,
size_t* outsize,
const char* filename)
374 file = fopen(filename,
"rb");
378 fseek(file , 0 , SEEK_END);
384 *out = (
unsigned char*)lodepng_malloc((
size_t)
size);
385 if(
size && (*out)) (*outsize) = fread(*out, 1, (
size_t)
size, file);
388 if(!(*out) &&
size)
return 83;
393 unsigned lodepng_save_file(
const unsigned char* buffer,
size_t buffersize,
const char* filename)
396 file = fopen(filename,
"wb" );
398 fwrite((
char*)buffer , 1 , buffersize, file);
411 #ifdef LODEPNG_COMPILE_ZLIB
412 #ifdef LODEPNG_COMPILE_ENCODER
414 #define addBitToStream( bitpointer, bitstream, bit)\
417 if(((*bitpointer) & 7) == 0) ucvector_push_back(bitstream, (unsigned char)0);\
419 (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7));\
423 static void addBitsToStream(
size_t* bitpointer, ucvector* bitstream,
unsigned value,
size_t nbits)
426 for(i = 0; i != nbits; ++i) addBitToStream(bitpointer, bitstream, (
unsigned char)((
value >> i) & 1));
429 static void addBitsToStreamReversed(
size_t* bitpointer, ucvector* bitstream,
unsigned value,
size_t nbits)
432 for(i = 0; i != nbits; ++i) addBitToStream(bitpointer, bitstream, (
unsigned char)((
value >> (nbits - 1 - i)) & 1));
436 #ifdef LODEPNG_COMPILE_DECODER
438 #define READBIT(bitpointer, bitstream) ((bitstream[bitpointer >> 3] >> (bitpointer & 0x7)) & (unsigned char)1)
440 static unsigned char readBitFromStream(
size_t* bitpointer,
const unsigned char* bitstream)
442 unsigned char result = (
unsigned char)(READBIT(*bitpointer, bitstream));
447 static unsigned readBitsFromStream(
size_t* bitpointer,
const unsigned char* bitstream,
size_t nbits)
449 unsigned result = 0, i;
450 for(i = 0; i != nbits; ++i)
452 result += ((unsigned)READBIT(*bitpointer, bitstream)) << i;
463 #define FIRST_LENGTH_CODE_INDEX 257
464 #define LAST_LENGTH_CODE_INDEX 285
466 #define NUM_DEFLATE_CODE_SYMBOLS 288
468 #define NUM_DISTANCE_SYMBOLS 32
470 #define NUM_CODE_LENGTH_CODES 19
473 static const unsigned LENGTHBASE[29]
474 = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
475 67, 83, 99, 115, 131, 163, 195, 227, 258};
478 static const unsigned LENGTHEXTRA[29]
479 = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
480 4, 4, 4, 4, 5, 5, 5, 5, 0};
483 static const unsigned DISTANCEBASE[30]
484 = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513,
485 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
488 static const unsigned DISTANCEEXTRA[30]
489 = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
490 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
494 static const unsigned CLCL_ORDER[NUM_CODE_LENGTH_CODES]
495 = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
502 typedef struct HuffmanTree
524 static void HuffmanTree_init(HuffmanTree* tree)
531 static void HuffmanTree_cleanup(HuffmanTree* tree)
533 lodepng_free(tree->tree2d);
534 lodepng_free(tree->tree1d);
535 lodepng_free(tree->lengths);
539 static unsigned HuffmanTree_make2DTree(HuffmanTree* tree)
541 unsigned nodefilled = 0;
542 unsigned treepos = 0;
545 tree->tree2d = (
unsigned*)lodepng_malloc(tree->numcodes * 2 *
sizeof(
unsigned));
546 if(!tree->tree2d)
return 83;
558 for(n = 0; n < tree->numcodes * 2; ++n)
560 tree->tree2d[n] = 32767;
563 for(n = 0; n < tree->numcodes; ++n)
565 for(i = 0; i != tree->lengths[n]; ++i)
567 unsigned char bit = (
unsigned char)((tree->tree1d[n] >> (tree->lengths[n] - i - 1)) & 1);
569 if(treepos > 2147483647 || treepos + 2 > tree->numcodes)
return 55;
570 if(tree->tree2d[2 * treepos + bit] == 32767)
572 if(i + 1 == tree->lengths[n])
574 tree->tree2d[2 * treepos + bit] = n;
583 tree->tree2d[2 * treepos + bit] = nodefilled + tree->numcodes;
584 treepos = nodefilled;
587 else treepos = tree->tree2d[2 * treepos + bit] - tree->numcodes;
591 for(n = 0; n < tree->numcodes * 2; ++n)
593 if(tree->tree2d[n] == 32767) tree->tree2d[n] = 0;
604 static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree)
611 uivector_init(&blcount);
612 uivector_init(&nextcode);
614 tree->tree1d = (
unsigned*)lodepng_malloc(tree->numcodes *
sizeof(
unsigned));
615 if(!tree->tree1d) error = 83;
617 if(!uivector_resizev(&blcount, tree->maxbitlen + 1, 0)
618 || !uivector_resizev(&nextcode, tree->maxbitlen + 1, 0))
624 for(bits = 0; bits != tree->numcodes; ++bits) ++blcount.data[tree->lengths[bits]];
626 for(bits = 1; bits <= tree->maxbitlen; ++bits)
628 nextcode.data[bits] = (nextcode.data[bits - 1] + blcount.data[bits - 1]) << 1;
631 for(n = 0; n != tree->numcodes; ++n)
633 if(tree->lengths[n] != 0) tree->tree1d[n] = nextcode.data[tree->lengths[n]]++;
637 uivector_cleanup(&blcount);
638 uivector_cleanup(&nextcode);
640 if(!error)
return HuffmanTree_make2DTree(tree);
649 static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree,
const unsigned* bitlen,
650 size_t numcodes,
unsigned maxbitlen)
653 tree->lengths = (
unsigned*)lodepng_malloc(numcodes *
sizeof(
unsigned));
654 if(!tree->lengths)
return 83;
655 for(i = 0; i != numcodes; ++i) tree->lengths[i] = bitlen[i];
656 tree->numcodes = (
unsigned)numcodes;
657 tree->maxbitlen = maxbitlen;
658 return HuffmanTree_makeFromLengths2(tree);
661 #ifdef LODEPNG_COMPILE_ENCODER
667 typedef struct BPMNode
671 struct BPMNode* tail;
676 typedef struct BPMLists
691 static BPMNode* bpmnode_create(BPMLists* lists,
int weight,
unsigned index, BPMNode* tail)
697 if(lists->nextfree >= lists->numfree)
700 for(i = 0; i != lists->memsize; ++i) lists->memory[i].in_use = 0;
701 for(i = 0; i != lists->listsize; ++i)
704 for(node = lists->chains0[i]; node != 0; node = node->tail) node->in_use = 1;
705 for(node = lists->chains1[i]; node != 0; node = node->tail) node->in_use = 1;
709 for(i = 0; i != lists->memsize; ++i)
711 if(!lists->memory[i].in_use) lists->freelist[lists->numfree++] = &lists->memory[i];
716 result = lists->freelist[lists->nextfree++];
717 result->weight = weight;
718 result->index =
index;
723 static int bpmnode_compare(
const void* a,
const void* b)
725 int wa = ((
const BPMNode*)a)->weight;
726 int wb = ((
const BPMNode*)b)->weight;
727 if(wa < wb)
return -1;
728 if(wa > wb)
return 1;
730 return ((
const BPMNode*)a)->
index < ((
const BPMNode*)b)->
index ? 1 : -1;
734 static void boundaryPM(BPMLists* lists, BPMNode* leaves,
size_t numpresent,
int c,
int num)
736 unsigned lastindex = lists->chains1[c]->index;
740 if(lastindex >= numpresent)
return;
741 lists->chains0[c] = lists->chains1[c];
742 lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, 0);
747 int sum = lists->chains0[c - 1]->weight + lists->chains1[c - 1]->weight;
748 lists->chains0[c] = lists->chains1[c];
749 if(lastindex < numpresent && sum > leaves[lastindex].weight)
751 lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, lists->chains1[c]->tail);
754 lists->chains1[c] = bpmnode_create(lists, sum, lastindex, lists->chains1[c - 1]);
757 if(num + 1 < (
int)(2 * numpresent - 2))
759 boundaryPM(lists, leaves, numpresent, c - 1, num);
760 boundaryPM(lists, leaves, numpresent, c - 1, num);
765 unsigned lodepng_huffman_code_lengths(
unsigned* lengths,
const unsigned* frequencies,
766 size_t numcodes,
unsigned maxbitlen)
770 size_t numpresent = 0;
773 if(numcodes == 0)
return 80;
774 if((1u << maxbitlen) < numcodes)
return 80;
776 leaves = (BPMNode*)lodepng_malloc(numcodes *
sizeof(*leaves));
777 if(!leaves)
return 83;
779 for(i = 0; i != numcodes; ++i)
781 if(frequencies[i] > 0)
783 leaves[numpresent].weight = frequencies[i];
784 leaves[numpresent].index = i;
789 for(i = 0; i != numcodes; ++i) lengths[i] = 0;
798 lengths[0] = lengths[1] = 1;
800 else if(numpresent == 1)
802 lengths[leaves[0].index] = 1;
803 lengths[leaves[0].index == 0 ? 1 : 0] = 1;
810 qsort(leaves, numpresent,
sizeof(BPMNode), bpmnode_compare);
812 lists.listsize = maxbitlen;
813 lists.memsize = 2 * maxbitlen * (maxbitlen + 1);
815 lists.numfree = lists.memsize;
816 lists.memory = (BPMNode*)lodepng_malloc(lists.memsize *
sizeof(*lists.memory));
817 lists.freelist = (BPMNode**)lodepng_malloc(lists.memsize *
sizeof(BPMNode*));
818 lists.chains0 = (BPMNode**)lodepng_malloc(lists.listsize *
sizeof(BPMNode*));
819 lists.chains1 = (BPMNode**)lodepng_malloc(lists.listsize *
sizeof(BPMNode*));
820 if(!lists.memory || !lists.freelist || !lists.chains0 || !lists.chains1) error = 83;
824 for(i = 0; i != lists.memsize; ++i) lists.freelist[i] = &lists.memory[i];
826 bpmnode_create(&lists, leaves[0].weight, 1, 0);
827 bpmnode_create(&lists, leaves[1].weight, 2, 0);
829 for(i = 0; i != lists.listsize; ++i)
831 lists.chains0[i] = &lists.memory[0];
832 lists.chains1[i] = &lists.memory[1];
836 for(i = 2; i != 2 * numpresent - 2; ++i) boundaryPM(&lists, leaves, numpresent, maxbitlen - 1, i);
838 for(node = lists.chains1[maxbitlen - 1]; node; node = node->tail)
840 for(i = 0; i != node->index; ++i) ++lengths[leaves[i].
index];
844 lodepng_free(lists.memory);
845 lodepng_free(lists.freelist);
846 lodepng_free(lists.chains0);
847 lodepng_free(lists.chains1);
850 lodepng_free(leaves);
855 static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree,
const unsigned* frequencies,
856 size_t mincodes,
size_t numcodes,
unsigned maxbitlen)
859 while(!frequencies[numcodes - 1] && numcodes > mincodes) --numcodes;
860 tree->maxbitlen = maxbitlen;
861 tree->numcodes = (unsigned)numcodes;
862 tree->lengths = (
unsigned*)lodepng_realloc(tree->lengths, numcodes *
sizeof(
unsigned));
863 if(!tree->lengths)
return 83;
865 memset(tree->lengths, 0, numcodes *
sizeof(
unsigned));
867 error = lodepng_huffman_code_lengths(tree->lengths, frequencies, numcodes, maxbitlen);
868 if(!error) error = HuffmanTree_makeFromLengths2(tree);
872 static unsigned HuffmanTree_getCode(
const HuffmanTree* tree,
unsigned index)
874 return tree->tree1d[
index];
877 static unsigned HuffmanTree_getLength(
const HuffmanTree* tree,
unsigned index)
879 return tree->lengths[
index];
884 static unsigned generateFixedLitLenTree(HuffmanTree* tree)
886 unsigned i, error = 0;
887 unsigned* bitlen = (
unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS *
sizeof(
unsigned));
888 if(!bitlen)
return 83;
891 for(i = 0; i <= 143; ++i) bitlen[i] = 8;
892 for(i = 144; i <= 255; ++i) bitlen[i] = 9;
893 for(i = 256; i <= 279; ++i) bitlen[i] = 7;
894 for(i = 280; i <= 287; ++i) bitlen[i] = 8;
896 error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15);
898 lodepng_free(bitlen);
903 static unsigned generateFixedDistanceTree(HuffmanTree* tree)
905 unsigned i, error = 0;
906 unsigned* bitlen = (
unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS *
sizeof(
unsigned));
907 if(!bitlen)
return 83;
910 for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen[i] = 5;
911 error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15);
913 lodepng_free(bitlen);
917 #ifdef LODEPNG_COMPILE_DECODER
923 static unsigned huffmanDecodeSymbol(
const unsigned char* in,
size_t* bp,
924 const HuffmanTree* codetree,
size_t inbitlength)
926 unsigned treepos = 0, ct;
929 if(*bp >= inbitlength)
return (
unsigned)(-1);
934 ct = codetree->tree2d[(treepos << 1) + READBIT(*bp, in)];
936 if(ct < codetree->numcodes)
return ct;
937 else treepos = ct - codetree->numcodes;
939 if(treepos >= codetree->numcodes)
return (
unsigned)(-1);
944 #ifdef LODEPNG_COMPILE_DECODER
951 static void getTreeInflateFixed(HuffmanTree* tree_ll, HuffmanTree* tree_d)
954 generateFixedLitLenTree(tree_ll);
955 generateFixedDistanceTree(tree_d);
959 static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d,
960 const unsigned char* in,
size_t* bp,
size_t inlength)
964 unsigned n, HLIT, HDIST, HCLEN, i;
965 size_t inbitlength = inlength * 8;
968 unsigned* bitlen_ll = 0;
969 unsigned* bitlen_d = 0;
971 unsigned* bitlen_cl = 0;
974 if((*bp) + 14 > (inlength << 3))
return 49;
977 HLIT = readBitsFromStream(bp, in, 5) + 257;
979 HDIST = readBitsFromStream(bp, in, 5) + 1;
981 HCLEN = readBitsFromStream(bp, in, 4) + 4;
983 if((*bp) + HCLEN * 3 > (inlength << 3))
return 50;
985 HuffmanTree_init(&tree_cl);
991 bitlen_cl = (
unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES *
sizeof(
unsigned));
992 if(!bitlen_cl) ERROR_BREAK(83 );
994 for(i = 0; i != NUM_CODE_LENGTH_CODES; ++i)
996 if(i < HCLEN) bitlen_cl[CLCL_ORDER[i]] = readBitsFromStream(bp, in, 3);
997 else bitlen_cl[CLCL_ORDER[i]] = 0;
1000 error = HuffmanTree_makeFromLengths(&tree_cl, bitlen_cl, NUM_CODE_LENGTH_CODES, 7);
1004 bitlen_ll = (
unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS *
sizeof(
unsigned));
1005 bitlen_d = (
unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS *
sizeof(
unsigned));
1006 if(!bitlen_ll || !bitlen_d) ERROR_BREAK(83 );
1007 for(i = 0; i != NUM_DEFLATE_CODE_SYMBOLS; ++i) bitlen_ll[i] = 0;
1008 for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen_d[i] = 0;
1012 while(i < HLIT + HDIST)
1014 unsigned code = huffmanDecodeSymbol(in, bp, &tree_cl, inbitlength);
1017 if(i < HLIT) bitlen_ll[i] = code;
1018 else bitlen_d[i - HLIT] = code;
1023 unsigned replength = 3;
1026 if(i == 0) ERROR_BREAK(54);
1028 if((*bp + 2) > inbitlength) ERROR_BREAK(50);
1029 replength += readBitsFromStream(bp, in, 2);
1031 if(i < HLIT + 1)
value = bitlen_ll[i - 1];
1032 else value = bitlen_d[i - HLIT - 1];
1034 for(n = 0; n < replength; ++n)
1036 if(i >= HLIT + HDIST) ERROR_BREAK(13);
1037 if(i < HLIT) bitlen_ll[i] =
value;
1038 else bitlen_d[i - HLIT] =
value;
1044 unsigned replength = 3;
1045 if((*bp + 3) > inbitlength) ERROR_BREAK(50);
1046 replength += readBitsFromStream(bp, in, 3);
1049 for(n = 0; n < replength; ++n)
1051 if(i >= HLIT + HDIST) ERROR_BREAK(14);
1053 if(i < HLIT) bitlen_ll[i] = 0;
1054 else bitlen_d[i - HLIT] = 0;
1060 unsigned replength = 11;
1061 if((*bp + 7) > inbitlength) ERROR_BREAK(50);
1062 replength += readBitsFromStream(bp, in, 7);
1065 for(n = 0; n < replength; ++n)
1067 if(i >= HLIT + HDIST) ERROR_BREAK(15);
1069 if(i < HLIT) bitlen_ll[i] = 0;
1070 else bitlen_d[i - HLIT] = 0;
1076 if(code == (
unsigned)(-1))
1080 error = (*bp) > inbitlength ? 10 : 11;
1088 if(bitlen_ll[256] == 0) ERROR_BREAK(64);
1091 error = HuffmanTree_makeFromLengths(tree_ll, bitlen_ll, NUM_DEFLATE_CODE_SYMBOLS, 15);
1093 error = HuffmanTree_makeFromLengths(tree_d, bitlen_d, NUM_DISTANCE_SYMBOLS, 15);
1098 lodepng_free(bitlen_cl);
1099 lodepng_free(bitlen_ll);
1100 lodepng_free(bitlen_d);
1101 HuffmanTree_cleanup(&tree_cl);
1107 static unsigned inflateHuffmanBlock(ucvector* out,
const unsigned char* in,
size_t* bp,
1108 size_t* pos,
size_t inlength,
unsigned btype)
1111 HuffmanTree tree_ll;
1113 size_t inbitlength = inlength * 8;
1115 HuffmanTree_init(&tree_ll);
1116 HuffmanTree_init(&tree_d);
1118 if(btype == 1) getTreeInflateFixed(&tree_ll, &tree_d);
1119 else if(btype == 2) error = getTreeInflateDynamic(&tree_ll, &tree_d, in, bp, inlength);
1124 unsigned code_ll = huffmanDecodeSymbol(in, bp, &tree_ll, inbitlength);
1128 if(!ucvector_resize(out, (*pos) + 1)) ERROR_BREAK(83 );
1129 out->data[*pos] = (
unsigned char)code_ll;
1132 else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX)
1134 unsigned code_d, distance;
1135 unsigned numextrabits_l, numextrabits_d;
1136 size_t start, forward, backward, length;
1139 length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX];
1142 numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX];
1143 if((*bp + numextrabits_l) > inbitlength) ERROR_BREAK(51);
1144 length += readBitsFromStream(bp, in, numextrabits_l);
1147 code_d = huffmanDecodeSymbol(in, bp, &tree_d, inbitlength);
1150 if(code_ll == (
unsigned)(-1))
1154 error = (*bp) > inlength * 8 ? 10 : 11;
1159 distance = DISTANCEBASE[code_d];
1162 numextrabits_d = DISTANCEEXTRA[code_d];
1163 if((*bp + numextrabits_d) > inbitlength) ERROR_BREAK(51);
1164 distance += readBitsFromStream(bp, in, numextrabits_d);
1168 if(distance > start) ERROR_BREAK(52);
1169 backward = start - distance;
1171 if(!ucvector_resize(out, (*pos) + length)) ERROR_BREAK(83 );
1172 if (distance < length) {
1173 for(forward = 0; forward < length; ++forward)
1175 out->data[(*pos)++] = out->data[backward++];
1178 memcpy(out->data + *pos, out->data + backward, length);
1182 else if(code_ll == 256)
1190 error = ((*bp) > inlength * 8) ? 10 : 11;
1195 HuffmanTree_cleanup(&tree_ll);
1196 HuffmanTree_cleanup(&tree_d);
1201 static unsigned inflateNoCompression(ucvector* out,
const unsigned char* in,
size_t* bp,
size_t* pos,
size_t inlength)
1204 unsigned LEN, NLEN, n, error = 0;
1207 while(((*bp) & 0x7) != 0) ++(*bp);
1211 if(p + 4 >= inlength)
return 52;
1212 LEN = in[p] + 256u * in[p + 1]; p += 2;
1213 NLEN = in[p] + 256u * in[p + 1]; p += 2;
1216 if(LEN + NLEN != 65535)
return 21;
1218 if(!ucvector_resize(out, (*pos) + LEN))
return 83;
1221 if(p + LEN > inlength)
return 23;
1222 for(n = 0; n < LEN; ++n) out->data[(*pos)++] = in[p++];
1229 static unsigned lodepng_inflatev(ucvector* out,
1230 const unsigned char* in,
size_t insize,
1231 const LodePNGDecompressSettings* settings)
1235 unsigned BFINAL = 0;
1244 if(bp + 2 >= insize * 8)
return 52;
1245 BFINAL = readBitFromStream(&bp, in);
1246 BTYPE = 1u * readBitFromStream(&bp, in);
1247 BTYPE += 2u * readBitFromStream(&bp, in);
1249 if(BTYPE == 3)
return 20;
1250 else if(BTYPE == 0) error = inflateNoCompression(out, in, &bp, &pos, insize);
1251 else error = inflateHuffmanBlock(out, in, &bp, &pos, insize, BTYPE);
1253 if(error)
return error;
1259 unsigned lodepng_inflate(
unsigned char** out,
size_t* outsize,
1260 const unsigned char* in,
size_t insize,
1261 const LodePNGDecompressSettings* settings)
1265 ucvector_init_buffer(&v, *out, *outsize);
1266 error = lodepng_inflatev(&v, in, insize, settings);
1272 static unsigned inflate(
unsigned char** out,
size_t* outsize,
1273 const unsigned char* in,
size_t insize,
1274 const LodePNGDecompressSettings* settings)
1276 if(settings->custom_inflate)
1278 return settings->custom_inflate(out, outsize, in, insize, settings);
1282 return lodepng_inflate(out, outsize, in, insize, settings);
1288 #ifdef LODEPNG_COMPILE_ENCODER
1294 static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258;
1297 static void addHuffmanSymbol(
size_t* bp, ucvector* compressed,
unsigned code,
unsigned bitlen)
1299 addBitsToStreamReversed(bp, compressed, code, bitlen);
1304 static size_t searchCodeIndex(
const unsigned* array,
size_t array_size,
size_t value)
1312 size_t right = array_size - 1;
1313 while(left <= right)
1315 size_t mid = (left + right) / 2;
1316 if(array[mid] <=
value) left = mid + 1;
1317 else if(array[mid - 1] >
value) right = mid - 1;
1318 else return mid - 1;
1320 return array_size - 1;
1323 static void addLengthDistance(uivector* values,
size_t length,
size_t distance)
1331 unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length);
1332 unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]);
1333 unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance);
1334 unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]);
1336 uivector_push_back(values, length_code + FIRST_LENGTH_CODE_INDEX);
1337 uivector_push_back(values, extra_length);
1338 uivector_push_back(values, dist_code);
1339 uivector_push_back(values, extra_distance);
1344 static const unsigned HASH_NUM_VALUES = 65536;
1345 static const unsigned HASH_BIT_MASK = 65535;
1351 unsigned short* chain;
1357 unsigned short* chainz;
1358 unsigned short* zeros;
1361 static unsigned hash_init(Hash* hash,
unsigned windowsize)
1364 hash->head = (
int*)lodepng_malloc(
sizeof(
int) * HASH_NUM_VALUES);
1365 hash->val = (
int*)lodepng_malloc(
sizeof(
int) * windowsize);
1366 hash->chain = (
unsigned short*)lodepng_malloc(
sizeof(
unsigned short) * windowsize);
1368 hash->zeros = (
unsigned short*)lodepng_malloc(
sizeof(
unsigned short) * windowsize);
1369 hash->headz = (
int*)lodepng_malloc(
sizeof(
int) * (MAX_SUPPORTED_DEFLATE_LENGTH + 1));
1370 hash->chainz = (
unsigned short*)lodepng_malloc(
sizeof(
unsigned short) * windowsize);
1372 if(!hash->head || !hash->chain || !hash->val || !hash->headz|| !hash->chainz || !hash->zeros)
1378 for(i = 0; i != HASH_NUM_VALUES; ++i) hash->head[i] = -1;
1379 for(i = 0; i != windowsize; ++i) hash->val[i] = -1;
1380 for(i = 0; i != windowsize; ++i) hash->chain[i] = i;
1382 for(i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; ++i) hash->headz[i] = -1;
1383 for(i = 0; i != windowsize; ++i) hash->chainz[i] = i;
1388 static void hash_cleanup(Hash* hash)
1390 lodepng_free(hash->head);
1391 lodepng_free(hash->val);
1392 lodepng_free(hash->chain);
1394 lodepng_free(hash->zeros);
1395 lodepng_free(hash->headz);
1396 lodepng_free(hash->chainz);
1401 static unsigned getHash(
const unsigned char*
data,
size_t size,
size_t pos)
1403 unsigned result = 0;
1410 result ^= (unsigned)(
data[pos + 0] << 0u);
1411 result ^= (unsigned)(
data[pos + 1] << 4u);
1412 result ^= (unsigned)(
data[pos + 2] << 8u);
1415 if(pos >=
size)
return 0;
1416 amount =
size - pos;
1417 for(i = 0; i != amount; ++i) result ^= (
unsigned)(
data[pos + i] << (i * 8u));
1419 return result & HASH_BIT_MASK;
1422 static unsigned countZeros(
const unsigned char*
data,
size_t size,
size_t pos)
1424 const unsigned char* start =
data + pos;
1425 const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH;
1430 return (
unsigned)(
data - start);
1434 static void updateHashChain(Hash* hash,
size_t wpos,
unsigned hashval,
unsigned short numzeros)
1436 hash->val[wpos] = (int)hashval;
1437 if(hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval];
1438 hash->head[hashval] = wpos;
1440 hash->zeros[wpos] = numzeros;
1441 if(hash->headz[numzeros] != -1) hash->chainz[wpos] = hash->headz[numzeros];
1442 hash->headz[numzeros] = wpos;
1454 static unsigned encodeLZ77(uivector* out, Hash* hash,
1455 const unsigned char* in,
size_t inpos,
size_t insize,
unsigned windowsize,
1456 unsigned minmatch,
unsigned nicematch,
unsigned lazymatching)
1459 unsigned i, error = 0;
1461 unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8;
1462 unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64;
1464 unsigned usezeros = 1;
1465 unsigned numzeros = 0;
1470 unsigned lazylength = 0, lazyoffset = 0;
1472 unsigned current_offset, current_length;
1473 unsigned prev_offset;
1474 const unsigned char *lastptr, *foreptr, *backptr;
1477 if(windowsize == 0 || windowsize > 32768)
return 60;
1478 if((windowsize & (windowsize - 1)) != 0)
return 90;
1480 if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH;
1482 for(pos = inpos; pos < insize; ++pos)
1484 size_t wpos = pos & (windowsize - 1);
1485 unsigned chainlength = 0;
1487 hashval = getHash(in, insize, pos);
1489 if(usezeros && hashval == 0)
1491 if(numzeros == 0) numzeros = countZeros(in, insize, pos);
1492 else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros;
1499 updateHashChain(hash, wpos, hashval, numzeros);
1505 hashpos = hash->chain[wpos];
1507 lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH];
1513 if(chainlength++ >= maxchainlength)
break;
1514 current_offset = hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize;
1516 if(current_offset < prev_offset)
break;
1517 prev_offset = current_offset;
1518 if(current_offset > 0)
1522 backptr = &in[pos - current_offset];
1527 unsigned skip = hash->zeros[hashpos];
1528 if(skip > numzeros) skip = numzeros;
1533 while(foreptr != lastptr && *backptr == *foreptr)
1538 current_length = (unsigned)(foreptr - &in[pos]);
1540 if(current_length > length)
1542 length = current_length;
1543 offset = current_offset;
1546 if(current_length >= nicematch)
break;
1550 if(hashpos == hash->chain[hashpos])
break;
1552 if(numzeros >= 3 && length > numzeros)
1554 hashpos = hash->chainz[hashpos];
1555 if(hash->zeros[hashpos] != numzeros)
break;
1559 hashpos = hash->chain[hashpos];
1561 if(hash->val[hashpos] != (
int)hashval)
break;
1567 if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH)
1570 lazylength = length;
1571 lazyoffset = offset;
1577 if(pos == 0) ERROR_BREAK(81);
1578 if(length > lazylength + 1)
1581 if(!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 );
1585 length = lazylength;
1586 offset = lazyoffset;
1587 hash->head[hashval] = -1;
1588 hash->headz[numzeros] = -1;
1593 if(length >= 3 && offset > windowsize) ERROR_BREAK(86 );
1598 if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 );
1600 else if(length < minmatch || (length == 3 && offset > 4096))
1604 if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 );
1608 addLengthDistance(out, length, offset);
1609 for(i = 1; i < length; ++i)
1612 wpos = pos & (windowsize - 1);
1613 hashval = getHash(in, insize, pos);
1614 if(usezeros && hashval == 0)
1616 if(numzeros == 0) numzeros = countZeros(in, insize, pos);
1617 else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros;
1623 updateHashChain(hash, wpos, hashval, numzeros);
1633 static unsigned deflateNoCompression(ucvector* out,
const unsigned char*
data,
size_t datasize)
1638 size_t i, j, numdeflateblocks = (datasize + 65534) / 65535;
1639 unsigned datapos = 0;
1640 for(i = 0; i != numdeflateblocks; ++i)
1642 unsigned BFINAL, BTYPE, LEN, NLEN;
1643 unsigned char firstbyte;
1645 BFINAL = (i == numdeflateblocks - 1);
1648 firstbyte = (
unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1));
1649 ucvector_push_back(out, firstbyte);
1652 if(datasize - datapos < 65535) LEN = (unsigned)datasize - datapos;
1655 ucvector_push_back(out, (
unsigned char)(LEN % 256));
1656 ucvector_push_back(out, (
unsigned char)(LEN / 256));
1657 ucvector_push_back(out, (
unsigned char)(NLEN % 256));
1658 ucvector_push_back(out, (
unsigned char)(NLEN / 256));
1661 for(j = 0; j < 65535 && datapos < datasize; ++j)
1663 ucvector_push_back(out,
data[datapos++]);
1675 static void writeLZ77data(
size_t* bp, ucvector* out,
const uivector* lz77_encoded,
1676 const HuffmanTree* tree_ll,
const HuffmanTree* tree_d)
1679 for(i = 0; i != lz77_encoded->size; ++i)
1681 unsigned val = lz77_encoded->data[i];
1682 addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_ll, val), HuffmanTree_getLength(tree_ll, val));
1685 unsigned length_index = val - FIRST_LENGTH_CODE_INDEX;
1686 unsigned n_length_extra_bits = LENGTHEXTRA[length_index];
1687 unsigned length_extra_bits = lz77_encoded->data[++i];
1689 unsigned distance_code = lz77_encoded->data[++i];
1691 unsigned distance_index = distance_code;
1692 unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index];
1693 unsigned distance_extra_bits = lz77_encoded->data[++i];
1695 addBitsToStream(bp, out, length_extra_bits, n_length_extra_bits);
1696 addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_d, distance_code),
1697 HuffmanTree_getLength(tree_d, distance_code));
1698 addBitsToStream(bp, out, distance_extra_bits, n_distance_extra_bits);
1704 static unsigned deflateDynamic(ucvector* out,
size_t* bp, Hash* hash,
1705 const unsigned char*
data,
size_t datapos,
size_t dataend,
1706 const LodePNGCompressSettings* settings,
unsigned final)
1722 uivector lz77_encoded;
1723 HuffmanTree tree_ll;
1725 HuffmanTree tree_cl;
1726 uivector frequencies_ll;
1727 uivector frequencies_d;
1728 uivector frequencies_cl;
1729 uivector bitlen_lld;
1730 uivector bitlen_lld_e;
1735 size_t datasize = dataend - datapos;
1744 unsigned BFINAL =
final;
1745 size_t numcodes_ll, numcodes_d, i;
1746 unsigned HLIT, HDIST, HCLEN;
1748 uivector_init(&lz77_encoded);
1749 HuffmanTree_init(&tree_ll);
1750 HuffmanTree_init(&tree_d);
1751 HuffmanTree_init(&tree_cl);
1752 uivector_init(&frequencies_ll);
1753 uivector_init(&frequencies_d);
1754 uivector_init(&frequencies_cl);
1755 uivector_init(&bitlen_lld);
1756 uivector_init(&bitlen_lld_e);
1757 uivector_init(&bitlen_cl);
1763 if(settings->use_lz77)
1765 error = encodeLZ77(&lz77_encoded, hash,
data, datapos, dataend, settings->windowsize,
1766 settings->minmatch, settings->nicematch, settings->lazymatching);
1771 if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 );
1772 for(i = datapos; i < dataend; ++i) lz77_encoded.data[i] =
data[i];
1775 if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83 );
1776 if(!uivector_resizev(&frequencies_d, 30, 0)) ERROR_BREAK(83 );
1779 for(i = 0; i != lz77_encoded.size; ++i)
1781 unsigned symbol = lz77_encoded.data[i];
1782 ++frequencies_ll.data[symbol];
1785 unsigned dist = lz77_encoded.data[i + 2];
1786 ++frequencies_d.data[dist];
1790 frequencies_ll.data[256] = 1;
1793 error = HuffmanTree_makeFromFrequencies(&tree_ll, frequencies_ll.data, 257, frequencies_ll.size, 15);
1796 error = HuffmanTree_makeFromFrequencies(&tree_d, frequencies_d.data, 2, frequencies_d.size, 15);
1799 numcodes_ll = tree_ll.numcodes;
if(numcodes_ll > 286) numcodes_ll = 286;
1800 numcodes_d = tree_d.numcodes;
if(numcodes_d > 30) numcodes_d = 30;
1802 for(i = 0; i != numcodes_ll; ++i) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_ll, (
unsigned)i));
1803 for(i = 0; i != numcodes_d; ++i) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_d, (
unsigned)i));
1807 for(i = 0; i != (unsigned)bitlen_lld.size; ++i)
1810 while(i + j + 1 < (
unsigned)bitlen_lld.size && bitlen_lld.data[i + j + 1] == bitlen_lld.data[i]) ++j;
1812 if(bitlen_lld.data[i] == 0 && j >= 2)
1817 uivector_push_back(&bitlen_lld_e, 17);
1818 uivector_push_back(&bitlen_lld_e, j - 3);
1822 if(j > 138) j = 138;
1823 uivector_push_back(&bitlen_lld_e, 18);
1824 uivector_push_back(&bitlen_lld_e, j - 11);
1831 unsigned num = j / 6, rest = j % 6;
1832 uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]);
1833 for(k = 0; k < num; ++k)
1835 uivector_push_back(&bitlen_lld_e, 16);
1836 uivector_push_back(&bitlen_lld_e, 6 - 3);
1840 uivector_push_back(&bitlen_lld_e, 16);
1841 uivector_push_back(&bitlen_lld_e, rest - 3);
1848 uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]);
1854 if(!uivector_resizev(&frequencies_cl, NUM_CODE_LENGTH_CODES, 0)) ERROR_BREAK(83 );
1855 for(i = 0; i != bitlen_lld_e.size; ++i)
1857 ++frequencies_cl.data[bitlen_lld_e.data[i]];
1860 if(bitlen_lld_e.data[i] >= 16) ++i;
1863 error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl.data,
1864 frequencies_cl.size, frequencies_cl.size, 7);
1867 if(!uivector_resize(&bitlen_cl, tree_cl.numcodes)) ERROR_BREAK(83 );
1868 for(i = 0; i != tree_cl.numcodes; ++i)
1871 bitlen_cl.data[i] = HuffmanTree_getLength(&tree_cl, CLCL_ORDER[i]);
1873 while(bitlen_cl.data[bitlen_cl.size - 1] == 0 && bitlen_cl.size > 4)
1876 if(!uivector_resize(&bitlen_cl, bitlen_cl.size - 1)) ERROR_BREAK(83 );
1895 addBitToStream(bp, out, BFINAL);
1896 addBitToStream(bp, out, 0);
1897 addBitToStream(bp, out, 1);
1900 HLIT = (unsigned)(numcodes_ll - 257);
1901 HDIST = (unsigned)(numcodes_d - 1);
1902 HCLEN = (unsigned)bitlen_cl.size - 4;
1904 while(!bitlen_cl.data[HCLEN + 4 - 1] && HCLEN > 0) --HCLEN;
1905 addBitsToStream(bp, out, HLIT, 5);
1906 addBitsToStream(bp, out, HDIST, 5);
1907 addBitsToStream(bp, out, HCLEN, 4);
1910 for(i = 0; i != HCLEN + 4; ++i) addBitsToStream(bp, out, bitlen_cl.data[i], 3);
1913 for(i = 0; i != bitlen_lld_e.size; ++i)
1915 addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_cl, bitlen_lld_e.data[i]),
1916 HuffmanTree_getLength(&tree_cl, bitlen_lld_e.data[i]));
1918 if(bitlen_lld_e.data[i] == 16) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 2);
1919 else if(bitlen_lld_e.data[i] == 17) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 3);
1920 else if(bitlen_lld_e.data[i] == 18) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 7);
1924 writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d);
1926 if(HuffmanTree_getLength(&tree_ll, 256) == 0) ERROR_BREAK(64);
1929 addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256));
1935 uivector_cleanup(&lz77_encoded);
1936 HuffmanTree_cleanup(&tree_ll);
1937 HuffmanTree_cleanup(&tree_d);
1938 HuffmanTree_cleanup(&tree_cl);
1939 uivector_cleanup(&frequencies_ll);
1940 uivector_cleanup(&frequencies_d);
1941 uivector_cleanup(&frequencies_cl);
1942 uivector_cleanup(&bitlen_lld_e);
1943 uivector_cleanup(&bitlen_lld);
1944 uivector_cleanup(&bitlen_cl);
1949 static unsigned deflateFixed(ucvector* out,
size_t* bp, Hash* hash,
1950 const unsigned char*
data,
1951 size_t datapos,
size_t dataend,
1952 const LodePNGCompressSettings* settings,
unsigned final)
1954 HuffmanTree tree_ll;
1957 unsigned BFINAL =
final;
1961 HuffmanTree_init(&tree_ll);
1962 HuffmanTree_init(&tree_d);
1964 generateFixedLitLenTree(&tree_ll);
1965 generateFixedDistanceTree(&tree_d);
1967 addBitToStream(bp, out, BFINAL);
1968 addBitToStream(bp, out, 1);
1969 addBitToStream(bp, out, 0);
1971 if(settings->use_lz77)
1973 uivector lz77_encoded;
1974 uivector_init(&lz77_encoded);
1975 error = encodeLZ77(&lz77_encoded, hash,
data, datapos, dataend, settings->windowsize,
1976 settings->minmatch, settings->nicematch, settings->lazymatching);
1977 if(!error) writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d);
1978 uivector_cleanup(&lz77_encoded);
1982 for(i = datapos; i < dataend; ++i)
1984 addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll,
data[i]), HuffmanTree_getLength(&tree_ll,
data[i]));
1988 if(!error) addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256));
1991 HuffmanTree_cleanup(&tree_ll);
1992 HuffmanTree_cleanup(&tree_d);
1997 static unsigned lodepng_deflatev(ucvector* out,
const unsigned char* in,
size_t insize,
1998 const LodePNGCompressSettings* settings)
2001 size_t i, blocksize, numdeflateblocks;
2005 if(settings->btype > 2)
return 61;
2006 else if(settings->btype == 0)
return deflateNoCompression(out, in, insize);
2007 else if(settings->btype == 1) blocksize = insize;
2011 blocksize = insize / 8 + 8;
2012 if(blocksize < 65536) blocksize = 65536;
2013 if(blocksize > 262144) blocksize = 262144;
2016 numdeflateblocks = (insize + blocksize - 1) / blocksize;
2017 if(numdeflateblocks == 0) numdeflateblocks = 1;
2019 error = hash_init(&hash, settings->windowsize);
2020 if(error)
return error;
2022 for(i = 0; i != numdeflateblocks && !error; ++i)
2024 unsigned final = (i == numdeflateblocks - 1);
2025 size_t start = i * blocksize;
2026 size_t end = start + blocksize;
2027 if(end > insize) end = insize;
2029 if(settings->btype == 1) error = deflateFixed(out, &bp, &hash, in, start, end, settings,
final);
2030 else if(settings->btype == 2) error = deflateDynamic(out, &bp, &hash, in, start, end, settings,
final);
2033 hash_cleanup(&hash);
2038 unsigned lodepng_deflate(
unsigned char** out,
size_t* outsize,
2039 const unsigned char* in,
size_t insize,
2040 const LodePNGCompressSettings* settings)
2044 ucvector_init_buffer(&v, *out, *outsize);
2045 error = lodepng_deflatev(&v, in, insize, settings);
2051 static unsigned deflate(
unsigned char** out,
size_t* outsize,
2052 const unsigned char* in,
size_t insize,
2053 const LodePNGCompressSettings* settings)
2055 if(settings->custom_deflate)
2057 return settings->custom_deflate(out, outsize, in, insize, settings);
2061 return lodepng_deflate(out, outsize, in, insize, settings);
2071 static unsigned update_adler32(
unsigned adler,
const unsigned char*
data,
unsigned len)
2073 unsigned s1 = adler & 0xffff;
2074 unsigned s2 = (adler >> 16) & 0xffff;
2079 unsigned amount = len > 5550 ? 5550 : len;
2091 return (s2 << 16) | s1;
2095 static unsigned adler32(
const unsigned char*
data,
unsigned len)
2097 return update_adler32(1
L,
data, len);
2104 #ifdef LODEPNG_COMPILE_DECODER
2106 unsigned lodepng_zlib_decompress(
unsigned char** out,
size_t* outsize,
const unsigned char* in,
2107 size_t insize,
const LodePNGDecompressSettings* settings)
2110 unsigned CM, CINFO, FDICT;
2112 if(insize < 2)
return 53;
2114 if((in[0] * 256 + in[1]) % 31 != 0)
2121 CINFO = (in[0] >> 4) & 15;
2123 FDICT = (in[1] >> 5) & 1;
2126 if(CM != 8 || CINFO > 7)
2138 error = inflate(out, outsize, in + 2, insize - 2, settings);
2139 if(error)
return error;
2141 if(!settings->ignore_adler32)
2143 unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]);
2144 unsigned checksum = adler32(*out, (
unsigned)(*outsize));
2151 static unsigned zlib_decompress(
unsigned char** out,
size_t* outsize,
const unsigned char* in,
2152 size_t insize,
const LodePNGDecompressSettings* settings)
2154 if(settings->custom_zlib)
2156 return settings->custom_zlib(out, outsize, in, insize, settings);
2160 return lodepng_zlib_decompress(out, outsize, in, insize, settings);
2166 #ifdef LODEPNG_COMPILE_ENCODER
2168 unsigned lodepng_zlib_compress(
unsigned char** out,
size_t* outsize,
const unsigned char* in,
2169 size_t insize,
const LodePNGCompressSettings* settings)
2176 unsigned char* deflatedata = 0;
2177 size_t deflatesize = 0;
2181 unsigned FLEVEL = 0;
2183 unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64;
2184 unsigned FCHECK = 31 - CMFFLG % 31;
2188 ucvector_init_buffer(&outv, *out, *outsize);
2190 ucvector_push_back(&outv, (
unsigned char)(CMFFLG / 256));
2191 ucvector_push_back(&outv, (
unsigned char)(CMFFLG % 256));
2193 error = deflate(&deflatedata, &deflatesize, in, insize, settings);
2197 unsigned ADLER32 = adler32(in, (
unsigned)insize);
2198 for(i = 0; i != deflatesize; ++i) ucvector_push_back(&outv, deflatedata[i]);
2199 lodepng_free(deflatedata);
2200 lodepng_add32bitInt(&outv, ADLER32);
2204 *outsize = outv.size;
2210 static unsigned zlib_compress(
unsigned char** out,
size_t* outsize,
const unsigned char* in,
2211 size_t insize,
const LodePNGCompressSettings* settings)
2213 if(settings->custom_zlib)
2215 return settings->custom_zlib(out, outsize, in, insize, settings);
2219 return lodepng_zlib_compress(out, outsize, in, insize, settings);
2227 #ifdef LODEPNG_COMPILE_DECODER
2228 static unsigned zlib_decompress(
unsigned char** out,
size_t* outsize,
const unsigned char* in,
2229 size_t insize,
const LodePNGDecompressSettings* settings)
2231 if(!settings->custom_zlib)
return 87;
2232 return settings->custom_zlib(out, outsize, in, insize, settings);
2235 #ifdef LODEPNG_COMPILE_ENCODER
2236 static unsigned zlib_compress(
unsigned char** out,
size_t* outsize,
const unsigned char* in,
2237 size_t insize,
const LodePNGCompressSettings* settings)
2239 if(!settings->custom_zlib)
return 87;
2240 return settings->custom_zlib(out, outsize, in, insize, settings);
2248 #ifdef LODEPNG_COMPILE_ENCODER
2251 #define DEFAULT_WINDOWSIZE 2048
2253 void lodepng_compress_settings_init(LodePNGCompressSettings* settings)
2256 settings->btype = 2;
2257 settings->use_lz77 = 1;
2258 settings->windowsize = DEFAULT_WINDOWSIZE;
2259 settings->minmatch = 3;
2260 settings->nicematch = 128;
2261 settings->lazymatching = 1;
2263 settings->custom_zlib = 0;
2264 settings->custom_deflate = 0;
2265 settings->custom_context = 0;
2268 const LodePNGCompressSettings lodepng_default_compress_settings = {2, 1, DEFAULT_WINDOWSIZE, 3, 128, 1, 0, 0, 0};
2273 #ifdef LODEPNG_COMPILE_DECODER
2275 void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings)
2277 settings->ignore_adler32 = 0;
2279 settings->custom_zlib = 0;
2280 settings->custom_inflate = 0;
2281 settings->custom_context = 0;
2284 const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, 0};
2294 #ifdef LODEPNG_COMPILE_PNG
2301 static unsigned lodepng_crc32_table[256] = {
2302 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u,
2303 249268274u, 2044508324u, 3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u,
2304 498536548u, 1789927666u, 4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u,
2305 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u, 4195302755u, 2366115317u,
2306 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u,
2307 901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u,
2308 651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u,
2309 671266974u, 1594198024u, 3322730930u, 2970347812u, 795835527u, 1483230225u, 3244367275u, 3060149565u,
2310 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u,
2311 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u,
2312 1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u,
2313 1706088902u, 314042704u, 2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u,
2314 1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u,
2315 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u, 2852801631u, 3708648649u,
2316 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u,
2317 1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u,
2318 3988292384u, 2596254646u, 62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u,
2319 3814918930u, 2489596804u, 225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u,
2320 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u, 426522225u, 1852507879u,
2321 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u,
2322 3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u,
2323 3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u,
2324 3412177804u, 3160834842u, 628085408u, 1382605366u, 3423369109u, 3138078467u, 570562233u, 1426400815u,
2325 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u,
2326 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u,
2327 2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u,
2328 2262029012u, 4057260610u, 1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u,
2329 2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u, 1634467795u, 376229701u,
2330 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u,
2331 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u,
2332 3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u,
2333 3009837614u, 3294710456u, 1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u
2337 unsigned lodepng_crc32(
const unsigned char*
buf,
size_t len)
2339 unsigned c = 0xffffffff
L;
2342 for(n = 0; n < len; ++n)
2344 c = lodepng_crc32_table[(c ^
buf[n]) & 0xff] ^ (c >> 8);
2346 return c ^ 0xffffffff
L;
2353 static unsigned char readBitFromReversedStream(
size_t* bitpointer,
const unsigned char* bitstream)
2355 unsigned char result = (
unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1);
2360 static unsigned readBitsFromReversedStream(
size_t* bitpointer,
const unsigned char* bitstream,
size_t nbits)
2362 unsigned result = 0;
2364 for(i = nbits - 1; i < nbits; --i)
2366 result += (unsigned)readBitFromReversedStream(bitpointer, bitstream) << i;
2371 #ifdef LODEPNG_COMPILE_DECODER
2372 static void setBitOfReversedStream0(
size_t* bitpointer,
unsigned char* bitstream,
unsigned char bit)
2378 bitstream[(*bitpointer) >> 3] |= (bit << (7 - ((*bitpointer) & 0x7)));
2384 static void setBitOfReversedStream(
size_t* bitpointer,
unsigned char* bitstream,
unsigned char bit)
2387 if(bit == 0) bitstream[(*bitpointer) >> 3] &= (
unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7))));
2388 else bitstream[(*bitpointer) >> 3] |= (1 << (7 - ((*bitpointer) & 0x7)));
2396 unsigned lodepng_chunk_length(
const unsigned char* chunk)
2398 return lodepng_read32bitInt(&chunk[0]);
2401 void lodepng_chunk_type(
char type[5],
const unsigned char* chunk)
2404 for(i = 0; i != 4; ++i) type[i] = (
char)chunk[4 + i];
2408 unsigned char lodepng_chunk_type_equals(
const unsigned char* chunk,
const char* type)
2410 if(strlen(type) != 4)
return 0;
2411 return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]);
2414 unsigned char lodepng_chunk_ancillary(
const unsigned char* chunk)
2416 return((chunk[4] & 32) != 0);
2419 unsigned char lodepng_chunk_private(
const unsigned char* chunk)
2421 return((chunk[6] & 32) != 0);
2424 unsigned char lodepng_chunk_safetocopy(
const unsigned char* chunk)
2426 return((chunk[7] & 32) != 0);
2429 unsigned char* lodepng_chunk_data(
unsigned char* chunk)
2434 const unsigned char* lodepng_chunk_data_const(
const unsigned char* chunk)
2439 unsigned lodepng_chunk_check_crc(
const unsigned char* chunk)
2441 unsigned length = lodepng_chunk_length(chunk);
2442 unsigned CRC = lodepng_read32bitInt(&chunk[length + 8]);
2444 unsigned checksum = lodepng_crc32(&chunk[4], length + 4);
2449 void lodepng_chunk_generate_crc(
unsigned char* chunk)
2451 unsigned length = lodepng_chunk_length(chunk);
2452 unsigned CRC = lodepng_crc32(&chunk[4], length + 4);
2453 lodepng_set32bitInt(chunk + 8 + length, CRC);
2456 unsigned char* lodepng_chunk_next(
unsigned char* chunk)
2458 unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12;
2459 return &chunk[total_chunk_length];
2462 const unsigned char* lodepng_chunk_next_const(
const unsigned char* chunk)
2464 unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12;
2465 return &chunk[total_chunk_length];
2468 unsigned lodepng_chunk_append(
unsigned char** out,
size_t* outlength,
const unsigned char* chunk)
2471 unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12;
2472 unsigned char *chunk_start, *new_buffer;
2473 size_t new_length = (*outlength) + total_chunk_length;
2474 if(new_length < total_chunk_length || new_length < (*outlength))
return 77;
2476 new_buffer = (
unsigned char*)lodepng_realloc(*out, new_length);
2477 if(!new_buffer)
return 83;
2478 (*out) = new_buffer;
2479 (*outlength) = new_length;
2480 chunk_start = &(*out)[new_length - total_chunk_length];
2482 for(i = 0; i != total_chunk_length; ++i) chunk_start[i] = chunk[i];
2487 unsigned lodepng_chunk_create(
unsigned char** out,
size_t* outlength,
unsigned length,
2488 const char* type,
const unsigned char*
data)
2491 unsigned char *chunk, *new_buffer;
2492 size_t new_length = (*outlength) + length + 12;
2493 if(new_length < length + 12 || new_length < (*outlength))
return 77;
2494 new_buffer = (
unsigned char*)lodepng_realloc(*out, new_length);
2495 if(!new_buffer)
return 83;
2496 (*out) = new_buffer;
2497 (*outlength) = new_length;
2498 chunk = &(*out)[(*outlength) - length - 12];
2501 lodepng_set32bitInt(chunk, (
unsigned)length);
2504 chunk[4] = (
unsigned char)type[0];
2505 chunk[5] = (
unsigned char)type[1];
2506 chunk[6] = (
unsigned char)type[2];
2507 chunk[7] = (
unsigned char)type[3];
2510 for(i = 0; i != length; ++i) chunk[8 + i] =
data[i];
2513 lodepng_chunk_generate_crc(chunk);
2523 static unsigned checkColorValidity(LodePNGColorType colortype,
unsigned bd)
2527 case 0:
if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16))
return 37;
break;
2528 case 2:
if(!( bd == 8 || bd == 16))
return 37;
break;
2529 case 3:
if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 ))
return 37;
break;
2530 case 4:
if(!( bd == 8 || bd == 16))
return 37;
break;
2531 case 6:
if(!( bd == 8 || bd == 16))
return 37;
break;
2537 static unsigned getNumColorChannels(LodePNGColorType colortype)
2550 static unsigned lodepng_get_bpp_lct(LodePNGColorType colortype,
unsigned bitdepth)
2553 return getNumColorChannels(colortype) * bitdepth;
2558 void lodepng_color_mode_init(LodePNGColorMode* info)
2560 info->key_defined = 0;
2561 info->key_r = info->key_g = info->key_b = 0;
2562 info->colortype = LCT_RGBA;
2565 info->palettesize = 0;
2568 void lodepng_color_mode_cleanup(LodePNGColorMode* info)
2570 lodepng_palette_clear(info);
2573 unsigned lodepng_color_mode_copy(LodePNGColorMode* dest,
const LodePNGColorMode* source)
2576 lodepng_color_mode_cleanup(dest);
2580 dest->palette = (
unsigned char*)lodepng_malloc(1024);
2581 if(!dest->palette && source->palettesize)
return 83;
2582 for(i = 0; i != source->palettesize * 4; ++i) dest->palette[i] = source->palette[i];
2587 static int lodepng_color_mode_equal(
const LodePNGColorMode* a,
const LodePNGColorMode* b)
2590 if(a->colortype != b->colortype)
return 0;
2591 if(a->bitdepth != b->bitdepth)
return 0;
2592 if(a->key_defined != b->key_defined)
return 0;
2595 if(a->key_r != b->key_r)
return 0;
2596 if(a->key_g != b->key_g)
return 0;
2597 if(a->key_b != b->key_b)
return 0;
2599 if(a->palettesize != b->palettesize)
return 0;
2600 for(i = 0; i != a->palettesize * 4; ++i)
2602 if(a->palette[i] != b->palette[i])
return 0;
2607 void lodepng_palette_clear(LodePNGColorMode* info)
2609 if(info->palette) lodepng_free(info->palette);
2611 info->palettesize = 0;
2614 unsigned lodepng_palette_add(LodePNGColorMode* info,
2615 unsigned char r,
unsigned char g,
unsigned char b,
unsigned char a)
2617 unsigned char*
data;
2623 data = (
unsigned char*)lodepng_realloc(info->palette, 1024);
2624 if(!
data)
return 83;
2625 else info->palette =
data;
2627 info->palette[4 * info->palettesize + 0] =
r;
2628 info->palette[4 * info->palettesize + 1] = g;
2629 info->palette[4 * info->palettesize + 2] = b;
2630 info->palette[4 * info->palettesize + 3] = a;
2631 ++info->palettesize;
2635 unsigned lodepng_get_bpp(
const LodePNGColorMode* info)
2638 return lodepng_get_bpp_lct(info->colortype, info->bitdepth);
2641 unsigned lodepng_get_channels(
const LodePNGColorMode* info)
2643 return getNumColorChannels(info->colortype);
2646 unsigned lodepng_is_greyscale_type(
const LodePNGColorMode* info)
2648 return info->colortype == LCT_GREY || info->colortype == LCT_GREY_ALPHA;
2651 unsigned lodepng_is_alpha_type(
const LodePNGColorMode* info)
2653 return (info->colortype & 4) != 0;
2656 unsigned lodepng_is_palette_type(
const LodePNGColorMode* info)
2658 return info->colortype == LCT_PALETTE;
2661 unsigned lodepng_has_palette_alpha(
const LodePNGColorMode* info)
2664 for(i = 0; i != info->palettesize; ++i)
2666 if(info->palette[i * 4 + 3] < 255)
return 1;
2671 unsigned lodepng_can_have_alpha(
const LodePNGColorMode* info)
2673 return info->key_defined
2674 || lodepng_is_alpha_type(info)
2675 || lodepng_has_palette_alpha(info);
2678 size_t lodepng_get_raw_size(
unsigned w,
unsigned h,
const LodePNGColorMode* color)
2680 return (w * h * lodepng_get_bpp(color) + 7) / 8;
2683 size_t lodepng_get_raw_size_lct(
unsigned w,
unsigned h, LodePNGColorType colortype,
unsigned bitdepth)
2685 return (w * h * lodepng_get_bpp_lct(colortype, bitdepth) + 7) / 8;
2689 #ifdef LODEPNG_COMPILE_PNG
2690 #ifdef LODEPNG_COMPILE_DECODER
2692 static size_t lodepng_get_raw_size_idat(
unsigned w,
unsigned h,
const LodePNGColorMode* color)
2694 return h * ((w * lodepng_get_bpp(color) + 7) / 8);
2699 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
2701 static void LodePNGUnknownChunks_init(LodePNGInfo* info)
2704 for(i = 0; i != 3; ++i) info->unknown_chunks_data[i] = 0;
2705 for(i = 0; i != 3; ++i) info->unknown_chunks_size[i] = 0;
2708 static void LodePNGUnknownChunks_cleanup(LodePNGInfo* info)
2711 for(i = 0; i != 3; ++i) lodepng_free(info->unknown_chunks_data[i]);
2714 static unsigned LodePNGUnknownChunks_copy(LodePNGInfo* dest,
const LodePNGInfo* src)
2718 LodePNGUnknownChunks_cleanup(dest);
2720 for(i = 0; i != 3; ++i)
2723 dest->unknown_chunks_size[i] = src->unknown_chunks_size[i];
2724 dest->unknown_chunks_data[i] = (
unsigned char*)lodepng_malloc(src->unknown_chunks_size[i]);
2725 if(!dest->unknown_chunks_data[i] && dest->unknown_chunks_size[i])
return 83;
2726 for(j = 0; j < src->unknown_chunks_size[i]; ++j)
2728 dest->unknown_chunks_data[i][j] = src->unknown_chunks_data[i][j];
2737 static void LodePNGText_init(LodePNGInfo* info)
2740 info->text_keys = NULL;
2741 info->text_strings = NULL;
2744 static void LodePNGText_cleanup(LodePNGInfo* info)
2747 for(i = 0; i != info->text_num; ++i)
2749 string_cleanup(&info->text_keys[i]);
2750 string_cleanup(&info->text_strings[i]);
2752 lodepng_free(info->text_keys);
2753 lodepng_free(info->text_strings);
2756 static unsigned LodePNGText_copy(LodePNGInfo* dest,
const LodePNGInfo* source)
2759 dest->text_keys = 0;
2760 dest->text_strings = 0;
2762 for(i = 0; i != source->text_num; ++i)
2764 CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i]));
2769 void lodepng_clear_text(LodePNGInfo* info)
2771 LodePNGText_cleanup(info);
2774 unsigned lodepng_add_text(LodePNGInfo* info,
const char* key,
const char* str)
2776 char** new_keys = (
char**)(lodepng_realloc(info->text_keys,
sizeof(
char*) * (info->text_num + 1)));
2777 char** new_strings = (
char**)(lodepng_realloc(info->text_strings,
sizeof(
char*) * (info->text_num + 1)));
2778 if(!new_keys || !new_strings)
2780 lodepng_free(new_keys);
2781 lodepng_free(new_strings);
2786 info->text_keys = new_keys;
2787 info->text_strings = new_strings;
2789 string_init(&info->text_keys[info->text_num - 1]);
2790 string_set(&info->text_keys[info->text_num - 1], key);
2792 string_init(&info->text_strings[info->text_num - 1]);
2793 string_set(&info->text_strings[info->text_num - 1], str);
2800 static void LodePNGIText_init(LodePNGInfo* info)
2802 info->itext_num = 0;
2803 info->itext_keys = NULL;
2804 info->itext_langtags = NULL;
2805 info->itext_transkeys = NULL;
2806 info->itext_strings = NULL;
2809 static void LodePNGIText_cleanup(LodePNGInfo* info)
2812 for(i = 0; i != info->itext_num; ++i)
2814 string_cleanup(&info->itext_keys[i]);
2815 string_cleanup(&info->itext_langtags[i]);
2816 string_cleanup(&info->itext_transkeys[i]);
2817 string_cleanup(&info->itext_strings[i]);
2819 lodepng_free(info->itext_keys);
2820 lodepng_free(info->itext_langtags);
2821 lodepng_free(info->itext_transkeys);
2822 lodepng_free(info->itext_strings);
2825 static unsigned LodePNGIText_copy(LodePNGInfo* dest,
const LodePNGInfo* source)
2828 dest->itext_keys = 0;
2829 dest->itext_langtags = 0;
2830 dest->itext_transkeys = 0;
2831 dest->itext_strings = 0;
2832 dest->itext_num = 0;
2833 for(i = 0; i != source->itext_num; ++i)
2835 CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i],
2836 source->itext_transkeys[i], source->itext_strings[i]));
2841 void lodepng_clear_itext(LodePNGInfo* info)
2843 LodePNGIText_cleanup(info);
2846 unsigned lodepng_add_itext(LodePNGInfo* info,
const char* key,
const char* langtag,
2847 const char* transkey,
const char* str)
2849 char** new_keys = (
char**)(lodepng_realloc(info->itext_keys,
sizeof(
char*) * (info->itext_num + 1)));
2850 char** new_langtags = (
char**)(lodepng_realloc(info->itext_langtags,
sizeof(
char*) * (info->itext_num + 1)));
2851 char** new_transkeys = (
char**)(lodepng_realloc(info->itext_transkeys,
sizeof(
char*) * (info->itext_num + 1)));
2852 char** new_strings = (
char**)(lodepng_realloc(info->itext_strings,
sizeof(
char*) * (info->itext_num + 1)));
2853 if(!new_keys || !new_langtags || !new_transkeys || !new_strings)
2855 lodepng_free(new_keys);
2856 lodepng_free(new_langtags);
2857 lodepng_free(new_transkeys);
2858 lodepng_free(new_strings);
2863 info->itext_keys = new_keys;
2864 info->itext_langtags = new_langtags;
2865 info->itext_transkeys = new_transkeys;
2866 info->itext_strings = new_strings;
2868 string_init(&info->itext_keys[info->itext_num - 1]);
2869 string_set(&info->itext_keys[info->itext_num - 1], key);
2871 string_init(&info->itext_langtags[info->itext_num - 1]);
2872 string_set(&info->itext_langtags[info->itext_num - 1], langtag);
2874 string_init(&info->itext_transkeys[info->itext_num - 1]);
2875 string_set(&info->itext_transkeys[info->itext_num - 1], transkey);
2877 string_init(&info->itext_strings[info->itext_num - 1]);
2878 string_set(&info->itext_strings[info->itext_num - 1], str);
2884 void lodepng_info_init(LodePNGInfo* info)
2886 lodepng_color_mode_init(&info->color);
2887 info->interlace_method = 0;
2888 info->compression_method = 0;
2889 info->filter_method = 0;
2890 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
2891 info->background_defined = 0;
2892 info->background_r = info->background_g = info->background_b = 0;
2894 LodePNGText_init(info);
2895 LodePNGIText_init(info);
2897 info->time_defined = 0;
2898 info->phys_defined = 0;
2900 LodePNGUnknownChunks_init(info);
2904 void lodepng_info_cleanup(LodePNGInfo* info)
2906 lodepng_color_mode_cleanup(&info->color);
2907 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
2908 LodePNGText_cleanup(info);
2909 LodePNGIText_cleanup(info);
2911 LodePNGUnknownChunks_cleanup(info);
2915 unsigned lodepng_info_copy(LodePNGInfo* dest,
const LodePNGInfo* source)
2917 lodepng_info_cleanup(dest);
2919 lodepng_color_mode_init(&dest->color);
2920 CERROR_TRY_RETURN(lodepng_color_mode_copy(&dest->color, &source->color));
2922 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
2923 CERROR_TRY_RETURN(LodePNGText_copy(dest, source));
2924 CERROR_TRY_RETURN(LodePNGIText_copy(dest, source));
2926 LodePNGUnknownChunks_init(dest);
2927 CERROR_TRY_RETURN(LodePNGUnknownChunks_copy(dest, source));
2932 void lodepng_info_swap(LodePNGInfo* a, LodePNGInfo* b)
2934 LodePNGInfo temp = *a;
2942 static void addColorBits(
unsigned char* out,
size_t index,
unsigned bits,
unsigned in)
2944 unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1;
2946 unsigned p =
index & m;
2947 in &= (1u << bits) - 1u;
2948 in = in << (bits * (m - p));
2949 if(p == 0) out[
index * bits / 8] = in;
2950 else out[
index * bits / 8] |= in;
2953 typedef struct ColorTree ColorTree;
2963 ColorTree* children[16];
2967 static void color_tree_init(ColorTree* tree)
2970 for(i = 0; i != 16; ++i) tree->children[i] = 0;
2974 static void color_tree_cleanup(ColorTree* tree)
2977 for(i = 0; i != 16; ++i)
2979 if(tree->children[i])
2981 color_tree_cleanup(tree->children[i]);
2982 lodepng_free(tree->children[i]);
2988 static int color_tree_get(ColorTree* tree,
unsigned char r,
unsigned char g,
unsigned char b,
unsigned char a)
2991 for(bit = 0; bit < 8; ++bit)
2993 int i = 8 * ((
r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1);
2994 if(!tree->children[i])
return -1;
2995 else tree = tree->children[i];
2997 return tree ? tree->index : -1;
3000 #ifdef LODEPNG_COMPILE_ENCODER
3001 static int color_tree_has(ColorTree* tree,
unsigned char r,
unsigned char g,
unsigned char b,
unsigned char a)
3003 return color_tree_get(tree,
r, g, b, a) >= 0;
3009 static void color_tree_add(ColorTree* tree,
3010 unsigned char r,
unsigned char g,
unsigned char b,
unsigned char a,
unsigned index)
3013 for(bit = 0; bit < 8; ++bit)
3015 int i = 8 * ((
r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1);
3016 if(!tree->children[i])
3018 tree->children[i] = (ColorTree*)lodepng_malloc(
sizeof(ColorTree));
3019 color_tree_init(tree->children[i]);
3021 tree = tree->children[i];
3023 tree->index = (int)
index;
3027 static unsigned rgba8ToPixel(
unsigned char* out,
size_t i,
3028 const LodePNGColorMode* mode, ColorTree* tree ,
3029 unsigned char r,
unsigned char g,
unsigned char b,
unsigned char a)
3031 if(
mode->colortype == LCT_GREY)
3033 unsigned char grey =
r; ;
3034 if(
mode->bitdepth == 8) out[i] = grey;
3035 else if(
mode->bitdepth == 16) out[i * 2 + 0] = out[i * 2 + 1] = grey;
3039 grey = (grey >> (8 -
mode->bitdepth)) & ((1 <<
mode->bitdepth) - 1);
3040 addColorBits(out, i,
mode->bitdepth, grey);
3043 else if(
mode->colortype == LCT_RGB)
3045 if(
mode->bitdepth == 8)
3053 out[i * 6 + 0] = out[i * 6 + 1] =
r;
3054 out[i * 6 + 2] = out[i * 6 + 3] = g;
3055 out[i * 6 + 4] = out[i * 6 + 5] = b;
3058 else if(
mode->colortype == LCT_PALETTE)
3060 int index = color_tree_get(tree,
r, g, b, a);
3061 if(
index < 0)
return 82;
3063 else addColorBits(out, i,
mode->bitdepth, (
unsigned)
index);
3065 else if(
mode->colortype == LCT_GREY_ALPHA)
3067 unsigned char grey =
r; ;
3068 if(
mode->bitdepth == 8)
3070 out[i * 2 + 0] = grey;
3073 else if(
mode->bitdepth == 16)
3075 out[i * 4 + 0] = out[i * 4 + 1] = grey;
3076 out[i * 4 + 2] = out[i * 4 + 3] = a;
3079 else if(
mode->colortype == LCT_RGBA)
3081 if(
mode->bitdepth == 8)
3090 out[i * 8 + 0] = out[i * 8 + 1] =
r;
3091 out[i * 8 + 2] = out[i * 8 + 3] = g;
3092 out[i * 8 + 4] = out[i * 8 + 5] = b;
3093 out[i * 8 + 6] = out[i * 8 + 7] = a;
3101 static void rgba16ToPixel(
unsigned char* out,
size_t i,
3102 const LodePNGColorMode* mode,
3103 unsigned short r,
unsigned short g,
unsigned short b,
unsigned short a)
3105 if(
mode->colortype == LCT_GREY)
3107 unsigned short grey =
r; ;
3108 out[i * 2 + 0] = (grey >> 8) & 255;
3109 out[i * 2 + 1] = grey & 255;
3111 else if(
mode->colortype == LCT_RGB)
3113 out[i * 6 + 0] = (
r >> 8) & 255;
3114 out[i * 6 + 1] =
r & 255;
3115 out[i * 6 + 2] = (g >> 8) & 255;
3116 out[i * 6 + 3] = g & 255;
3117 out[i * 6 + 4] = (b >> 8) & 255;
3118 out[i * 6 + 5] = b & 255;
3120 else if(
mode->colortype == LCT_GREY_ALPHA)
3122 unsigned short grey =
r; ;
3123 out[i * 4 + 0] = (grey >> 8) & 255;
3124 out[i * 4 + 1] = grey & 255;
3125 out[i * 4 + 2] = (a >> 8) & 255;
3126 out[i * 4 + 3] = a & 255;
3128 else if(
mode->colortype == LCT_RGBA)
3130 out[i * 8 + 0] = (
r >> 8) & 255;
3131 out[i * 8 + 1] =
r & 255;
3132 out[i * 8 + 2] = (g >> 8) & 255;
3133 out[i * 8 + 3] = g & 255;
3134 out[i * 8 + 4] = (b >> 8) & 255;
3135 out[i * 8 + 5] = b & 255;
3136 out[i * 8 + 6] = (a >> 8) & 255;
3137 out[i * 8 + 7] = a & 255;
3142 static void getPixelColorRGBA8(
unsigned char*
r,
unsigned char* g,
3143 unsigned char* b,
unsigned char* a,
3144 const unsigned char* in,
size_t i,
3145 const LodePNGColorMode* mode)
3147 if(
mode->colortype == LCT_GREY)
3149 if(
mode->bitdepth == 8)
3151 *
r = *g = *b = in[i];
3152 if(
mode->key_defined && *
r ==
mode->key_r) *a = 0;
3155 else if(
mode->bitdepth == 16)
3157 *
r = *g = *b = in[i * 2 + 0];
3158 if(
mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] ==
mode->key_r) *a = 0;
3163 unsigned highest = ((1U <<
mode->bitdepth) - 1U);
3164 size_t j = i *
mode->bitdepth;
3165 unsigned value = readBitsFromReversedStream(&j, in,
mode->bitdepth);
3166 *
r = *g = *b = (
value * 255) / highest;
3171 else if(
mode->colortype == LCT_RGB)
3173 if(
mode->bitdepth == 8)
3175 *
r = in[i * 3 + 0]; *g = in[i * 3 + 1]; *b = in[i * 3 + 2];
3176 if(
mode->key_defined && *
r ==
mode->key_r && *g ==
mode->key_g && *b ==
mode->key_b) *a = 0;
3184 if(
mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] ==
mode->key_r
3185 && 256U * in[i * 6 + 2] + in[i * 6 + 3] ==
mode->key_g
3186 && 256U * in[i * 6 + 4] + in[i * 6 + 5] ==
mode->key_b) *a = 0;
3190 else if(
mode->colortype == LCT_PALETTE)
3196 size_t j = i *
mode->bitdepth;
3197 index = readBitsFromReversedStream(&j, in,
mode->bitdepth);
3215 else if(
mode->colortype == LCT_GREY_ALPHA)
3217 if(
mode->bitdepth == 8)
3219 *
r = *g = *b = in[i * 2 + 0];
3224 *
r = *g = *b = in[i * 4 + 0];
3228 else if(
mode->colortype == LCT_RGBA)
3230 if(
mode->bitdepth == 8)
3252 static void getPixelColorsRGBA8(
unsigned char* buffer,
size_t numpixels,
3253 unsigned has_alpha,
const unsigned char* in,
3254 const LodePNGColorMode* mode)
3256 unsigned num_channels = has_alpha ? 4 : 3;
3258 if(
mode->colortype == LCT_GREY)
3260 if(
mode->bitdepth == 8)
3262 for(i = 0; i != numpixels; ++i, buffer += num_channels)
3264 buffer[0] = buffer[1] = buffer[2] = in[i];
3265 if(has_alpha) buffer[3] =
mode->key_defined && in[i] ==
mode->key_r ? 0 : 255;
3268 else if(
mode->bitdepth == 16)
3270 for(i = 0; i != numpixels; ++i, buffer += num_channels)
3272 buffer[0] = buffer[1] = buffer[2] = in[i * 2];
3273 if(has_alpha) buffer[3] =
mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] ==
mode->key_r ? 0 : 255;
3278 unsigned highest = ((1U <<
mode->bitdepth) - 1U);
3280 for(i = 0; i != numpixels; ++i, buffer += num_channels)
3282 unsigned value = readBitsFromReversedStream(&j, in,
mode->bitdepth);
3283 buffer[0] = buffer[1] = buffer[2] = (
value * 255) / highest;
3284 if(has_alpha) buffer[3] =
mode->key_defined &&
value ==
mode->key_r ? 0 : 255;
3288 else if(
mode->colortype == LCT_RGB)
3290 if(
mode->bitdepth == 8)
3292 for(i = 0; i != numpixels; ++i, buffer += num_channels)
3294 buffer[0] = in[i * 3 + 0];
3295 buffer[1] = in[i * 3 + 1];
3296 buffer[2] = in[i * 3 + 2];
3297 if(has_alpha) buffer[3] =
mode->key_defined && buffer[0] ==
mode->key_r
3298 && buffer[1]==
mode->key_g && buffer[2] ==
mode->key_b ? 0 : 255;
3303 for(i = 0; i != numpixels; ++i, buffer += num_channels)
3305 buffer[0] = in[i * 6 + 0];
3306 buffer[1] = in[i * 6 + 2];
3307 buffer[2] = in[i * 6 + 4];
3308 if(has_alpha) buffer[3] =
mode->key_defined
3309 && 256U * in[i * 6 + 0] + in[i * 6 + 1] ==
mode->key_r
3310 && 256U * in[i * 6 + 2] + in[i * 6 + 3] ==
mode->key_g
3311 && 256U * in[i * 6 + 4] + in[i * 6 + 5] ==
mode->key_b ? 0 : 255;
3315 else if(
mode->colortype == LCT_PALETTE)
3319 for(i = 0; i != numpixels; ++i, buffer += num_channels)
3322 else index = readBitsFromReversedStream(&j, in,
mode->bitdepth);
3328 buffer[0] = buffer[1] = buffer[2] = 0;
3329 if(has_alpha) buffer[3] = 255;
3333 buffer[0] =
mode->palette[
index * 4 + 0];
3334 buffer[1] =
mode->palette[
index * 4 + 1];
3335 buffer[2] =
mode->palette[
index * 4 + 2];
3336 if(has_alpha) buffer[3] =
mode->palette[
index * 4 + 3];
3340 else if(
mode->colortype == LCT_GREY_ALPHA)
3342 if(
mode->bitdepth == 8)
3344 for(i = 0; i != numpixels; ++i, buffer += num_channels)
3346 buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0];
3347 if(has_alpha) buffer[3] = in[i * 2 + 1];
3352 for(i = 0; i != numpixels; ++i, buffer += num_channels)
3354 buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0];
3355 if(has_alpha) buffer[3] = in[i * 4 + 2];
3359 else if(
mode->colortype == LCT_RGBA)
3361 if(
mode->bitdepth == 8)
3363 for(i = 0; i != numpixels; ++i, buffer += num_channels)
3365 buffer[0] = in[i * 4 + 0];
3366 buffer[1] = in[i * 4 + 1];
3367 buffer[2] = in[i * 4 + 2];
3368 if(has_alpha) buffer[3] = in[i * 4 + 3];
3373 for(i = 0; i != numpixels; ++i, buffer += num_channels)
3375 buffer[0] = in[i * 8 + 0];
3376 buffer[1] = in[i * 8 + 2];
3377 buffer[2] = in[i * 8 + 4];
3378 if(has_alpha) buffer[3] = in[i * 8 + 6];
3386 static void getPixelColorRGBA16(
unsigned short*
r,
unsigned short* g,
unsigned short* b,
unsigned short* a,
3387 const unsigned char* in,
size_t i,
const LodePNGColorMode* mode)
3389 if(
mode->colortype == LCT_GREY)
3391 *
r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1];
3392 if(
mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] ==
mode->key_r) *a = 0;
3395 else if(
mode->colortype == LCT_RGB)
3397 *
r = 256 * in[i * 6 + 0] + in[i * 6 + 1];
3398 *g = 256 * in[i * 6 + 2] + in[i * 6 + 3];
3399 *b = 256 * in[i * 6 + 4] + in[i * 6 + 5];
3400 if(
mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] ==
mode->key_r
3401 && 256U * in[i * 6 + 2] + in[i * 6 + 3] ==
mode->key_g
3402 && 256U * in[i * 6 + 4] + in[i * 6 + 5] ==
mode->key_b) *a = 0;
3405 else if(
mode->colortype == LCT_GREY_ALPHA)
3407 *
r = *g = *b = 256 * in[i * 4 + 0] + in[i * 4 + 1];
3408 *a = 256 * in[i * 4 + 2] + in[i * 4 + 3];
3410 else if(
mode->colortype == LCT_RGBA)
3412 *
r = 256 * in[i * 8 + 0] + in[i * 8 + 1];
3413 *g = 256 * in[i * 8 + 2] + in[i * 8 + 3];
3414 *b = 256 * in[i * 8 + 4] + in[i * 8 + 5];
3415 *a = 256 * in[i * 8 + 6] + in[i * 8 + 7];
3419 unsigned lodepng_convert(
unsigned char* out,
const unsigned char* in,
3420 LodePNGColorMode* mode_out,
const LodePNGColorMode* mode_in,
3421 unsigned w,
unsigned h)
3425 size_t numpixels = w * h;
3427 if(lodepng_color_mode_equal(mode_out, mode_in))
3429 size_t numbytes = lodepng_get_raw_size(w, h, mode_in);
3430 for(i = 0; i != numbytes; ++i) out[i] = in[i];
3434 if(mode_out->colortype == LCT_PALETTE)
3436 size_t palsize = 1u << mode_out->bitdepth;
3437 if(mode_out->palettesize < palsize) palsize = mode_out->palettesize;
3438 color_tree_init(&tree);
3439 for(i = 0; i != palsize; ++i)
3441 unsigned char* p = &mode_out->palette[i * 4];
3442 color_tree_add(&tree, p[0], p[1], p[2], p[3], i);
3446 if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16)
3448 for(i = 0; i != numpixels; ++i)
3450 unsigned short r = 0, g = 0, b = 0, a = 0;
3451 getPixelColorRGBA16(&
r, &g, &b, &a, in, i, mode_in);
3452 rgba16ToPixel(out, i, mode_out,
r, g, b, a);
3455 else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA)
3457 getPixelColorsRGBA8(out, numpixels, 1, in, mode_in);
3459 else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB)
3461 getPixelColorsRGBA8(out, numpixels, 0, in, mode_in);
3465 unsigned char r = 0, g = 0, b = 0, a = 0;
3466 for(i = 0; i != numpixels; ++i)
3468 getPixelColorRGBA8(&
r, &g, &b, &a, in, i, mode_in);
3469 rgba8ToPixel(out, i, mode_out, &tree,
r, g, b, a);
3473 if(mode_out->colortype == LCT_PALETTE)
3475 color_tree_cleanup(&tree);
3481 #ifdef LODEPNG_COMPILE_ENCODER
3483 void lodepng_color_profile_init(LodePNGColorProfile* profile)
3485 profile->colored = 0;
3488 profile->key_r = profile->key_g = profile->key_b = 0;
3489 profile->numcolors = 0;
3507 static unsigned getValueRequiredBits(
unsigned char value)
3511 if(
value % 17 == 0)
return value % 85 == 0 ? 2 : 4;
3517 unsigned lodepng_get_color_profile(LodePNGColorProfile* profile,
3518 const unsigned char* in,
unsigned w,
unsigned h,
3519 const LodePNGColorMode* mode)
3524 size_t numpixels = w * h;
3526 unsigned colored_done = lodepng_is_greyscale_type(mode) ? 1 : 0;
3527 unsigned alpha_done = lodepng_can_have_alpha(mode) ? 0 : 1;
3528 unsigned numcolors_done = 0;
3529 unsigned bpp = lodepng_get_bpp(mode);
3530 unsigned bits_done = bpp == 1 ? 1 : 0;
3531 unsigned maxnumcolors = 257;
3532 unsigned sixteen = 0;
3533 if(bpp <= 8) maxnumcolors = bpp == 1 ? 2 : (bpp == 2 ? 4 : (bpp == 4 ? 16 : 256));
3535 color_tree_init(&tree);
3538 if(
mode->bitdepth == 16)
3540 unsigned short r, g, b, a;
3541 for(i = 0; i != numpixels; ++i)
3543 getPixelColorRGBA16(&
r, &g, &b, &a, in, i, mode);
3544 if((
r & 255) != ((
r >> 8) & 255) || (g & 255) != ((g >> 8) & 255) ||
3545 (b & 255) != ((b >> 8) & 255) || (a & 255) != ((a >> 8) & 255))
3555 unsigned short r = 0, g = 0, b = 0, a = 0;
3557 bits_done = numcolors_done = 1;
3559 for(i = 0; i != numpixels; ++i)
3561 getPixelColorRGBA16(&
r, &g, &b, &a, in, i, mode);
3563 if(!colored_done && (
r != g ||
r != b))
3565 profile->colored = 1;
3571 unsigned matchkey = (
r == profile->key_r && g == profile->key_g && b == profile->key_b);
3572 if(a != 65535 && (a != 0 || (profile->key && !matchkey)))
3576 if(profile->bits < 8) profile->bits = 8;
3578 else if(a == 0 && !profile->alpha && !profile->key)
3585 else if(a == 65535 && profile->key && matchkey)
3593 if(alpha_done && numcolors_done && colored_done && bits_done)
break;
3598 for(i = 0; i != numpixels; ++i)
3600 unsigned char r = 0, g = 0, b = 0, a = 0;
3601 getPixelColorRGBA8(&
r, &g, &b, &a, in, i, mode);
3603 if(!bits_done && profile->bits < 8)
3606 unsigned bits = getValueRequiredBits(
r);
3607 if(bits > profile->bits) profile->bits = bits;
3609 bits_done = (profile->bits >= bpp);
3611 if(!colored_done && (
r != g ||
r != b))
3613 profile->colored = 1;
3615 if(profile->bits < 8) profile->bits = 8;
3620 unsigned matchkey = (
r == profile->key_r && g == profile->key_g && b == profile->key_b);
3621 if(a != 255 && (a != 0 || (profile->key && !matchkey)))
3625 if(profile->bits < 8) profile->bits = 8;
3627 else if(a == 0 && !profile->alpha && !profile->key)
3634 else if(a == 255 && profile->key && matchkey)
3639 if(profile->bits < 8) profile->bits = 8;
3645 if(!color_tree_has(&tree,
r, g, b, a))
3647 color_tree_add(&tree,
r, g, b, a, profile->numcolors);
3648 if(profile->numcolors < 256)
3650 unsigned char* p = profile->palette;
3651 unsigned n = profile->numcolors;
3657 ++profile->numcolors;
3658 numcolors_done = profile->numcolors >= maxnumcolors;
3662 if(alpha_done && numcolors_done && colored_done && bits_done)
break;
3666 profile->key_r += (profile->key_r << 8);
3667 profile->key_g += (profile->key_g << 8);
3668 profile->key_b += (profile->key_b << 8);
3671 color_tree_cleanup(&tree);
3680 unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out,
3681 const unsigned char* image,
unsigned w,
unsigned h,
3682 const LodePNGColorMode* mode_in)
3684 LodePNGColorProfile prof;
3686 unsigned i, n, palettebits, grey_ok, palette_ok;
3688 lodepng_color_profile_init(&prof);
3689 error = lodepng_get_color_profile(&prof, image, w, h, mode_in);
3690 if(error)
return error;
3691 mode_out->key_defined = 0;
3693 if(prof.key && w * h <= 16)
3696 if(prof.bits < 8) prof.bits = 8;
3698 grey_ok = !prof.colored && !prof.alpha;
3700 palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8));
3701 palette_ok = n <= 256 && (n * 2 < w * h) && prof.bits <= 8;
3702 if(w * h < n * 2) palette_ok = 0;
3703 if(grey_ok && prof.bits <= palettebits) palette_ok = 0;
3707 unsigned char* p = prof.palette;
3708 lodepng_palette_clear(mode_out);
3709 for(i = 0; i != prof.numcolors; ++i)
3711 error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]);
3715 mode_out->colortype = LCT_PALETTE;
3716 mode_out->bitdepth = palettebits;
3718 if(mode_in->colortype == LCT_PALETTE && mode_in->palettesize >= mode_out->palettesize
3719 && mode_in->bitdepth == mode_out->bitdepth)
3722 lodepng_color_mode_cleanup(mode_out);
3723 lodepng_color_mode_copy(mode_out, mode_in);
3728 mode_out->bitdepth = prof.bits;
3729 mode_out->colortype = prof.alpha ? (prof.colored ? LCT_RGBA : LCT_GREY_ALPHA)
3730 : (prof.colored ? LCT_RGB : LCT_GREY);
3732 if(prof.key && !prof.alpha)
3734 unsigned mask = (1u << mode_out->bitdepth) - 1u;
3735 mode_out->key_r = prof.key_r &
mask;
3736 mode_out->key_g = prof.key_g &
mask;
3737 mode_out->key_b = prof.key_b &
mask;
3738 mode_out->key_defined = 1;
3752 static unsigned char paethPredictor(
short a,
short b,
short c)
3754 short pa = abs(b - c);
3755 short pb = abs(a - c);
3756 short pc = abs(a + b - c - c);
3758 if(
pc < pa &&
pc < pb)
return (
unsigned char)c;
3759 else if(pb < pa)
return (
unsigned char)b;
3760 else return (
unsigned char)a;
3765 static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 };
3766 static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 };
3767 static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 };
3768 static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 };
3785 static void Adam7_getpassvalues(
unsigned passw[7],
unsigned passh[7],
size_t filter_passstart[8],
3786 size_t padded_passstart[8],
size_t passstart[8],
unsigned w,
unsigned h,
unsigned bpp)
3792 for(i = 0; i != 7; ++i)
3794 passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i];
3795 passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i];
3796 if(passw[i] == 0) passh[i] = 0;
3797 if(passh[i] == 0) passw[i] = 0;
3800 filter_passstart[0] = padded_passstart[0] = passstart[0] = 0;
3801 for(i = 0; i != 7; ++i)
3804 filter_passstart[i + 1] = filter_passstart[i]
3805 + ((passw[i] && passh[i]) ? passh[i] * (1 + (passw[i] * bpp + 7) / 8) : 0);
3807 padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7) / 8);
3809 passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7) / 8;
3813 #ifdef LODEPNG_COMPILE_DECODER
3820 unsigned lodepng_inspect(
unsigned* w,
unsigned* h, LodePNGState* state,
3821 const unsigned char* in,
size_t insize)
3823 LodePNGInfo* info = &state->info_png;
3824 if(insize == 0 || in == 0)
3826 CERROR_RETURN_ERROR(state->error, 48);
3830 CERROR_RETURN_ERROR(state->error, 27);
3834 lodepng_info_cleanup(info);
3835 lodepng_info_init(info);
3837 if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71
3838 || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10)
3840 CERROR_RETURN_ERROR(state->error, 28);
3842 if(in[12] !=
'I' || in[13] !=
'H' || in[14] !=
'D' || in[15] !=
'R')
3844 CERROR_RETURN_ERROR(state->error, 29);
3848 *w = lodepng_read32bitInt(&in[16]);
3849 *h = lodepng_read32bitInt(&in[20]);
3850 info->color.bitdepth = in[24];
3851 info->color.colortype = (LodePNGColorType)in[25];
3852 info->compression_method = in[26];
3853 info->filter_method = in[27];
3854 info->interlace_method = in[28];
3856 if(*w == 0 || *h == 0)
3858 CERROR_RETURN_ERROR(state->error, 93);
3861 if(!state->decoder.ignore_crc)
3863 unsigned CRC = lodepng_read32bitInt(&in[29]);
3864 unsigned checksum = lodepng_crc32(&in[12], 17);
3867 CERROR_RETURN_ERROR(state->error, 57);
3872 if(info->compression_method != 0) CERROR_RETURN_ERROR(state->error, 32);
3874 if(info->filter_method != 0) CERROR_RETURN_ERROR(state->error, 33);
3876 if(info->interlace_method > 1) CERROR_RETURN_ERROR(state->error, 34);
3878 state->error = checkColorValidity(info->color.colortype, info->color.bitdepth);
3879 return state->error;
3882 static unsigned unfilterScanline(
unsigned char* recon,
const unsigned char* scanline,
const unsigned char* precon,
3883 size_t bytewidth,
unsigned char filterType,
size_t length)
3898 for(i = 0; i != length; ++i) recon[i] = scanline[i];
3901 for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
3902 for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth];
3907 for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i];
3911 for(i = 0; i != length; ++i) recon[i] = scanline[i];
3917 for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + precon[i] / 2;
3918 for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2);
3922 for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
3923 for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth] / 2;
3929 for(i = 0; i != bytewidth; ++i)
3931 recon[i] = (
scanline[i] + precon[i]);
3933 for(i = bytewidth; i < length; ++i)
3935 recon[i] = (
scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
3940 for(i = 0; i != bytewidth; ++i)
3944 for(i = bytewidth; i < length; ++i)
3947 recon[i] = (
scanline[i] + recon[i - bytewidth]);
3956 static unsigned unfilter(
unsigned char* out,
const unsigned char* in,
unsigned w,
unsigned h,
unsigned bpp)
3967 unsigned char* prevline = 0;
3970 size_t bytewidth = (bpp + 7) / 8;
3971 size_t linebytes = (w * bpp + 7) / 8;
3973 for(
y = 0;
y < h; ++
y)
3975 size_t outindex = linebytes *
y;
3976 size_t inindex = (1 + linebytes) *
y;
3977 unsigned char filterType = in[inindex];
3979 CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes));
3981 prevline = &out[outindex];
3998 static void Adam7_deinterlace(
unsigned char* out,
const unsigned char* in,
unsigned w,
unsigned h,
unsigned bpp)
4000 unsigned passw[7], passh[7];
4001 size_t filter_passstart[8], padded_passstart[8], passstart[8];
4004 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
4008 for(i = 0; i != 7; ++i)
4011 size_t bytewidth = bpp / 8;
4012 for(
y = 0;
y < passh[i]; ++
y)
4013 for(
x = 0;
x < passw[i]; ++
x)
4015 size_t pixelinstart = passstart[i] + (
y * passw[i] +
x) * bytewidth;
4016 size_t pixeloutstart = ((ADAM7_IY[i] +
y * ADAM7_DY[i]) * w + ADAM7_IX[i] +
x * ADAM7_DX[i]) * bytewidth;
4017 for(b = 0; b < bytewidth; ++b)
4019 out[pixeloutstart + b] = in[pixelinstart + b];
4026 for(i = 0; i != 7; ++i)
4029 unsigned ilinebits = bpp * passw[i];
4030 unsigned olinebits = bpp * w;
4032 for(
y = 0;
y < passh[i]; ++
y)
4033 for(
x = 0;
x < passw[i]; ++
x)
4035 ibp = (8 * passstart[i]) + (
y * ilinebits +
x * bpp);
4036 obp = (ADAM7_IY[i] +
y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] +
x * ADAM7_DX[i]) * bpp;
4037 for(b = 0; b < bpp; ++b)
4039 unsigned char bit = readBitFromReversedStream(&ibp, in);
4041 setBitOfReversedStream0(&obp, out, bit);
4048 static void removePaddingBits(
unsigned char* out,
const unsigned char* in,
4049 size_t olinebits,
size_t ilinebits,
unsigned h)
4061 size_t diff = ilinebits - olinebits;
4062 size_t ibp = 0, obp = 0;
4063 for(
y = 0;
y < h; ++
y)
4066 for(
x = 0;
x < olinebits; ++
x)
4068 unsigned char bit = readBitFromReversedStream(&ibp, in);
4069 setBitOfReversedStream(&obp, out, bit);
4078 static unsigned postProcessScanlines(
unsigned char* out,
unsigned char* in,
4079 unsigned w,
unsigned h,
const LodePNGInfo* info_png)
4088 unsigned bpp = lodepng_get_bpp(&info_png->color);
4089 if(bpp == 0)
return 31;
4091 if(info_png->interlace_method == 0)
4093 if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8)
4095 CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp));
4096 removePaddingBits(out, in, w * bpp, ((w * bpp + 7) / 8) * 8, h);
4099 else CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp));
4103 unsigned passw[7], passh[7];
size_t filter_passstart[8], padded_passstart[8], passstart[8];
4106 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
4108 for(i = 0; i != 7; ++i)
4110 CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp));
4117 removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp,
4118 ((passw[i] * bpp + 7) / 8) * 8, passh[i]);
4122 Adam7_deinterlace(out, in, w, h, bpp);
4128 static unsigned readChunk_PLTE(LodePNGColorMode* color,
const unsigned char*
data,
size_t chunkLength)
4130 unsigned pos = 0, i;
4131 if(color->palette) lodepng_free(color->palette);
4132 color->palettesize = chunkLength / 3;
4133 color->palette = (
unsigned char*)lodepng_malloc(4 * color->palettesize);
4134 if(!color->palette && color->palettesize)
4136 color->palettesize = 0;
4139 if(color->palettesize > 256)
return 38;
4141 for(i = 0; i != color->palettesize; ++i)
4143 color->palette[4 * i + 0] =
data[pos++];
4144 color->palette[4 * i + 1] =
data[pos++];
4145 color->palette[4 * i + 2] =
data[pos++];
4146 color->palette[4 * i + 3] = 255;
4152 static unsigned readChunk_tRNS(LodePNGColorMode* color,
const unsigned char*
data,
size_t chunkLength)
4155 if(color->colortype == LCT_PALETTE)
4158 if(chunkLength > color->palettesize)
return 38;
4160 for(i = 0; i != chunkLength; ++i) color->palette[4 * i + 3] =
data[i];
4162 else if(color->colortype == LCT_GREY)
4165 if(chunkLength != 2)
return 30;
4167 color->key_defined = 1;
4168 color->key_r = color->key_g = color->key_b = 256u *
data[0] +
data[1];
4170 else if(color->colortype == LCT_RGB)
4173 if(chunkLength != 6)
return 41;
4175 color->key_defined = 1;
4176 color->key_r = 256u *
data[0] +
data[1];
4177 color->key_g = 256u *
data[2] +
data[3];
4178 color->key_b = 256u *
data[4] +
data[5];
4186 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4188 static unsigned readChunk_bKGD(LodePNGInfo* info,
const unsigned char*
data,
size_t chunkLength)
4190 if(info->color.colortype == LCT_PALETTE)
4193 if(chunkLength != 1)
return 43;
4195 info->background_defined = 1;
4196 info->background_r = info->background_g = info->background_b =
data[0];
4198 else if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA)
4201 if(chunkLength != 2)
return 44;
4203 info->background_defined = 1;
4204 info->background_r = info->background_g = info->background_b = 256u *
data[0] +
data[1];
4206 else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA)
4209 if(chunkLength != 6)
return 45;
4211 info->background_defined = 1;
4212 info->background_r = 256u *
data[0] +
data[1];
4213 info->background_g = 256u *
data[2] +
data[3];
4214 info->background_b = 256u *
data[4] +
data[5];
4221 static unsigned readChunk_tEXt(LodePNGInfo* info,
const unsigned char*
data,
size_t chunkLength)
4224 char *key = 0, *str = 0;
4229 unsigned length, string2_begin;
4232 while(length < chunkLength &&
data[length] != 0) ++length;
4235 if(length < 1 || length > 79) CERROR_BREAK(error, 89);
4237 key = (
char*)lodepng_malloc(length + 1);
4238 if(!key) CERROR_BREAK(error, 83);
4241 for(i = 0; i != length; ++i) key[i] = (
char)
data[i];
4243 string2_begin = length + 1;
4245 length = chunkLength < string2_begin ? 0 : chunkLength - string2_begin;
4246 str = (
char*)lodepng_malloc(length + 1);
4247 if(!str) CERROR_BREAK(error, 83);
4250 for(i = 0; i != length; ++i) str[i] = (
char)
data[string2_begin + i];
4252 error = lodepng_add_text(info, key, str);
4264 static unsigned readChunk_zTXt(LodePNGInfo* info,
const LodePNGDecompressSettings* zlibsettings,
4265 const unsigned char*
data,
size_t chunkLength)
4270 unsigned length, string2_begin;
4274 ucvector_init(&decoded);
4278 for(length = 0; length < chunkLength &&
data[length] != 0; ++length) ;
4279 if(length + 2 >= chunkLength) CERROR_BREAK(error, 75);
4280 if(length < 1 || length > 79) CERROR_BREAK(error, 89);
4282 key = (
char*)lodepng_malloc(length + 1);
4283 if(!key) CERROR_BREAK(error, 83);
4286 for(i = 0; i != length; ++i) key[i] = (
char)
data[i];
4288 if(
data[length + 1] != 0) CERROR_BREAK(error, 72);
4290 string2_begin = length + 2;
4291 if(string2_begin > chunkLength) CERROR_BREAK(error, 75);
4293 length = chunkLength - string2_begin;
4295 error = zlib_decompress(&decoded.data, &decoded.size,
4296 (
unsigned char*)(&
data[string2_begin]),
4297 length, zlibsettings);
4299 ucvector_push_back(&decoded, 0);
4301 error = lodepng_add_text(info, key, (
char*)decoded.data);
4307 ucvector_cleanup(&decoded);
4313 static unsigned readChunk_iTXt(LodePNGInfo* info,
const LodePNGDecompressSettings* zlibsettings,
4314 const unsigned char*
data,
size_t chunkLength)
4319 unsigned length, begin, compressed;
4320 char *key = 0, *langtag = 0, *transkey = 0;
4322 ucvector_init(&decoded);
4328 if(chunkLength < 5) CERROR_BREAK(error, 30);
4331 for(length = 0; length < chunkLength &&
data[length] != 0; ++length) ;
4332 if(length + 3 >= chunkLength) CERROR_BREAK(error, 75);
4333 if(length < 1 || length > 79) CERROR_BREAK(error, 89);
4335 key = (
char*)lodepng_malloc(length + 1);
4336 if(!key) CERROR_BREAK(error, 83);
4339 for(i = 0; i != length; ++i) key[i] = (
char)
data[i];
4342 compressed =
data[length + 1];
4343 if(
data[length + 2] != 0) CERROR_BREAK(error, 72);
4351 for(i = begin; i < chunkLength &&
data[i] != 0; ++i) ++length;
4353 langtag = (
char*)lodepng_malloc(length + 1);
4354 if(!langtag) CERROR_BREAK(error, 83);
4356 langtag[length] = 0;
4357 for(i = 0; i != length; ++i) langtag[i] = (
char)
data[begin + i];
4360 begin += length + 1;
4362 for(i = begin; i < chunkLength &&
data[i] != 0; ++i) ++length;
4364 transkey = (
char*)lodepng_malloc(length + 1);
4365 if(!transkey) CERROR_BREAK(error, 83);
4367 transkey[length] = 0;
4368 for(i = 0; i != length; ++i) transkey[i] = (
char)
data[begin + i];
4371 begin += length + 1;
4373 length = chunkLength < begin ? 0 : chunkLength - begin;
4378 error = zlib_decompress(&decoded.data, &decoded.size,
4379 (
unsigned char*)(&
data[begin]),
4380 length, zlibsettings);
4382 if(decoded.allocsize < decoded.size) decoded.allocsize = decoded.size;
4383 ucvector_push_back(&decoded, 0);
4387 if(!ucvector_resize(&decoded, length + 1)) CERROR_BREAK(error, 83 );
4389 decoded.data[length] = 0;
4390 for(i = 0; i != length; ++i) decoded.data[i] =
data[begin + i];
4393 error = lodepng_add_itext(info, key, langtag, transkey, (
char*)decoded.data);
4399 lodepng_free(langtag);
4400 lodepng_free(transkey);
4401 ucvector_cleanup(&decoded);
4406 static unsigned readChunk_tIME(LodePNGInfo* info,
const unsigned char*
data,
size_t chunkLength)
4408 if(chunkLength != 7)
return 73;
4410 info->time_defined = 1;
4411 info->time.year = 256u *
data[0] +
data[1];
4412 info->time.month =
data[2];
4413 info->time.day =
data[3];
4414 info->time.hour =
data[4];
4415 info->time.minute =
data[5];
4416 info->time.second =
data[6];
4421 static unsigned readChunk_pHYs(LodePNGInfo* info,
const unsigned char*
data,
size_t chunkLength)
4423 if(chunkLength != 9)
return 74;
4425 info->phys_defined = 1;
4426 info->phys_x = 16777216u *
data[0] + 65536u *
data[1] + 256u *
data[2] +
data[3];
4427 info->phys_y = 16777216u *
data[4] + 65536u *
data[5] + 256u *
data[6] +
data[7];
4428 info->phys_unit =
data[8];
4435 static void decodeGeneric(
unsigned char** out,
unsigned* w,
unsigned* h,
4436 LodePNGState* state,
4437 const unsigned char* in,
size_t insize)
4439 unsigned char IEND = 0;
4440 const unsigned char* chunk;
4448 unsigned unknown = 0;
4449 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4450 unsigned critical_pos = 1;
4456 state->error = lodepng_inspect(w, h, state, in, insize);
4457 if(state->error)
return;
4459 numpixels = *w * *h;
4462 if(*h != 0 && numpixels / *h != *w) CERROR_RETURN(state->error, 92);
4465 if(numpixels > 268435455) CERROR_RETURN(state->error, 92);
4467 ucvector_init(&idat);
4472 while(!IEND && !state->error)
4474 unsigned chunkLength;
4475 const unsigned char*
data;
4478 if((
size_t)((chunk - in) + 12) > insize || chunk < in) CERROR_BREAK(state->error, 30);
4481 chunkLength = lodepng_chunk_length(chunk);
4483 if(chunkLength > 2147483647) CERROR_BREAK(state->error, 63);
4485 if((
size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in)
4487 CERROR_BREAK(state->error, 64);
4490 data = lodepng_chunk_data_const(chunk);
4493 if(lodepng_chunk_type_equals(chunk,
"IDAT"))
4495 size_t oldsize = idat.size;
4496 if(!ucvector_resize(&idat, oldsize + chunkLength)) CERROR_BREAK(state->error, 83 );
4497 for(i = 0; i != chunkLength; ++i) idat.data[oldsize + i] =
data[i];
4498 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4503 else if(lodepng_chunk_type_equals(chunk,
"IEND"))
4508 else if(lodepng_chunk_type_equals(chunk,
"PLTE"))
4510 state->error = readChunk_PLTE(&state->info_png.color,
data, chunkLength);
4511 if(state->error)
break;
4512 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4517 else if(lodepng_chunk_type_equals(chunk,
"tRNS"))
4519 state->error = readChunk_tRNS(&state->info_png.color,
data, chunkLength);
4520 if(state->error)
break;
4522 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4524 else if(lodepng_chunk_type_equals(chunk,
"bKGD"))
4526 state->error = readChunk_bKGD(&state->info_png,
data, chunkLength);
4527 if(state->error)
break;
4530 else if(lodepng_chunk_type_equals(chunk,
"tEXt"))
4532 if(state->decoder.read_text_chunks)
4534 state->error = readChunk_tEXt(&state->info_png,
data, chunkLength);
4535 if(state->error)
break;
4539 else if(lodepng_chunk_type_equals(chunk,
"zTXt"))
4541 if(state->decoder.read_text_chunks)
4543 state->error = readChunk_zTXt(&state->info_png, &state->decoder.zlibsettings,
data, chunkLength);
4544 if(state->error)
break;
4548 else if(lodepng_chunk_type_equals(chunk,
"iTXt"))
4550 if(state->decoder.read_text_chunks)
4552 state->error = readChunk_iTXt(&state->info_png, &state->decoder.zlibsettings,
data, chunkLength);
4553 if(state->error)
break;
4556 else if(lodepng_chunk_type_equals(chunk,
"tIME"))
4558 state->error = readChunk_tIME(&state->info_png,
data, chunkLength);
4559 if(state->error)
break;
4561 else if(lodepng_chunk_type_equals(chunk,
"pHYs"))
4563 state->error = readChunk_pHYs(&state->info_png,
data, chunkLength);
4564 if(state->error)
break;
4570 if(!lodepng_chunk_ancillary(chunk)) CERROR_BREAK(state->error, 69);
4573 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4574 if(state->decoder.remember_unknown_chunks)
4576 state->error = lodepng_chunk_append(&state->info_png.unknown_chunks_data[critical_pos - 1],
4577 &state->info_png.unknown_chunks_size[critical_pos - 1], chunk);
4578 if(state->error)
break;
4583 if(!state->decoder.ignore_crc && !unknown)
4585 if(lodepng_chunk_check_crc(chunk)) CERROR_BREAK(state->error, 57);
4588 if(!IEND) chunk = lodepng_chunk_next_const(chunk);
4591 ucvector_init(&scanlines);
4594 if(state->info_png.interlace_method == 0)
4597 predict = lodepng_get_raw_size_idat(*w, *h, &state->info_png.color) + *h;
4602 const LodePNGColorMode* color = &state->info_png.color;
4604 predict += lodepng_get_raw_size_idat((*w + 7) / 8, (*h + 7) / 8, color) + (*h + 7) / 8;
4605 if(*w > 4) predict += lodepng_get_raw_size_idat((*w + 3) / 8, (*h + 7) / 8, color) + (*h + 7) / 8;
4606 predict += lodepng_get_raw_size_idat((*w + 3) / 4, (*h + 3) / 8, color) + (*h + 3) / 8;
4607 if(*w > 2) predict += lodepng_get_raw_size_idat((*w + 1) / 4, (*h + 3) / 4, color) + (*h + 3) / 4;
4608 predict += lodepng_get_raw_size_idat((*w + 1) / 2, (*h + 1) / 4, color) + (*h + 1) / 4;
4609 if(*w > 1) predict += lodepng_get_raw_size_idat((*w + 0) / 2, (*h + 1) / 2, color) + (*h + 1) / 2;
4610 predict += lodepng_get_raw_size_idat((*w + 0) / 1, (*h + 0) / 2, color) + (*h + 0) / 2;
4612 if(!state->error && !ucvector_reserve(&scanlines, predict)) state->error = 83;
4615 state->error = zlib_decompress(&scanlines.data, &scanlines.size, idat.data,
4616 idat.size, &state->decoder.zlibsettings);
4617 if(!state->error && scanlines.size != predict) state->error = 91;
4619 ucvector_cleanup(&idat);
4623 size_t outsize = lodepng_get_raw_size(*w, *h, &state->info_png.color);
4625 ucvector_init(&outv);
4626 if(!ucvector_resizev(&outv, outsize, 0)) state->error = 83;
4627 if(!state->error) state->error = postProcessScanlines(outv.data, scanlines.data, *w, *h, &state->info_png);
4630 ucvector_cleanup(&scanlines);
4633 unsigned lodepng_decode(
unsigned char** out,
unsigned* w,
unsigned* h,
4634 LodePNGState* state,
4635 const unsigned char* in,
size_t insize)
4638 decodeGeneric(out, w, h, state, in, insize);
4639 if(state->error)
return state->error;
4640 if(!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color))
4645 if(!state->decoder.color_convert)
4647 state->error = lodepng_color_mode_copy(&state->info_raw, &state->info_png.color);
4648 if(state->error)
return state->error;
4654 unsigned char*
data = *out;
4659 if(!(state->info_raw.colortype == LCT_RGB || state->info_raw.colortype == LCT_RGBA)
4660 && !(state->info_raw.bitdepth == 8))
4665 outsize = lodepng_get_raw_size(*w, *h, &state->info_raw);
4666 *out = (
unsigned char*)lodepng_malloc(outsize);
4671 else state->error = lodepng_convert(*out,
data, &state->info_raw,
4672 &state->info_png.color, *w, *h);
4675 return state->error;
4678 unsigned lodepng_decode_memory(
unsigned char** out,
unsigned* w,
unsigned* h,
const unsigned char* in,
4679 size_t insize, LodePNGColorType colortype,
unsigned bitdepth)
4683 lodepng_state_init(&state);
4684 state.info_raw.colortype = colortype;
4685 state.info_raw.bitdepth = bitdepth;
4686 error = lodepng_decode(out, w, h, &state, in, insize);
4687 lodepng_state_cleanup(&state);
4691 unsigned lodepng_decode32(
unsigned char** out,
unsigned* w,
unsigned* h,
const unsigned char* in,
size_t insize)
4693 return lodepng_decode_memory(out, w, h, in, insize, LCT_RGBA, 8);
4696 unsigned lodepng_decode24(
unsigned char** out,
unsigned* w,
unsigned* h,
const unsigned char* in,
size_t insize)
4698 return lodepng_decode_memory(out, w, h, in, insize, LCT_RGB, 8);
4701 #ifdef LODEPNG_COMPILE_DISK
4702 unsigned lodepng_decode_file(
unsigned char** out,
unsigned* w,
unsigned* h,
const char* filename,
4703 LodePNGColorType colortype,
unsigned bitdepth)
4705 unsigned char* buffer;
4708 error = lodepng_load_file(&buffer, &buffersize, filename);
4709 if(!error) error = lodepng_decode_memory(out, w, h, buffer, buffersize, colortype, bitdepth);
4710 lodepng_free(buffer);
4714 unsigned lodepng_decode32_file(
unsigned char** out,
unsigned* w,
unsigned* h,
const char* filename)
4716 return lodepng_decode_file(out, w, h, filename, LCT_RGBA, 8);
4719 unsigned lodepng_decode24_file(
unsigned char** out,
unsigned* w,
unsigned* h,
const char* filename)
4721 return lodepng_decode_file(out, w, h, filename, LCT_RGB, 8);
4725 void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings)
4727 settings->color_convert = 1;
4728 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4729 settings->read_text_chunks = 1;
4730 settings->remember_unknown_chunks = 0;
4732 settings->ignore_crc = 0;
4733 lodepng_decompress_settings_init(&settings->zlibsettings);
4738 #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER)
4740 void lodepng_state_init(LodePNGState* state)
4742 #ifdef LODEPNG_COMPILE_DECODER
4743 lodepng_decoder_settings_init(&state->decoder);
4745 #ifdef LODEPNG_COMPILE_ENCODER
4746 lodepng_encoder_settings_init(&state->encoder);
4748 lodepng_color_mode_init(&state->info_raw);
4749 lodepng_info_init(&state->info_png);
4753 void lodepng_state_cleanup(LodePNGState* state)
4755 lodepng_color_mode_cleanup(&state->info_raw);
4756 lodepng_info_cleanup(&state->info_png);
4759 void lodepng_state_copy(LodePNGState* dest,
const LodePNGState* source)
4761 lodepng_state_cleanup(dest);
4763 lodepng_color_mode_init(&dest->info_raw);
4764 lodepng_info_init(&dest->info_png);
4765 dest->error = lodepng_color_mode_copy(&dest->info_raw, &source->info_raw);
if(dest->error)
return;
4766 dest->error = lodepng_info_copy(&dest->info_png, &source->info_png);
if(dest->error)
return;
4771 #ifdef LODEPNG_COMPILE_ENCODER
4778 static unsigned addChunk(ucvector* out,
const char* chunkName,
const unsigned char*
data,
size_t length)
4780 CERROR_TRY_RETURN(lodepng_chunk_create(&out->data, &out->size, (
unsigned)length, chunkName,
data));
4781 out->allocsize = out->size;
4785 static void writeSignature(ucvector* out)
4788 ucvector_push_back(out, 137);
4789 ucvector_push_back(out, 80);
4790 ucvector_push_back(out, 78);
4791 ucvector_push_back(out, 71);
4792 ucvector_push_back(out, 13);
4793 ucvector_push_back(out, 10);
4794 ucvector_push_back(out, 26);
4795 ucvector_push_back(out, 10);
4798 static unsigned addChunk_IHDR(ucvector* out,
unsigned w,
unsigned h,
4799 LodePNGColorType colortype,
unsigned bitdepth,
unsigned interlace_method)
4803 ucvector_init(&header);
4805 lodepng_add32bitInt(&header, w);
4806 lodepng_add32bitInt(&header, h);
4807 ucvector_push_back(&header, (
unsigned char)bitdepth);
4808 ucvector_push_back(&header, (
unsigned char)colortype);
4809 ucvector_push_back(&header, 0);
4810 ucvector_push_back(&header, 0);
4811 ucvector_push_back(&header, interlace_method);
4813 error = addChunk(out,
"IHDR", header.data, header.size);
4814 ucvector_cleanup(&header);
4819 static unsigned addChunk_PLTE(ucvector* out,
const LodePNGColorMode* info)
4824 ucvector_init(&PLTE);
4825 for(i = 0; i != info->palettesize * 4; ++i)
4828 if(i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]);
4830 error = addChunk(out,
"PLTE", PLTE.data, PLTE.size);
4831 ucvector_cleanup(&PLTE);
4836 static unsigned addChunk_tRNS(ucvector* out,
const LodePNGColorMode* info)
4841 ucvector_init(&tRNS);
4842 if(info->colortype == LCT_PALETTE)
4844 size_t amount = info->palettesize;
4846 for(i = info->palettesize; i != 0; --i)
4848 if(info->palette[4 * (i - 1) + 3] == 255) --amount;
4852 for(i = 0; i != amount; ++i) ucvector_push_back(&tRNS, info->palette[4 * i + 3]);
4854 else if(info->colortype == LCT_GREY)
4856 if(info->key_defined)
4858 ucvector_push_back(&tRNS, (
unsigned char)(info->key_r / 256));
4859 ucvector_push_back(&tRNS, (
unsigned char)(info->key_r % 256));
4862 else if(info->colortype == LCT_RGB)
4864 if(info->key_defined)
4866 ucvector_push_back(&tRNS, (
unsigned char)(info->key_r / 256));
4867 ucvector_push_back(&tRNS, (
unsigned char)(info->key_r % 256));
4868 ucvector_push_back(&tRNS, (
unsigned char)(info->key_g / 256));
4869 ucvector_push_back(&tRNS, (
unsigned char)(info->key_g % 256));
4870 ucvector_push_back(&tRNS, (
unsigned char)(info->key_b / 256));
4871 ucvector_push_back(&tRNS, (
unsigned char)(info->key_b % 256));
4875 error = addChunk(out,
"tRNS", tRNS.data, tRNS.size);
4876 ucvector_cleanup(&tRNS);
4881 static unsigned addChunk_IDAT(ucvector* out,
const unsigned char*
data,
size_t datasize,
4882 LodePNGCompressSettings* zlibsettings)
4888 ucvector_init(&zlibdata);
4889 error = zlib_compress(&zlibdata.data, &zlibdata.size,
data, datasize, zlibsettings);
4890 if(!error) error = addChunk(out,
"IDAT", zlibdata.data, zlibdata.size);
4891 ucvector_cleanup(&zlibdata);
4896 static unsigned addChunk_IEND(ucvector* out)
4899 error = addChunk(out,
"IEND", 0, 0);
4903 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4905 static unsigned addChunk_tEXt(ucvector* out,
const char* keyword,
const char* textstring)
4910 ucvector_init(&
text);
4911 for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&
text, (
unsigned char)keyword[i]);
4912 if(i < 1 || i > 79)
return 89;
4913 ucvector_push_back(&
text, 0);
4914 for(i = 0; textstring[i] != 0; ++i) ucvector_push_back(&
text, (
unsigned char)textstring[i]);
4915 error = addChunk(out,
"tEXt",
text.data,
text.size);
4916 ucvector_cleanup(&
text);
4921 static unsigned addChunk_zTXt(ucvector* out,
const char* keyword,
const char* textstring,
4922 LodePNGCompressSettings* zlibsettings)
4925 ucvector
data, compressed;
4926 size_t i, textsize = strlen(textstring);
4928 ucvector_init(&
data);
4929 ucvector_init(&compressed);
4930 for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&
data, (
unsigned char)keyword[i]);
4931 if(i < 1 || i > 79)
return 89;
4932 ucvector_push_back(&
data, 0);
4933 ucvector_push_back(&
data, 0);
4935 error = zlib_compress(&compressed.data, &compressed.size,
4936 (
unsigned char*)textstring, textsize, zlibsettings);
4939 for(i = 0; i != compressed.size; ++i) ucvector_push_back(&
data, compressed.data[i]);
4940 error = addChunk(out,
"zTXt",
data.data,
data.size);
4943 ucvector_cleanup(&compressed);
4944 ucvector_cleanup(&
data);
4948 static unsigned addChunk_iTXt(ucvector* out,
unsigned compressed,
const char* keyword,
const char* langtag,
4949 const char* transkey,
const char* textstring, LodePNGCompressSettings* zlibsettings)
4953 size_t i, textsize = strlen(textstring);
4955 ucvector_init(&
data);
4957 for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&
data, (
unsigned char)keyword[i]);
4958 if(i < 1 || i > 79)
return 89;
4959 ucvector_push_back(&
data, 0);
4960 ucvector_push_back(&
data, compressed ? 1 : 0);
4961 ucvector_push_back(&
data, 0);
4962 for(i = 0; langtag[i] != 0; ++i) ucvector_push_back(&
data, (
unsigned char)langtag[i]);
4963 ucvector_push_back(&
data, 0);
4964 for(i = 0; transkey[i] != 0; ++i) ucvector_push_back(&
data, (
unsigned char)transkey[i]);
4965 ucvector_push_back(&
data, 0);
4969 ucvector compressed_data;
4970 ucvector_init(&compressed_data);
4971 error = zlib_compress(&compressed_data.data, &compressed_data.size,
4972 (
unsigned char*)textstring, textsize, zlibsettings);
4975 for(i = 0; i != compressed_data.size; ++i) ucvector_push_back(&
data, compressed_data.data[i]);
4977 ucvector_cleanup(&compressed_data);
4981 for(i = 0; textstring[i] != 0; ++i) ucvector_push_back(&
data, (
unsigned char)textstring[i]);
4984 if(!error) error = addChunk(out,
"iTXt",
data.data,
data.size);
4985 ucvector_cleanup(&
data);
4989 static unsigned addChunk_bKGD(ucvector* out,
const LodePNGInfo* info)
4993 ucvector_init(&bKGD);
4994 if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA)
4996 ucvector_push_back(&bKGD, (
unsigned char)(info->background_r / 256));
4997 ucvector_push_back(&bKGD, (
unsigned char)(info->background_r % 256));
4999 else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA)
5001 ucvector_push_back(&bKGD, (
unsigned char)(info->background_r / 256));
5002 ucvector_push_back(&bKGD, (
unsigned char)(info->background_r % 256));
5003 ucvector_push_back(&bKGD, (
unsigned char)(info->background_g / 256));
5004 ucvector_push_back(&bKGD, (
unsigned char)(info->background_g % 256));
5005 ucvector_push_back(&bKGD, (
unsigned char)(info->background_b / 256));
5006 ucvector_push_back(&bKGD, (
unsigned char)(info->background_b % 256));
5008 else if(info->color.colortype == LCT_PALETTE)
5010 ucvector_push_back(&bKGD, (
unsigned char)(info->background_r % 256));
5013 error = addChunk(out,
"bKGD", bKGD.data, bKGD.size);
5014 ucvector_cleanup(&bKGD);
5019 static unsigned addChunk_tIME(ucvector* out,
const LodePNGTime* time)
5022 unsigned char*
data = (
unsigned char*)lodepng_malloc(7);
5023 if(!
data)
return 83;
5024 data[0] = (
unsigned char)(time->year / 256);
5025 data[1] = (
unsigned char)(time->year % 256);
5026 data[2] = (
unsigned char)time->month;
5027 data[3] = (
unsigned char)time->day;
5028 data[4] = (
unsigned char)time->hour;
5029 data[5] = (
unsigned char)time->minute;
5030 data[6] = (
unsigned char)time->second;
5031 error = addChunk(out,
"tIME",
data, 7);
5036 static unsigned addChunk_pHYs(ucvector* out,
const LodePNGInfo* info)
5040 ucvector_init(&
data);
5042 lodepng_add32bitInt(&
data, info->phys_x);
5043 lodepng_add32bitInt(&
data, info->phys_y);
5044 ucvector_push_back(&
data, info->phys_unit);
5046 error = addChunk(out,
"pHYs",
data.data,
data.size);
5047 ucvector_cleanup(&
data);
5054 static void filterScanline(
unsigned char* out,
const unsigned char* scanline,
const unsigned char* prevline,
5055 size_t length,
size_t bytewidth,
unsigned char filterType)
5061 for(i = 0; i != length; ++i) out[i] = scanline[i];
5064 for(i = 0; i != bytewidth; ++i) out[i] = scanline[i];
5065 for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth];
5070 for(i = 0; i != length; ++i) out[i] = scanline[i] - prevline[i];
5074 for(i = 0; i != length; ++i) out[i] = scanline[i];
5080 for(i = 0; i != bytewidth; ++i) out[i] = scanline[i] - prevline[i] / 2;
5081 for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) / 2);
5085 for(i = 0; i != bytewidth; ++i) out[i] = scanline[i];
5086 for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth] / 2;
5093 for(i = 0; i != bytewidth; ++i) out[i] = (scanline[i] - prevline[i]);
5094 for(i = bytewidth; i < length; ++i)
5096 out[i] = (
scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth]));
5101 for(i = 0; i != bytewidth; ++i) out[i] = scanline[i];
5103 for(i = bytewidth; i < length; ++i) out[i] = (scanline[i] - scanline[i - bytewidth]);
5111 static float flog2(
float f)
5114 while(f > 32) { result += 4; f /= 16; }
5115 while(f > 2) { ++result; f /= 2; }
5116 return result + 1.442695f * (f * f * f / 3 - 3 * f * f / 2 + 3 * f - 1.83333f);
5119 static unsigned filter(
unsigned char* out,
const unsigned char* in,
unsigned w,
unsigned h,
5120 const LodePNGColorMode* info,
const LodePNGEncoderSettings* settings)
5128 unsigned bpp = lodepng_get_bpp(info);
5130 size_t linebytes = (w * bpp + 7) / 8;
5132 size_t bytewidth = (bpp + 7) / 8;
5133 const unsigned char* prevline = 0;
5136 LodePNGFilterStrategy strategy = settings->filter_strategy;
5151 if(settings->filter_palette_zero &&
5152 (info->colortype == LCT_PALETTE || info->bitdepth < 8)) strategy = LFS_ZERO;
5154 if(bpp == 0)
return 31;
5156 if(strategy == LFS_ZERO)
5158 for(
y = 0;
y != h; ++
y)
5160 size_t outindex = (1 + linebytes) *
y;
5161 size_t inindex = linebytes *
y;
5163 filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, 0);
5164 prevline = &in[inindex];
5167 else if(strategy == LFS_MINSUM)
5171 ucvector attempt[5];
5172 size_t smallest = 0;
5173 unsigned char type, bestType = 0;
5175 for(type = 0; type != 5; ++type)
5177 ucvector_init(&attempt[type]);
5178 if(!ucvector_resize(&attempt[type], linebytes))
return 83;
5183 for(
y = 0;
y != h; ++
y)
5186 for(type = 0; type != 5; ++type)
5188 filterScanline(attempt[type].
data, &in[
y * linebytes], prevline, linebytes, bytewidth, type);
5194 for(
x = 0;
x != linebytes; ++
x) sum[type] += (
unsigned char)(attempt[type].data[
x]);
5198 for(
x = 0;
x != linebytes; ++
x)
5203 unsigned char s = attempt[type].data[
x];
5204 sum[type] += s < 128 ? s : (255U - s);
5209 if(type == 0 || sum[type] < smallest)
5212 smallest = sum[type];
5216 prevline = &in[
y * linebytes];
5219 out[
y * (linebytes + 1)] = bestType;
5220 for(
x = 0;
x != linebytes; ++
x) out[
y * (linebytes + 1) + 1 +
x] = attempt[bestType].data[
x];
5224 for(type = 0; type != 5; ++type) ucvector_cleanup(&attempt[type]);
5226 else if(strategy == LFS_ENTROPY)
5229 ucvector attempt[5];
5231 unsigned type, bestType = 0;
5232 unsigned count[256];
5234 for(type = 0; type != 5; ++type)
5236 ucvector_init(&attempt[type]);
5237 if(!ucvector_resize(&attempt[type], linebytes))
return 83;
5240 for(
y = 0;
y != h; ++
y)
5243 for(type = 0; type != 5; ++type)
5245 filterScanline(attempt[type].
data, &in[
y * linebytes], prevline, linebytes, bytewidth, type);
5246 for(
x = 0;
x != 256; ++
x) count[
x] = 0;
5247 for(
x = 0;
x != linebytes; ++
x) ++count[attempt[type].
data[
x]];
5250 for(
x = 0;
x != 256; ++
x)
5252 float p = count[
x] / (float)(linebytes + 1);
5253 sum[type] += count[
x] == 0 ? 0 : flog2(1 / p) * p;
5256 if(type == 0 || sum[type] < smallest)
5259 smallest = sum[type];
5263 prevline = &in[
y * linebytes];
5266 out[
y * (linebytes + 1)] = bestType;
5267 for(
x = 0;
x != linebytes; ++
x) out[
y * (linebytes + 1) + 1 +
x] = attempt[bestType].data[
x];
5270 for(type = 0; type != 5; ++type) ucvector_cleanup(&attempt[type]);
5272 else if(strategy == LFS_PREDEFINED)
5274 for(
y = 0;
y != h; ++
y)
5276 size_t outindex = (1 + linebytes) *
y;
5277 size_t inindex = linebytes *
y;
5278 unsigned char type = settings->predefined_filters[
y];
5279 out[outindex] = type;
5280 filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type);
5281 prevline = &in[inindex];
5284 else if(strategy == LFS_BRUTE_FORCE)
5290 ucvector attempt[5];
5291 size_t smallest = 0;
5292 unsigned type = 0, bestType = 0;
5293 unsigned char* dummy;
5294 LodePNGCompressSettings zlibsettings = settings->zlibsettings;
5299 zlibsettings.btype = 1;
5302 zlibsettings.custom_zlib = 0;
5303 zlibsettings.custom_deflate = 0;
5304 for(type = 0; type != 5; ++type)
5306 ucvector_init(&attempt[type]);
5307 ucvector_resize(&attempt[type], linebytes);
5309 for(
y = 0;
y != h; ++
y)
5311 for(type = 0; type != 5; ++type)
5313 unsigned testsize = attempt[type].size;
5316 filterScanline(attempt[type].
data, &in[
y * linebytes], prevline, linebytes, bytewidth, type);
5319 zlib_compress(&dummy, &
size[type], attempt[type].
data, testsize, &zlibsettings);
5320 lodepng_free(dummy);
5322 if(type == 0 ||
size[type] < smallest)
5325 smallest =
size[type];
5328 prevline = &in[
y * linebytes];
5329 out[
y * (linebytes + 1)] = bestType;
5330 for(
x = 0;
x != linebytes; ++
x) out[
y * (linebytes + 1) + 1 +
x] = attempt[bestType].data[
x];
5332 for(type = 0; type != 5; ++type) ucvector_cleanup(&attempt[type]);
5339 static void addPaddingBits(
unsigned char* out,
const unsigned char* in,
5340 size_t olinebits,
size_t ilinebits,
unsigned h)
5345 size_t diff = olinebits - ilinebits;
5346 size_t obp = 0, ibp = 0;
5347 for(
y = 0;
y != h; ++
y)
5350 for(
x = 0;
x < ilinebits; ++
x)
5352 unsigned char bit = readBitFromReversedStream(&ibp, in);
5353 setBitOfReversedStream(&obp, out, bit);
5357 for(
x = 0;
x != diff; ++
x) setBitOfReversedStream(&obp, out, 0);
5372 static void Adam7_interlace(
unsigned char* out,
const unsigned char* in,
unsigned w,
unsigned h,
unsigned bpp)
5374 unsigned passw[7], passh[7];
5375 size_t filter_passstart[8], padded_passstart[8], passstart[8];
5378 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
5382 for(i = 0; i != 7; ++i)
5385 size_t bytewidth = bpp / 8;
5386 for(
y = 0;
y < passh[i]; ++
y)
5387 for(
x = 0;
x < passw[i]; ++
x)
5389 size_t pixelinstart = ((ADAM7_IY[i] +
y * ADAM7_DY[i]) * w + ADAM7_IX[i] +
x * ADAM7_DX[i]) * bytewidth;
5390 size_t pixeloutstart = passstart[i] + (
y * passw[i] +
x) * bytewidth;
5391 for(b = 0; b < bytewidth; ++b)
5393 out[pixeloutstart + b] = in[pixelinstart + b];
5400 for(i = 0; i != 7; ++i)
5403 unsigned ilinebits = bpp * passw[i];
5404 unsigned olinebits = bpp * w;
5406 for(
y = 0;
y < passh[i]; ++
y)
5407 for(
x = 0;
x < passw[i]; ++
x)
5409 ibp = (ADAM7_IY[i] +
y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] +
x * ADAM7_DX[i]) * bpp;
5410 obp = (8 * passstart[i]) + (
y * ilinebits +
x * bpp);
5411 for(b = 0; b < bpp; ++b)
5413 unsigned char bit = readBitFromReversedStream(&ibp, in);
5414 setBitOfReversedStream(&obp, out, bit);
5423 static unsigned preProcessScanlines(
unsigned char** out,
size_t* outsize,
const unsigned char* in,
5424 unsigned w,
unsigned h,
5425 const LodePNGInfo* info_png,
const LodePNGEncoderSettings* settings)
5432 unsigned bpp = lodepng_get_bpp(&info_png->color);
5435 if(info_png->interlace_method == 0)
5437 *outsize = h + (h * ((w * bpp + 7) / 8));
5438 *out = (
unsigned char*)lodepng_malloc(*outsize);
5439 if(!(*out) && (*outsize)) error = 83;
5444 if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8)
5446 unsigned char* padded = (
unsigned char*)lodepng_malloc(h * ((w * bpp + 7) / 8));
5447 if(!padded) error = 83;
5450 addPaddingBits(padded, in, ((w * bpp + 7) / 8) * 8, w * bpp, h);
5451 error = filter(*out, padded, w, h, &info_png->color, settings);
5453 lodepng_free(padded);
5458 error = filter(*out, in, w, h, &info_png->color, settings);
5464 unsigned passw[7], passh[7];
5465 size_t filter_passstart[8], padded_passstart[8], passstart[8];
5466 unsigned char* adam7;
5468 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
5470 *outsize = filter_passstart[7];
5471 *out = (
unsigned char*)lodepng_malloc(*outsize);
5472 if(!(*out)) error = 83;
5474 adam7 = (
unsigned char*)lodepng_malloc(passstart[7]);
5475 if(!adam7 && passstart[7]) error = 83;
5481 Adam7_interlace(adam7, in, w, h, bpp);
5482 for(i = 0; i != 7; ++i)
5486 unsigned char* padded = (
unsigned char*)lodepng_malloc(padded_passstart[i + 1] - padded_passstart[i]);
5487 if(!padded) ERROR_BREAK(83);
5488 addPaddingBits(padded, &adam7[passstart[i]],
5489 ((passw[i] * bpp + 7) / 8) * 8, passw[i] * bpp, passh[i]);
5490 error = filter(&(*out)[filter_passstart[i]], padded,
5491 passw[i], passh[i], &info_png->color, settings);
5492 lodepng_free(padded);
5496 error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]],
5497 passw[i], passh[i], &info_png->color, settings);
5504 lodepng_free(adam7);
5516 static unsigned getPaletteTranslucency(
const unsigned char* palette,
size_t palettesize)
5520 unsigned r = 0, g = 0, b = 0;
5521 for(i = 0; i != palettesize; ++i)
5523 if(!key && palette[4 * i + 3] == 0)
5529 else if(palette[4 * i + 3] != 255)
return 2;
5531 else if(key &&
r == palette[i * 4 + 0] && g == palette[i * 4 + 1] && b == palette[i * 4 + 2])
return 2;
5536 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5537 static unsigned addUnknownChunks(ucvector* out,
unsigned char*
data,
size_t datasize)
5539 unsigned char* inchunk =
data;
5540 while((
size_t)(inchunk -
data) < datasize)
5542 CERROR_TRY_RETURN(lodepng_chunk_append(&out->data, &out->size, inchunk));
5543 out->allocsize = out->size;
5544 inchunk = lodepng_chunk_next(inchunk);
5550 unsigned lodepng_encode(
unsigned char** out,
size_t* outsize,
5551 const unsigned char* image,
unsigned w,
unsigned h,
5552 LodePNGState* state)
5556 unsigned char*
data = 0;
5557 size_t datasize = 0;
5564 lodepng_info_init(&info);
5565 lodepng_info_copy(&info, &state->info_png);
5567 if((info.color.colortype == LCT_PALETTE || state->encoder.force_palette)
5568 && (info.color.palettesize == 0 || info.color.palettesize > 256))
5571 return state->error;
5574 if(state->encoder.auto_convert)
5576 state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw);
5578 if(state->error)
return state->error;
5580 if(state->encoder.zlibsettings.btype > 2)
5582 CERROR_RETURN_ERROR(state->error, 61);
5584 if(state->info_png.interlace_method > 1)
5586 CERROR_RETURN_ERROR(state->error, 71);
5589 state->error = checkColorValidity(info.color.colortype, info.color.bitdepth);
5590 if(state->error)
return state->error;
5591 state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth);
5592 if(state->error)
return state->error;
5594 if(!lodepng_color_mode_equal(&state->info_raw, &info.color))
5596 unsigned char* converted;
5597 size_t size = (w * h * lodepng_get_bpp(&info.color) + 7) / 8;
5599 converted = (
unsigned char*)lodepng_malloc(
size);
5600 if(!converted &&
size) state->error = 83;
5603 state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h);
5605 if(!state->error) preProcessScanlines(&
data, &datasize, converted, w, h, &info, &state->encoder);
5606 lodepng_free(converted);
5608 else preProcessScanlines(&
data, &datasize, image, w, h, &info, &state->encoder);
5610 ucvector_init(&outv);
5611 while(!state->error)
5613 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5617 writeSignature(&outv);
5619 addChunk_IHDR(&outv, w, h, info.color.colortype, info.color.bitdepth, info.interlace_method);
5620 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5622 if(info.unknown_chunks_data[0])
5624 state->error = addUnknownChunks(&outv, info.unknown_chunks_data[0], info.unknown_chunks_size[0]);
5625 if(state->error)
break;
5629 if(info.color.colortype == LCT_PALETTE)
5631 addChunk_PLTE(&outv, &info.color);
5633 if(state->encoder.force_palette && (info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA))
5635 addChunk_PLTE(&outv, &info.color);
5638 if(info.color.colortype == LCT_PALETTE && getPaletteTranslucency(info.color.palette, info.color.palettesize) != 0)
5640 addChunk_tRNS(&outv, &info.color);
5642 if((info.color.colortype == LCT_GREY || info.color.colortype == LCT_RGB) && info.color.key_defined)
5644 addChunk_tRNS(&outv, &info.color);
5646 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5648 if(info.background_defined) addChunk_bKGD(&outv, &info);
5650 if(info.phys_defined) addChunk_pHYs(&outv, &info);
5653 if(info.unknown_chunks_data[1])
5655 state->error = addUnknownChunks(&outv, info.unknown_chunks_data[1], info.unknown_chunks_size[1]);
5656 if(state->error)
break;
5660 state->error = addChunk_IDAT(&outv,
data, datasize, &state->encoder.zlibsettings);
5661 if(state->error)
break;
5662 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5664 if(info.time_defined) addChunk_tIME(&outv, &info.time);
5666 for(i = 0; i != info.text_num; ++i)
5668 if(strlen(info.text_keys[i]) > 79)
5673 if(strlen(info.text_keys[i]) < 1)
5678 if(state->encoder.text_compression)
5680 addChunk_zTXt(&outv, info.text_keys[i], info.text_strings[i], &state->encoder.zlibsettings);
5684 addChunk_tEXt(&outv, info.text_keys[i], info.text_strings[i]);
5688 if(state->encoder.add_id)
5690 unsigned alread_added_id_text = 0;
5691 for(i = 0; i != info.text_num; ++i)
5693 if(!strcmp(info.text_keys[i],
"LodePNG"))
5695 alread_added_id_text = 1;
5699 if(alread_added_id_text == 0)
5701 addChunk_tEXt(&outv,
"LodePNG", LODEPNG_VERSION_STRING);
5705 for(i = 0; i != info.itext_num; ++i)
5707 if(strlen(info.itext_keys[i]) > 79)
5712 if(strlen(info.itext_keys[i]) < 1)
5717 addChunk_iTXt(&outv, state->encoder.text_compression,
5718 info.itext_keys[i], info.itext_langtags[i], info.itext_transkeys[i], info.itext_strings[i],
5719 &state->encoder.zlibsettings);
5723 if(info.unknown_chunks_data[2])
5725 state->error = addUnknownChunks(&outv, info.unknown_chunks_data[2], info.unknown_chunks_size[2]);
5726 if(state->error)
break;
5729 addChunk_IEND(&outv);
5734 lodepng_info_cleanup(&info);
5738 *outsize = outv.size;
5740 return state->error;
5743 unsigned lodepng_encode_memory(
unsigned char** out,
size_t* outsize,
const unsigned char* image,
5744 unsigned w,
unsigned h, LodePNGColorType colortype,
unsigned bitdepth)
5748 lodepng_state_init(&state);
5749 state.info_raw.colortype = colortype;
5750 state.info_raw.bitdepth = bitdepth;
5751 state.info_png.color.colortype = colortype;
5752 state.info_png.color.bitdepth = bitdepth;
5753 lodepng_encode(out, outsize, image, w, h, &state);
5754 error = state.error;
5755 lodepng_state_cleanup(&state);
5759 unsigned lodepng_encode32(
unsigned char** out,
size_t* outsize,
const unsigned char* image,
unsigned w,
unsigned h)
5761 return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGBA, 8);
5764 unsigned lodepng_encode24(
unsigned char** out,
size_t* outsize,
const unsigned char* image,
unsigned w,
unsigned h)
5766 return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGB, 8);
5769 #ifdef LODEPNG_COMPILE_DISK
5770 unsigned lodepng_encode_file(
const char* filename,
const unsigned char* image,
unsigned w,
unsigned h,
5771 LodePNGColorType colortype,
unsigned bitdepth)
5773 unsigned char* buffer;
5775 unsigned error = lodepng_encode_memory(&buffer, &buffersize, image, w, h, colortype, bitdepth);
5776 if(!error) error = lodepng_save_file(buffer, buffersize, filename);
5777 lodepng_free(buffer);
5781 unsigned lodepng_encode32_file(
const char* filename,
const unsigned char* image,
unsigned w,
unsigned h)
5783 return lodepng_encode_file(filename, image, w, h, LCT_RGBA, 8);
5786 unsigned lodepng_encode24_file(
const char* filename,
const unsigned char* image,
unsigned w,
unsigned h)
5788 return lodepng_encode_file(filename, image, w, h, LCT_RGB, 8);
5792 void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings)
5794 lodepng_compress_settings_init(&settings->zlibsettings);
5795 settings->filter_palette_zero = 1;
5796 settings->filter_strategy = LFS_MINSUM;
5797 settings->auto_convert = 1;
5798 settings->force_palette = 0;
5799 settings->predefined_filters = 0;
5800 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5801 settings->add_id = 0;
5802 settings->text_compression = 1;
5809 #ifdef LODEPNG_COMPILE_ERROR_TEXT
5814 const char* lodepng_error_text(
unsigned code)
5818 case 0:
return "no error, everything went ok";
5819 case 1:
return "nothing done yet";
5820 case 10:
return "end of input memory reached without huffman end code";
5821 case 11:
return "error in code tree made it jump outside of huffman tree";
5822 case 13:
return "problem while processing dynamic deflate block";
5823 case 14:
return "problem while processing dynamic deflate block";
5824 case 15:
return "problem while processing dynamic deflate block";
5825 case 16:
return "unexisting code while processing dynamic deflate block";
5826 case 17:
return "end of out buffer memory reached while inflating";
5827 case 18:
return "invalid distance code while inflating";
5828 case 19:
return "end of out buffer memory reached while inflating";
5829 case 20:
return "invalid deflate block BTYPE encountered while decoding";
5830 case 21:
return "NLEN is not ones complement of LEN in a deflate block";
5835 case 22:
return "end of out buffer memory reached while inflating";
5836 case 23:
return "end of in buffer memory reached while inflating";
5837 case 24:
return "invalid FCHECK in zlib header";
5838 case 25:
return "invalid compression method in zlib header";
5839 case 26:
return "FDICT encountered in zlib header while it's not used for PNG";
5840 case 27:
return "PNG file is smaller than a PNG header";
5842 case 28:
return "incorrect PNG signature, it's no PNG or corrupted";
5843 case 29:
return "first chunk is not the header chunk";
5844 case 30:
return "chunk length too large, chunk broken off at end of file";
5845 case 31:
return "illegal PNG color type or bpp";
5846 case 32:
return "illegal PNG compression method";
5847 case 33:
return "illegal PNG filter method";
5848 case 34:
return "illegal PNG interlace method";
5849 case 35:
return "chunk length of a chunk is too large or the chunk too small";
5850 case 36:
return "illegal PNG filter type encountered";
5851 case 37:
return "illegal bit depth for this color type given";
5852 case 38:
return "the palette is too big";
5853 case 39:
return "more palette alpha values given in tRNS chunk than there are colors in the palette";
5854 case 40:
return "tRNS chunk has wrong size for greyscale image";
5855 case 41:
return "tRNS chunk has wrong size for RGB image";
5856 case 42:
return "tRNS chunk appeared while it was not allowed for this color type";
5857 case 43:
return "bKGD chunk has wrong size for palette image";
5858 case 44:
return "bKGD chunk has wrong size for greyscale image";
5859 case 45:
return "bKGD chunk has wrong size for RGB image";
5861 case 48:
return "empty input or file doesn't exist";
5862 case 49:
return "jumped past memory while generating dynamic huffman tree";
5863 case 50:
return "jumped past memory while generating dynamic huffman tree";
5864 case 51:
return "jumped past memory while inflating huffman block";
5865 case 52:
return "jumped past memory while inflating";
5866 case 53:
return "size of zlib data too small";
5867 case 54:
return "repeat symbol in tree while there was no value symbol yet";
5871 case 55:
return "jumped past tree while generating huffman tree";
5872 case 56:
return "given output image colortype or bitdepth not supported for color conversion";
5873 case 57:
return "invalid CRC encountered (checking CRC can be disabled)";
5874 case 58:
return "invalid ADLER32 encountered (checking ADLER32 can be disabled)";
5875 case 59:
return "requested color conversion not supported";
5876 case 60:
return "invalid window size given in the settings of the encoder (must be 0-32768)";
5877 case 61:
return "invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)";
5879 case 62:
return "conversion from color to greyscale not supported";
5880 case 63:
return "length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk";
5882 case 64:
return "the length of the END symbol 256 in the Huffman tree is 0";
5883 case 66:
return "the length of a text chunk keyword given to the encoder is longer than the maximum of 79 bytes";
5884 case 67:
return "the length of a text chunk keyword given to the encoder is smaller than the minimum of 1 byte";
5885 case 68:
return "tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors";
5886 case 69:
return "unknown chunk type with 'critical' flag encountered by the decoder";
5887 case 71:
return "unexisting interlace mode given to encoder (must be 0 or 1)";
5888 case 72:
return "while decoding, unexisting compression method encountering in zTXt or iTXt chunk (it must be 0)";
5889 case 73:
return "invalid tIME chunk size";
5890 case 74:
return "invalid pHYs chunk size";
5892 case 75:
return "no null termination char found while decoding text chunk";
5893 case 76:
return "iTXt chunk too short to contain required bytes";
5894 case 77:
return "integer overflow in buffer size";
5895 case 78:
return "failed to open file for reading";
5896 case 79:
return "failed to open file for writing";
5897 case 80:
return "tried creating a tree of 0 symbols";
5898 case 81:
return "lazy matching at pos 0 is impossible";
5899 case 82:
return "color conversion to palette requested while a color isn't in palette";
5900 case 83:
return "memory allocation failed";
5901 case 84:
return "given image too small to contain all pixels to be encoded";
5902 case 86:
return "impossible offset in lz77 encoding (internal bug)";
5903 case 87:
return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined";
5904 case 88:
return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy";
5905 case 89:
return "text chunk keyword too short or long: must have size 1-79";
5907 case 90:
return "windowsize must be a power of two";
5908 case 91:
return "invalid decompressed idat size";
5909 case 92:
return "too many pixels, not supported";
5910 case 93:
return "zero width or height is invalid";
5912 return "unknown error code";