34 #define USE_BRUTE_FORCE_ENCODING 1 36 #define VERSION_STRING "20080927" 49 #ifdef LODEPNG_COMPILE_ZLIB 50 #ifdef LODEPNG_COMPILE_ENCODER 64 size_t newsize = size * p->
typesize * 2;
65 void*
data = realloc(p->
data, newsize);
81 if(size < p->size)
for(i = size; i < p->
size; i++) dtor(&((
char*)(p->
data))[i * p->
typesize]);
123 #ifdef LODEPNG_COMPILE_ZLIB 140 if(size *
sizeof(
unsigned) > p->
allocsize)
142 size_t newsize = size *
sizeof(unsigned) * 2;
143 void*
data = realloc(p->
data, newsize);
147 p->
data = (
unsigned*)data;
158 size_t oldsize = p->
size, i;
160 for(i = oldsize; i <
size; i++) p->
data[i] = value;
170 #ifdef LODEPNG_COMPILE_ENCODER 215 if(size *
sizeof(
unsigned) > p->
allocsize)
217 size_t newsize = size *
sizeof(unsigned) * 2;
218 void*
data = realloc(p->
data, newsize);
222 p->
data = (
unsigned char*)data;
231 #ifdef LODEPNG_COMPILE_DECODER 232 #ifdef LODEPNG_COMPILE_PNG 233 static unsigned ucvector_resizev(
ucvector* p,
size_t size,
unsigned char value)
235 size_t oldsize = p->
size, i;
237 for(i = oldsize; i <
size; i++) p->
data[i] = value;
249 #ifdef LODEPNG_COMPILE_ZLIB 267 #ifdef LODEPNG_COMPILE_PNG 268 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 269 static unsigned string_resize(
char** out,
size_t size)
271 char*
data = (
char*)realloc(*out, size + 1);
280 static void string_init(
char** out)
283 string_resize(out, 0);
286 static void string_cleanup(
char** out)
292 static void string_set(
char** out,
const char* in)
294 size_t insize = strlen(in), i = 0;
295 if(string_resize(out, insize))
for(i = 0; i < insize; i++) (*out)[i] = in[i];
300 #ifdef LODEPNG_COMPILE_ZLIB 306 #ifdef LODEPNG_COMPILE_ENCODER 310 (bitstream->
data[bitstream->
size - 1]) |= (bit << ((*bitpointer) & 0x7));
317 for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> i) & 1));
323 for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> (nbits - 1 - i)) & 1));
327 #ifdef LODEPNG_COMPILE_DECODER 328 static unsigned char readBitFromStream(
size_t* bitpointer,
const unsigned char* bitstream)
330 unsigned char result = (
unsigned char)((bitstream[(*bitpointer) >> 3] >> ((*bitpointer) & 0x7)) & 1);
335 static unsigned readBitsFromStream(
size_t* bitpointer,
const unsigned char* bitstream,
size_t nbits)
338 for(i = 0; i < nbits; i++) result += ((
unsigned)readBitFromStream(bitpointer, bitstream)) << i;
347 #define FIRST_LENGTH_CODE_INDEX 257 348 #define LAST_LENGTH_CODE_INDEX 285 349 #define NUM_DEFLATE_CODE_SYMBOLS 288 350 #define NUM_DISTANCE_SYMBOLS 32 351 #define NUM_CODE_LENGTH_CODES 19 354 = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
356 = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
358 = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
360 = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
362 = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
366 #ifdef LODEPNG_COMPILE_ENCODER 400 unsigned char swapped = 0;
401 while(gap > 1 || swapped)
404 gap = (gap * 10) / 13;
405 if(gap == 9 || gap == 10) gap = 11;
408 for(i = 0; i < amount - gap; i++)
461 unsigned nodefilled = 0;
462 unsigned treepos = 0;
470 for(n = 0; n < tree->numcodes; n++)
474 if(treepos > tree->
numcodes - 2)
return 55;
475 if(tree->
tree2d.
data[2 * treepos + bit] == 32767)
486 treepos = nodefilled;
500 unsigned bits,
n,
error = 0;
514 for(bits = 1; bits <= tree->maxbitlen; bits++) nextcode.
data[bits] = (nextcode.
data[bits - 1] + blcount.
data[bits - 1]) << 1;
531 for(i = 0; i < numcodes; i++) tree->
lengths.
data[i] = bitlen[i];
532 tree->
numcodes = (
unsigned)numcodes;
537 #ifdef LODEPNG_COMPILE_ENCODER 541 for(i = 0; i < numcodes; i++)
544 if(frequencies[i] == 0)
continue;
558 size_t sum = 0, numpresent = 0;
566 for(i = 0; i < numcodes; i++)
568 if(frequencies[i] > 0)
571 sum += frequencies[i];
575 if(numcodes == 0)
return 80;
576 tree->
numcodes = (unsigned)numcodes;
585 else if(numpresent == 1)
587 for(i = 0; i < numcodes; i++)
if(frequencies[i]) tree->
lengths.
data[i] = 1;
601 for(j = 1; j <= maxbitlen && !
error; j++)
606 for(i = 0; i + 1 < prev_row.
size; i += 2)
626 for(i = 0; i < coins.
size; i++)
648 unsigned i,
error = 0;
656 for(i = 0; i <= 143; i++) bitlen.
data[i] = 8;
657 for(i = 144; i <= 255; i++) bitlen.
data[i] = 9;
658 for(i = 256; i <= 279; i++) bitlen.
data[i] = 7;
659 for(i = 280; i <= 287; i++) bitlen.
data[i] = 8;
670 unsigned i,
error = 0;
685 #ifdef LODEPNG_COMPILE_DECODER 691 static unsigned HuffmanTree_decode(
const HuffmanTree*
tree,
unsigned* decoded,
unsigned*
result,
unsigned* treepos,
unsigned char bit)
693 if((*treepos) >= tree->
numcodes)
return 11;
695 (*result) = tree->
tree2d.
data[2 * (*treepos) + bit];
696 (*decoded) = ((*result) < tree->
numcodes);
698 if(*decoded) (*treepos) = 0;
699 else (*treepos) = (*result) - tree->
numcodes;
704 static unsigned huffmanDecodeSymbol(
unsigned int*
error,
const unsigned char* in,
size_t* bp,
const HuffmanTree* codetree,
size_t inlength)
706 unsigned treepos = 0, decoded, ct;
710 if(((*bp) & 0x07) == 0 && ((*bp) >> 3) > inlength) { *error = 10;
return 0; }
711 bit = readBitFromStream(bp, in);
712 *error = HuffmanTree_decode(codetree, &decoded, &ct, &treepos, bit);
714 if(decoded)
return ct;
719 #ifdef LODEPNG_COMPILE_DECODER 735 const unsigned char* in,
size_t* bp,
size_t inlength)
740 unsigned n, HLIT, HDIST, HCLEN, i;
745 if((*bp) >> 3 >= inlength - 2) {
return 49; }
747 HLIT = readBitsFromStream(bp, in, 5) + 257;
748 HDIST = readBitsFromStream(bp, in, 5) + 1;
749 HCLEN = readBitsFromStream(bp, in, 4) + 4;
759 if(i < HCLEN) codelengthcode.
data[
CLCL[i]] = readBitsFromStream(bp, in, 3);
760 else codelengthcode.
data[
CLCL[i]] = 0;
767 if(error)
return error;
775 if(!bitlen.
data || !bitlenD.
data) error = 9912;
776 else while(i < HLIT + HDIST)
778 unsigned code = huffmanDecodeSymbol(&error, in, bp, codelengthcodetree, inlength);
789 unsigned replength = 3;
792 if((*bp) >> 3 >= inlength) { error = 50;
break; }
794 replength += readBitsFromStream(bp, in, 2);
796 if((i - 1) < HLIT) value = bitlen.
data[i - 1];
797 else value = bitlenD.
data[i - HLIT - 1];
799 for(n = 0; n < replength; n++)
801 if(i >= HLIT + HDIST) { error = 13;
break; }
809 unsigned replength = 3;
810 if((*bp) >> 3 >= inlength) { error = 50;
break; }
812 replength += readBitsFromStream(bp, in, 3);
815 for(n = 0; n < replength; n++)
817 if(i >= HLIT + HDIST) { error = 14;
break; }
818 if(i < HLIT) bitlen.
data[i] = 0;
819 else bitlenD.
data[i - HLIT] = 0;
825 unsigned replength = 11;
826 if((*bp) >> 3 >= inlength) { error = 50;
break; }
827 replength += readBitsFromStream(bp, in, 7);
830 for(n = 0; n < replength; n++)
832 if(i >= HLIT + HDIST) { error = 15;
break; }
833 if(i < HLIT) bitlen.
data[i] = 0;
834 else bitlenD.
data[i - HLIT] = 0;
838 else { error = 16;
break; }
841 if(!error && bitlen.
data[256] == 0) { error = 64; }
854 static unsigned inflateHuffmanBlock(
ucvector* out,
const unsigned char* in,
size_t* bp,
size_t*
pos,
size_t inlength,
unsigned btype)
856 unsigned endreached = 0, error = 0;
863 if(btype == 1) getTreeInflateFixed(&codetree, &codetreeD);
868 error = getTreeInflateDynamic(&codetree, &codetreeD, &codelengthcodetree, in, bp, inlength);
872 while(!endreached && !error)
874 unsigned code = huffmanDecodeSymbol(&error, in, bp, &codetree, inlength);
876 if(code == 256) endreached = 1;
880 if((*pos) >= out->
size) { error = 9913;
break; }
881 out->
data[(*pos)] = (
unsigned char)(code);
888 unsigned codeD,
distance, numextrabitsD;
889 size_t start, forward, backward, numextrabits;
893 if(((*bp) >> 3) >= inlength) { error = 51;
break; }
894 length += readBitsFromStream(bp, in, numextrabits);
897 codeD = huffmanDecodeSymbol(&error, in, bp, &codetreeD, inlength);
899 if(codeD > 29) { error = 18;
break; }
904 if(((*bp) >> 3) >= inlength) { error = 51;
break; }
905 distance += readBitsFromStream(bp, in, numextrabitsD);
911 if((*pos) + length >= out->
size) { error = 9914;
break; }
913 for(forward = 0; forward < length; forward++)
915 out->
data[(*pos)] = out->
data[backward];
918 if(backward >= start) backward = start -
distance;
929 static unsigned inflateNoCompression(
ucvector* out,
const unsigned char* in,
size_t* bp,
size_t* pos,
size_t inlength)
933 unsigned LEN, NLEN,
n, error = 0;
934 while(((*bp) & 0x7) != 0) (*bp)++;
938 if(p >= inlength - 4)
return 52;
939 LEN = in[
p] + 256 * in[p + 1]; p += 2;
940 NLEN = in[
p] + 256 * in[p + 1]; p += 2;
943 if(LEN + NLEN != 65535)
return 21;
948 if(p + LEN > inlength)
return 23;
949 for(n = 0; n <
LEN; n++) out->
data[(*pos)++] = in[p++];
957 unsigned LodeFlate_inflate(
ucvector* out,
const unsigned char* in,
size_t insize,
size_t inpos)
968 if((bp >> 3) >= insize)
return 52;
969 BFINAL = readBitFromStream(&bp, &in[inpos]);
970 BTYPE = 1 * readBitFromStream(&bp, &in[inpos]); BTYPE += 2 * readBitFromStream(&bp, &in[inpos]);
972 if(BTYPE == 3)
return 20;
973 else if(BTYPE == 0) error = inflateNoCompression(out, &in[inpos], &bp, &pos, insize);
974 else error = inflateHuffmanBlock(out, &in[inpos], &bp, &pos, insize, BTYPE);
975 if(error)
return error;
985 #ifdef LODEPNG_COMPILE_ENCODER 1008 size_t right = array_size - 1;
1009 while(left <= right)
1011 size_t mid = (left +
right) / 2;
1012 if(array[mid] <= value) left = mid + 1;
1013 else if(array[mid - 1] > value) right = mid - 1;
1014 else return mid - 1;
1016 return array_size - 1;
1028 unsigned extra_length = (unsigned)(length -
LENGTHBASE[length_code]);
1030 unsigned extra_distance = (unsigned)(distance -
DISTANCEBASE[dist_code]);
1038 #if USE_BRUTE_FORCE_ENCODING 1039 #define encodeLZ77 encodeLZ77_brute 1045 for(pos = 0; pos <
size; pos++)
1048 const int minLength = 4;
1050 if(pos < size - minLength * 4)
1053 size_t current_length;
1060 while(fp < size && in[p] == in[fp] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH)
1067 if (current_length > (minLength - 1 ) * 4)
1075 pos += current_length + 4 - 1;
1084 while(fp < size && in[p] == in[fp] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH)
1091 if (current_length > (minLength - 1 ) * 3)
1098 pos += current_length + 3 - 1;
1103 size_t length = 0, offset = 0;
1104 size_t max_offset = pos < windowSize ? pos : windowSize;
1105 size_t current_offset;
1108 for(current_offset = 1; current_offset < max_offset; current_offset++)
1110 size_t backpos = pos - current_offset;
1111 if(in[backpos] == in[pos])
1114 size_t current_length = 1;
1115 size_t backtest = backpos + 1;
1116 size_t foretest = pos + 1;
1117 while(foretest < size && in[backtest] == in[foretest] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH)
1119 if(backpos >= pos) backpos -= current_offset;
1124 if(current_length > length)
1126 length = current_length;
1127 offset = current_offset;
1128 if(current_length == MAX_SUPPORTED_DEFLATE_LENGTH)
break;
1141 pos += (length - 1);
1158 #if !defined(USE_BRUTE_FORCE_ENCODING) 1159 static unsigned getHash(
const unsigned char*
data,
size_t size,
size_t pos)
1161 unsigned result = 0;
1163 if(pos >= size)
return 0;
1164 amount = HASH_NUM_CHARACTERS;
if(pos + amount >= size) amount = size -
pos;
1165 for(i = 0; i < amount; i++) result ^= (data[pos + i] << (i * HASH_SHIFT));
1166 return result % HASH_NUM_VALUES;
1170 static unsigned encodeLZ77(
uivector* out,
const unsigned char* in,
size_t size,
unsigned windowSize)
1175 unsigned pos, i, error = 0;
1179 for(i = 0; i < HASH_NUM_VALUES; i++)
1193 for(pos = 0; pos <
size; pos++)
1195 unsigned length = 0, offset = 0;
1196 unsigned max_offset = pos < windowSize ? pos : windowSize;
1201 unsigned hash = getHash(in, size, pos);
1207 for(tablepos = tablepos2.
data[hash] - 1; tablepos >= tablepos1.
data[hash] && tablepos < tablepos2.
data[hash]; tablepos--)
1210 unsigned current_offset = pos - backpos;
1213 unsigned current_length = 0;
1214 unsigned backtest = backpos;
1215 unsigned foretest =
pos;
1216 while(foretest < size && in[backtest] == in[foretest] && current_length < MAX_SUPPORTED_DEFLATE_LENGTH)
1218 if(backpos >= pos) backpos -= current_offset;
1223 if(current_length > length)
1225 length = current_length;
1226 offset = current_offset;
1227 if(current_length == MAX_SUPPORTED_DEFLATE_LENGTH)
break;
1240 for(j = 0; j < length - 1; j++)
1250 for(i = 0; i < table.
size; i++)
1268 size_t i, j, numdeflateblocks = datasize / 65536 + 1;
1269 unsigned datapos = 0;
1270 for(i = 0; i < numdeflateblocks; i++)
1272 unsigned BFINAL, BTYPE,
LEN, NLEN;
1273 unsigned char firstbyte;
1275 BFINAL = (i == numdeflateblocks - 1);
1278 firstbyte = (
unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1));
1282 if(datasize - datapos < 65535) LEN = (unsigned)datasize - datapos;
1291 for(j = 0; j < 65535 && datapos < datasize; j++)
1304 for(i = 0; i < lz77_encoded->
size; i++)
1306 unsigned val = lz77_encoded->
data[i];
1311 unsigned n_length_extra_bits =
LENGTHEXTRA[length_index];
1312 unsigned length_extra_bits = lz77_encoded->
data[++i];
1314 unsigned distance_code = lz77_encoded->
data[++i];
1316 unsigned distance_index = distance_code;
1317 unsigned n_distance_extra_bits =
DISTANCEEXTRA[distance_index];
1318 unsigned distance_extra_bits = lz77_encoded->
data[++i];
1352 unsigned BFINAL = 1;
1353 size_t numcodes, numcodesD, i, bp = 0;
1354 unsigned HLIT, HDIST, HCLEN;
1376 if(!
uivector_resize(&lz77_encoded, datasize)) { error = 9923;
break; }
1377 for(i = 0; i < datasize; i++) lz77_encoded.
data[i] = data[i];
1382 for(i = 0; i < lz77_encoded.
size; i++)
1384 unsigned symbol = lz77_encoded.
data[i];
1385 frequencies.
data[symbol]++;
1388 unsigned dist = lz77_encoded.
data[i + 2];
1393 frequencies.
data[256] = 1;
1404 numcodes = codes.
numcodes;
if(numcodes > 286) numcodes = 286;
1405 numcodesD = codesD.
numcodes;
if(numcodesD > 30) numcodesD = 30;
1410 for(i = 0; i < (unsigned)lldll.
size; i++)
1413 while(i + j + 1 < (
unsigned)lldll.
size && lldll.
data[i + j + 1] == lldll.
data[i]) j++;
1415 if(lldll.
data[i] == 0 && j >= 2)
1421 if(j > 138) j = 138;
1429 unsigned num = j / 6, rest = j % 6;
1441 for(i = 0; i < lldl.
size; i++)
1444 if(lldl.
data[i] >= 16) i++;
1452 while(clcls.
data[clcls.
size - 1] == 0 && clcls.
size > 4)
1459 HLIT = (unsigned)(numcodes - 257);
1460 HDIST = (unsigned)(numcodesD - 1);
1461 HCLEN = (unsigned)clcls.
size - 4;
1470 for(i = 0; i < lldl.
size; i++)
1507 unsigned BFINAL = 1;
1526 if(!error)
writeLZ77data(&bp, out, &lz77_encoded, &codes, &codesD);
1546 else if(settings->
btype == 1) error =
deflateFixed(out, data, datasize, settings);
1558 static unsigned update_adler32(
unsigned adler,
const unsigned char* data,
unsigned len)
1560 unsigned s1 = adler & 0xffff;
1561 unsigned s2 = (adler >> 16) & 0xffff;
1566 unsigned amount = len > 5550 ? 5550 : len;
1570 s1 = (s1 + *data++);
1578 return (s2 << 16) | s1;
1582 static unsigned adler32(
const unsigned char* data,
unsigned len)
1591 #ifdef LODEPNG_COMPILE_ENCODER 1603 return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
1610 #ifdef LODEPNG_COMPILE_DECODER 1612 unsigned LodeZlib_decompress(
unsigned char** out,
size_t* outsize,
const unsigned char* in,
size_t insize,
const LodeZlib_DecompressSettings* settings)
1615 unsigned CM, CINFO, FDICT;
1618 if(insize < 2) { error = 53;
return error; }
1620 if((in[0] * 256 + in[1]) % 31 != 0) { error = 24;
return error; }
1623 CINFO = (in[0] >> 4) & 15;
1625 FDICT = (in[1] >> 5) & 1;
1628 if(CM != 8 || CINFO > 7) { error = 25;
return error; }
1629 if(FDICT != 0) { error = 26;
return error; }
1632 error = LodeFlate_inflate(&outv, in, insize, 2);
1634 *outsize = outv.
size;
1635 if(error)
return error;
1637 if(!settings->ignoreAdler32)
1641 if(checksum != ADLER32) { error = 58;
return error; }
1649 #ifdef LODEPNG_COMPILE_ENCODER 1661 unsigned FLEVEL = 0;
1663 unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64;
1664 unsigned FCHECK = 31 - CMFFLG % 31;
1677 ADLER32 =
adler32(in, (
unsigned)insize);
1684 *outsize = outv.
size;
1695 #ifdef LODEPNG_COMPILE_ENCODER 1699 settings->
btype = 2;
1708 #ifdef LODEPNG_COMPILE_DECODER 1710 void LodeZlib_DecompressSettings_init(LodeZlib_DecompressSettings* settings)
1712 settings->ignoreAdler32 = 0;
1715 const LodeZlib_DecompressSettings LodeZlib_defaultDecompressSettings = {0};
1731 #ifdef LODEPNG_COMPILE_PNG 1745 #ifdef LODEPNG_COMPILE_DECODER 1746 static unsigned LodePNG_decompress(
unsigned char** out,
size_t* outsize,
const unsigned char* in,
size_t insize,
const LodeZlib_DecompressSettings* settings)
1748 return LodeZlib_decompress(out, outsize, in, insize, settings);
1751 #ifdef LODEPNG_COMPILE_ENCODER 1768 unsigned int c,
k,
n;
1769 for(n = 0; n < 256; n++)
1772 for(k = 0; k < 8; k++)
1774 if(c & 1) c = (
unsigned int)(0xedb88320L ^ (c >> 1));
1777 Crc32_crc_table[
n] =
c;
1779 Crc32_crc_table_computed = 1;
1787 unsigned int c = crc;
1791 for(n = 0; n < len; n++)
1793 c = Crc32_crc_table[(c ^ buf[
n]) & 0xff] ^ (c >> 8);
1799 static unsigned Crc32_crc(
const unsigned char* buf,
size_t len)
1810 unsigned char result = (
unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1);
1817 unsigned result = 0;
1823 #ifdef LODEPNG_COMPILE_DECODER 1824 static void setBitOfReversedStream0(
size_t* bitpointer,
unsigned char* bitstream,
unsigned char bit)
1827 if(bit) bitstream[(*bitpointer) >> 3] |= (bit << (7 - ((*bitpointer) & 0x7)));
1835 if(bit == 0) bitstream[(*bitpointer) >> 3] &= (
unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7))));
1836 else bitstream[(*bitpointer) >> 3] |= (1 << (7 - ((*bitpointer) & 0x7)));
1842 return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
1847 buffer[0] = (
unsigned char)((value >> 24) & 0xff);
1848 buffer[1] = (
unsigned char)((value >> 16) & 0xff);
1849 buffer[2] = (
unsigned char)((value >> 8) & 0xff);
1850 buffer[3] = (
unsigned char)((value ) & 0xff);
1853 #ifdef LODEPNG_COMPILE_ENCODER 1873 for(i = 0; i < 4; i++) type[i] = chunk[4 + i];
1879 if(strlen(type) != 4)
return 0;
1880 return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]);
1886 return((chunk[4] & 32) == 0);
1891 return((chunk[6] & 32) != 0);
1896 return((chunk[7] & 32) != 0);
1913 unsigned checksum =
Crc32_crc(&chunk[4], length + 4);
1914 if(CRC != checksum)
return 1;
1921 unsigned CRC =
Crc32_crc(&chunk[4], length + 4);
1928 return &chunk[total_chunk_length];
1934 return &chunk[total_chunk_length];
1941 unsigned char *chunk_start, *new_buffer;
1942 size_t new_length = (*outlength) + total_chunk_length;
1943 if(new_length < total_chunk_length || new_length < (*outlength))
return 77;
1945 new_buffer = (
unsigned char*)realloc(*out, new_length);
1946 if(!new_buffer)
return 9929;
1947 (*out) = new_buffer;
1948 (*outlength) = new_length;
1949 chunk_start = &(*out)[new_length - total_chunk_length];
1951 for(i = 0; i < total_chunk_length; i++) chunk_start[i] = chunk[i];
1959 unsigned char *chunk, *new_buffer;
1960 size_t new_length = (*outlength) + length + 12;
1961 if(new_length < length + 12 || new_length < (*outlength))
return 77;
1962 new_buffer = (
unsigned char*)realloc(*out, new_length);
1963 if(!new_buffer)
return 9930;
1964 (*out) = new_buffer;
1965 (*outlength) = new_length;
1966 chunk = &(*out)[(*outlength) - length - 12];
1978 for(i = 0; i < length; i++) chunk[8 + i] = data[i];
1995 case 0:
if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16))
return 37;
break;
1996 case 2:
if(!( bd == 8 || bd == 16))
return 37;
break;
1997 case 3:
if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 ))
return 37;
break;
1998 case 4:
if(!( bd == 8 || bd == 16))
return 37;
break;
1999 case 6:
if(!( bd == 8 || bd == 16))
return 37;
break;
2018 static unsigned getBpp(
unsigned colorType,
unsigned bitDepth)
2048 unsigned char*
data;
2054 data = (
unsigned char*)realloc(info->
palette, alloc_size);
2055 if(!data)
return 9931;
2077 #ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS 2079 void LodePNG_UnknownChunks_init(LodePNG_UnknownChunks* chunks)
2082 for(i = 0; i < 3; i++) chunks->data[i] = 0;
2083 for(i = 0; i < 3; i++) chunks->datasize[i] = 0;
2086 void LodePNG_UnknownChunks_cleanup(LodePNG_UnknownChunks* chunks)
2089 for(i = 0; i < 3; i++) free(chunks->data[i]);
2092 unsigned LodePNG_UnknownChunks_copy(LodePNG_UnknownChunks*
dest,
const LodePNG_UnknownChunks* src)
2096 LodePNG_UnknownChunks_cleanup(dest);
2098 for(i = 0; i < 3; i++)
2101 dest->datasize[i] = src->datasize[i];
2102 dest->data[i] = (
unsigned char*)malloc(src->datasize[i]);
2103 if(!dest->data[i] && dest->datasize[i])
return 9932;
2104 for(j = 0; j < src->datasize[i]; j++) dest->data[i][j] = src->data[i][j];
2112 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 2114 void LodePNG_Text_init(LodePNG_Text* text)
2118 text->strings = NULL;
2121 void LodePNG_Text_cleanup(LodePNG_Text* text)
2123 LodePNG_Text_clear(text);
2126 unsigned LodePNG_Text_copy(LodePNG_Text* dest,
const LodePNG_Text* source)
2132 for(i = 0; i < source->num; i++)
2134 unsigned error = LodePNG_Text_add(dest, source->keys[i], source->strings[i]);
2135 if(error)
return error;
2140 void LodePNG_Text_clear(LodePNG_Text* text)
2143 for(i = 0; i < text->num; i++)
2145 string_cleanup(&text->keys[i]);
2146 string_cleanup(&text->strings[i]);
2149 free(text->strings);
2152 unsigned LodePNG_Text_add(LodePNG_Text* text,
const char*
key,
const char*
str)
2154 char** new_keys = (
char**)(realloc(text->keys,
sizeof(
char*) * (text->num + 1)));
2155 char** new_strings = (
char**)(realloc(text->strings,
sizeof(
char*) * (text->num + 1)));
2156 if(!new_keys || !new_strings)
2164 text->keys = new_keys;
2165 text->strings = new_strings;
2167 string_init(&text->keys[text->num - 1]);
2168 string_set(&text->keys[text->num - 1], key);
2170 string_init(&text->strings[text->num - 1]);
2171 string_set(&text->strings[text->num - 1], str);
2178 void LodePNG_IText_init(LodePNG_IText* text)
2182 text->langtags = NULL;
2183 text->transkeys = NULL;
2184 text->strings = NULL;
2187 void LodePNG_IText_cleanup(LodePNG_IText* text)
2189 LodePNG_IText_clear(text);
2192 unsigned LodePNG_IText_copy(LodePNG_IText* dest,
const LodePNG_IText* source)
2197 dest->transkeys = 0;
2200 for(i = 0; i < source->num; i++)
2202 unsigned error = LodePNG_IText_add(dest, source->keys[i], source->langtags[i], source->transkeys[i], source->strings[i]);
2203 if(error)
return error;
2208 void LodePNG_IText_clear(LodePNG_IText* text)
2211 for(i = 0; i < text->num; i++)
2213 string_cleanup(&text->keys[i]);
2214 string_cleanup(&text->langtags[i]);
2215 string_cleanup(&text->transkeys[i]);
2216 string_cleanup(&text->strings[i]);
2219 free(text->langtags);
2220 free(text->transkeys);
2221 free(text->strings);
2224 unsigned LodePNG_IText_add(LodePNG_IText* text,
const char* key,
const char* langtag,
const char* transkey,
const char* str)
2226 char** new_keys = (
char**)(realloc(text->keys,
sizeof(
char*) * (text->num + 1)));
2227 char** new_langtags = (
char**)(realloc(text->langtags,
sizeof(
char*) * (text->num + 1)));
2228 char** new_transkeys = (
char**)(realloc(text->transkeys,
sizeof(
char*) * (text->num + 1)));
2229 char** new_strings = (
char**)(realloc(text->strings,
sizeof(
char*) * (text->num + 1)));
2230 if(!new_keys || !new_langtags || !new_transkeys || !new_strings)
2234 free(new_transkeys);
2240 text->keys = new_keys;
2241 text->langtags = new_langtags;
2242 text->transkeys = new_transkeys;
2243 text->strings = new_strings;
2245 string_init(&text->keys[text->num - 1]);
2246 string_set(&text->keys[text->num - 1], key);
2248 string_init(&text->langtags[text->num - 1]);
2249 string_set(&text->langtags[text->num - 1], langtag);
2251 string_init(&text->transkeys[text->num - 1]);
2252 string_set(&text->transkeys[text->num - 1], transkey);
2254 string_init(&text->strings[text->num - 1]);
2255 string_set(&text->strings[text->num - 1], str);
2269 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 2270 info->background_defined = 0;
2271 info->background_r = info->background_g = info->background_b = 0;
2273 LodePNG_Text_init(&info->text);
2274 LodePNG_IText_init(&info->itext);
2276 info->time_defined = 0;
2277 info->phys_defined = 0;
2279 #ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS 2280 LodePNG_UnknownChunks_init(&info->unknown_chunks);
2287 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 2288 LodePNG_Text_cleanup(&info->text);
2289 LodePNG_IText_cleanup(&info->itext);
2291 #ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS 2292 LodePNG_UnknownChunks_cleanup(&info->unknown_chunks);
2304 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 2305 error = LodePNG_Text_copy(&dest->text, &source->text);
if(error)
return error;
2306 error = LodePNG_IText_copy(&dest->itext, &source->itext);
if(error)
return error;
2309 #ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS 2310 LodePNG_UnknownChunks_init(&dest->unknown_chunks);
2311 error = LodePNG_UnknownChunks_copy(&dest->unknown_chunks, &source->unknown_chunks);
if(error)
return error;
2363 const size_t numpixels = w *
h;
2366 size_t i,
c, bp = 0;
2372 for(i = 0; i <
size; i++) out[i] = in[i];
2383 for(i = 0; i < numpixels; i++)
2385 if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
2386 out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[i];
2387 if(OUT_ALPHA && infoIn->
key_defined && in[i] == infoIn->
key_r) out[OUT_BYTES * i + 3] = 0;
2391 for(i = 0; i < numpixels; i++)
2393 if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
2394 for(c = 0; c < 3; c++) out[OUT_BYTES * i + c] = in[3 * i + c];
2395 if(OUT_ALPHA && infoIn->
key_defined == 1 && in[3 * i + 0] == infoIn->
key_r && in[3 * i + 1] == infoIn->
key_g && in[3 * i + 2] == infoIn->
key_b) out[OUT_BYTES * i + 3] = 0;
2399 for(i = 0; i < numpixels; i++)
2401 if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
2403 for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = infoIn->
palette[4 * in[i] + c];
2407 for(i = 0; i < numpixels; i++)
2409 out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[2 * i + 0];
2410 if(OUT_ALPHA) out[OUT_BYTES * i + 3] = in[2 * i + 1];
2414 for(i = 0; i < numpixels; i++)
2416 for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = in[4 * i + c];
2427 for(i = 0; i < numpixels; i++)
2429 if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
2430 out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[2 * i];
2431 if(OUT_ALPHA && infoIn->
key_defined && 256U * in[i] + in[i + 1] == infoIn->
key_r) out[OUT_BYTES * i + 3] = 0;
2435 for(i = 0; i < numpixels; i++)
2437 if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
2438 for(c = 0; c < 3; c++) out[OUT_BYTES * i + c] = in[6 * i + 2 * c];
2439 if(OUT_ALPHA && infoIn->
key_defined && 256U * in[6 * i + 0] + in[6 * i + 1] == infoIn->
key_r && 256U * in[6 * i + 2] + in[6 * i + 3] == infoIn->
key_g && 256U * in[6 * i + 4] + in[6 * i + 5] == infoIn->
key_b) out[OUT_BYTES * i + 3] = 0;
2443 for(i = 0; i < numpixels; i++)
2445 out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = in[4 * i];
2446 if(OUT_ALPHA) out[OUT_BYTES * i + 3] = in[4 * i + 2];
2450 for(i = 0; i < numpixels; i++)
2452 for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = in[8 * i + 2 * c];
2463 for(i = 0; i < numpixels; i++)
2466 if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
2467 if(OUT_ALPHA && infoIn->
key_defined && value && ((1U << infoIn->
bitDepth) - 1U) == infoIn->
key_r && ((1U << infoIn->
bitDepth) - 1U)) out[OUT_BYTES * i + 3] = 0;
2468 value = (value * 255) / ((1 << infoIn->
bitDepth) - 1);
2469 out[OUT_BYTES * i + 0] = out[OUT_BYTES * i + 1] = out[OUT_BYTES * i + 2] = (
unsigned char)(value);
2473 for(i = 0; i < numpixels; i++)
2476 if(OUT_ALPHA) out[OUT_BYTES * i + 3] = 255;
2478 for(c = 0; c < OUT_BYTES; c++) out[OUT_BYTES * i + c] = infoIn->
palette[4 * value + c];
2493 for(i = 0; i < numpixels; i++)
2495 if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255;
2496 out[OUT_BYTES * i] = in[i];
2497 if(OUT_ALPHA && infoIn->
key_defined && in[i] == infoIn->
key_r) out[OUT_BYTES * i + 1] = 0;
2501 for(i = 0; i < numpixels; i++)
2503 out[OUT_BYTES * i + 0] = in[2 * i + 0];
2504 if(OUT_ALPHA) out[OUT_BYTES * i + 1] = in[2 * i + 1];
2515 for(i = 0; i < numpixels; i++)
2517 if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255;
2518 out[OUT_BYTES * i] = in[2 * i];
2519 if(OUT_ALPHA && infoIn->
key_defined && 256U * in[i] + in[i + 1] == infoIn->
key_r) out[OUT_BYTES * i + 1] = 0;
2523 for(i = 0; i < numpixels; i++)
2525 out[OUT_BYTES * i] = in[4 * i];
2526 if(OUT_ALPHA) out[OUT_BYTES * i + 1] = in[4 * i + 2];
2535 for(i = 0; i < numpixels; i++)
2538 if(OUT_ALPHA) out[OUT_BYTES * i + 1] = 255;
2539 if(OUT_ALPHA && infoIn->
key_defined && value && ((1U << infoIn->
bitDepth) - 1U) == infoIn->
key_r && ((1U << infoIn->
bitDepth) - 1U)) out[OUT_BYTES * i + 1] = 0;
2540 value = (value * 255) / ((1 << infoIn->
bitDepth) - 1);
2541 out[OUT_BYTES * i] = (
unsigned char)(value);
2554 int pa = p > a ? p - a : a -
p;
2555 int pb = p > b ? p - b : b -
p;
2556 int pc = p > c ? p - c : c -
p;
2558 if(pa <= pb && pa <= pc)
return a;
2559 else if(pb <= pc)
return b;
2565 static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 };
2566 static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 };
2567 static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 };
2568 static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 };
2570 static void Adam7_getpassvalues(
unsigned passw[7],
unsigned passh[7],
size_t filter_passstart[8],
size_t padded_passstart[8],
size_t passstart[8],
unsigned w,
unsigned h,
unsigned bpp)
2576 for(i = 0; i < 7; i++)
2578 passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i];
2579 passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i];
2580 if(passw[i] == 0) passh[i] = 0;
2581 if(passh[i] == 0) passw[i] = 0;
2584 filter_passstart[0] = padded_passstart[0] = passstart[0] = 0;
2585 for(i = 0; i < 7; i++)
2587 filter_passstart[i + 1] = filter_passstart[i] + ((passw[i] && passh[i]) ? passh[i] * (1 + (passw[i] * bpp + 7) / 8) : 0);
2588 padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7) / 8);
2589 passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7) / 8;
2593 #ifdef LODEPNG_COMPILE_DECODER 2600 void LodePNG_inspect(LodePNG_Decoder*
decoder,
const unsigned char* in,
size_t inlength)
2602 if(inlength == 0 || in == 0) { decoder->error = 48;
return; }
2603 if(inlength < 29) { decoder->error = 27;
return; }
2610 if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) { decoder->error = 28;
return; }
2611 if(in[12] !=
'I' || in[13] !=
'H' || in[14] !=
'D' || in[15] !=
'R') { decoder->error = 29;
return; }
2616 decoder->infoPng.color.bitDepth = in[24];
2617 decoder->infoPng.color.colorType = in[25];
2618 decoder->infoPng.compressionMethod = in[26];
2619 decoder->infoPng.filterMethod = in[27];
2620 decoder->infoPng.interlaceMethod = in[28];
2622 if(!decoder->settings.ignoreCrc)
2625 unsigned checksum =
Crc32_crc(&in[12], 17);
2626 if(CRC != checksum) { decoder->error = 57;
return; }
2629 if(decoder->infoPng.compressionMethod != 0) { decoder->error = 32;
return; }
2630 if(decoder->infoPng.filterMethod != 0) { decoder->error = 33;
return; }
2631 if(decoder->infoPng.interlaceMethod > 1) { decoder->error = 34;
return; }
2633 decoder->error =
checkColorValidity(decoder->infoPng.color.colorType, decoder->infoPng.color.bitDepth);
2636 static unsigned unfilterScanline(
unsigned char* recon,
const unsigned char* scanline,
const unsigned char* precon,
size_t bytewidth,
unsigned char filterType,
size_t length)
2650 for(i = 0; i < length; i++) recon[i] = scanline[i];
2653 for(i = 0; i < bytewidth; i++) recon[i] = scanline[i];
2654 for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth];
2657 if(precon)
for(i = 0; i < length; i++) recon[i] = scanline[i] + precon[i];
2658 else for(i = 0; i < length; i++) recon[i] = scanline[i];
2663 for(i = 0; i < bytewidth; i++) recon[i] = scanline[i] + precon[i] / 2;
2664 for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2);
2668 for(i = 0; i < bytewidth; i++) recon[i] = scanline[i];
2669 for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth] / 2;
2675 for(i = 0; i < bytewidth; i++) recon[i] = (
unsigned char)(scanline[i] +
paethPredictor(0, precon[i], 0));
2676 for(i = bytewidth; i < length; i++) recon[i] = (
unsigned char)(scanline[i] +
paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
2680 for(i = 0; i < bytewidth; i++) recon[i] = scanline[i];
2681 for(i = bytewidth; i < length; i++) recon[i] = (
unsigned char)(scanline[i] +
paethPredictor(recon[i - bytewidth], 0, 0));
2689 static unsigned unfilter(
unsigned char* out,
const unsigned char* in,
unsigned w,
unsigned h,
unsigned bpp)
2700 unsigned char* prevline = 0;
2702 size_t bytewidth = (bpp + 7) / 8;
2703 size_t linebytes = (w * bpp + 7) / 8;
2705 for(y = 0; y <
h; y++)
2707 size_t outindex = linebytes *
y;
2708 size_t inindex = (1 + linebytes) * y;
2709 unsigned char filterType = in[inindex];
2711 unsigned error = unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes);
2712 if(error)
return error;
2714 prevline = &out[outindex];
2720 static void Adam7_deinterlace(
unsigned char* out,
const unsigned char* in,
unsigned w,
unsigned h,
unsigned bpp)
2724 unsigned passw[7], passh[7];
size_t filter_passstart[8], padded_passstart[8], passstart[8];
2727 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
2731 for(i = 0; i < 7; i++)
2734 size_t bytewidth = bpp / 8;
2735 for(y = 0; y < passh[i]; y++)
2736 for(x = 0; x < passw[i]; x++)
2738 size_t pixelinstart = passstart[i] + (y * passw[i] +
x) * bytewidth;
2739 size_t pixeloutstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth;
2740 for(b = 0; b < bytewidth; b++)
2742 out[pixeloutstart +
b] = in[pixelinstart +
b];
2749 for(i = 0; i < 7; i++)
2752 unsigned ilinebits = bpp * passw[i];
2753 unsigned olinebits = bpp *
w;
2755 for(y = 0; y < passh[i]; y++)
2756 for(x = 0; x < passw[i]; x++)
2758 ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp);
2759 obp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp;
2760 for(b = 0; b < bpp; b++)
2763 setBitOfReversedStream0(&obp, out, bit);
2770 static void removePaddingBits(
unsigned char* out,
const unsigned char* in,
size_t olinebits,
size_t ilinebits,
unsigned h)
2779 size_t diff = ilinebits - olinebits;
2780 size_t obp = 0, ibp = 0;
2781 for(y = 0; y <
h; y++)
2784 for(x = 0; x < olinebits; x++)
2794 static unsigned postProcessScanlines(
unsigned char* out,
unsigned char* in,
const LodePNG_InfoPng* infoPng)
2803 unsigned w = infoPng->
width;
2804 unsigned h = infoPng->
height;
2806 if(bpp == 0)
return 31;
2810 if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8)
2812 error = unfilter(in, in, w, h, bpp);
2813 if(error)
return error;
2814 removePaddingBits(out, in, w * bpp, ((w * bpp + 7) / 8) * 8, h);
2816 else error = unfilter(out, in, w, h, bpp);
2820 unsigned passw[7], passh[7];
size_t filter_passstart[8], padded_passstart[8], passstart[8];
2823 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
2825 for(i = 0; i < 7; i++)
2827 error = unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp);
2828 if(error)
return error;
2832 removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp, ((passw[i] * bpp + 7) / 8) * 8, passh[i]);
2836 Adam7_deinterlace(out, in, w, h, bpp);
2843 static void decodeGeneric(LodePNG_Decoder* decoder,
unsigned char** out,
size_t* outsize,
const unsigned char* in,
size_t size)
2845 unsigned char IEND = 0;
2846 const unsigned char* chunk;
2852 unsigned critical_pos = 1;
2858 if(size == 0 || in == 0) { decoder->error = 48;
return; }
2860 LodePNG_inspect(decoder, in, size);
2861 if(decoder->error)
return;
2869 unsigned chunkLength;
2870 const unsigned char*
data;
2872 if((
size_t)((chunk - in) + 12) > size || chunk < in) { decoder->error = 30;
break; }
2874 if(chunkLength > 2147483647) { decoder->error = 63;
break; }
2875 if((
size_t)((chunk - in) + chunkLength + 12) > size || (chunk + chunkLength + 12) < in) { decoder->error = 35;
break; }
2881 size_t oldsize = idat.
size;
2882 if(!
ucvector_resize(&idat, oldsize + chunkLength)) { decoder->error = 9936;
break; }
2883 for(i = 0; i < chunkLength; i++) idat.
data[oldsize + i] = data[i];
2895 if(decoder->infoPng.color.palette) free(decoder->infoPng.color.palette);
2896 decoder->infoPng.color.palettesize = chunkLength / 3;
2897 decoder->infoPng.color.palette = (
unsigned char*)malloc(4 * decoder->infoPng.color.palettesize);
2898 if(!decoder->infoPng.color.palette && decoder->infoPng.color.palettesize) { decoder->error = 9937;
break; }
2899 if(!decoder->infoPng.color.palette) decoder->infoPng.color.palettesize = 0;
2900 if(decoder->infoPng.color.palettesize > 256) { decoder->error = 38;
break; }
2901 for(i = 0; i < decoder->infoPng.color.palettesize; i++)
2903 decoder->infoPng.color.palette[4 * i + 0] = data[pos++];
2904 decoder->infoPng.color.palette[4 * i + 1] = data[pos++];
2905 decoder->infoPng.color.palette[4 * i + 2] = data[pos++];
2906 decoder->infoPng.color.palette[4 * i + 3] = 255;
2913 if(decoder->infoPng.color.colorType == 3)
2915 if(chunkLength > decoder->infoPng.color.palettesize) { decoder->error = 39;
break; }
2916 for(i = 0; i < chunkLength; i++) decoder->infoPng.color.palette[4 * i + 3] = data[i];
2918 else if(decoder->infoPng.color.colorType == 0)
2920 if(chunkLength != 2) { decoder->error = 40;
break; }
2921 decoder->infoPng.color.key_defined = 1;
2922 decoder->infoPng.color.key_r = decoder->infoPng.color.key_g = decoder->infoPng.color.key_b = 256 * data[0] + data[1];
2924 else if(decoder->infoPng.color.colorType == 2)
2926 if(chunkLength != 6) { decoder->error = 41;
break; }
2927 decoder->infoPng.color.key_defined = 1;
2928 decoder->infoPng.color.key_r = 256 * data[0] + data[1];
2929 decoder->infoPng.color.key_g = 256 * data[2] + data[3];
2930 decoder->infoPng.color.key_b = 256 * data[4] + data[5];
2932 else { decoder->error = 42;
break; }
2934 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 2938 if(decoder->infoPng.color.colorType == 3)
2940 if(chunkLength != 1) { decoder->error = 43;
break; }
2941 decoder->infoPng.background_defined = 1;
2942 decoder->infoPng.background_r = decoder->infoPng.background_g = decoder->infoPng.background_g = data[0];
2944 else if(decoder->infoPng.color.colorType == 0 || decoder->infoPng.color.colorType == 4)
2946 if(chunkLength != 2) { decoder->error = 44;
break; }
2947 decoder->infoPng.background_defined = 1;
2948 decoder->infoPng.background_r = decoder->infoPng.background_g = decoder->infoPng.background_b = 256 * data[0] + data[1];
2950 else if(decoder->infoPng.color.colorType == 2 || decoder->infoPng.color.colorType == 6)
2952 if(chunkLength != 6) { decoder->error = 45;
break; }
2953 decoder->infoPng.background_defined = 1;
2954 decoder->infoPng.background_r = 256 * data[0] + data[1];
2955 decoder->infoPng.background_g = 256 * data[2] + data[3];
2956 decoder->infoPng.background_b = 256 * data[4] + data[5];
2962 if(decoder->settings.readTextChunks)
2964 char *key = 0, *str = 0;
2966 while(!decoder->error)
2968 unsigned length, string2_begin;
2970 for(length = 0; length < chunkLength && data[length] != 0; length++) ;
2971 if(length + 1 >= chunkLength) { decoder->error = 75;
break; }
2972 key = (
char*)malloc(length + 1);
2973 if(!key) { decoder->error = 9938;
break; }
2975 for(i = 0; i < length; i++) key[i] = data[i];
2977 string2_begin = length + 1;
2978 if(string2_begin > chunkLength) { decoder->error = 75;
break; }
2979 length = chunkLength - string2_begin;
2980 str = (
char*)malloc(length + 1);
2981 if(!str) { decoder->error = 9939;
break; }
2983 for(i = 0; i < length; i++) str[i] = data[string2_begin + i];
2985 decoder->error = LodePNG_Text_add(&decoder->infoPng.text, key, str);
2997 if(decoder->settings.readTextChunks)
2999 unsigned length, string2_begin;
3005 while(!decoder->error)
3007 for(length = 0; length < chunkLength && data[length] != 0; length++) ;
3008 if(length + 2 >= chunkLength) { decoder->error = 75;
break; }
3009 key = (
char*)malloc(length + 1);
3010 if(!key) { decoder->error = 9940;
break; }
3012 for(i = 0; i < length; i++) key[i] = data[i];
3014 if(data[length + 1] != 0) { decoder->error = 72;
break; }
3016 string2_begin = length + 2;
3017 if(string2_begin > chunkLength) { decoder->error = 75;
break; }
3018 length = chunkLength - string2_begin;
3019 decoder->error = LodePNG_decompress(&decoded.
data, &decoded.
size, (
unsigned char*)(&data[string2_begin]), length, &decoder->settings.zlibsettings);
3020 if(decoder->error)
break;
3023 decoder->error = LodePNG_Text_add(&decoder->infoPng.text, key, (
char*)decoded.
data);
3030 if(decoder->error)
break;
3036 if(decoder->settings.readTextChunks)
3038 unsigned length,
begin, compressed;
3039 char *key = 0, *langtag = 0, *transkey = 0;
3043 while(!decoder->error)
3045 if(chunkLength < 5) { decoder->error = 76;
break; }
3046 for(length = 0; length < chunkLength && data[length] != 0; length++) ;
3047 if(length + 2 >= chunkLength) { decoder->error = 75;
break; }
3048 key = (
char*)malloc(length + 1);
3049 if(!key) { decoder->error = 9941;
break; }
3051 for(i = 0; i < length; i++) key[i] = data[i];
3053 compressed = data[length + 1];
3054 if(data[length + 2] != 0) { decoder->error = 72;
break; }
3058 for(i = begin; i < chunkLength && data[i] != 0; i++) length++;
3059 if(begin + length + 1 >= chunkLength) { decoder->error = 75;
break; }
3060 langtag = (
char*)malloc(length + 1);
3061 if(!langtag) { decoder->error = 9942;
break; }
3062 langtag[length] = 0;
3063 for(i = 0; i < length; i++) langtag[i] = data[begin + i];
3065 begin += length + 1;
3067 for(i = begin; i < chunkLength && data[i] != 0; i++) length++;
3068 if(begin + length + 1 >= chunkLength) { decoder->error = 75;
break; }
3069 transkey = (
char*)malloc(length + 1);
3070 if(!transkey) { decoder->error = 9943;
break; }
3071 transkey[length] = 0;
3072 for(i = 0; i < length; i++) transkey[i] = data[begin + i];
3074 begin += length + 1;
3075 if(begin > chunkLength) { decoder->error = 75;
break; }
3076 length = chunkLength -
begin;
3080 decoder->error = LodePNG_decompress(&decoded.
data, &decoded.
size, (
unsigned char*)(&data[begin]), length, &decoder->settings.zlibsettings);
3081 if(decoder->error)
break;
3086 if(!
ucvector_resize(&decoded, length + 1)) { decoder->error = 9944;
break; }
3087 decoded.
data[length] = 0;
3088 for(i = 0; i < length; i++) decoded.
data[i] = data[begin + i];
3091 decoder->error = LodePNG_IText_add(&decoder->infoPng.itext, key, langtag, transkey, (
char*)decoded.
data);
3100 if(decoder->error)
break;
3105 if(chunkLength != 7) { decoder->error = 73;
break; }
3106 decoder->infoPng.time_defined = 1;
3107 decoder->infoPng.time.year = 256 * data[0] + data[+ 1];
3108 decoder->infoPng.time.month = data[2];
3109 decoder->infoPng.time.day = data[3];
3110 decoder->infoPng.time.hour = data[4];
3111 decoder->infoPng.time.minute = data[5];
3112 decoder->infoPng.time.second = data[6];
3116 if(chunkLength != 9) { decoder->error = 74;
break; }
3117 decoder->infoPng.phys_defined = 1;
3118 decoder->infoPng.phys_x = 16777216 * data[0] + 65536 * data[1] + 256 * data[2] + data[3];
3119 decoder->infoPng.phys_y = 16777216 * data[4] + 65536 * data[5] + 256 * data[6] + data[7];
3120 decoder->infoPng.phys_unit = data[8];
3127 #ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS 3128 if(decoder->settings.rememberUnknownChunks)
3130 LodePNG_UnknownChunks* unknown = &decoder->infoPng.unknown_chunks;
3131 decoder->error =
LodePNG_append_chunk(&unknown->data[critical_pos - 1], &unknown->datasize[critical_pos - 1], chunk);
3132 if(decoder->error)
break;
3137 if(!decoder->settings.ignoreCrc && !unknown)
3149 if(!
ucvector_resize(&scanlines, ((decoder->infoPng.width * (decoder->infoPng.height *
LodePNG_InfoColor_getBpp(&decoder->infoPng.color) + 7)) / 8) + decoder->infoPng.height)) decoder->error = 9945;
3150 if(!decoder->error) decoder->error = LodePNG_decompress(&scanlines.
data, &scanlines.
size, idat.
data, idat.
size, &decoder->settings.zlibsettings);
3156 if(!ucvector_resizev(&outv, (decoder->infoPng.height * decoder->infoPng.width *
LodePNG_InfoColor_getBpp(&decoder->infoPng.color) + 7) / 8, 0)) decoder->error = 9946;
3157 if(!decoder->error) decoder->error = postProcessScanlines(outv.
data, scanlines.
data, &decoder->infoPng);
3159 *outsize = outv.
size;
3167 void LodePNG_decode(LodePNG_Decoder* decoder,
unsigned char** out,
size_t* outsize,
const unsigned char* in,
size_t insize)
3171 decodeGeneric(decoder, out, outsize, in, insize);
3172 if(decoder->error)
return;
3173 if(!decoder->settings.color_convert ||
LodePNG_InfoColor_equal(&decoder->infoRaw.color, &decoder->infoPng.color))
3178 if(!decoder->settings.color_convert)
3181 if(decoder->error)
return;
3187 unsigned char* data = *out;
3190 if(!(decoder->infoRaw.color.colorType == 2 || decoder->infoRaw.color.colorType == 6) && !(decoder->infoRaw.color.bitDepth == 8)) { decoder->error = 56;
return; }
3192 *outsize = (decoder->infoPng.width * decoder->infoPng.height *
LodePNG_InfoColor_getBpp(&decoder->infoRaw.color) + 7) / 8;
3193 *out = (
unsigned char*)malloc(*outsize);
3196 decoder->error = 9947;
3199 else decoder->error =
LodePNG_convert(*out, data, &decoder->infoRaw.color, &decoder->infoPng.color, decoder->infoPng.width, decoder->infoPng.height);
3204 unsigned LodePNG_decode32(
unsigned char** out,
unsigned* w,
unsigned* h,
const unsigned char* in,
size_t insize)
3209 LodePNG_Decoder_init(&decoder);
3210 LodePNG_decode(&decoder, out, &dummy_size, in, insize);
3211 error = decoder.error;
3212 *w = decoder.infoPng.width;
3213 *h = decoder.infoPng.height;
3214 LodePNG_Decoder_cleanup(&decoder);
3218 #ifdef LODEPNG_COMPILE_DISK 3219 unsigned LodePNG_decode32f(
unsigned char** out,
unsigned* w,
unsigned* h,
const char*
filename)
3221 unsigned char* buffer;
3225 if(!error) error = LodePNG_decode32(out, w, h, buffer, buffersize);
3231 void LodePNG_DecodeSettings_init(LodePNG_DecodeSettings* settings)
3233 settings->color_convert = 1;
3234 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 3235 settings->readTextChunks = 1;
3237 settings->ignoreCrc = 0;
3238 #ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS 3239 settings->rememberUnknownChunks = 0;
3241 LodeZlib_DecompressSettings_init(&settings->zlibsettings);
3244 void LodePNG_Decoder_init(LodePNG_Decoder* decoder)
3246 LodePNG_DecodeSettings_init(&decoder->settings);
3252 void LodePNG_Decoder_cleanup(LodePNG_Decoder* decoder)
3258 void LodePNG_Decoder_copy(LodePNG_Decoder* dest,
const LodePNG_Decoder* source)
3260 LodePNG_Decoder_cleanup(dest);
3270 #ifdef LODEPNG_COMPILE_ENCODER 3277 static unsigned addChunk(
ucvector* out,
const char* chunkName,
const unsigned char* data,
size_t length)
3280 if(error)
return error;
3298 static unsigned addChunk_IHDR(
ucvector* out,
unsigned w,
unsigned h,
unsigned bitDepth,
unsigned colorType,
unsigned interlaceMethod)
3385 error =
addChunk(out,
"IEND", 0, 0);
3389 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 3391 static unsigned addChunk_tEXt(
ucvector* out,
const char* keyword,
const char* textstring)
3397 for(i = 0; keyword[i] != 0; i++)
ucvector_push_back(&text, (
unsigned char)keyword[i]);
3399 for(i = 0; textstring[i] != 0; i++)
ucvector_push_back(&text, (
unsigned char)textstring[i]);
3410 size_t i, textsize = strlen(textstring);
3414 for(i = 0; keyword[i] != 0; i++)
ucvector_push_back(&data, (
unsigned char)keyword[i]);
3430 static unsigned addChunk_iTXt(
ucvector* out,
unsigned compressed,
const char* keyword,
const char* langtag,
const char* transkey,
const char* textstring,
LodeZlib_DeflateSettings* zlibsettings)
3434 size_t i, textsize = strlen(textstring);
3438 for(i = 0; keyword[i] != 0; i++)
ucvector_push_back(&data, (
unsigned char)keyword[i]);
3442 for(i = 0; langtag[i] != 0; i++)
ucvector_push_back(&data, (
unsigned char)langtag[i]);
3444 for(i = 0; transkey[i] != 0; i++)
ucvector_push_back(&data, (
unsigned char)transkey[i]);
3450 error =
LodePNG_compress(&compressed_data.
data, &compressed_data.
size, (
unsigned char*)textstring, textsize, zlibsettings);
3454 for(i = 0; textstring[i] != 0; i++)
ucvector_push_back(&data, (
unsigned char)textstring[i]);
3459 for(i = 0; textstring[i] != 0; i++)
ucvector_push_back(&data, (
unsigned char)textstring[i]);
3497 static unsigned addChunk_tIME(
ucvector* out,
const LodePNG_Time*
time)
3500 unsigned char* data = (
unsigned char*)malloc(7);
3501 if(!data)
return 9948;
3502 data[0] = (
unsigned char)(time->year / 256);
3503 data[1] = (
unsigned char)(time->year % 256);
3504 data[2] = time->month;
3505 data[3] = time->day;
3506 data[4] = time->hour;
3507 data[5] = time->minute;
3508 data[6] = time->second;
3509 error =
addChunk(out,
"tIME", data, 7);
3532 static void filterScanline(
unsigned char* out,
const unsigned char* scanline,
const unsigned char* prevline,
size_t length,
size_t bytewidth,
unsigned char filterType)
3538 for(i = 0; i < length; i++) out[i] = scanline[i];
3541 for(i = 0; i < bytewidth; i++) out[i] = scanline[i];
3542 for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth];
3545 if(prevline)
for(i = 0; i < length; i++) out[i] = scanline[i] - prevline[i];
3546 else for(i = 0; i < length; i++) out[i] = scanline[i];
3551 for(i = 0; i < bytewidth; i++) out[i] = scanline[i] - prevline[i] / 2;
3552 for(i = bytewidth; i < length; i++) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) / 2);
3556 for(i = 0; i < length; i++) out[i] = scanline[i];
3557 for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth] / 2;
3563 for(i = 0; i < bytewidth; i++) out[i] = (
unsigned char)(scanline[i] -
paethPredictor(0, prevline[i], 0));
3564 for(i = bytewidth; i < length; i++) out[i] = (
unsigned char)(scanline[i] -
paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth]));
3568 for(i = 0; i < bytewidth; i++) out[i] = scanline[i];
3569 for(i = bytewidth; i < length; i++) out[i] = (
unsigned char)(scanline[i] -
paethPredictor(scanline[i - bytewidth], 0, 0));
3590 size_t linebytes = (w * bpp + 7) / 8;
3591 size_t bytewidth = (bpp + 7) / 8;
3592 const unsigned char* prevline = 0;
3597 if(bpp == 0)
return 31;
3605 for(y = 0; y <
h; y++)
3607 size_t outindex = (1 + linebytes) * y;
3608 size_t inindex = linebytes *
y;
3609 const unsigned TYPE = 0;
3610 out[outindex] = TYPE;
3611 filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, TYPE);
3612 prevline = &in[inindex];
3615 else if(heuristic == 1)
3619 size_t smallest = 0;
3620 unsigned type, bestType = 0;
3622 for(type = 0; type < 5; type++)
ucvector_init(&attempt[type]);
3623 for(type = 0; type < 5; type++)
3625 if(!
ucvector_resize(&attempt[type], linebytes)) { error = 9949;
break; }
3630 for(y = 0; y <
h; y++)
3633 for(type = 0; type < 5; type++)
3635 filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type);
3639 for(x = 0; x < attempt[
type].
size; x+=3) sum[type] += attempt[type].data[x];
3642 if(type == 0 || sum[type] < smallest)
3645 smallest = sum[
type];
3649 prevline = &in[y * linebytes];
3652 out[y * (linebytes + 1)] = bestType;
3653 for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 +
x] = attempt[bestType].
data[
x];
3660 else if(heuristic == 2)
3665 unsigned type = 0, bestType = 0;
3666 unsigned char*
dummy;
3668 deflatesettings.
btype = 1;
3670 for(y = 0; y <
h; y++)
3672 for(type = 0; type < 5; type++)
3674 filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type);
3675 size[
type] = 0; dummy = 0;
3676 LodePNG_compress(&dummy, &size[type], attempt[type].data, attempt[type].size, &deflatesettings);
3679 if(type == 0 || size[type] < smallest) { bestType =
type; smallest = size[
type]; }
3681 prevline = &in[y * linebytes];
3682 out[y * (linebytes + 1)] = bestType;
3683 for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 +
x] = attempt[bestType].
data[
x];
3692 static void addPaddingBits(
unsigned char* out,
const unsigned char* in,
size_t olinebits,
size_t ilinebits,
unsigned h)
3697 size_t diff = olinebits - ilinebits;
3698 size_t obp = 0, ibp = 0;
3699 for(y = 0; y <
h; y++)
3702 for(x = 0; x < ilinebits; x++)
3712 static void Adam7_interlace(
unsigned char* out,
const unsigned char* in,
unsigned w,
unsigned h,
unsigned bpp)
3715 unsigned passw[7], passh[7];
size_t filter_passstart[8], padded_passstart[8], passstart[8];
3718 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
3722 for(i = 0; i < 7; i++)
3725 size_t bytewidth = bpp / 8;
3726 for(y = 0; y < passh[i]; y++)
3727 for(x = 0; x < passw[i]; x++)
3729 size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth;
3730 size_t pixeloutstart = passstart[i] + (y * passw[i] +
x) * bytewidth;
3731 for(b = 0; b < bytewidth; b++)
3733 out[pixeloutstart +
b] = in[pixelinstart +
b];
3740 for(i = 0; i < 7; i++)
3743 unsigned ilinebits = bpp * passw[i];
3744 unsigned olinebits = bpp *
w;
3746 for(y = 0; y < passh[i]; y++)
3747 for(x = 0; x < passw[i]; x++)
3749 ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp;
3750 obp = (8 * passstart[i]) + (y * ilinebits + x * bpp);
3751 for(b = 0; b < bpp; b++)
3770 unsigned w = infoPng->
width;
3771 unsigned h = infoPng->
height;
3776 *outsize = h + (h * ((w * bpp + 7) / 8));
3777 *out = (
unsigned char*)malloc(*outsize);
3778 if(!(*out) && (*outsize)) error = 9950;
3782 if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8)
3794 else error =
filter(*out, in, w, h, &infoPng->
color);
3799 unsigned char* adam7 = (
unsigned char*)malloc((h * w * bpp + 7) / 8);
3800 if(!adam7 && ((h * w * bpp + 7) / 8)) error = 9952;
3804 unsigned passw[7], passh[7];
size_t filter_passstart[8], padded_passstart[8], passstart[8];
3807 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
3809 *outsize = filter_passstart[7];
3810 *out = (
unsigned char*)malloc(*outsize);
3811 if(!(*out) && (*outsize)) { error = 9953;
break; }
3815 for(i = 0; i < 7; i++)
3824 addPaddingBits(&padded.
data[padded_passstart[i]], &adam7[passstart[i]], ((passw[i] * bpp + 7) / 8) * 8, passw[i] * bpp, passh[i]);
3825 error =
filter(&(*out)[filter_passstart[i]], &padded.
data[padded_passstart[i]], passw[i], passh[i], &infoPng->
color);
3832 error =
filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]], passw[i], passh[i], &infoPng->
color);
3849 for(i = 0; i < palettesize; i++)
3851 if(palette[4 * i + 3] != 255)
return 0;
3861 unsigned i, numpixels = w *
h;
3866 for(i = 0; i < numpixels; i++)
if(image[i * 4 + 3] != 255)
return 0;
3870 for(i = 0; i < numpixels; i++)
if(image[i * 8 + 6] != 255 || image[i * 8 + 7] != 255)
return 0;
3878 for(i = 0; i < numpixels; i++)
if(image[i * 2 + 1] != 255)
return 0;
3882 for(i = 0; i < numpixels; i++)
if(image[i * 4 + 2] != 255 || image[i * 4 + 3] != 255)
return 0;
3895 #ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS 3896 static unsigned addUnknownChunks(
ucvector* out,
unsigned char* data,
size_t datasize)
3898 unsigned char* inchunk =
data;
3899 while((
size_t)(inchunk - data) < datasize)
3902 if(error)
return error;
3914 unsigned char* data = 0;
3915 size_t datasize = 0;
3941 unsigned char* converted;
3945 converted = (
unsigned char*)malloc(size);
3946 if(!converted && size) encoder->
error = 9955;
3954 while(!encoder->
error)
3956 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 3963 #ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS 3965 if(info.unknown_chunks.data[0]) { encoder->
error = addUnknownChunks(&outv, info.unknown_chunks.data[0], info.unknown_chunks.datasize[0]);
if(encoder->
error)
break; }
3981 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 3983 if(info.background_defined) addChunk_bKGD(&outv, &info);
3985 if(info.phys_defined) addChunk_pHYs(&outv, &info);
3987 #ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS 3989 if(info.unknown_chunks.data[1]) { encoder->
error = addUnknownChunks(&outv, info.unknown_chunks.data[1], info.unknown_chunks.datasize[1]);
if(encoder->
error)
break; }
3993 if(encoder->
error)
break;
3994 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 3996 if(info.time_defined) addChunk_tIME(&outv, &info.time);
3998 for(i = 0; i < info.text.num; i++)
4000 if(strlen(info.text.keys[i]) > 79) { encoder->
error = 66;
break; }
4001 if(strlen(info.text.keys[i]) < 1) { encoder->
error = 67;
break; }
4002 if(encoder->
settings.text_compression)
4003 addChunk_zTXt(&outv, info.text.keys[i], info.text.strings[i], &encoder->
settings.
zlibsettings);
4005 addChunk_tEXt(&outv, info.text.keys[i], info.text.strings[i]);
4010 unsigned alread_added_id_text = 0;
4011 for(i = 0; i < info.text.num; i++)
4012 if(!
strcmp(info.text.keys[i],
"LodePNG")) { alread_added_id_text = 1;
break; }
4013 if(alread_added_id_text == 0)
4017 for(i = 0; i < info.itext.num; i++)
4019 if(strlen(info.itext.keys[i]) > 79) { encoder->
error = 66;
break; }
4020 if(strlen(info.itext.keys[i]) < 1) { encoder->
error = 67;
break; }
4021 addChunk_iTXt(&outv, encoder->
settings.text_compression,
4022 info.itext.keys[i], info.itext.langtags[i], info.itext.transkeys[i], info.itext.strings[i],
4026 #ifdef LODEPNG_COMPILE_UNKNOWN_CHUNKS 4028 if(info.unknown_chunks.data[2]) { encoder->
error = addUnknownChunks(&outv, info.unknown_chunks.data[2], info.unknown_chunks.datasize[2]);
if(encoder->
error)
break; }
4039 *outsize = outv.
size;
4042 unsigned LodePNG_encode32(
unsigned char** out,
size_t* outsize,
const unsigned char* image,
unsigned w,
unsigned h)
4048 error = encoder.
error;
4053 #ifdef LODEPNG_COMPILE_DISK 4054 unsigned LodePNG_encode32f(
const char* filename,
const unsigned char* image,
unsigned w,
unsigned h)
4056 unsigned char* buffer;
4070 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS 4071 settings->add_id = 1;
4072 settings->text_compression = 0;
4108 #ifdef LODEPNG_COMPILE_DISK 4120 if(!file)
return 78;
4123 fseek(file , 0 , SEEK_END);
4131 *out = (
unsigned char*)malloc((
size_t)
size);
4132 if(size && (*out)) (*outsize) = fread(*out, 1, (
size_t)size, file);
4136 if(!(*out) && size)
return 80;
4141 unsigned LodePNG_saveFile(
const unsigned char* buffer,
size_t buffersize,
const char* filename)
4145 if(!file)
return 79;
4146 fwrite((
char*)buffer , 1 , buffersize, file);
static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree *tree, const unsigned *frequencies, size_t numcodes, unsigned maxbitlen)
static void addBitsToStream(size_t *bitpointer, ucvector *bitstream, unsigned value, size_t nbits)
static unsigned HuffmanTree_getLength(const HuffmanTree *tree, unsigned index)
static unsigned isFullyOpaque(const unsigned char *image, unsigned w, unsigned h, const LodePNG_InfoColor *info)
static unsigned update_adler32(unsigned adler, const unsigned char *data, unsigned len)
static void Adam7_interlace(unsigned char *out, const unsigned char *in, unsigned w, unsigned h, unsigned bpp)
unsigned LodePNG_InfoPng_copy(LodePNG_InfoPng *dest, const LodePNG_InfoPng *source)
unsigned LodePNG_loadFile(unsigned char **out, size_t *outsize, const char *filename)
unsigned LodePNG_InfoColor_getBpp(const LodePNG_InfoColor *info)
static unsigned vector_resize(vector *p, size_t size)
static unsigned uivector_resize(uivector *p, size_t size)
static constexpr double g
unsigned char * LodePNG_chunk_next(unsigned char *chunk)
static const unsigned ADAM7_DY[7]
const LodeZlib_DeflateSettings LodeZlib_defaultDeflateSettings
unsigned compressionMethod
#define NUM_DEFLATE_CODE_SYMBOLS
static unsigned Crc32_update_crc(const unsigned char *buf, unsigned int crc, size_t len)
void LodePNG_InfoColor_clearPalette(LodePNG_InfoColor *info)
static void Crc32_make_crc_table(void)
static void LodePNG_add32bitInt(ucvector *buffer, unsigned value)
static const unsigned ADAM7_DX[7]
unsigned LodePNG_create_chunk(unsigned char **out, size_t *outlength, unsigned length, const char *type, const unsigned char *data)
static int paethPredictor(int a, int b, int c)
void LodeZlib_add32bitInt(ucvector *buffer, unsigned value)
void LodeZlib_DeflateSettings_init(LodeZlib_DeflateSettings *settings)
void LodePNG_InfoColor_cleanup(LodePNG_InfoColor *info)
struct HuffmanTree HuffmanTree
static void addPaddingBits(unsigned char *out, const unsigned char *in, size_t olinebits, size_t ilinebits, unsigned h)
static void Coin_sort(Coin *data, size_t amount)
static const unsigned ADAM7_IX[7]
static unsigned Crc32_crc_table[256]
static unsigned isPaletteFullyOpaque(const unsigned char *palette, size_t palettesize)
unsigned LodePNG_InfoColor_getChannels(const LodePNG_InfoColor *info)
static unsigned uivector_copy(uivector *p, const uivector *q)
void LodePNG_InfoPng_swap(LodePNG_InfoPng *a, LodePNG_InfoPng *b)
unsigned LodePNG_encode32f(const char *filename, const unsigned char *image, unsigned w, unsigned h)
void LodePNG_Encoder_init(LodePNG_Encoder *encoder)
void LodePNG_InfoColor_init(LodePNG_InfoColor *info)
LodePNG_EncodeSettings settings
static unsigned ucvector_push_back(ucvector *p, unsigned char c)
static unsigned addChunk_PLTE(ucvector *out, const LodePNG_InfoColor *info)
void LodePNG_encode(LodePNG_Encoder *encoder, unsigned char **out, size_t *outsize, const unsigned char *image, unsigned w, unsigned h)
static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8], size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp)
unsigned LodePNG_chunk_check_crc(const unsigned char *chunk)
static size_t searchCodeIndex(const unsigned *array, size_t array_size, size_t value)
static void writeLZ77data(size_t *bp, ucvector *out, const uivector *lz77_encoded, const HuffmanTree *codes, const HuffmanTree *codesD)
static unsigned char readBitFromReversedStream(size_t *bitpointer, const unsigned char *bitstream)
static unsigned generateDistanceTree(HuffmanTree *tree)
static unsigned addChunk_tRNS(ucvector *out, const LodePNG_InfoColor *info)
static unsigned addChunk(ucvector *out, const char *chunkName, const unsigned char *data, size_t length)
static unsigned HuffmanTree_makeFromLengths2(HuffmanTree *tree)
static void Coin_init(Coin *c)
static void uivector_cleanup(void *p)
static const unsigned DISTANCEBASE[30]
unsigned LodePNG_InfoColor_addPalette(LodePNG_InfoColor *info, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
static QFile::DecoderFn decoder
constexpr ProductStatus unknown() noexcept
void LodePNG_Encoder_cleanup(LodePNG_Encoder *encoder)
LodeZlib_DeflateSettings zlibsettings
static unsigned checkColorValidity(unsigned colorType, unsigned bd)
static void LodePNG_set32bitInt(unsigned char *buffer, unsigned value)
static void writeSignature(ucvector *out)
static unsigned LodePNG_compress(unsigned char **out, size_t *outsize, const unsigned char *in, size_t insize, const LodeZlib_DeflateSettings *settings)
static void addLengthDistance(uivector *values, size_t length, size_t distance)
unsigned char LodePNG_chunk_critical(const unsigned char *chunk)
static void Coin_cleanup(void *c)
const unsigned char * LodePNG_chunk_data_const(const unsigned char *chunk)
unsigned char LodePNG_chunk_safetocopy(const unsigned char *chunk)
static unsigned readBitsFromReversedStream(size_t *bitpointer, const unsigned char *bitstream, size_t nbits)
static unsigned addChunk_IEND(ucvector *out)
#define NUM_DISTANCE_SYMBOLS
static void vector_cleanup(void *p)
static void ucvector_cleanup(void *p)
static void HuffmanTree_init(HuffmanTree *tree)
unsigned LodePNG_chunk_length(const unsigned char *chunk)
static void addBitToStream(size_t *bitpointer, ucvector *bitstream, unsigned char bit)
#define LAST_LENGTH_CODE_INDEX
CodeOutputInterface * code
static void vector_swap(vector *p, vector *q)
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
static void ucvector_init(ucvector *p)
static unsigned getNumColorChannels(unsigned colorType)
unsigned LodeFlate_deflate(ucvector *out, const unsigned char *data, size_t datasize, const LodeZlib_DeflateSettings *settings)
const unsigned char * LodePNG_chunk_next_const(const unsigned char *chunk)
static unsigned uivector_push_back(uivector *p, unsigned c)
unsigned LodePNG_saveFile(const unsigned char *buffer, size_t buffersize, const char *filename)
static void * vector_get(vector *p, size_t index)
static unsigned preProcessScanlines(unsigned char **out, size_t *outsize, const unsigned char *in, const LodePNG_InfoPng *infoPng)
static const unsigned LENGTHBASE[29]
static unsigned Crc32_crc_table_computed
static unsigned deflateNoCompression(ucvector *out, const unsigned char *data, size_t datasize)
static unsigned addChunk_IDAT(ucvector *out, const unsigned char *data, size_t datasize, LodeZlib_DeflateSettings *zlibsettings)
void LodePNG_InfoRaw_init(LodePNG_InfoRaw *info)
void LodePNG_InfoPng_cleanup(LodePNG_InfoPng *info)
static void ucvector_init_buffer(ucvector *p, unsigned char *buffer, size_t size)
static const unsigned ADAM7_IY[7]
static unsigned adler32(const unsigned char *data, unsigned len)
static unsigned deflateDynamic(ucvector *out, const unsigned char *data, size_t datasize, const LodeZlib_DeflateSettings *settings)
auto array(Array const &a)
Returns a manipulator which will print the specified array.
#define NUM_CODE_LENGTH_CODES
static void addBitsToStreamReversed(size_t *bitpointer, ucvector *bitstream, unsigned value, size_t nbits)
unsigned LodePNG_convert(unsigned char *out, const unsigned char *in, LodePNG_InfoColor *infoOut, LodePNG_InfoColor *infoIn, unsigned w, unsigned h)
static unsigned vector_resized(vector *p, size_t size, void dtor(void *))
static void addCoins(Coin *c1, const Coin *c2)
static unsigned generateFixedTree(HuffmanTree *tree)
int strcmp(const String &s1, const String &s2)
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
static const size_t MAX_SUPPORTED_DEFLATE_LENGTH
unsigned char LodePNG_chunk_type_equals(const unsigned char *chunk, const char *type)
static unsigned HuffmanTree_make2DTree(HuffmanTree *tree)
static void uivector_init(uivector *p)
unsigned LodePNG_InfoColor_copy(LodePNG_InfoColor *dest, const LodePNG_InfoColor *source)
static unsigned encodeLZ77_brute(uivector *out, const unsigned char *in, size_t size, unsigned windowSize)
static const unsigned DISTANCEEXTRA[30]
unsigned LodeZlib_read32bitInt(const unsigned char *buffer)
unsigned LodePNG_InfoColor_isGreyscaleType(const LodePNG_InfoColor *info)
static const unsigned LENGTHEXTRA[29]
unsigned LodePNG_append_chunk(unsigned char **out, size_t *outlength, const unsigned char *chunk)
static unsigned deflateFixed(ucvector *out, const unsigned char *data, size_t datasize, const LodeZlib_DeflateSettings *settings)
static unsigned HuffmanTree_getCode(const HuffmanTree *tree, unsigned index)
static void vector_cleanupd(vector *p, void dtor(void *))
#define FIRST_LENGTH_CODE_INDEX
static unsigned ucvector_resize(ucvector *p, size_t size)
unsigned char * LodePNG_chunk_data(unsigned char *chunk)
static void setBitOfReversedStream(size_t *bitpointer, unsigned char *bitstream, unsigned char bit)
cet::LibraryManager dummy("noplugin")
static unsigned LodePNG_read32bitInt(const unsigned char *buffer)
static void addHuffmanSymbol(size_t *bp, ucvector *compressed, unsigned code, unsigned bitlen)
static void HuffmanTree_cleanup(HuffmanTree *tree)
static constexpr double pb
static unsigned getBpp(unsigned colorType, unsigned bitDepth)
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
static void filterScanline(unsigned char *out, const unsigned char *scanline, const unsigned char *prevline, size_t length, size_t bytewidth, unsigned char filterType)
unsigned LodePNG_encode32(unsigned char **out, size_t *outsize, const unsigned char *image, unsigned w, unsigned h)
void LodePNG_chunk_generate_crc(unsigned char *chunk)
static unsigned filter(unsigned char *out, const unsigned char *in, unsigned w, unsigned h, const LodePNG_InfoColor *info)
unsigned LodePNG_InfoColor_equal(const LodePNG_InfoColor *info1, const LodePNG_InfoColor *info2)
static unsigned addChunk_IHDR(ucvector *out, unsigned w, unsigned h, unsigned bitDepth, unsigned colorType, unsigned interlaceMethod)
static unsigned uivector_resizev(uivector *p, size_t size, unsigned value)
unsigned LodeZlib_compress(unsigned char **out, size_t *outsize, const unsigned char *in, size_t insize, const LodeZlib_DeflateSettings *settings)
unsigned LodePNG_InfoColor_isAlphaType(const LodePNG_InfoColor *info)
static unsigned Crc32_crc(const unsigned char *buf, size_t len)
unsigned LodePNG_InfoRaw_copy(LodePNG_InfoRaw *dest, const LodePNG_InfoRaw *source)
void LodePNG_InfoRaw_cleanup(LodePNG_InfoRaw *info)
void LodePNG_InfoPng_init(LodePNG_InfoPng *info)
FILE * portable_fopen(const char *fileName, const char *mode)
static void uivector_swap(uivector *p, uivector *q)
void LodePNG_Encoder_copy(LodePNG_Encoder *dest, const LodePNG_Encoder *source)
static unsigned HuffmanTree_fillInCoins(vector *coins, const unsigned *frequencies, unsigned numcodes, size_t sum)
static unsigned HuffmanTree_makeFromLengths(HuffmanTree *tree, const unsigned *bitlen, size_t numcodes, unsigned maxbitlen)
static QFile::EncoderFn encoder
unsigned autoLeaveOutAlphaChannel
static void vector_init(vector *p, unsigned typesize)
Portable versions of functions that are platform dependent.
void LodePNG_chunk_type(char type[5], const unsigned char *chunk)
static const unsigned CLCL[NUM_CODE_LENGTH_CODES]
unsigned char LodePNG_chunk_private(const unsigned char *chunk)
void LodePNG_EncodeSettings_init(LodePNG_EncodeSettings *settings)
static void Coin_copy(Coin *c1, const Coin *c2)