1 /*
2 LodePNG version 20190805
3 
4 Copyright (c) 2005-2019 Lode Vandevenne
5 
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
9 
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
13 
14     1. The origin of this software must not be misrepresented; you must not
15     claim that you wrote the original software. If you use this software
16     in a product, an acknowledgment in the product documentation would be
17     appreciated but is not required.
18 
19     2. Altered source versions must be plainly marked as such, and must not be
20     misrepresented as being the original software.
21 
22     3. This notice may not be removed or altered from any source
23     distribution.
24 */
25 
26 /*
27 The manual and changelog are in the header file "lodepng.h"
28 Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for C.
29 */
30 
31 #include "lodepng.h"
32 
33 #ifdef LODEPNG_COMPILE_DISK
34 #include <limits.h> /* LONG_MAX */
35 #include <stdio.h> /* file handling */
36 #endif /* LODEPNG_COMPILE_DISK */
37 
38 #ifdef LODEPNG_COMPILE_ALLOCATORS
39 #include <stdlib.h> /* allocations */
40 #endif /* LODEPNG_COMPILE_ALLOCATORS */
41 
42 #if defined(_MSC_VER) && (_MSC_VER >= 1310) /*Visual Studio: A few warning types are not desired here.*/
43 #pragma warning( disable : 4244 ) /*implicit conversions: not warned by gcc -Wall -Wextra and requires too much casts*/
44 #pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/
45 #endif /*_MSC_VER */
46 
47 const char* LODEPNG_VERSION_STRING = "20190805";
48 
49 /*
50 This source file is built up in the following large parts. The code sections
51 with the "LODEPNG_COMPILE_" #defines divide this up further in an intermixed way.
52 -Tools for C and common code for PNG and Zlib
53 -C Code for Zlib (huffman, deflate, ...)
54 -C Code for PNG (file format chunks, adam7, PNG filters, color conversions, ...)
55 -The C++ wrapper around all of the above
56 */
57 
58 /* ////////////////////////////////////////////////////////////////////////// */
59 /* ////////////////////////////////////////////////////////////////////////// */
60 /* // Tools for C, and common code for PNG and Zlib.                       // */
61 /* ////////////////////////////////////////////////////////////////////////// */
62 /* ////////////////////////////////////////////////////////////////////////// */
63 
64 /*The malloc, realloc and free functions defined here with "lodepng_" in front
65 of the name, so that you can easily change them to others related to your
66 platform if needed. Everything else in the code calls these. Pass
67 -DLODEPNG_NO_COMPILE_ALLOCATORS to the compiler, or comment out
68 #define LODEPNG_COMPILE_ALLOCATORS in the header, to disable the ones here and
69 define them in your own project's source files without needing to change
70 lodepng source code. Don't forget to remove "static" if you copypaste them
71 from here.*/
72 
73 #ifdef LODEPNG_COMPILE_ALLOCATORS
lodepng_malloc(size_t size)74 static void* lodepng_malloc(size_t size) {
75 #ifdef LODEPNG_MAX_ALLOC
76   if(size > LODEPNG_MAX_ALLOC) return 0;
77 #endif
78   return malloc(size);
79 }
80 
lodepng_realloc(void * ptr,size_t new_size)81 static void* lodepng_realloc(void* ptr, size_t new_size) {
82 #ifdef LODEPNG_MAX_ALLOC
83   if(new_size > LODEPNG_MAX_ALLOC) return 0;
84 #endif
85   return realloc(ptr, new_size);
86 }
87 
lodepng_free(void * ptr)88 static void lodepng_free(void* ptr) {
89   free(ptr);
90 }
91 #else /*LODEPNG_COMPILE_ALLOCATORS*/
92 /* TODO: support giving additional void* payload to the custom allocators */
93 void* lodepng_malloc(size_t size);
94 void* lodepng_realloc(void* ptr, size_t new_size);
95 void lodepng_free(void* ptr);
96 #endif /*LODEPNG_COMPILE_ALLOCATORS*/
97 
98 #if (defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1)) ||\
99     (defined(_MSC_VER) && (_MSC_VER >= 1400))
100 #define LODEPNG_RESTRICT __restrict
101 #else
102 #define LODEPNG_RESTRICT /* not available */
103 #endif
104 
105 /* Replacements for C library functions memcpy and strlen, to support those platforms
106 where a full C library is not available. The compiler can recognize them and compile
107 to something as fast. */
108 
lodepng_memcpy(void * LODEPNG_RESTRICT dst,const void * LODEPNG_RESTRICT src,size_t size)109 static void lodepng_memcpy(void* LODEPNG_RESTRICT dst,
110                            const void* LODEPNG_RESTRICT src, size_t size) {
111   size_t i;
112   for(i = 0; i < size; i++) ((char*)dst)[i] = ((const char*)src)[i];
113 }
114 
115 /* does not check memory out of bounds, do not use on untrusted data */
lodepng_strlen(const char * a)116 static size_t lodepng_strlen(const char* a) {
117   const char* orig = a;
118   /* avoid warning about unused function in case of disabled COMPILE... macros */
119   (void)lodepng_strlen;
120   while(*a) a++;
121   return (size_t)(a - orig);
122 }
123 
124 #define LODEPNG_MAX(a, b) (((a) > (b)) ? (a) : (b))
125 #define LODEPNG_MIN(a, b) (((a) < (b)) ? (a) : (b))
126 #define LODEPNG_ABS(x) ((x) < 0 ? -(x) : (x))
127 
128 /*
129 Often in case of an error a value is assigned to a variable and then it breaks
130 out of a loop (to go to the cleanup phase of a function). This macro does that.
131 It makes the error handling code shorter and more readable.
132 
133 Example: if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83);
134 */
135 #define CERROR_BREAK(errorvar, code){\
136   errorvar = code;\
137   break;\
138 }
139 
140 /*version of CERROR_BREAK that assumes the common case where the error variable is named "error"*/
141 #define ERROR_BREAK(code) CERROR_BREAK(error, code)
142 
143 /*Set error var to the error code, and return it.*/
144 #define CERROR_RETURN_ERROR(errorvar, code){\
145   errorvar = code;\
146   return code;\
147 }
148 
149 /*Try the code, if it returns error, also return the error.*/
150 #define CERROR_TRY_RETURN(call){\
151   unsigned error = call;\
152   if(error) return error;\
153 }
154 
155 /*Set error var to the error code, and return from the void function.*/
156 #define CERROR_RETURN(errorvar, code){\
157   errorvar = code;\
158   return;\
159 }
160 
161 /*
162 About uivector, ucvector and string:
163 -All of them wrap dynamic arrays or text strings in a similar way.
164 -LodePNG was originally written in C++. The vectors replace the std::vectors that were used in the C++ version.
165 -The string tools are made to avoid problems with compilers that declare things like strncat as deprecated.
166 -They're not used in the interface, only internally in this file as static functions.
167 -As with many other structs in this file, the init and cleanup functions serve as ctor and dtor.
168 */
169 
170 #ifdef LODEPNG_COMPILE_ZLIB
171 /*dynamic vector of unsigned ints*/
172 typedef struct uivector {
173   unsigned* data;
174   size_t size; /*size in number of unsigned longs*/
175   size_t allocsize; /*allocated size in bytes*/
176 } uivector;
177 
uivector_cleanup(void * p)178 static void uivector_cleanup(void* p) {
179   ((uivector*)p)->size = ((uivector*)p)->allocsize = 0;
180   lodepng_free(((uivector*)p)->data);
181   ((uivector*)p)->data = NULL;
182 }
183 
184 /*returns 1 if success, 0 if failure ==> nothing done*/
uivector_reserve(uivector * p,size_t allocsize)185 static unsigned uivector_reserve(uivector* p, size_t allocsize) {
186   if(allocsize > p->allocsize) {
187     size_t newsize = (allocsize > p->allocsize * 2u) ? allocsize : ((allocsize * 3u) >> 1u);
188     void* data = lodepng_realloc(p->data, newsize);
189     if(data) {
190       p->allocsize = newsize;
191       p->data = (unsigned*)data;
192     }
193     else return 0; /*error: not enough memory*/
194   }
195   return 1;
196 }
197 
198 /*returns 1 if success, 0 if failure ==> nothing done*/
uivector_resize(uivector * p,size_t size)199 static unsigned uivector_resize(uivector* p, size_t size) {
200   if(!uivector_reserve(p, size * sizeof(unsigned))) return 0;
201   p->size = size;
202   return 1; /*success*/
203 }
204 
205 /*resize and give all new elements the value*/
uivector_resizev(uivector * p,size_t size,unsigned value)206 static unsigned uivector_resizev(uivector* p, size_t size, unsigned value) {
207   size_t oldsize = p->size, i;
208   if(!uivector_resize(p, size)) return 0;
209   for(i = oldsize; i < size; ++i) p->data[i] = value;
210   return 1;
211 }
212 
uivector_init(uivector * p)213 static void uivector_init(uivector* p) {
214   p->data = NULL;
215   p->size = p->allocsize = 0;
216 }
217 
218 #ifdef LODEPNG_COMPILE_ENCODER
219 /*returns 1 if success, 0 if failure ==> nothing done*/
uivector_push_back(uivector * p,unsigned c)220 static unsigned uivector_push_back(uivector* p, unsigned c) {
221   if(!uivector_resize(p, p->size + 1)) return 0;
222   p->data[p->size - 1] = c;
223   return 1;
224 }
225 #endif /*LODEPNG_COMPILE_ENCODER*/
226 #endif /*LODEPNG_COMPILE_ZLIB*/
227 
228 /* /////////////////////////////////////////////////////////////////////////// */
229 
230 /*dynamic vector of unsigned chars*/
231 typedef struct ucvector {
232   unsigned char* data;
233   size_t size; /*used size*/
234   size_t allocsize; /*allocated size*/
235 } ucvector;
236 
237 /*returns 1 if success, 0 if failure ==> nothing done*/
ucvector_reserve(ucvector * p,size_t allocsize)238 static unsigned ucvector_reserve(ucvector* p, size_t allocsize) {
239   if(allocsize > p->allocsize) {
240     size_t newsize = (allocsize > p->allocsize * 2u) ? allocsize : ((allocsize * 3u) >> 1u);
241     void* data = lodepng_realloc(p->data, newsize);
242     if(data) {
243       p->allocsize = newsize;
244       p->data = (unsigned char*)data;
245     }
246     else return 0; /*error: not enough memory*/
247   }
248   return 1;
249 }
250 
251 /*returns 1 if success, 0 if failure ==> nothing done*/
ucvector_resize(ucvector * p,size_t size)252 static unsigned ucvector_resize(ucvector* p, size_t size) {
253   if(!ucvector_reserve(p, size * sizeof(unsigned char))) return 0;
254   p->size = size;
255   return 1; /*success*/
256 }
257 
258 #ifdef LODEPNG_COMPILE_PNG
259 
ucvector_cleanup(void * p)260 static void ucvector_cleanup(void* p) {
261   ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0;
262   lodepng_free(((ucvector*)p)->data);
263   ((ucvector*)p)->data = NULL;
264 }
265 
ucvector_init(ucvector * p)266 static void ucvector_init(ucvector* p) {
267   p->data = NULL;
268   p->size = p->allocsize = 0;
269 }
270 #endif /*LODEPNG_COMPILE_PNG*/
271 
272 #ifdef LODEPNG_COMPILE_ZLIB
273 /*you can both convert from vector to buffer&size and vica versa. If you use
274 init_buffer to take over a buffer and size, it is not needed to use cleanup*/
ucvector_init_buffer(ucvector * p,unsigned char * buffer,size_t size)275 static void ucvector_init_buffer(ucvector* p, unsigned char* buffer, size_t size) {
276   p->data = buffer;
277   p->allocsize = p->size = size;
278 }
279 #endif /*LODEPNG_COMPILE_ZLIB*/
280 
281 #if (defined(LODEPNG_COMPILE_PNG) && defined(LODEPNG_COMPILE_ANCILLARY_CHUNKS)) || defined(LODEPNG_COMPILE_ENCODER)
282 /*returns 1 if success, 0 if failure ==> nothing done*/
ucvector_push_back(ucvector * p,unsigned char c)283 static unsigned ucvector_push_back(ucvector* p, unsigned char c) {
284   if(!ucvector_resize(p, p->size + 1)) return 0;
285   p->data[p->size - 1] = c;
286   return 1;
287 }
288 #endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/
289 
290 
291 /* ////////////////////////////////////////////////////////////////////////// */
292 
293 #ifdef LODEPNG_COMPILE_PNG
294 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
295 
296 /*free string pointer and set it to NULL*/
string_cleanup(char ** out)297 static void string_cleanup(char** out) {
298   lodepng_free(*out);
299   *out = NULL;
300 }
301 
302 /* dynamically allocates a new string with a copy of the null terminated input text */
alloc_string(const char * in)303 static char* alloc_string(const char* in) {
304   size_t insize = lodepng_strlen(in);
305   char* out = (char*)lodepng_malloc(insize + 1);
306   if(out) {
307     size_t i;
308     for(i = 0; i != insize; ++i) {
309       out[i] = in[i];
310     }
311     out[i] = 0;
312   }
313   return out;
314 }
315 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
316 #endif /*LODEPNG_COMPILE_PNG*/
317 
318 /* ////////////////////////////////////////////////////////////////////////// */
319 
lodepng_read32bitInt(const unsigned char * buffer)320 unsigned lodepng_read32bitInt(const unsigned char* buffer) {
321   return (unsigned)((buffer[0] << 24u) | (buffer[1] << 16u) | (buffer[2] << 8u) | buffer[3]);
322 }
323 
324 #if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)
325 /*buffer must have at least 4 allocated bytes available*/
lodepng_set32bitInt(unsigned char * buffer,unsigned value)326 static void lodepng_set32bitInt(unsigned char* buffer, unsigned value) {
327   buffer[0] = (unsigned char)((value >> 24) & 0xff);
328   buffer[1] = (unsigned char)((value >> 16) & 0xff);
329   buffer[2] = (unsigned char)((value >>  8) & 0xff);
330   buffer[3] = (unsigned char)((value      ) & 0xff);
331 }
332 #endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/
333 
334 #ifdef LODEPNG_COMPILE_ENCODER
lodepng_add32bitInt(ucvector * buffer,unsigned value)335 static void lodepng_add32bitInt(ucvector* buffer, unsigned value) {
336   ucvector_resize(buffer, buffer->size + 4); /*todo: give error if resize failed*/
337   lodepng_set32bitInt(&buffer->data[buffer->size - 4], value);
338 }
339 #endif /*LODEPNG_COMPILE_ENCODER*/
340 
341 /* ////////////////////////////////////////////////////////////////////////// */
342 /* / File IO                                                                / */
343 /* ////////////////////////////////////////////////////////////////////////// */
344 
345 #ifdef LODEPNG_COMPILE_DISK
346 
347 /* returns negative value on error. This should be pure C compatible, so no fstat. */
lodepng_filesize(const char * filename)348 static long lodepng_filesize(const char* filename) {
349   FILE* file;
350   long size;
351   file = fopen(filename, "rb");
352   if(!file) return -1;
353 
354   if(fseek(file, 0, SEEK_END) != 0) {
355     fclose(file);
356     return -1;
357   }
358 
359   size = ftell(file);
360   /* It may give LONG_MAX as directory size, this is invalid for us. */
361   if(size == LONG_MAX) size = -1;
362 
363   fclose(file);
364   return size;
365 }
366 
367 /* load file into buffer that already has the correct allocated size. Returns error code.*/
lodepng_buffer_file(unsigned char * out,size_t size,const char * filename)368 static unsigned lodepng_buffer_file(unsigned char* out, size_t size, const char* filename) {
369   FILE* file;
370   size_t readsize;
371   file = fopen(filename, "rb");
372   if(!file) return 78;
373 
374   readsize = fread(out, 1, size, file);
375   fclose(file);
376 
377   if (readsize != size) return 78;
378   return 0;
379 }
380 
lodepng_load_file(unsigned char ** out,size_t * outsize,const char * filename)381 unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename) {
382   long size = lodepng_filesize(filename);
383   if (size < 0) return 78;
384   *outsize = (size_t)size;
385 
386   *out = (unsigned char*)lodepng_malloc((size_t)size);
387   if(!(*out) && size > 0) return 83; /*the above malloc failed*/
388 
389   return lodepng_buffer_file(*out, (size_t)size, filename);
390 }
391 
392 /*write given buffer to the file, overwriting the file, it doesn't append to it.*/
lodepng_save_file(const unsigned char * buffer,size_t buffersize,const char * filename)393 unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename) {
394   FILE* file;
395   file = fopen(filename, "wb" );
396   if(!file) return 79;
397   fwrite(buffer, 1, buffersize, file);
398   fclose(file);
399   return 0;
400 }
401 
402 #endif /*LODEPNG_COMPILE_DISK*/
403 
404 /* ////////////////////////////////////////////////////////////////////////// */
405 /* ////////////////////////////////////////////////////////////////////////// */
406 /* // End of common code and tools. Begin of Zlib related code.            // */
407 /* ////////////////////////////////////////////////////////////////////////// */
408 /* ////////////////////////////////////////////////////////////////////////// */
409 
410 #ifdef LODEPNG_COMPILE_ZLIB
411 #ifdef LODEPNG_COMPILE_ENCODER
412 
413 typedef struct {
414   ucvector* data;
415   size_t bp;
416 } LodePNGBitWriter;
417 
LodePNGBitWriter_init(LodePNGBitWriter * writer,ucvector * data)418 void LodePNGBitWriter_init(LodePNGBitWriter* writer, ucvector* data) {
419   writer->data = data;
420   writer->bp = 0;
421 }
422 
423 /*TODO: this ignores potential out of memory errors*/
424 #define WRITEBIT(/*size_t**/ writer, /*unsigned char*/ bit){\
425   /* append new byte */\
426   if(((writer->bp) & 7u) == 0) ucvector_push_back(writer->data, (unsigned char)0);\
427   (writer->data->data[writer->data->size - 1]) |= (bit << ((writer->bp) & 7u));\
428   ++writer->bp;\
429 }
430 
431 /* LSB of value is written first, and LSB of bytes is used first */
writeBits(LodePNGBitWriter * writer,unsigned value,size_t nbits)432 static void writeBits(LodePNGBitWriter* writer, unsigned value, size_t nbits) {
433   if(nbits == 1) { /* compiler should statically compile this case if nbits == 1 */
434     WRITEBIT(writer, value);
435   } else {
436     /* TODO: increase output size nly once here rather than in each WRITEBIT */
437     size_t i;
438     for(i = 0; i != nbits; ++i) {
439       WRITEBIT(writer, (unsigned char)((value >> i) & 1));
440     }
441   }
442 }
443 
444 /* This one is to use for adding huffman symbol, the value bits are written MSB first */
writeBitsReversed(LodePNGBitWriter * writer,unsigned value,size_t nbits)445 static void writeBitsReversed(LodePNGBitWriter* writer, unsigned value, size_t nbits) {
446   size_t i;
447   for(i = 0; i != nbits; ++i) {
448     /* TODO: increase output size only once here rather than in each WRITEBIT */
449     WRITEBIT(writer, (unsigned char)((value >> (nbits - 1u - i)) & 1u));
450   }
451 }
452 #endif /*LODEPNG_COMPILE_ENCODER*/
453 
454 #ifdef LODEPNG_COMPILE_DECODER
455 
456 typedef struct {
457   const unsigned char* data;
458   size_t bitsize;
459   size_t bp;
460 } LodePNGBitReader;
461 
462 /* data size argument is in bytes */
LodePNGBitReader_init(LodePNGBitReader * reader,const unsigned char * data,size_t size)463 void LodePNGBitReader_init(LodePNGBitReader* reader, const unsigned char* data, size_t size) {
464   reader->data = data;
465   reader->bitsize = size << 3u; /* size in bits */
466   reader->bp = 0;
467 }
468 
469 /* Out of bounds must be checked before using this function */
readBits(LodePNGBitReader * reader,size_t nbits)470 static unsigned readBits(LodePNGBitReader* reader, size_t nbits) {
471   /* TODO: faster bit reading technique */
472   if(nbits == 1) { /* compiler should statically compile only this case if nbits == 1 */
473     unsigned result = (unsigned)(reader->data[reader->bp >> 3u] >> (reader->bp & 0x7u)) & 1u;
474     reader->bp++;
475     return result;
476   } else {
477     unsigned result = 0, i;
478     for(i = 0; i != nbits; ++i) {
479       result += (((unsigned)reader->data[reader->bp >> 3u] >> (unsigned)(reader->bp & 0x7u)) & 1u) << i;
480       reader->bp++;
481     }
482     return result;
483   }
484 }
485 #endif /*LODEPNG_COMPILE_DECODER*/
486 
487 /* ////////////////////////////////////////////////////////////////////////// */
488 /* / Deflate - Huffman                                                      / */
489 /* ////////////////////////////////////////////////////////////////////////// */
490 
491 #define FIRST_LENGTH_CODE_INDEX 257
492 #define LAST_LENGTH_CODE_INDEX 285
493 /*256 literals, the end code, some length codes, and 2 unused codes*/
494 #define NUM_DEFLATE_CODE_SYMBOLS 288
495 /*the distance codes have their own symbols, 30 used, 2 unused*/
496 #define NUM_DISTANCE_SYMBOLS 32
497 /*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/
498 #define NUM_CODE_LENGTH_CODES 19
499 
500 /*the base lengths represented by codes 257-285*/
501 static const unsigned LENGTHBASE[29]
502   = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
503      67, 83, 99, 115, 131, 163, 195, 227, 258};
504 
505 /*the extra bits used by codes 257-285 (added to base length)*/
506 static const unsigned LENGTHEXTRA[29]
507   = {0, 0, 0, 0, 0, 0, 0,  0,  1,  1,  1,  1,  2,  2,  2,  2,  3,  3,  3,  3,
508       4,  4,  4,   4,   5,   5,   5,   5,   0};
509 
510 /*the base backwards distances (the bits of distance codes appear after length codes and use their own huffman tree)*/
511 static const unsigned DISTANCEBASE[30]
512   = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513,
513      769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
514 
515 /*the extra bits of backwards distances (added to base)*/
516 static const unsigned DISTANCEEXTRA[30]
517   = {0, 0, 0, 0, 1, 1, 2,  2,  3,  3,  4,  4,  5,  5,   6,   6,   7,   7,   8,
518        8,    9,    9,   10,   10,   11,   11,   12,    12,    13,    13};
519 
520 /*the order in which "code length alphabet code lengths" are stored, out of this
521 the huffman tree of the dynamic huffman tree lengths is generated*/
522 static const unsigned CLCL_ORDER[NUM_CODE_LENGTH_CODES]
523   = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
524 
525 /* ////////////////////////////////////////////////////////////////////////// */
526 
527 /*
528 Huffman tree struct, containing multiple representations of the tree
529 */
530 typedef struct HuffmanTree {
531   unsigned* tree2d;
532   unsigned* tree1d;
533   unsigned* lengths; /*the lengths of the codes of the 1d-tree*/
534   unsigned maxbitlen; /*maximum number of bits a single code can get*/
535   unsigned numcodes; /*number of symbols in the alphabet = number of codes*/
536 } HuffmanTree;
537 
538 /*function used for debug purposes to draw the tree in ascii art with C++*/
539 /*
540 static void HuffmanTree_draw(HuffmanTree* tree) {
541   std::cout << "tree. length: " << tree->numcodes << " maxbitlen: " << tree->maxbitlen << std::endl;
542   for(size_t i = 0; i != tree->tree1d.size; ++i) {
543     if(tree->lengths.data[i])
544       std::cout << i << " " << tree->tree1d.data[i] << " " << tree->lengths.data[i] << std::endl;
545   }
546   std::cout << std::endl;
547 }*/
548 
HuffmanTree_init(HuffmanTree * tree)549 static void HuffmanTree_init(HuffmanTree* tree) {
550   tree->tree2d = 0;
551   tree->tree1d = 0;
552   tree->lengths = 0;
553 }
554 
HuffmanTree_cleanup(HuffmanTree * tree)555 static void HuffmanTree_cleanup(HuffmanTree* tree) {
556   lodepng_free(tree->tree2d);
557   lodepng_free(tree->tree1d);
558   lodepng_free(tree->lengths);
559 }
560 
561 /*the tree representation used by the decoder. return value is error*/
HuffmanTree_make2DTree(HuffmanTree * tree)562 static unsigned HuffmanTree_make2DTree(HuffmanTree* tree) {
563   unsigned nodefilled = 0; /*up to which node it is filled*/
564   unsigned treepos = 0; /*position in the tree (1 of the numcodes columns)*/
565   unsigned n, i;
566 
567   tree->tree2d = (unsigned*)lodepng_malloc(tree->numcodes * 2 * sizeof(unsigned));
568   if(!tree->tree2d) return 83; /*alloc fail*/
569 
570   /*
571   convert tree1d[] to tree2d[][]. In the 2D array, a value of 32767 means
572   uninited, a value >= numcodes is an address to another bit, a value < numcodes
573   is a code. The 2 rows are the 2 possible bit values (0 or 1), there are as
574   many columns as codes - 1.
575   A good huffman tree has N * 2 - 1 nodes, of which N - 1 are internal nodes.
576   Here, the internal nodes are stored (what their 0 and 1 option point to).
577   There is only memory for such good tree currently, if there are more nodes
578   (due to too long length codes), error 55 will happen
579   */
580   for(n = 0; n < tree->numcodes * 2; ++n) {
581     tree->tree2d[n] = 32767; /*32767 here means the tree2d isn't filled there yet*/
582   }
583 
584   for(n = 0; n < tree->numcodes; ++n) /*the codes*/ {
585     for(i = 0; i != tree->lengths[n]; ++i) /*the bits for this code*/ {
586       unsigned char bit = (unsigned char)((tree->tree1d[n] >> (tree->lengths[n] - i - 1)) & 1);
587       /*oversubscribed, see comment in lodepng_error_text*/
588       if(treepos > 2147483647 || treepos + 2 > tree->numcodes) return 55;
589       if(tree->tree2d[2 * treepos + bit] == 32767) /*not yet filled in*/ {
590         if(i + 1 == tree->lengths[n]) /*last bit*/ {
591           tree->tree2d[2 * treepos + bit] = n; /*put the current code in it*/
592           treepos = 0;
593         } else {
594           /*put address of the next step in here, first that address has to be found of course
595           (it's just nodefilled + 1)...*/
596           ++nodefilled;
597           /*addresses encoded with numcodes added to it*/
598           tree->tree2d[2 * treepos + bit] = nodefilled + tree->numcodes;
599           treepos = nodefilled;
600         }
601       }
602       else treepos = tree->tree2d[2 * treepos + bit] - tree->numcodes;
603     }
604   }
605 
606   for(n = 0; n < tree->numcodes * 2; ++n) {
607     if(tree->tree2d[n] == 32767) tree->tree2d[n] = 0; /*remove possible remaining 32767's*/
608   }
609 
610   return 0;
611 }
612 
613 /*
614 Second step for the ...makeFromLengths and ...makeFromFrequencies functions.
615 numcodes, lengths and maxbitlen must already be filled in correctly. return
616 value is error.
617 */
HuffmanTree_makeFromLengths2(HuffmanTree * tree)618 static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) {
619   uivector blcount;
620   uivector nextcode;
621   unsigned error = 0;
622   unsigned bits, n;
623 
624   uivector_init(&blcount);
625   uivector_init(&nextcode);
626 
627   tree->tree1d = (unsigned*)lodepng_malloc(tree->numcodes * sizeof(unsigned));
628   if(!tree->tree1d) error = 83; /*alloc fail*/
629 
630   if(!uivector_resizev(&blcount, tree->maxbitlen + 1, 0)
631   || !uivector_resizev(&nextcode, tree->maxbitlen + 1, 0))
632     error = 83; /*alloc fail*/
633 
634   if(!error) {
635     /*step 1: count number of instances of each code length*/
636     for(bits = 0; bits != tree->numcodes; ++bits) ++blcount.data[tree->lengths[bits]];
637     /*step 2: generate the nextcode values*/
638     for(bits = 1; bits <= tree->maxbitlen; ++bits) {
639       nextcode.data[bits] = (nextcode.data[bits - 1] + blcount.data[bits - 1]) << 1;
640     }
641     /*step 3: generate all the codes*/
642     for(n = 0; n != tree->numcodes; ++n) {
643       if(tree->lengths[n] != 0) tree->tree1d[n] = nextcode.data[tree->lengths[n]]++;
644     }
645   }
646 
647   uivector_cleanup(&blcount);
648   uivector_cleanup(&nextcode);
649 
650   if(!error) return HuffmanTree_make2DTree(tree);
651   else return error;
652 }
653 
654 /*
655 given the code lengths (as stored in the PNG file), generate the tree as defined
656 by Deflate. maxbitlen is the maximum bits that a code in the tree can have.
657 return value is error.
658 */
HuffmanTree_makeFromLengths(HuffmanTree * tree,const unsigned * bitlen,size_t numcodes,unsigned maxbitlen)659 static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* bitlen,
660                                             size_t numcodes, unsigned maxbitlen) {
661   unsigned i;
662   tree->lengths = (unsigned*)lodepng_malloc(numcodes * sizeof(unsigned));
663   if(!tree->lengths) return 83; /*alloc fail*/
664   for(i = 0; i != numcodes; ++i) tree->lengths[i] = bitlen[i];
665   tree->numcodes = (unsigned)numcodes; /*number of symbols*/
666   tree->maxbitlen = maxbitlen;
667   return HuffmanTree_makeFromLengths2(tree);
668 }
669 
670 #ifdef LODEPNG_COMPILE_ENCODER
671 
672 /*BPM: Boundary Package Merge, see "A Fast and Space-Economical Algorithm for Length-Limited Coding",
673 Jyrki Katajainen, Alistair Moffat, Andrew Turpin, 1995.*/
674 
675 /*chain node for boundary package merge*/
676 typedef struct BPMNode {
677   int weight; /*the sum of all weights in this chain*/
678   unsigned index; /*index of this leaf node (called "count" in the paper)*/
679   struct BPMNode* tail; /*the next nodes in this chain (null if last)*/
680   int in_use;
681 } BPMNode;
682 
683 /*lists of chains*/
684 typedef struct BPMLists {
685   /*memory pool*/
686   unsigned memsize;
687   BPMNode* memory;
688   unsigned numfree;
689   unsigned nextfree;
690   BPMNode** freelist;
691   /*two heads of lookahead chains per list*/
692   unsigned listsize;
693   BPMNode** chains0;
694   BPMNode** chains1;
695 } BPMLists;
696 
697 /*creates a new chain node with the given parameters, from the memory in the lists */
bpmnode_create(BPMLists * lists,int weight,unsigned index,BPMNode * tail)698 static BPMNode* bpmnode_create(BPMLists* lists, int weight, unsigned index, BPMNode* tail) {
699   unsigned i;
700   BPMNode* result;
701 
702   /*memory full, so garbage collect*/
703   if(lists->nextfree >= lists->numfree) {
704     /*mark only those that are in use*/
705     for(i = 0; i != lists->memsize; ++i) lists->memory[i].in_use = 0;
706     for(i = 0; i != lists->listsize; ++i) {
707       BPMNode* node;
708       for(node = lists->chains0[i]; node != 0; node = node->tail) node->in_use = 1;
709       for(node = lists->chains1[i]; node != 0; node = node->tail) node->in_use = 1;
710     }
711     /*collect those that are free*/
712     lists->numfree = 0;
713     for(i = 0; i != lists->memsize; ++i) {
714       if(!lists->memory[i].in_use) lists->freelist[lists->numfree++] = &lists->memory[i];
715     }
716     lists->nextfree = 0;
717   }
718 
719   result = lists->freelist[lists->nextfree++];
720   result->weight = weight;
721   result->index = index;
722   result->tail = tail;
723   return result;
724 }
725 
726 /*sort the leaves with stable mergesort*/
bpmnode_sort(BPMNode * leaves,size_t num)727 static void bpmnode_sort(BPMNode* leaves, size_t num) {
728   BPMNode* mem = (BPMNode*)lodepng_malloc(sizeof(*leaves) * num);
729   size_t width, counter = 0;
730   for(width = 1; width < num; width *= 2) {
731     BPMNode* a = (counter & 1) ? mem : leaves;
732     BPMNode* b = (counter & 1) ? leaves : mem;
733     size_t p;
734     for(p = 0; p < num; p += 2 * width) {
735       size_t q = (p + width > num) ? num : (p + width);
736       size_t r = (p + 2 * width > num) ? num : (p + 2 * width);
737       size_t i = p, j = q, k;
738       for(k = p; k < r; k++) {
739         if(i < q && (j >= r || a[i].weight <= a[j].weight)) b[k] = a[i++];
740         else b[k] = a[j++];
741       }
742     }
743     counter++;
744   }
745   if(counter & 1) lodepng_memcpy(leaves, mem, sizeof(*leaves) * num);
746   lodepng_free(mem);
747 }
748 
749 /*Boundary Package Merge step, numpresent is the amount of leaves, and c is the current chain.*/
boundaryPM(BPMLists * lists,BPMNode * leaves,size_t numpresent,int c,int num)750 static void boundaryPM(BPMLists* lists, BPMNode* leaves, size_t numpresent, int c, int num) {
751   unsigned lastindex = lists->chains1[c]->index;
752 
753   if(c == 0) {
754     if(lastindex >= numpresent) return;
755     lists->chains0[c] = lists->chains1[c];
756     lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, 0);
757   } else {
758     /*sum of the weights of the head nodes of the previous lookahead chains.*/
759     int sum = lists->chains0[c - 1]->weight + lists->chains1[c - 1]->weight;
760     lists->chains0[c] = lists->chains1[c];
761     if(lastindex < numpresent && sum > leaves[lastindex].weight) {
762       lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, lists->chains1[c]->tail);
763       return;
764     }
765     lists->chains1[c] = bpmnode_create(lists, sum, lastindex, lists->chains1[c - 1]);
766     /*in the end we are only interested in the chain of the last list, so no
767     need to recurse if we're at the last one (this gives measurable speedup)*/
768     if(num + 1 < (int)(2 * numpresent - 2)) {
769       boundaryPM(lists, leaves, numpresent, c - 1, num);
770       boundaryPM(lists, leaves, numpresent, c - 1, num);
771     }
772   }
773 }
774 
lodepng_huffman_code_lengths(unsigned * lengths,const unsigned * frequencies,size_t numcodes,unsigned maxbitlen)775 unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies,
776                                       size_t numcodes, unsigned maxbitlen) {
777   unsigned error = 0;
778   unsigned i;
779   size_t numpresent = 0; /*number of symbols with non-zero frequency*/
780   BPMNode* leaves; /*the symbols, only those with > 0 frequency*/
781 
782   if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/
783   if((1u << maxbitlen) < (unsigned)numcodes) return 80; /*error: represent all symbols*/
784 
785   leaves = (BPMNode*)lodepng_malloc(numcodes * sizeof(*leaves));
786   if(!leaves) return 83; /*alloc fail*/
787 
788   for(i = 0; i != numcodes; ++i) {
789     if(frequencies[i] > 0) {
790       leaves[numpresent].weight = (int)frequencies[i];
791       leaves[numpresent].index = i;
792       ++numpresent;
793     }
794   }
795 
796   for(i = 0; i != numcodes; ++i) lengths[i] = 0;
797 
798   /*ensure at least two present symbols. There should be at least one symbol
799   according to RFC 1951 section 3.2.7. Some decoders incorrectly require two. To
800   make these work as well ensure there are at least two symbols. The
801   Package-Merge code below also doesn't work correctly if there's only one
802   symbol, it'd give it the theoritical 0 bits but in practice zlib wants 1 bit*/
803   if(numpresent == 0) {
804     lengths[0] = lengths[1] = 1; /*note that for RFC 1951 section 3.2.7, only lengths[0] = 1 is needed*/
805   } else if(numpresent == 1) {
806     lengths[leaves[0].index] = 1;
807     lengths[leaves[0].index == 0 ? 1 : 0] = 1;
808   } else {
809     BPMLists lists;
810     BPMNode* node;
811 
812     bpmnode_sort(leaves, numpresent);
813 
814     lists.listsize = maxbitlen;
815     lists.memsize = 2 * maxbitlen * (maxbitlen + 1);
816     lists.nextfree = 0;
817     lists.numfree = lists.memsize;
818     lists.memory = (BPMNode*)lodepng_malloc(lists.memsize * sizeof(*lists.memory));
819     lists.freelist = (BPMNode**)lodepng_malloc(lists.memsize * sizeof(BPMNode*));
820     lists.chains0 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*));
821     lists.chains1 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*));
822     if(!lists.memory || !lists.freelist || !lists.chains0 || !lists.chains1) error = 83; /*alloc fail*/
823 
824     if(!error) {
825       for(i = 0; i != lists.memsize; ++i) lists.freelist[i] = &lists.memory[i];
826 
827       bpmnode_create(&lists, leaves[0].weight, 1, 0);
828       bpmnode_create(&lists, leaves[1].weight, 2, 0);
829 
830       for(i = 0; i != lists.listsize; ++i) {
831         lists.chains0[i] = &lists.memory[0];
832         lists.chains1[i] = &lists.memory[1];
833       }
834 
835       /*each boundaryPM call adds one chain to the last list, and we need 2 * numpresent - 2 chains.*/
836       for(i = 2; i != 2 * numpresent - 2; ++i) boundaryPM(&lists, leaves, numpresent, (int)maxbitlen - 1, (int)i);
837 
838       for(node = lists.chains1[maxbitlen - 1]; node; node = node->tail) {
839         for(i = 0; i != node->index; ++i) ++lengths[leaves[i].index];
840       }
841     }
842 
843     lodepng_free(lists.memory);
844     lodepng_free(lists.freelist);
845     lodepng_free(lists.chains0);
846     lodepng_free(lists.chains1);
847   }
848 
849   lodepng_free(leaves);
850   return error;
851 }
852 
853 /*Create the Huffman tree given the symbol frequencies*/
HuffmanTree_makeFromFrequencies(HuffmanTree * tree,const unsigned * frequencies,size_t mincodes,size_t numcodes,unsigned maxbitlen)854 static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigned* frequencies,
855                                                 size_t mincodes, size_t numcodes, unsigned maxbitlen) {
856   size_t i;
857   unsigned error = 0;
858   while(!frequencies[numcodes - 1] && numcodes > mincodes) --numcodes; /*trim zeroes*/
859   tree->maxbitlen = maxbitlen;
860   tree->numcodes = (unsigned)numcodes; /*number of symbols*/
861   tree->lengths = (unsigned*)lodepng_realloc(tree->lengths, numcodes * sizeof(unsigned));
862   if(!tree->lengths) return 83; /*alloc fail*/
863   /*initialize all lengths to 0*/
864   for(i = 0; i < numcodes; i++) tree->lengths[i] = 0;
865 
866   error = lodepng_huffman_code_lengths(tree->lengths, frequencies, numcodes, maxbitlen);
867   if(!error) error = HuffmanTree_makeFromLengths2(tree);
868   return error;
869 }
870 
HuffmanTree_getCode(const HuffmanTree * tree,unsigned index)871 static unsigned HuffmanTree_getCode(const HuffmanTree* tree, unsigned index) {
872   return tree->tree1d[index];
873 }
874 
HuffmanTree_getLength(const HuffmanTree * tree,unsigned index)875 static unsigned HuffmanTree_getLength(const HuffmanTree* tree, unsigned index) {
876   return tree->lengths[index];
877 }
878 #endif /*LODEPNG_COMPILE_ENCODER*/
879 
880 /*get the literal and length code tree of a deflated block with fixed tree, as per the deflate specification*/
generateFixedLitLenTree(HuffmanTree * tree)881 static unsigned generateFixedLitLenTree(HuffmanTree* tree) {
882   unsigned i, error = 0;
883   unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned));
884   if(!bitlen) return 83; /*alloc fail*/
885 
886   /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/
887   for(i =   0; i <= 143; ++i) bitlen[i] = 8;
888   for(i = 144; i <= 255; ++i) bitlen[i] = 9;
889   for(i = 256; i <= 279; ++i) bitlen[i] = 7;
890   for(i = 280; i <= 287; ++i) bitlen[i] = 8;
891 
892   error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15);
893 
894   lodepng_free(bitlen);
895   return error;
896 }
897 
898 /*get the distance code tree of a deflated block with fixed tree, as specified in the deflate specification*/
generateFixedDistanceTree(HuffmanTree * tree)899 static unsigned generateFixedDistanceTree(HuffmanTree* tree) {
900   unsigned i, error = 0;
901   unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned));
902   if(!bitlen) return 83; /*alloc fail*/
903 
904   /*there are 32 distance codes, but 30-31 are unused*/
905   for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen[i] = 5;
906   error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15);
907 
908   lodepng_free(bitlen);
909   return error;
910 }
911 
912 #ifdef LODEPNG_COMPILE_DECODER
913 
914 /*
915 returns the code, or (unsigned)(-1) if error happened
916 */
huffmanDecodeSymbol(LodePNGBitReader * reader,const HuffmanTree * codetree)917 static unsigned huffmanDecodeSymbol(LodePNGBitReader* reader, const HuffmanTree* codetree) {
918   unsigned treepos = 0, ct;
919   /* TODO: make faster: read multipe bits at once and use lookup table */
920   for(;;) {
921     if(reader->bp >= reader->bitsize) return (unsigned)(-1); /*error: end of input memory reached without endcode*/
922     ct = codetree->tree2d[(treepos << 1) + readBits(reader, 1)];
923     if(ct < codetree->numcodes) return ct; /*the symbol is decoded, return it*/
924     else treepos = ct - codetree->numcodes; /*symbol not yet decoded, instead move tree position*/
925 
926     if(treepos >= codetree->numcodes) return (unsigned)(-1); /*error: it appeared outside the codetree*/
927   }
928 }
929 #endif /*LODEPNG_COMPILE_DECODER*/
930 
931 #ifdef LODEPNG_COMPILE_DECODER
932 
933 /* ////////////////////////////////////////////////////////////////////////// */
934 /* / Inflator (Decompressor)                                                / */
935 /* ////////////////////////////////////////////////////////////////////////// */
936 
937 /*get the tree of a deflated block with fixed tree, as specified in the deflate specification*/
getTreeInflateFixed(HuffmanTree * tree_ll,HuffmanTree * tree_d)938 static void getTreeInflateFixed(HuffmanTree* tree_ll, HuffmanTree* tree_d) {
939   /*TODO: check for out of memory errors*/
940   generateFixedLitLenTree(tree_ll);
941   generateFixedDistanceTree(tree_d);
942 }
943 
944 /*get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree*/
getTreeInflateDynamic(HuffmanTree * tree_ll,HuffmanTree * tree_d,LodePNGBitReader * reader)945 static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d,
946                                       LodePNGBitReader* reader) {
947   /*make sure that length values that aren't filled in will be 0, or a wrong tree will be generated*/
948   unsigned error = 0;
949   unsigned n, HLIT, HDIST, HCLEN, i;
950 
951   /*see comments in deflateDynamic for explanation of the context and these variables, it is analogous*/
952   unsigned* bitlen_ll = 0; /*lit,len code lengths*/
953   unsigned* bitlen_d = 0; /*dist code lengths*/
954   /*code length code lengths ("clcl"), the bit lengths of the huffman tree used to compress bitlen_ll and bitlen_d*/
955   unsigned* bitlen_cl = 0;
956   HuffmanTree tree_cl; /*the code tree for code length codes (the huffman tree for compressed huffman trees)*/
957 
958   if((reader->bp) + 14 > reader->bitsize) return 49; /*error: the bit pointer is or will go past the memory*/
959 
960   /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/
961   HLIT =  readBits(reader, 5) + 257;
962   /*number of distance codes. Unlike the spec, the value 1 is added to it here already*/
963   HDIST = readBits(reader, 5) + 1;
964   /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/
965   HCLEN = readBits(reader, 4) + 4;
966 
967   if((reader->bp) + HCLEN * 3 > reader->bitsize) return 50; /*error: the bit pointer is or will go past the memory*/
968 
969   HuffmanTree_init(&tree_cl);
970 
971   while(!error) {
972     /*read the code length codes out of 3 * (amount of code length codes) bits*/
973 
974     bitlen_cl = (unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(unsigned));
975     if(!bitlen_cl) ERROR_BREAK(83 /*alloc fail*/);
976 
977     for(i = 0; i != NUM_CODE_LENGTH_CODES; ++i) {
978       if(i < HCLEN) bitlen_cl[CLCL_ORDER[i]] = readBits(reader, 3);
979       else bitlen_cl[CLCL_ORDER[i]] = 0; /*if not, it must stay 0*/
980     }
981 
982     error = HuffmanTree_makeFromLengths(&tree_cl, bitlen_cl, NUM_CODE_LENGTH_CODES, 7);
983     if(error) break;
984 
985     /*now we can use this tree to read the lengths for the tree that this function will return*/
986     bitlen_ll = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned));
987     bitlen_d = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned));
988     if(!bitlen_ll || !bitlen_d) ERROR_BREAK(83 /*alloc fail*/);
989     for(i = 0; i != NUM_DEFLATE_CODE_SYMBOLS; ++i) bitlen_ll[i] = 0;
990     for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen_d[i] = 0;
991 
992     /*i is the current symbol we're reading in the part that contains the code lengths of lit/len and dist codes*/
993     i = 0;
994     while(i < HLIT + HDIST) {
995       unsigned code = huffmanDecodeSymbol(reader, &tree_cl);
996       if(code <= 15) /*a length code*/ {
997         if(i < HLIT) bitlen_ll[i] = code;
998         else bitlen_d[i - HLIT] = code;
999         ++i;
1000       } else if(code == 16) /*repeat previous*/ {
1001         unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/
1002         unsigned value; /*set value to the previous code*/
1003 
1004         if(i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/
1005 
1006         if((reader->bp + 2) > reader->bitsize) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/
1007         replength += readBits(reader, 2);
1008 
1009         if(i < HLIT + 1) value = bitlen_ll[i - 1];
1010         else value = bitlen_d[i - HLIT - 1];
1011         /*repeat this value in the next lengths*/
1012         for(n = 0; n < replength; ++n) {
1013           if(i >= HLIT + HDIST) ERROR_BREAK(13); /*error: i is larger than the amount of codes*/
1014           if(i < HLIT) bitlen_ll[i] = value;
1015           else bitlen_d[i - HLIT] = value;
1016           ++i;
1017         }
1018       } else if(code == 17) /*repeat "0" 3-10 times*/ {
1019         unsigned replength = 3; /*read in the bits that indicate repeat length*/
1020         if((reader->bp + 3) > reader->bitsize) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/
1021         replength += readBits(reader, 3);
1022 
1023         /*repeat this value in the next lengths*/
1024         for(n = 0; n < replength; ++n) {
1025           if(i >= HLIT + HDIST) ERROR_BREAK(14); /*error: i is larger than the amount of codes*/
1026 
1027           if(i < HLIT) bitlen_ll[i] = 0;
1028           else bitlen_d[i - HLIT] = 0;
1029           ++i;
1030         }
1031       } else if(code == 18) /*repeat "0" 11-138 times*/ {
1032         unsigned replength = 11; /*read in the bits that indicate repeat length*/
1033         if((reader->bp + 7) > reader->bitsize) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/
1034         replength += readBits(reader, 7);
1035 
1036         /*repeat this value in the next lengths*/
1037         for(n = 0; n < replength; ++n) {
1038           if(i >= HLIT + HDIST) ERROR_BREAK(15); /*error: i is larger than the amount of codes*/
1039 
1040           if(i < HLIT) bitlen_ll[i] = 0;
1041           else bitlen_d[i - HLIT] = 0;
1042           ++i;
1043         }
1044       } else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ {
1045         if(code == (unsigned)(-1)) {
1046           /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol
1047           (10=no endcode, 11=wrong jump outside of tree)*/
1048           error = (reader->bp) > reader->bitsize ? 10 : 11;
1049         }
1050         else error = 16; /*unexisting code, this can never happen*/
1051         break;
1052       }
1053     }
1054     if(error) break;
1055 
1056     if(bitlen_ll[256] == 0) ERROR_BREAK(64); /*the length of the end code 256 must be larger than 0*/
1057 
1058     /*now we've finally got HLIT and HDIST, so generate the code trees, and the function is done*/
1059     error = HuffmanTree_makeFromLengths(tree_ll, bitlen_ll, NUM_DEFLATE_CODE_SYMBOLS, 15);
1060     if(error) break;
1061     error = HuffmanTree_makeFromLengths(tree_d, bitlen_d, NUM_DISTANCE_SYMBOLS, 15);
1062 
1063     break; /*end of error-while*/
1064   }
1065 
1066   lodepng_free(bitlen_cl);
1067   lodepng_free(bitlen_ll);
1068   lodepng_free(bitlen_d);
1069   HuffmanTree_cleanup(&tree_cl);
1070 
1071   return error;
1072 }
1073 
1074 /*inflate a block with dynamic of fixed Huffman tree. btype must be 1 or 2.*/
inflateHuffmanBlock(ucvector * out,size_t * pos,LodePNGBitReader * reader,unsigned btype)1075 static unsigned inflateHuffmanBlock(ucvector* out, size_t* pos, LodePNGBitReader* reader,
1076                                     unsigned btype) {
1077   unsigned error = 0;
1078   HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/
1079   HuffmanTree tree_d; /*the huffman tree for distance codes*/
1080 
1081   HuffmanTree_init(&tree_ll);
1082   HuffmanTree_init(&tree_d);
1083 
1084   if(btype == 1) getTreeInflateFixed(&tree_ll, &tree_d);
1085   else /*if(btype == 2)*/ error = getTreeInflateDynamic(&tree_ll, &tree_d, reader);
1086 
1087   while(!error) /*decode all symbols until end reached, breaks at end code*/ {
1088     /*code_ll is literal, length or end code*/
1089     unsigned code_ll = huffmanDecodeSymbol(reader, &tree_ll);
1090     if(code_ll <= 255) /*literal symbol*/ {
1091       /*ucvector_push_back would do the same, but for some reason the two lines below run 10% faster*/
1092       if(!ucvector_resize(out, (*pos) + 1)) ERROR_BREAK(83 /*alloc fail*/);
1093       out->data[*pos] = (unsigned char)code_ll;
1094       ++(*pos);
1095     } else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/ {
1096       unsigned code_d, distance;
1097       unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/
1098       size_t start, backward, length;
1099 
1100       /*part 1: get length base*/
1101       length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX];
1102 
1103       /*part 2: get extra bits and add the value of that to length*/
1104       numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX];
1105       if((reader->bp + numextrabits_l) > reader->bitsize) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/
1106       length += readBits(reader, numextrabits_l);
1107 
1108       /*part 3: get distance code*/
1109       code_d = huffmanDecodeSymbol(reader, &tree_d);
1110       if(code_d > 29) {
1111         if(code_d == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ {
1112           /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol
1113           (10=no endcode, 11=wrong jump outside of tree)*/
1114           error = (reader->bp > reader->bitsize) ? 10 : 11;
1115         }
1116         else error = 18; /*error: invalid distance code (30-31 are never used)*/
1117         break;
1118       }
1119       distance = DISTANCEBASE[code_d];
1120 
1121       /*part 4: get extra bits from distance*/
1122       numextrabits_d = DISTANCEEXTRA[code_d];
1123       if((reader->bp + numextrabits_d) > reader->bitsize) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/
1124       distance += readBits(reader, numextrabits_d);
1125 
1126       /*part 5: fill in all the out[n] values based on the length and dist*/
1127       start = (*pos);
1128       if(distance > start) ERROR_BREAK(52); /*too long backward distance*/
1129       backward = start - distance;
1130 
1131       if(!ucvector_resize(out, (*pos) + length)) ERROR_BREAK(83 /*alloc fail*/);
1132       if (distance < length) {
1133         size_t forward;
1134         for(forward = 0; forward < length; ++forward) {
1135           out->data[(*pos)++] = out->data[backward++];
1136         }
1137       } else {
1138         lodepng_memcpy(out->data + *pos, out->data + backward, length);
1139         *pos += length;
1140       }
1141     } else if(code_ll == 256) {
1142       break; /*end code, break the loop*/
1143     } else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ {
1144       /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol
1145       (10=no endcode, 11=wrong jump outside of tree)*/
1146       error = (reader->bp > reader->bitsize) ? 10 : 11;
1147       break;
1148     }
1149   }
1150 
1151   HuffmanTree_cleanup(&tree_ll);
1152   HuffmanTree_cleanup(&tree_d);
1153 
1154   return error;
1155 }
1156 
inflateNoCompression(ucvector * out,size_t * pos,LodePNGBitReader * reader,const LodePNGDecompressSettings * settings)1157 static unsigned inflateNoCompression(ucvector* out, size_t* pos,
1158                                      LodePNGBitReader* reader, const LodePNGDecompressSettings* settings) {
1159   size_t bytepos;
1160   size_t size = reader->bitsize >> 3u;
1161   unsigned LEN, NLEN, error = 0;
1162 
1163   /*go to first boundary of byte*/
1164   bytepos = (reader->bp + 7u) >> 3u;
1165 
1166   /*read LEN (2 bytes) and NLEN (2 bytes)*/
1167   if(bytepos + 4 >= size) return 52; /*error, bit pointer will jump past memory*/
1168   LEN = (unsigned)reader->data[bytepos] + (unsigned)(reader->data[bytepos + 1] << 8u); bytepos += 2;
1169   NLEN = (unsigned)reader->data[bytepos] + (unsigned)(reader->data[bytepos + 1] << 8u); bytepos += 2;
1170 
1171   /*check if 16-bit NLEN is really the one's complement of LEN*/
1172   if(!settings->ignore_nlen && LEN + NLEN != 65535) {
1173     return 21; /*error: NLEN is not one's complement of LEN*/
1174   }
1175 
1176   if(!ucvector_resize(out, (*pos) + LEN)) return 83; /*alloc fail*/
1177 
1178   /*read the literal data: LEN bytes are now stored in the out buffer*/
1179   if(bytepos + LEN > size) return 23; /*error: reading outside of in buffer*/
1180 
1181   lodepng_memcpy(out->data + *pos, reader->data + bytepos, LEN);
1182   *pos += LEN;
1183   bytepos += LEN;
1184 
1185   reader->bp = bytepos << 3u;
1186 
1187   return error;
1188 }
1189 
lodepng_inflatev(ucvector * out,const unsigned char * in,size_t insize,const LodePNGDecompressSettings * settings)1190 static unsigned lodepng_inflatev(ucvector* out,
1191                                  const unsigned char* in, size_t insize,
1192                                  const LodePNGDecompressSettings* settings) {
1193   unsigned BFINAL = 0;
1194   size_t pos = 0; /*byte position in the out buffer*/
1195   unsigned error = 0;
1196   LodePNGBitReader reader;
1197   LodePNGBitReader_init(&reader, in, insize);
1198 
1199   while(!BFINAL) {
1200     unsigned BTYPE;
1201     if(reader.bp + 2 >= reader.bitsize) return 52; /*error, bit pointer will jump past memory*/
1202     BFINAL = readBits(&reader, 1);
1203     BTYPE = 1u * readBits(&reader, 1);
1204     BTYPE += 2u * readBits(&reader, 1);
1205 
1206     if(BTYPE == 3) return 20; /*error: invalid BTYPE*/
1207     else if(BTYPE == 0) error = inflateNoCompression(out, &pos, &reader, settings); /*no compression*/
1208     else error = inflateHuffmanBlock(out, &pos, &reader, BTYPE); /*compression, BTYPE 01 or 10*/
1209 
1210     if(error) return error;
1211   }
1212 
1213   return error;
1214 }
1215 
lodepng_inflate(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGDecompressSettings * settings)1216 unsigned lodepng_inflate(unsigned char** out, size_t* outsize,
1217                          const unsigned char* in, size_t insize,
1218                          const LodePNGDecompressSettings* settings) {
1219   unsigned error;
1220   ucvector v;
1221   ucvector_init_buffer(&v, *out, *outsize);
1222   error = lodepng_inflatev(&v, in, insize, settings);
1223   *out = v.data;
1224   *outsize = v.size;
1225   return error;
1226 }
1227 
inflate(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGDecompressSettings * settings)1228 static unsigned inflate(unsigned char** out, size_t* outsize,
1229                         const unsigned char* in, size_t insize,
1230                         const LodePNGDecompressSettings* settings) {
1231   if(settings->custom_inflate) {
1232     return settings->custom_inflate(out, outsize, in, insize, settings);
1233   } else {
1234     return lodepng_inflate(out, outsize, in, insize, settings);
1235   }
1236 }
1237 
1238 #endif /*LODEPNG_COMPILE_DECODER*/
1239 
1240 #ifdef LODEPNG_COMPILE_ENCODER
1241 
1242 /* ////////////////////////////////////////////////////////////////////////// */
1243 /* / Deflator (Compressor)                                                  / */
1244 /* ////////////////////////////////////////////////////////////////////////// */
1245 
1246 static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258;
1247 
1248 /*search the index in the array, that has the largest value smaller than or equal to the given value,
1249 given array must be sorted (if no value is smaller, it returns the size of the given array)*/
searchCodeIndex(const unsigned * array,size_t array_size,size_t value)1250 static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value) {
1251   /*binary search (only small gain over linear). TODO: use CPU log2 instruction for getting symbols instead*/
1252   size_t left = 1;
1253   size_t right = array_size - 1;
1254 
1255   while(left <= right) {
1256     size_t mid = (left + right) >> 1;
1257     if (array[mid] >= value) right = mid - 1;
1258     else left = mid + 1;
1259   }
1260   if(left >= array_size || array[left] > value) left--;
1261   return left;
1262 }
1263 
addLengthDistance(uivector * values,size_t length,size_t distance)1264 static void addLengthDistance(uivector* values, size_t length, size_t distance) {
1265   /*values in encoded vector are those used by deflate:
1266   0-255: literal bytes
1267   256: end
1268   257-285: length/distance pair (length code, followed by extra length bits, distance code, extra distance bits)
1269   286-287: invalid*/
1270 
1271   unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length);
1272   unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]);
1273   unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance);
1274   unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]);
1275 
1276   uivector_push_back(values, length_code + FIRST_LENGTH_CODE_INDEX);
1277   uivector_push_back(values, extra_length);
1278   uivector_push_back(values, dist_code);
1279   uivector_push_back(values, extra_distance);
1280 }
1281 
1282 /*3 bytes of data get encoded into two bytes. The hash cannot use more than 3
1283 bytes as input because 3 is the minimum match length for deflate*/
1284 static const unsigned HASH_NUM_VALUES = 65536;
1285 static const unsigned HASH_BIT_MASK = 65535; /*HASH_NUM_VALUES - 1, but C90 does not like that as initializer*/
1286 
1287 typedef struct Hash {
1288   int* head; /*hash value to head circular pos - can be outdated if went around window*/
1289   /*circular pos to prev circular pos*/
1290   unsigned short* chain;
1291   int* val; /*circular pos to hash value*/
1292 
1293   /*TODO: do this not only for zeros but for any repeated byte. However for PNG
1294   it's always going to be the zeros that dominate, so not important for PNG*/
1295   int* headz; /*similar to head, but for chainz*/
1296   unsigned short* chainz; /*those with same amount of zeros*/
1297   unsigned short* zeros; /*length of zeros streak, used as a second hash chain*/
1298 } Hash;
1299 
hash_init(Hash * hash,unsigned windowsize)1300 static unsigned hash_init(Hash* hash, unsigned windowsize) {
1301   unsigned i;
1302   hash->head = (int*)lodepng_malloc(sizeof(int) * HASH_NUM_VALUES);
1303   hash->val = (int*)lodepng_malloc(sizeof(int) * windowsize);
1304   hash->chain = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize);
1305 
1306   hash->zeros = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize);
1307   hash->headz = (int*)lodepng_malloc(sizeof(int) * (MAX_SUPPORTED_DEFLATE_LENGTH + 1));
1308   hash->chainz = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize);
1309 
1310   if(!hash->head || !hash->chain || !hash->val  || !hash->headz|| !hash->chainz || !hash->zeros) {
1311     return 83; /*alloc fail*/
1312   }
1313 
1314   /*initialize hash table*/
1315   for(i = 0; i != HASH_NUM_VALUES; ++i) hash->head[i] = -1;
1316   for(i = 0; i != windowsize; ++i) hash->val[i] = -1;
1317   for(i = 0; i != windowsize; ++i) hash->chain[i] = i; /*same value as index indicates uninitialized*/
1318 
1319   for(i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; ++i) hash->headz[i] = -1;
1320   for(i = 0; i != windowsize; ++i) hash->chainz[i] = i; /*same value as index indicates uninitialized*/
1321 
1322   return 0;
1323 }
1324 
hash_cleanup(Hash * hash)1325 static void hash_cleanup(Hash* hash) {
1326   lodepng_free(hash->head);
1327   lodepng_free(hash->val);
1328   lodepng_free(hash->chain);
1329 
1330   lodepng_free(hash->zeros);
1331   lodepng_free(hash->headz);
1332   lodepng_free(hash->chainz);
1333 }
1334 
1335 
1336 
getHash(const unsigned char * data,size_t size,size_t pos)1337 static unsigned getHash(const unsigned char* data, size_t size, size_t pos) {
1338   unsigned result = 0;
1339   if(pos + 2 < size) {
1340     /*A simple shift and xor hash is used. Since the data of PNGs is dominated
1341     by zeroes due to the filters, a better hash does not have a significant
1342     effect on speed in traversing the chain, and causes more time spend on
1343     calculating the hash.*/
1344     result ^= (unsigned)(data[pos + 0] << 0u);
1345     result ^= (unsigned)(data[pos + 1] << 4u);
1346     result ^= (unsigned)(data[pos + 2] << 8u);
1347   } else {
1348     size_t amount, i;
1349     if(pos >= size) return 0;
1350     amount = size - pos;
1351     for(i = 0; i != amount; ++i) result ^= (unsigned)(data[pos + i] << (i * 8u));
1352   }
1353   return result & HASH_BIT_MASK;
1354 }
1355 
countZeros(const unsigned char * data,size_t size,size_t pos)1356 static unsigned countZeros(const unsigned char* data, size_t size, size_t pos) {
1357   const unsigned char* start = data + pos;
1358   const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH;
1359   if(end > data + size) end = data + size;
1360   data = start;
1361   while(data != end && *data == 0) ++data;
1362   /*subtracting two addresses returned as 32-bit number (max value is MAX_SUPPORTED_DEFLATE_LENGTH)*/
1363   return (unsigned)(data - start);
1364 }
1365 
1366 /*wpos = pos & (windowsize - 1)*/
updateHashChain(Hash * hash,size_t wpos,unsigned hashval,unsigned short numzeros)1367 static void updateHashChain(Hash* hash, size_t wpos, unsigned hashval, unsigned short numzeros) {
1368   hash->val[wpos] = (int)hashval;
1369   if(hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval];
1370   hash->head[hashval] = (int)wpos;
1371 
1372   hash->zeros[wpos] = numzeros;
1373   if(hash->headz[numzeros] != -1) hash->chainz[wpos] = hash->headz[numzeros];
1374   hash->headz[numzeros] = (int)wpos;
1375 }
1376 
1377 /*
1378 LZ77-encode the data. Return value is error code. The input are raw bytes, the output
1379 is in the form of unsigned integers with codes representing for example literal bytes, or
1380 length/distance pairs.
1381 It uses a hash table technique to let it encode faster. When doing LZ77 encoding, a
1382 sliding window (of windowsize) is used, and all past bytes in that window can be used as
1383 the "dictionary". A brute force search through all possible distances would be slow, and
1384 this hash technique is one out of several ways to speed this up.
1385 */
encodeLZ77(uivector * out,Hash * hash,const unsigned char * in,size_t inpos,size_t insize,unsigned windowsize,unsigned minmatch,unsigned nicematch,unsigned lazymatching)1386 static unsigned encodeLZ77(uivector* out, Hash* hash,
1387                            const unsigned char* in, size_t inpos, size_t insize, unsigned windowsize,
1388                            unsigned minmatch, unsigned nicematch, unsigned lazymatching) {
1389   size_t pos;
1390   unsigned i, error = 0;
1391   /*for large window lengths, assume the user wants no compression loss. Otherwise, max hash chain length speedup.*/
1392   unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8u;
1393   unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64;
1394 
1395   unsigned usezeros = 1; /*not sure if setting it to false for windowsize < 8192 is better or worse*/
1396   unsigned numzeros = 0;
1397 
1398   unsigned offset; /*the offset represents the distance in LZ77 terminology*/
1399   unsigned length;
1400   unsigned lazy = 0;
1401   unsigned lazylength = 0, lazyoffset = 0;
1402   unsigned hashval;
1403   unsigned current_offset, current_length;
1404   unsigned prev_offset;
1405   const unsigned char *lastptr, *foreptr, *backptr;
1406   unsigned hashpos;
1407 
1408   if(windowsize == 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/
1409   if((windowsize & (windowsize - 1)) != 0) return 90; /*error: must be power of two*/
1410 
1411   if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH;
1412 
1413   for(pos = inpos; pos < insize; ++pos) {
1414     size_t wpos = pos & (windowsize - 1); /*position for in 'circular' hash buffers*/
1415     unsigned chainlength = 0;
1416 
1417     hashval = getHash(in, insize, pos);
1418 
1419     if(usezeros && hashval == 0) {
1420       if(numzeros == 0) numzeros = countZeros(in, insize, pos);
1421       else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros;
1422     } else {
1423       numzeros = 0;
1424     }
1425 
1426     updateHashChain(hash, wpos, hashval, numzeros);
1427 
1428     /*the length and offset found for the current position*/
1429     length = 0;
1430     offset = 0;
1431 
1432     hashpos = hash->chain[wpos];
1433 
1434     lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH];
1435 
1436     /*search for the longest string*/
1437     prev_offset = 0;
1438     for(;;) {
1439       if(chainlength++ >= maxchainlength) break;
1440       current_offset = (unsigned)(hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize);
1441 
1442       if(current_offset < prev_offset) break; /*stop when went completely around the circular buffer*/
1443       prev_offset = current_offset;
1444       if(current_offset > 0) {
1445         /*test the next characters*/
1446         foreptr = &in[pos];
1447         backptr = &in[pos - current_offset];
1448 
1449         /*common case in PNGs is lots of zeros. Quickly skip over them as a speedup*/
1450         if(numzeros >= 3) {
1451           unsigned skip = hash->zeros[hashpos];
1452           if(skip > numzeros) skip = numzeros;
1453           backptr += skip;
1454           foreptr += skip;
1455         }
1456 
1457         while(foreptr != lastptr && *backptr == *foreptr) /*maximum supported length by deflate is max length*/ {
1458           ++backptr;
1459           ++foreptr;
1460         }
1461         current_length = (unsigned)(foreptr - &in[pos]);
1462 
1463         if(current_length > length) {
1464           length = current_length; /*the longest length*/
1465           offset = current_offset; /*the offset that is related to this longest length*/
1466           /*jump out once a length of max length is found (speed gain). This also jumps
1467           out if length is MAX_SUPPORTED_DEFLATE_LENGTH*/
1468           if(current_length >= nicematch) break;
1469         }
1470       }
1471 
1472       if(hashpos == hash->chain[hashpos]) break;
1473 
1474       if(numzeros >= 3 && length > numzeros) {
1475         hashpos = hash->chainz[hashpos];
1476         if(hash->zeros[hashpos] != numzeros) break;
1477       } else {
1478         hashpos = hash->chain[hashpos];
1479         /*outdated hash value, happens if particular value was not encountered in whole last window*/
1480         if(hash->val[hashpos] != (int)hashval) break;
1481       }
1482     }
1483 
1484     if(lazymatching) {
1485       if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH) {
1486         lazy = 1;
1487         lazylength = length;
1488         lazyoffset = offset;
1489         continue; /*try the next byte*/
1490       }
1491       if(lazy) {
1492         lazy = 0;
1493         if(pos == 0) ERROR_BREAK(81);
1494         if(length > lazylength + 1) {
1495           /*push the previous character as literal*/
1496           if(!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 /*alloc fail*/);
1497         } else {
1498           length = lazylength;
1499           offset = lazyoffset;
1500           hash->head[hashval] = -1; /*the same hashchain update will be done, this ensures no wrong alteration*/
1501           hash->headz[numzeros] = -1; /*idem*/
1502           --pos;
1503         }
1504       }
1505     }
1506     if(length >= 3 && offset > windowsize) ERROR_BREAK(86 /*too big (or overflown negative) offset*/);
1507 
1508     /*encode it as length/distance pair or literal value*/
1509     if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/ {
1510       if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/);
1511     } else if(length < minmatch || (length == 3 && offset > 4096)) {
1512       /*compensate for the fact that longer offsets have more extra bits, a
1513       length of only 3 may be not worth it then*/
1514       if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/);
1515     } else {
1516       addLengthDistance(out, length, offset);
1517       for(i = 1; i < length; ++i) {
1518         ++pos;
1519         wpos = pos & (windowsize - 1);
1520         hashval = getHash(in, insize, pos);
1521         if(usezeros && hashval == 0) {
1522           if(numzeros == 0) numzeros = countZeros(in, insize, pos);
1523           else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros;
1524         } else {
1525           numzeros = 0;
1526         }
1527         updateHashChain(hash, wpos, hashval, numzeros);
1528       }
1529     }
1530   } /*end of the loop through each character of input*/
1531 
1532   return error;
1533 }
1534 
1535 /* /////////////////////////////////////////////////////////////////////////// */
1536 
deflateNoCompression(ucvector * out,const unsigned char * data,size_t datasize)1537 static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, size_t datasize) {
1538   /*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte,
1539   2 bytes LEN, 2 bytes NLEN, LEN bytes literal DATA*/
1540 
1541   size_t i, j, numdeflateblocks = (datasize + 65534u) / 65535u;
1542   unsigned datapos = 0;
1543   for(i = 0; i != numdeflateblocks; ++i) {
1544     unsigned BFINAL, BTYPE, LEN, NLEN;
1545     unsigned char firstbyte;
1546 
1547     BFINAL = (i == numdeflateblocks - 1);
1548     BTYPE = 0;
1549 
1550     firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1));
1551     ucvector_push_back(out, firstbyte);
1552 
1553     LEN = 65535;
1554     if(datasize - datapos < 65535u) LEN = (unsigned)datasize - datapos;
1555     NLEN = 65535 - LEN;
1556 
1557     ucvector_push_back(out, (unsigned char)(LEN & 255));
1558     ucvector_push_back(out, (unsigned char)(LEN >> 8u));
1559     ucvector_push_back(out, (unsigned char)(NLEN & 255));
1560     ucvector_push_back(out, (unsigned char)(NLEN >> 8u));
1561 
1562     /*Decompressed data*/
1563     for(j = 0; j < 65535 && datapos < datasize; ++j) {
1564       ucvector_push_back(out, data[datapos++]);
1565     }
1566   }
1567 
1568   return 0;
1569 }
1570 
1571 /*
1572 write the lz77-encoded data, which has lit, len and dist codes, to compressed stream using huffman trees.
1573 tree_ll: the tree for lit and len codes.
1574 tree_d: the tree for distance codes.
1575 */
writeLZ77data(LodePNGBitWriter * writer,const uivector * lz77_encoded,const HuffmanTree * tree_ll,const HuffmanTree * tree_d)1576 static void writeLZ77data(LodePNGBitWriter* writer, const uivector* lz77_encoded,
1577                           const HuffmanTree* tree_ll, const HuffmanTree* tree_d) {
1578   size_t i = 0;
1579   for(i = 0; i != lz77_encoded->size; ++i) {
1580     unsigned val = lz77_encoded->data[i];
1581     writeBitsReversed(writer, HuffmanTree_getCode(tree_ll, val), HuffmanTree_getLength(tree_ll, val));
1582     if(val > 256) /*for a length code, 3 more things have to be added*/ {
1583       unsigned length_index = val - FIRST_LENGTH_CODE_INDEX;
1584       unsigned n_length_extra_bits = LENGTHEXTRA[length_index];
1585       unsigned length_extra_bits = lz77_encoded->data[++i];
1586 
1587       unsigned distance_code = lz77_encoded->data[++i];
1588 
1589       unsigned distance_index = distance_code;
1590       unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index];
1591       unsigned distance_extra_bits = lz77_encoded->data[++i];
1592 
1593       writeBits(writer, length_extra_bits, n_length_extra_bits);
1594       writeBitsReversed(writer, HuffmanTree_getCode(tree_d, distance_code),
1595                        HuffmanTree_getLength(tree_d, distance_code));
1596       writeBits(writer, distance_extra_bits, n_distance_extra_bits);
1597     }
1598   }
1599 }
1600 
1601 /*Deflate for a block of type "dynamic", that is, with freely, optimally, created huffman trees*/
deflateDynamic(LodePNGBitWriter * writer,Hash * hash,const unsigned char * data,size_t datapos,size_t dataend,const LodePNGCompressSettings * settings,unsigned final)1602 static unsigned deflateDynamic(LodePNGBitWriter* writer, Hash* hash,
1603                                const unsigned char* data, size_t datapos, size_t dataend,
1604                                const LodePNGCompressSettings* settings, unsigned final) {
1605   unsigned error = 0;
1606 
1607   /*
1608   A block is compressed as follows: The PNG data is lz77 encoded, resulting in
1609   literal bytes and length/distance pairs. This is then huffman compressed with
1610   two huffman trees. One huffman tree is used for the lit and len values ("ll"),
1611   another huffman tree is used for the dist values ("d"). These two trees are
1612   stored using their code lengths, and to compress even more these code lengths
1613   are also run-length encoded and huffman compressed. This gives a huffman tree
1614   of code lengths "cl". The code lenghts used to describe this third tree are
1615   the code length code lengths ("clcl").
1616   */
1617 
1618   /*The lz77 encoded data, represented with integers since there will also be length and distance codes in it*/
1619   uivector lz77_encoded;
1620   HuffmanTree tree_ll; /*tree for lit,len values*/
1621   HuffmanTree tree_d; /*tree for distance codes*/
1622   HuffmanTree tree_cl; /*tree for encoding the code lengths representing tree_ll and tree_d*/
1623   uivector frequencies_ll; /*frequency of lit,len codes*/
1624   uivector frequencies_d; /*frequency of dist codes*/
1625   uivector frequencies_cl; /*frequency of code length codes*/
1626   uivector bitlen_lld; /*lit,len,dist code lenghts (int bits), literally (without repeat codes).*/
1627   uivector bitlen_lld_e; /*bitlen_lld encoded with repeat codes (this is a rudemtary run length compression)*/
1628   /*bitlen_cl is the code length code lengths ("clcl"). The bit lengths of codes to represent tree_cl
1629   (these are written as is in the file, it would be crazy to compress these using yet another huffman
1630   tree that needs to be represented by yet another set of code lengths)*/
1631   uivector bitlen_cl;
1632   size_t datasize = dataend - datapos;
1633 
1634   /*
1635   Due to the huffman compression of huffman tree representations ("two levels"), there are some anologies:
1636   bitlen_lld is to tree_cl what data is to tree_ll and tree_d.
1637   bitlen_lld_e is to bitlen_lld what lz77_encoded is to data.
1638   bitlen_cl is to bitlen_lld_e what bitlen_lld is to lz77_encoded.
1639   */
1640 
1641   unsigned BFINAL = final;
1642   size_t numcodes_ll, numcodes_d, i;
1643   unsigned HLIT, HDIST, HCLEN;
1644 
1645   uivector_init(&lz77_encoded);
1646   HuffmanTree_init(&tree_ll);
1647   HuffmanTree_init(&tree_d);
1648   HuffmanTree_init(&tree_cl);
1649   uivector_init(&frequencies_ll);
1650   uivector_init(&frequencies_d);
1651   uivector_init(&frequencies_cl);
1652   uivector_init(&bitlen_lld);
1653   uivector_init(&bitlen_lld_e);
1654   uivector_init(&bitlen_cl);
1655 
1656   /*This while loop never loops due to a break at the end, it is here to
1657   allow breaking out of it to the cleanup phase on error conditions.*/
1658   while(!error) {
1659     if(settings->use_lz77) {
1660       error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize,
1661                          settings->minmatch, settings->nicematch, settings->lazymatching);
1662       if(error) break;
1663     } else {
1664       if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 /*alloc fail*/);
1665       for(i = datapos; i < dataend; ++i) lz77_encoded.data[i - datapos] = data[i]; /*no LZ77, but still will be Huffman compressed*/
1666     }
1667 
1668     if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83 /*alloc fail*/);
1669     if(!uivector_resizev(&frequencies_d, 30, 0)) ERROR_BREAK(83 /*alloc fail*/);
1670 
1671     /*Count the frequencies of lit, len and dist codes*/
1672     for(i = 0; i != lz77_encoded.size; ++i) {
1673       unsigned symbol = lz77_encoded.data[i];
1674       ++frequencies_ll.data[symbol];
1675       if(symbol > 256) {
1676         unsigned dist = lz77_encoded.data[i + 2];
1677         ++frequencies_d.data[dist];
1678         i += 3;
1679       }
1680     }
1681     frequencies_ll.data[256] = 1; /*there will be exactly 1 end code, at the end of the block*/
1682 
1683     /*Make both huffman trees, one for the lit and len codes, one for the dist codes*/
1684     error = HuffmanTree_makeFromFrequencies(&tree_ll, frequencies_ll.data, 257, frequencies_ll.size, 15);
1685     if(error) break;
1686     /*2, not 1, is chosen for mincodes: some buggy PNG decoders require at least 2 symbols in the dist tree*/
1687     error = HuffmanTree_makeFromFrequencies(&tree_d, frequencies_d.data, 2, frequencies_d.size, 15);
1688     if(error) break;
1689 
1690     numcodes_ll = tree_ll.numcodes; if(numcodes_ll > 286) numcodes_ll = 286;
1691     numcodes_d = tree_d.numcodes; if(numcodes_d > 30) numcodes_d = 30;
1692     /*store the code lengths of both generated trees in bitlen_lld*/
1693     for(i = 0; i != numcodes_ll; ++i) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_ll, (unsigned)i));
1694     for(i = 0; i != numcodes_d; ++i) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_d, (unsigned)i));
1695 
1696     /*run-length compress bitlen_ldd into bitlen_lld_e by using repeat codes 16 (copy length 3-6 times),
1697     17 (3-10 zeroes), 18 (11-138 zeroes)*/
1698     for(i = 0; i != (unsigned)bitlen_lld.size; ++i) {
1699       unsigned j = 0; /*amount of repititions*/
1700       while(i + j + 1 < (unsigned)bitlen_lld.size && bitlen_lld.data[i + j + 1] == bitlen_lld.data[i]) ++j;
1701 
1702       if(bitlen_lld.data[i] == 0 && j >= 2) /*repeat code for zeroes*/ {
1703         ++j; /*include the first zero*/
1704         if(j <= 10) /*repeat code 17 supports max 10 zeroes*/ {
1705           uivector_push_back(&bitlen_lld_e, 17);
1706           uivector_push_back(&bitlen_lld_e, j - 3);
1707         } else /*repeat code 18 supports max 138 zeroes*/ {
1708           if(j > 138) j = 138;
1709           uivector_push_back(&bitlen_lld_e, 18);
1710           uivector_push_back(&bitlen_lld_e, j - 11);
1711         }
1712         i += (j - 1);
1713       } else if(j >= 3) /*repeat code for value other than zero*/ {
1714         size_t k;
1715         unsigned num = j / 6u, rest = j % 6u;
1716         uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]);
1717         for(k = 0; k < num; ++k) {
1718           uivector_push_back(&bitlen_lld_e, 16);
1719           uivector_push_back(&bitlen_lld_e, 6 - 3);
1720         }
1721         if(rest >= 3) {
1722           uivector_push_back(&bitlen_lld_e, 16);
1723           uivector_push_back(&bitlen_lld_e, rest - 3);
1724         }
1725         else j -= rest;
1726         i += j;
1727       } else /*too short to benefit from repeat code*/ {
1728         uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]);
1729       }
1730     }
1731 
1732     /*generate tree_cl, the huffmantree of huffmantrees*/
1733 
1734     if(!uivector_resizev(&frequencies_cl, NUM_CODE_LENGTH_CODES, 0)) ERROR_BREAK(83 /*alloc fail*/);
1735     for(i = 0; i != bitlen_lld_e.size; ++i) {
1736       ++frequencies_cl.data[bitlen_lld_e.data[i]];
1737       /*after a repeat code come the bits that specify the number of repetitions,
1738       those don't need to be in the frequencies_cl calculation*/
1739       if(bitlen_lld_e.data[i] >= 16) ++i;
1740     }
1741 
1742     error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl.data,
1743                                             frequencies_cl.size, frequencies_cl.size, 7);
1744     if(error) break;
1745 
1746     if(!uivector_resize(&bitlen_cl, tree_cl.numcodes)) ERROR_BREAK(83 /*alloc fail*/);
1747     for(i = 0; i != tree_cl.numcodes; ++i) {
1748       /*lenghts of code length tree is in the order as specified by deflate*/
1749       bitlen_cl.data[i] = HuffmanTree_getLength(&tree_cl, CLCL_ORDER[i]);
1750     }
1751     while(bitlen_cl.data[bitlen_cl.size - 1] == 0 && bitlen_cl.size > 4) {
1752       /*remove zeros at the end, but minimum size must be 4*/
1753       if(!uivector_resize(&bitlen_cl, bitlen_cl.size - 1)) ERROR_BREAK(83 /*alloc fail*/);
1754     }
1755     if(error) break;
1756 
1757     /*
1758     Write everything into the output
1759 
1760     After the BFINAL and BTYPE, the dynamic block consists out of the following:
1761     - 5 bits HLIT, 5 bits HDIST, 4 bits HCLEN
1762     - (HCLEN+4)*3 bits code lengths of code length alphabet
1763     - HLIT + 257 code lenghts of lit/length alphabet (encoded using the code length
1764       alphabet, + possible repetition codes 16, 17, 18)
1765     - HDIST + 1 code lengths of distance alphabet (encoded using the code length
1766       alphabet, + possible repetition codes 16, 17, 18)
1767     - compressed data
1768     - 256 (end code)
1769     */
1770 
1771     /*Write block type*/
1772     writeBits(writer, BFINAL, 1);
1773     writeBits(writer, 0, 1); /*first bit of BTYPE "dynamic"*/
1774     writeBits(writer, 1, 1); /*second bit of BTYPE "dynamic"*/
1775 
1776     /*write the HLIT, HDIST and HCLEN values*/
1777     HLIT = (unsigned)(numcodes_ll - 257);
1778     HDIST = (unsigned)(numcodes_d - 1);
1779     HCLEN = (unsigned)bitlen_cl.size - 4;
1780     /*trim zeroes for HCLEN. HLIT and HDIST were already trimmed at tree creation*/
1781     while(!bitlen_cl.data[HCLEN + 4 - 1] && HCLEN > 0) --HCLEN;
1782     writeBits(writer, HLIT, 5);
1783     writeBits(writer, HDIST, 5);
1784     writeBits(writer, HCLEN, 4);
1785 
1786     /*write the code lenghts of the code length alphabet*/
1787     for(i = 0; i != HCLEN + 4; ++i) writeBits(writer, bitlen_cl.data[i], 3);
1788 
1789     /*write the lenghts of the lit/len AND the dist alphabet*/
1790     for(i = 0; i != bitlen_lld_e.size; ++i) {
1791       writeBitsReversed(writer, HuffmanTree_getCode(&tree_cl, bitlen_lld_e.data[i]),
1792                        HuffmanTree_getLength(&tree_cl, bitlen_lld_e.data[i]));
1793       /*extra bits of repeat codes*/
1794       if(bitlen_lld_e.data[i] == 16) writeBits(writer, bitlen_lld_e.data[++i], 2);
1795       else if(bitlen_lld_e.data[i] == 17) writeBits(writer, bitlen_lld_e.data[++i], 3);
1796       else if(bitlen_lld_e.data[i] == 18) writeBits(writer, bitlen_lld_e.data[++i], 7);
1797     }
1798 
1799     /*write the compressed data symbols*/
1800     writeLZ77data(writer, &lz77_encoded, &tree_ll, &tree_d);
1801     /*error: the length of the end code 256 must be larger than 0*/
1802     if(HuffmanTree_getLength(&tree_ll, 256) == 0) ERROR_BREAK(64);
1803 
1804     /*write the end code*/
1805     writeBitsReversed(writer, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256));
1806 
1807     break; /*end of error-while*/
1808   }
1809 
1810   /*cleanup*/
1811   uivector_cleanup(&lz77_encoded);
1812   HuffmanTree_cleanup(&tree_ll);
1813   HuffmanTree_cleanup(&tree_d);
1814   HuffmanTree_cleanup(&tree_cl);
1815   uivector_cleanup(&frequencies_ll);
1816   uivector_cleanup(&frequencies_d);
1817   uivector_cleanup(&frequencies_cl);
1818   uivector_cleanup(&bitlen_lld_e);
1819   uivector_cleanup(&bitlen_lld);
1820   uivector_cleanup(&bitlen_cl);
1821 
1822   return error;
1823 }
1824 
deflateFixed(LodePNGBitWriter * writer,Hash * hash,const unsigned char * data,size_t datapos,size_t dataend,const LodePNGCompressSettings * settings,unsigned final)1825 static unsigned deflateFixed(LodePNGBitWriter* writer, Hash* hash,
1826                              const unsigned char* data,
1827                              size_t datapos, size_t dataend,
1828                              const LodePNGCompressSettings* settings, unsigned final) {
1829   HuffmanTree tree_ll; /*tree for literal values and length codes*/
1830   HuffmanTree tree_d; /*tree for distance codes*/
1831 
1832   unsigned BFINAL = final;
1833   unsigned error = 0;
1834   size_t i;
1835 
1836   HuffmanTree_init(&tree_ll);
1837   HuffmanTree_init(&tree_d);
1838 
1839   generateFixedLitLenTree(&tree_ll);
1840   generateFixedDistanceTree(&tree_d);
1841 
1842   writeBits(writer, BFINAL, 1);
1843   writeBits(writer, 1, 1); /*first bit of BTYPE*/
1844   writeBits(writer, 0, 1); /*second bit of BTYPE*/
1845 
1846   if(settings->use_lz77) /*LZ77 encoded*/ {
1847     uivector lz77_encoded;
1848     uivector_init(&lz77_encoded);
1849     error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize,
1850                        settings->minmatch, settings->nicematch, settings->lazymatching);
1851     if(!error) writeLZ77data(writer, &lz77_encoded, &tree_ll, &tree_d);
1852     uivector_cleanup(&lz77_encoded);
1853   } else /*no LZ77, but still will be Huffman compressed*/ {
1854     for(i = datapos; i < dataend; ++i) {
1855       writeBitsReversed(writer, HuffmanTree_getCode(&tree_ll, data[i]), HuffmanTree_getLength(&tree_ll, data[i]));
1856     }
1857   }
1858   /*add END code*/
1859   if(!error) writeBitsReversed(writer, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256));
1860 
1861   /*cleanup*/
1862   HuffmanTree_cleanup(&tree_ll);
1863   HuffmanTree_cleanup(&tree_d);
1864 
1865   return error;
1866 }
1867 
lodepng_deflatev(ucvector * out,const unsigned char * in,size_t insize,const LodePNGCompressSettings * settings)1868 static unsigned lodepng_deflatev(ucvector* out, const unsigned char* in, size_t insize,
1869                                  const LodePNGCompressSettings* settings) {
1870   unsigned error = 0;
1871   size_t i, blocksize, numdeflateblocks;
1872   Hash hash;
1873   LodePNGBitWriter writer;
1874 
1875   LodePNGBitWriter_init(&writer, out);
1876 
1877   if(settings->btype > 2) return 61;
1878   else if(settings->btype == 0) return deflateNoCompression(out, in, insize);
1879   else if(settings->btype == 1) blocksize = insize;
1880   else /*if(settings->btype == 2)*/ {
1881     /*on PNGs, deflate blocks of 65-262k seem to give most dense encoding*/
1882     blocksize = insize / 8u + 8;
1883     if(blocksize < 65536) blocksize = 65536;
1884     if(blocksize > 262144) blocksize = 262144;
1885   }
1886 
1887   numdeflateblocks = (insize + blocksize - 1) / blocksize;
1888   if(numdeflateblocks == 0) numdeflateblocks = 1;
1889 
1890   error = hash_init(&hash, settings->windowsize);
1891   if(error) return error;
1892 
1893   for(i = 0; i != numdeflateblocks && !error; ++i) {
1894     unsigned final = (i == numdeflateblocks - 1);
1895     size_t start = i * blocksize;
1896     size_t end = start + blocksize;
1897     if(end > insize) end = insize;
1898 
1899     if(settings->btype == 1) error = deflateFixed(&writer, &hash, in, start, end, settings, final);
1900     else if(settings->btype == 2) error = deflateDynamic(&writer, &hash, in, start, end, settings, final);
1901   }
1902 
1903   hash_cleanup(&hash);
1904 
1905   return error;
1906 }
1907 
lodepng_deflate(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGCompressSettings * settings)1908 unsigned lodepng_deflate(unsigned char** out, size_t* outsize,
1909                          const unsigned char* in, size_t insize,
1910                          const LodePNGCompressSettings* settings) {
1911   unsigned error;
1912   ucvector v;
1913   ucvector_init_buffer(&v, *out, *outsize);
1914   error = lodepng_deflatev(&v, in, insize, settings);
1915   *out = v.data;
1916   *outsize = v.size;
1917   return error;
1918 }
1919 
deflate(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGCompressSettings * settings)1920 static unsigned deflate(unsigned char** out, size_t* outsize,
1921                         const unsigned char* in, size_t insize,
1922                         const LodePNGCompressSettings* settings) {
1923   if(settings->custom_deflate) {
1924     return settings->custom_deflate(out, outsize, in, insize, settings);
1925   } else {
1926     return lodepng_deflate(out, outsize, in, insize, settings);
1927   }
1928 }
1929 
1930 #endif /*LODEPNG_COMPILE_DECODER*/
1931 
1932 /* ////////////////////////////////////////////////////////////////////////// */
1933 /* / Adler32                                                                / */
1934 /* ////////////////////////////////////////////////////////////////////////// */
1935 
update_adler32(unsigned adler,const unsigned char * data,unsigned len)1936 static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len) {
1937   unsigned s1 = adler & 0xffff;
1938   unsigned s2 = (adler >> 16) & 0xffff;
1939 
1940   while(len > 0) {
1941     /*at least 5552 sums can be done before the sums overflow, saving a lot of module divisions*/
1942     unsigned amount = len > 5552 ? 5552 : len;
1943     len -= amount;
1944     while(amount > 0) {
1945       s1 += (*data++);
1946       s2 += s1;
1947       --amount;
1948     }
1949     s1 %= 65521;
1950     s2 %= 65521;
1951   }
1952 
1953   return (s2 << 16) | s1;
1954 }
1955 
1956 /*Return the adler32 of the bytes data[0..len-1]*/
adler32(const unsigned char * data,unsigned len)1957 static unsigned adler32(const unsigned char* data, unsigned len) {
1958   return update_adler32(1L, data, len);
1959 }
1960 
1961 /* ////////////////////////////////////////////////////////////////////////// */
1962 /* / Zlib                                                                   / */
1963 /* ////////////////////////////////////////////////////////////////////////// */
1964 
1965 #ifdef LODEPNG_COMPILE_DECODER
1966 
lodepng_zlib_decompress(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGDecompressSettings * settings)1967 unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in,
1968                                  size_t insize, const LodePNGDecompressSettings* settings) {
1969   unsigned error = 0;
1970   unsigned CM, CINFO, FDICT;
1971 
1972   if(insize < 2) return 53; /*error, size of zlib data too small*/
1973   /*read information from zlib header*/
1974   if((in[0] * 256 + in[1]) % 31 != 0) {
1975     /*error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way*/
1976     return 24;
1977   }
1978 
1979   CM = in[0] & 15;
1980   CINFO = (in[0] >> 4) & 15;
1981   /*FCHECK = in[1] & 31;*/ /*FCHECK is already tested above*/
1982   FDICT = (in[1] >> 5) & 1;
1983   /*FLEVEL = (in[1] >> 6) & 3;*/ /*FLEVEL is not used here*/
1984 
1985   if(CM != 8 || CINFO > 7) {
1986     /*error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec*/
1987     return 25;
1988   }
1989   if(FDICT != 0) {
1990     /*error: the specification of PNG says about the zlib stream:
1991       "The additional flags shall not specify a preset dictionary."*/
1992     return 26;
1993   }
1994 
1995   error = inflate(out, outsize, in + 2, insize - 2, settings);
1996   if(error) return error;
1997 
1998   if(!settings->ignore_adler32) {
1999     unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]);
2000     unsigned checksum = adler32(*out, (unsigned)(*outsize));
2001     if(checksum != ADLER32) return 58; /*error, adler checksum not correct, data must be corrupted*/
2002   }
2003 
2004   return 0; /*no error*/
2005 }
2006 
zlib_decompress(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGDecompressSettings * settings)2007 static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in,
2008                                 size_t insize, const LodePNGDecompressSettings* settings) {
2009   if(settings->custom_zlib) {
2010     return settings->custom_zlib(out, outsize, in, insize, settings);
2011   } else {
2012     return lodepng_zlib_decompress(out, outsize, in, insize, settings);
2013   }
2014 }
2015 
2016 #endif /*LODEPNG_COMPILE_DECODER*/
2017 
2018 #ifdef LODEPNG_COMPILE_ENCODER
2019 
lodepng_zlib_compress(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGCompressSettings * settings)2020 unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in,
2021                                size_t insize, const LodePNGCompressSettings* settings) {
2022   /*initially, *out must be NULL and outsize 0, if you just give some random *out
2023   that's pointing to a non allocated buffer, this'll crash*/
2024   ucvector outv;
2025   size_t i;
2026   unsigned error;
2027   unsigned char* deflatedata = 0;
2028   size_t deflatesize = 0;
2029 
2030   /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/
2031   unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/
2032   unsigned FLEVEL = 0;
2033   unsigned FDICT = 0;
2034   unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64;
2035   unsigned FCHECK = 31 - CMFFLG % 31;
2036   CMFFLG += FCHECK;
2037 
2038   /*ucvector-controlled version of the output buffer, for dynamic array*/
2039   ucvector_init_buffer(&outv, *out, *outsize);
2040 
2041   ucvector_push_back(&outv, (unsigned char)(CMFFLG >> 8));
2042   ucvector_push_back(&outv, (unsigned char)(CMFFLG & 255));
2043 
2044   error = deflate(&deflatedata, &deflatesize, in, insize, settings);
2045 
2046   if(!error) {
2047     unsigned ADLER32 = adler32(in, (unsigned)insize);
2048     for(i = 0; i != deflatesize; ++i) ucvector_push_back(&outv, deflatedata[i]);
2049     lodepng_free(deflatedata);
2050     lodepng_add32bitInt(&outv, ADLER32);
2051   }
2052 
2053   *out = outv.data;
2054   *outsize = outv.size;
2055 
2056   return error;
2057 }
2058 
2059 /* compress using the default or custom zlib function */
zlib_compress(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGCompressSettings * settings)2060 static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in,
2061                               size_t insize, const LodePNGCompressSettings* settings) {
2062   if(settings->custom_zlib) {
2063     return settings->custom_zlib(out, outsize, in, insize, settings);
2064   } else {
2065     return lodepng_zlib_compress(out, outsize, in, insize, settings);
2066   }
2067 }
2068 
2069 #endif /*LODEPNG_COMPILE_ENCODER*/
2070 
2071 #else /*no LODEPNG_COMPILE_ZLIB*/
2072 
2073 #ifdef LODEPNG_COMPILE_DECODER
zlib_decompress(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGDecompressSettings * settings)2074 static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in,
2075                                 size_t insize, const LodePNGDecompressSettings* settings) {
2076   if(!settings->custom_zlib) return 87; /*no custom zlib function provided */
2077   return settings->custom_zlib(out, outsize, in, insize, settings);
2078 }
2079 #endif /*LODEPNG_COMPILE_DECODER*/
2080 #ifdef LODEPNG_COMPILE_ENCODER
zlib_compress(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGCompressSettings * settings)2081 static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in,
2082                               size_t insize, const LodePNGCompressSettings* settings) {
2083   if(!settings->custom_zlib) return 87; /*no custom zlib function provided */
2084   return settings->custom_zlib(out, outsize, in, insize, settings);
2085 }
2086 #endif /*LODEPNG_COMPILE_ENCODER*/
2087 
2088 #endif /*LODEPNG_COMPILE_ZLIB*/
2089 
2090 /* ////////////////////////////////////////////////////////////////////////// */
2091 
2092 #ifdef LODEPNG_COMPILE_ENCODER
2093 
2094 /*this is a good tradeoff between speed and compression ratio*/
2095 #define DEFAULT_WINDOWSIZE 2048
2096 
lodepng_compress_settings_init(LodePNGCompressSettings * settings)2097 void lodepng_compress_settings_init(LodePNGCompressSettings* settings) {
2098   /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/
2099   settings->btype = 2;
2100   settings->use_lz77 = 1;
2101   settings->windowsize = DEFAULT_WINDOWSIZE;
2102   settings->minmatch = 3;
2103   settings->nicematch = 128;
2104   settings->lazymatching = 1;
2105 
2106   settings->custom_zlib = 0;
2107   settings->custom_deflate = 0;
2108   settings->custom_context = 0;
2109 }
2110 
2111 const LodePNGCompressSettings lodepng_default_compress_settings = {2, 1, DEFAULT_WINDOWSIZE, 3, 128, 1, 0, 0, 0};
2112 
2113 
2114 #endif /*LODEPNG_COMPILE_ENCODER*/
2115 
2116 #ifdef LODEPNG_COMPILE_DECODER
2117 
lodepng_decompress_settings_init(LodePNGDecompressSettings * settings)2118 void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings) {
2119   settings->ignore_adler32 = 0;
2120   settings->ignore_nlen = 0;
2121 
2122   settings->custom_zlib = 0;
2123   settings->custom_inflate = 0;
2124   settings->custom_context = 0;
2125 }
2126 
2127 const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, 0, 0};
2128 
2129 #endif /*LODEPNG_COMPILE_DECODER*/
2130 
2131 /* ////////////////////////////////////////////////////////////////////////// */
2132 /* ////////////////////////////////////////////////////////////////////////// */
2133 /* // End of Zlib related code. Begin of PNG related code.                 // */
2134 /* ////////////////////////////////////////////////////////////////////////// */
2135 /* ////////////////////////////////////////////////////////////////////////// */
2136 
2137 #ifdef LODEPNG_COMPILE_PNG
2138 
2139 /* ////////////////////////////////////////////////////////////////////////// */
2140 /* / CRC32                                                                  / */
2141 /* ////////////////////////////////////////////////////////////////////////// */
2142 
2143 
2144 #ifndef LODEPNG_NO_COMPILE_CRC
2145 /* CRC polynomial: 0xedb88320 */
2146 static unsigned lodepng_crc32_table[256] = {
2147            0u, 1996959894u, 3993919788u, 2567524794u,  124634137u, 1886057615u, 3915621685u, 2657392035u,
2148    249268274u, 2044508324u, 3772115230u, 2547177864u,  162941995u, 2125561021u, 3887607047u, 2428444049u,
2149    498536548u, 1789927666u, 4089016648u, 2227061214u,  450548861u, 1843258603u, 4107580753u, 2211677639u,
2150    325883990u, 1684777152u, 4251122042u, 2321926636u,  335633487u, 1661365465u, 4195302755u, 2366115317u,
2151    997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u,
2152    901097722u, 1119000684u, 3686517206u, 2898065728u,  853044451u, 1172266101u, 3705015759u, 2882616665u,
2153    651767980u, 1373503546u, 3369554304u, 3218104598u,  565507253u, 1454621731u, 3485111705u, 3099436303u,
2154    671266974u, 1594198024u, 3322730930u, 2970347812u,  795835527u, 1483230225u, 3244367275u, 3060149565u,
2155   1994146192u,   31158534u, 2563907772u, 4023717930u, 1907459465u,  112637215u, 2680153253u, 3904427059u,
2156   2013776290u,  251722036u, 2517215374u, 3775830040u, 2137656763u,  141376813u, 2439277719u, 3865271297u,
2157   1802195444u,  476864866u, 2238001368u, 4066508878u, 1812370925u,  453092731u, 2181625025u, 4111451223u,
2158   1706088902u,  314042704u, 2344532202u, 4240017532u, 1658658271u,  366619977u, 2362670323u, 4224994405u,
2159   1303535960u,  984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u,
2160   1131014506u,  879679996u, 2909243462u, 3663771856u, 1141124467u,  855842277u, 2852801631u, 3708648649u,
2161   1342533948u,  654459306u, 3188396048u, 3373015174u, 1466479909u,  544179635u, 3110523913u, 3462522015u,
2162   1591671054u,  702138776u, 2966460450u, 3352799412u, 1504918807u,  783551873u, 3082640443u, 3233442989u,
2163   3988292384u, 2596254646u,   62317068u, 1957810842u, 3939845945u, 2647816111u,   81470997u, 1943803523u,
2164   3814918930u, 2489596804u,  225274430u, 2053790376u, 3826175755u, 2466906013u,  167816743u, 2097651377u,
2165   4027552580u, 2265490386u,  503444072u, 1762050814u, 4150417245u, 2154129355u,  426522225u, 1852507879u,
2166   4275313526u, 2312317920u,  282753626u, 1742555852u, 4189708143u, 2394877945u,  397917763u, 1622183637u,
2167   3604390888u, 2714866558u,  953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u,
2168   3624741850u, 2936675148u,  906185462u, 1090812512u, 3747672003u, 2825379669u,  829329135u, 1181335161u,
2169   3412177804u, 3160834842u,  628085408u, 1382605366u, 3423369109u, 3138078467u,  570562233u, 1426400815u,
2170   3317316542u, 2998733608u,  733239954u, 1555261956u, 3268935591u, 3050360625u,  752459403u, 1541320221u,
2171   2607071920u, 3965973030u, 1969922972u,   40735498u, 2617837225u, 3943577151u, 1913087877u,   83908371u,
2172   2512341634u, 3803740692u, 2075208622u,  213261112u, 2463272603u, 3855990285u, 2094854071u,  198958881u,
2173   2262029012u, 4057260610u, 1759359992u,  534414190u, 2176718541u, 4139329115u, 1873836001u,  414664567u,
2174   2282248934u, 4279200368u, 1711684554u,  285281116u, 2405801727u, 4167216745u, 1634467795u,  376229701u,
2175   2685067896u, 3608007406u, 1308918612u,  956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u,
2176   2932959818u, 3654703836u, 1088359270u,  936918000u, 2847714899u, 3736837829u, 1202900863u,  817233897u,
2177   3183342108u, 3401237130u, 1404277552u,  615818150u, 3134207493u, 3453421203u, 1423857449u,  601450431u,
2178   3009837614u, 3294710456u, 1567103746u,  711928724u, 3020668471u, 3272380065u, 1510334235u,  755167117u
2179 };
2180 
2181 /*Return the CRC of the bytes buf[0..len-1].*/
lodepng_crc32(const unsigned char * data,size_t length)2182 unsigned lodepng_crc32(const unsigned char* data, size_t length) {
2183   unsigned r = 0xffffffffu;
2184   size_t i;
2185   for(i = 0; i < length; ++i) {
2186     r = lodepng_crc32_table[(r ^ data[i]) & 0xffu] ^ (r >> 8u);
2187   }
2188   return r ^ 0xffffffffu;
2189 }
2190 #else /* !LODEPNG_NO_COMPILE_CRC */
2191 unsigned lodepng_crc32(const unsigned char* data, size_t length);
2192 #endif /* !LODEPNG_NO_COMPILE_CRC */
2193 
2194 /* ////////////////////////////////////////////////////////////////////////// */
2195 /* / Reading and writing PNG color channel bits                             / */
2196 /* ////////////////////////////////////////////////////////////////////////// */
2197 
2198 /* The color channel bits of less-than-8-bit pixels are read with the MSB of bytes first,
2199 so LodePNGBitWriter and LodePNGBitReader can't be used for those. */
2200 
readBitFromReversedStream(size_t * bitpointer,const unsigned char * bitstream)2201 static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream) {
2202   unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1);
2203   ++(*bitpointer);
2204   return result;
2205 }
2206 
readBitsFromReversedStream(size_t * bitpointer,const unsigned char * bitstream,size_t nbits)2207 static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) {
2208   unsigned result = 0;
2209   size_t i;
2210   for(i = 0 ; i < nbits; ++i) {
2211     result <<= 1;
2212     result |= (unsigned)readBitFromReversedStream(bitpointer, bitstream);
2213   }
2214   return result;
2215 }
2216 
setBitOfReversedStream(size_t * bitpointer,unsigned char * bitstream,unsigned char bit)2217 static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) {
2218   /*the current bit in bitstream may be 0 or 1 for this to work*/
2219   if(bit == 0) bitstream[(*bitpointer) >> 3] &=  (unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7))));
2220   else         bitstream[(*bitpointer) >> 3] |=  (1 << (7 - ((*bitpointer) & 0x7)));
2221   ++(*bitpointer);
2222 }
2223 
2224 /* ////////////////////////////////////////////////////////////////////////// */
2225 /* / PNG chunks                                                             / */
2226 /* ////////////////////////////////////////////////////////////////////////// */
2227 
lodepng_chunk_length(const unsigned char * chunk)2228 unsigned lodepng_chunk_length(const unsigned char* chunk) {
2229   return lodepng_read32bitInt(&chunk[0]);
2230 }
2231 
lodepng_chunk_type(char type[5],const unsigned char * chunk)2232 void lodepng_chunk_type(char type[5], const unsigned char* chunk) {
2233   unsigned i;
2234   for(i = 0; i != 4; ++i) type[i] = (char)chunk[4 + i];
2235   type[4] = 0; /*null termination char*/
2236 }
2237 
lodepng_chunk_type_equals(const unsigned char * chunk,const char * type)2238 unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type) {
2239   if(lodepng_strlen(type) != 4) return 0;
2240   return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]);
2241 }
2242 
lodepng_chunk_ancillary(const unsigned char * chunk)2243 unsigned char lodepng_chunk_ancillary(const unsigned char* chunk) {
2244   return((chunk[4] & 32) != 0);
2245 }
2246 
lodepng_chunk_private(const unsigned char * chunk)2247 unsigned char lodepng_chunk_private(const unsigned char* chunk) {
2248   return((chunk[6] & 32) != 0);
2249 }
2250 
lodepng_chunk_safetocopy(const unsigned char * chunk)2251 unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk) {
2252   return((chunk[7] & 32) != 0);
2253 }
2254 
lodepng_chunk_data(unsigned char * chunk)2255 unsigned char* lodepng_chunk_data(unsigned char* chunk) {
2256   return &chunk[8];
2257 }
2258 
lodepng_chunk_data_const(const unsigned char * chunk)2259 const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk) {
2260   return &chunk[8];
2261 }
2262 
lodepng_chunk_check_crc(const unsigned char * chunk)2263 unsigned lodepng_chunk_check_crc(const unsigned char* chunk) {
2264   unsigned length = lodepng_chunk_length(chunk);
2265   unsigned CRC = lodepng_read32bitInt(&chunk[length + 8]);
2266   /*the CRC is taken of the data and the 4 chunk type letters, not the length*/
2267   unsigned checksum = lodepng_crc32(&chunk[4], length + 4);
2268   if(CRC != checksum) return 1;
2269   else return 0;
2270 }
2271 
lodepng_chunk_generate_crc(unsigned char * chunk)2272 void lodepng_chunk_generate_crc(unsigned char* chunk) {
2273   unsigned length = lodepng_chunk_length(chunk);
2274   unsigned CRC = lodepng_crc32(&chunk[4], length + 4);
2275   lodepng_set32bitInt(chunk + 8 + length, CRC);
2276 }
2277 
lodepng_chunk_next(unsigned char * chunk)2278 unsigned char* lodepng_chunk_next(unsigned char* chunk) {
2279   if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47
2280     && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) {
2281     /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */
2282     return chunk + 8;
2283   } else {
2284     unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12;
2285     return chunk + total_chunk_length;
2286   }
2287 }
2288 
lodepng_chunk_next_const(const unsigned char * chunk)2289 const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk) {
2290   if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47
2291     && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) {
2292     /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */
2293     return chunk + 8;
2294   } else {
2295     unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12;
2296     return chunk + total_chunk_length;
2297   }
2298 }
2299 
lodepng_chunk_find(unsigned char * chunk,const unsigned char * end,const char type[5])2300 unsigned char* lodepng_chunk_find(unsigned char* chunk, const unsigned char* end, const char type[5]) {
2301   for(;;) {
2302     if(chunk + 12 >= end) return 0;
2303     if(lodepng_chunk_type_equals(chunk, type)) return chunk;
2304     chunk = lodepng_chunk_next(chunk);
2305   }
2306 }
2307 
lodepng_chunk_find_const(const unsigned char * chunk,const unsigned char * end,const char type[5])2308 const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const unsigned char* end, const char type[5]) {
2309   for(;;) {
2310     if(chunk + 12 >= end) return 0;
2311     if(lodepng_chunk_type_equals(chunk, type)) return chunk;
2312     chunk = lodepng_chunk_next_const(chunk);
2313   }
2314 }
2315 
lodepng_chunk_append(unsigned char ** out,size_t * outlength,const unsigned char * chunk)2316 unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk) {
2317   unsigned i;
2318   unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12;
2319   unsigned char *chunk_start, *new_buffer;
2320   size_t new_length = (*outlength) + total_chunk_length;
2321   if(new_length < total_chunk_length || new_length < (*outlength)) return 77; /*integer overflow happened*/
2322 
2323   new_buffer = (unsigned char*)lodepng_realloc(*out, new_length);
2324   if(!new_buffer) return 83; /*alloc fail*/
2325   (*out) = new_buffer;
2326   (*outlength) = new_length;
2327   chunk_start = &(*out)[new_length - total_chunk_length];
2328 
2329   for(i = 0; i != total_chunk_length; ++i) chunk_start[i] = chunk[i];
2330 
2331   return 0;
2332 }
2333 
lodepng_chunk_create(unsigned char ** out,size_t * outlength,unsigned length,const char * type,const unsigned char * data)2334 unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length,
2335                               const char* type, const unsigned char* data) {
2336   unsigned i;
2337   unsigned char *chunk, *new_buffer;
2338   size_t new_length = (*outlength) + length + 12;
2339   if(new_length < length + 12 || new_length < (*outlength)) return 77; /*integer overflow happened*/
2340   new_buffer = (unsigned char*)lodepng_realloc(*out, new_length);
2341   if(!new_buffer) return 83; /*alloc fail*/
2342   (*out) = new_buffer;
2343   (*outlength) = new_length;
2344   chunk = &(*out)[(*outlength) - length - 12];
2345 
2346   /*1: length*/
2347   lodepng_set32bitInt(chunk, (unsigned)length);
2348 
2349   /*2: chunk name (4 letters)*/
2350   chunk[4] = (unsigned char)type[0];
2351   chunk[5] = (unsigned char)type[1];
2352   chunk[6] = (unsigned char)type[2];
2353   chunk[7] = (unsigned char)type[3];
2354 
2355   /*3: the data*/
2356   for(i = 0; i != length; ++i) chunk[8 + i] = data[i];
2357 
2358   /*4: CRC (of the chunkname characters and the data)*/
2359   lodepng_chunk_generate_crc(chunk);
2360 
2361   return 0;
2362 }
2363 
2364 /* ////////////////////////////////////////////////////////////////////////// */
2365 /* / Color types, channels, bits                                            / */
2366 /* ////////////////////////////////////////////////////////////////////////// */
2367 
2368 /*checks if the colortype is valid and the bitdepth bd is allowed for this colortype.
2369 Return value is a LodePNG error code.*/
checkColorValidity(LodePNGColorType colortype,unsigned bd)2370 static unsigned checkColorValidity(LodePNGColorType colortype, unsigned bd) {
2371   switch(colortype) {
2372     case LCT_GREY:       if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break;
2373     case LCT_RGB:        if(!(                                 bd == 8 || bd == 16)) return 37; break;
2374     case LCT_PALETTE:    if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8            )) return 37; break;
2375     case LCT_GREY_ALPHA: if(!(                                 bd == 8 || bd == 16)) return 37; break;
2376     case LCT_RGBA:       if(!(                                 bd == 8 || bd == 16)) return 37; break;
2377     default: return 31; /* invalid color type */
2378   }
2379   return 0; /*allowed color type / bits combination*/
2380 }
2381 
getNumColorChannels(LodePNGColorType colortype)2382 static unsigned getNumColorChannels(LodePNGColorType colortype) {
2383   switch(colortype) {
2384     case LCT_GREY: return 1;
2385     case LCT_RGB: return 3;
2386     case LCT_PALETTE: return 1;
2387     case LCT_GREY_ALPHA: return 2;
2388     case LCT_RGBA: return 4;
2389     default: return 0; /*invalid color type*/
2390   }
2391 }
2392 
lodepng_get_bpp_lct(LodePNGColorType colortype,unsigned bitdepth)2393 static unsigned lodepng_get_bpp_lct(LodePNGColorType colortype, unsigned bitdepth) {
2394   /*bits per pixel is amount of channels * bits per channel*/
2395   return getNumColorChannels(colortype) * bitdepth;
2396 }
2397 
2398 /* ////////////////////////////////////////////////////////////////////////// */
2399 
lodepng_color_mode_init(LodePNGColorMode * info)2400 void lodepng_color_mode_init(LodePNGColorMode* info) {
2401   info->key_defined = 0;
2402   info->key_r = info->key_g = info->key_b = 0;
2403   info->colortype = LCT_RGBA;
2404   info->bitdepth = 8;
2405   info->palette = 0;
2406   info->palettesize = 0;
2407 }
2408 
lodepng_color_mode_cleanup(LodePNGColorMode * info)2409 void lodepng_color_mode_cleanup(LodePNGColorMode* info) {
2410   lodepng_palette_clear(info);
2411 }
2412 
lodepng_color_mode_copy(LodePNGColorMode * dest,const LodePNGColorMode * source)2413 unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source) {
2414   size_t i;
2415   lodepng_color_mode_cleanup(dest);
2416   *dest = *source;
2417   if(source->palette) {
2418     dest->palette = (unsigned char*)lodepng_malloc(1024);
2419     if(!dest->palette && source->palettesize) return 83; /*alloc fail*/
2420     for(i = 0; i != source->palettesize * 4; ++i) dest->palette[i] = source->palette[i];
2421   }
2422   return 0;
2423 }
2424 
lodepng_color_mode_make(LodePNGColorType colortype,unsigned bitdepth)2425 LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth) {
2426   LodePNGColorMode result;
2427   lodepng_color_mode_init(&result);
2428   result.colortype = colortype;
2429   result.bitdepth = bitdepth;
2430   return result;
2431 }
2432 
lodepng_color_mode_equal(const LodePNGColorMode * a,const LodePNGColorMode * b)2433 static int lodepng_color_mode_equal(const LodePNGColorMode* a, const LodePNGColorMode* b) {
2434   size_t i;
2435   if(a->colortype != b->colortype) return 0;
2436   if(a->bitdepth != b->bitdepth) return 0;
2437   if(a->key_defined != b->key_defined) return 0;
2438   if(a->key_defined) {
2439     if(a->key_r != b->key_r) return 0;
2440     if(a->key_g != b->key_g) return 0;
2441     if(a->key_b != b->key_b) return 0;
2442   }
2443   if(a->palettesize != b->palettesize) return 0;
2444   for(i = 0; i != a->palettesize * 4; ++i) {
2445     if(a->palette[i] != b->palette[i]) return 0;
2446   }
2447   return 1;
2448 }
2449 
lodepng_palette_clear(LodePNGColorMode * info)2450 void lodepng_palette_clear(LodePNGColorMode* info) {
2451   if(info->palette) lodepng_free(info->palette);
2452   info->palette = 0;
2453   info->palettesize = 0;
2454 }
2455 
lodepng_palette_add(LodePNGColorMode * info,unsigned char r,unsigned char g,unsigned char b,unsigned char a)2456 unsigned lodepng_palette_add(LodePNGColorMode* info,
2457                              unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
2458   unsigned char* data;
2459   /*the same resize technique as C++ std::vectors is used, and here it's made so that for a palette with
2460   the max of 256 colors, it'll have the exact alloc size*/
2461   if(!info->palette) /*allocate palette if empty*/ {
2462     /*room for 256 colors with 4 bytes each*/
2463     data = (unsigned char*)lodepng_realloc(info->palette, 1024);
2464     if(!data) return 83; /*alloc fail*/
2465     else info->palette = data;
2466   }
2467   info->palette[4 * info->palettesize + 0] = r;
2468   info->palette[4 * info->palettesize + 1] = g;
2469   info->palette[4 * info->palettesize + 2] = b;
2470   info->palette[4 * info->palettesize + 3] = a;
2471   ++info->palettesize;
2472   return 0;
2473 }
2474 
2475 /*calculate bits per pixel out of colortype and bitdepth*/
lodepng_get_bpp(const LodePNGColorMode * info)2476 unsigned lodepng_get_bpp(const LodePNGColorMode* info) {
2477   return lodepng_get_bpp_lct(info->colortype, info->bitdepth);
2478 }
2479 
lodepng_get_channels(const LodePNGColorMode * info)2480 unsigned lodepng_get_channels(const LodePNGColorMode* info) {
2481   return getNumColorChannels(info->colortype);
2482 }
2483 
lodepng_is_greyscale_type(const LodePNGColorMode * info)2484 unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info) {
2485   return info->colortype == LCT_GREY || info->colortype == LCT_GREY_ALPHA;
2486 }
2487 
lodepng_is_alpha_type(const LodePNGColorMode * info)2488 unsigned lodepng_is_alpha_type(const LodePNGColorMode* info) {
2489   return (info->colortype & 4) != 0; /*4 or 6*/
2490 }
2491 
lodepng_is_palette_type(const LodePNGColorMode * info)2492 unsigned lodepng_is_palette_type(const LodePNGColorMode* info) {
2493   return info->colortype == LCT_PALETTE;
2494 }
2495 
lodepng_has_palette_alpha(const LodePNGColorMode * info)2496 unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info) {
2497   size_t i;
2498   for(i = 0; i != info->palettesize; ++i) {
2499     if(info->palette[i * 4 + 3] < 255) return 1;
2500   }
2501   return 0;
2502 }
2503 
lodepng_can_have_alpha(const LodePNGColorMode * info)2504 unsigned lodepng_can_have_alpha(const LodePNGColorMode* info) {
2505   return info->key_defined
2506       || lodepng_is_alpha_type(info)
2507       || lodepng_has_palette_alpha(info);
2508 }
2509 
lodepng_get_raw_size_lct(unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)2510 size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) {
2511   size_t bpp = lodepng_get_bpp_lct(colortype, bitdepth);
2512   size_t n = (size_t)w * (size_t)h;
2513   return ((n / 8u) * bpp) + ((n & 7u) * bpp + 7u) / 8u;
2514 }
2515 
lodepng_get_raw_size(unsigned w,unsigned h,const LodePNGColorMode * color)2516 size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color) {
2517   return lodepng_get_raw_size_lct(w, h, color->colortype, color->bitdepth);
2518 }
2519 
2520 
2521 #ifdef LODEPNG_COMPILE_PNG
2522 #ifdef LODEPNG_COMPILE_DECODER
2523 
2524 /*in an idat chunk, each scanline is a multiple of 8 bits, unlike the lodepng output buffer,
2525 and in addition has one extra byte per line: the filter byte. So this gives a larger
2526 result than lodepng_get_raw_size. */
lodepng_get_raw_size_idat(unsigned w,unsigned h,const LodePNGColorMode * color)2527 static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, const LodePNGColorMode* color) {
2528   size_t bpp = lodepng_get_bpp(color);
2529   /* + 1 for the filter byte, and possibly plus padding bits per line */
2530   size_t line = ((size_t)(w / 8u) * bpp) + 1u + ((w & 7u) * bpp + 7u) / 8u;
2531   return (size_t)h * line;
2532 }
2533 
2534 /* Safely check if multiplying two integers will overflow (no undefined
2535 behavior, compiler removing the code, etc...) and output result. */
lodepng_mulofl(size_t a,size_t b,size_t * result)2536 static int lodepng_mulofl(size_t a, size_t b, size_t* result) {
2537   *result = a * b; /* Unsigned multiplication is well defined and safe in C90 */
2538   return (a != 0 && *result / a != b);
2539 }
2540 
2541 /* Safely check if adding two integers will overflow (no undefined
2542 behavior, compiler removing the code, etc...) and output result. */
lodepng_addofl(size_t a,size_t b,size_t * result)2543 static int lodepng_addofl(size_t a, size_t b, size_t* result) {
2544   *result = a + b; /* Unsigned addition is well defined and safe in C90 */
2545   return *result < a;
2546 }
2547 
2548 /*Safely checks whether size_t overflow can be caused due to amount of pixels.
2549 This check is overcautious rather than precise. If this check indicates no overflow,
2550 you can safely compute in a size_t (but not an unsigned):
2551 -(size_t)w * (size_t)h * 8
2552 -amount of bytes in IDAT (including filter, padding and Adam7 bytes)
2553 -amount of bytes in raw color model
2554 Returns 1 if overflow possible, 0 if not.
2555 */
lodepng_pixel_overflow(unsigned w,unsigned h,const LodePNGColorMode * pngcolor,const LodePNGColorMode * rawcolor)2556 static int lodepng_pixel_overflow(unsigned w, unsigned h,
2557                                   const LodePNGColorMode* pngcolor, const LodePNGColorMode* rawcolor) {
2558   size_t bpp = LODEPNG_MAX(lodepng_get_bpp(pngcolor), lodepng_get_bpp(rawcolor));
2559   size_t numpixels, total;
2560   size_t line; /* bytes per line in worst case */
2561 
2562   if(lodepng_mulofl((size_t)w, (size_t)h, &numpixels)) return 1;
2563   if(lodepng_mulofl(numpixels, 8, &total)) return 1; /* bit pointer with 8-bit color, or 8 bytes per channel color */
2564 
2565   /* Bytes per scanline with the expression "(w / 8u) * bpp) + ((w & 7u) * bpp + 7u) / 8u" */
2566   if(lodepng_mulofl((size_t)(w / 8u), bpp, &line)) return 1;
2567   if(lodepng_addofl(line, ((w & 7u) * bpp + 7u) / 8u, &line)) return 1;
2568 
2569   if(lodepng_addofl(line, 5, &line)) return 1; /* 5 bytes overhead per line: 1 filterbyte, 4 for Adam7 worst case */
2570   if(lodepng_mulofl(line, h, &total)) return 1; /* Total bytes in worst case */
2571 
2572   return 0; /* no overflow */
2573 }
2574 #endif /*LODEPNG_COMPILE_DECODER*/
2575 #endif /*LODEPNG_COMPILE_PNG*/
2576 
2577 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
2578 
LodePNGUnknownChunks_init(LodePNGInfo * info)2579 static void LodePNGUnknownChunks_init(LodePNGInfo* info) {
2580   unsigned i;
2581   for(i = 0; i != 3; ++i) info->unknown_chunks_data[i] = 0;
2582   for(i = 0; i != 3; ++i) info->unknown_chunks_size[i] = 0;
2583 }
2584 
LodePNGUnknownChunks_cleanup(LodePNGInfo * info)2585 static void LodePNGUnknownChunks_cleanup(LodePNGInfo* info) {
2586   unsigned i;
2587   for(i = 0; i != 3; ++i) lodepng_free(info->unknown_chunks_data[i]);
2588 }
2589 
LodePNGUnknownChunks_copy(LodePNGInfo * dest,const LodePNGInfo * src)2590 static unsigned LodePNGUnknownChunks_copy(LodePNGInfo* dest, const LodePNGInfo* src) {
2591   unsigned i;
2592 
2593   LodePNGUnknownChunks_cleanup(dest);
2594 
2595   for(i = 0; i != 3; ++i) {
2596     size_t j;
2597     dest->unknown_chunks_size[i] = src->unknown_chunks_size[i];
2598     dest->unknown_chunks_data[i] = (unsigned char*)lodepng_malloc(src->unknown_chunks_size[i]);
2599     if(!dest->unknown_chunks_data[i] && dest->unknown_chunks_size[i]) return 83; /*alloc fail*/
2600     for(j = 0; j < src->unknown_chunks_size[i]; ++j) {
2601       dest->unknown_chunks_data[i][j] = src->unknown_chunks_data[i][j];
2602     }
2603   }
2604 
2605   return 0;
2606 }
2607 
2608 /******************************************************************************/
2609 
LodePNGText_init(LodePNGInfo * info)2610 static void LodePNGText_init(LodePNGInfo* info) {
2611   info->text_num = 0;
2612   info->text_keys = NULL;
2613   info->text_strings = NULL;
2614 }
2615 
LodePNGText_cleanup(LodePNGInfo * info)2616 static void LodePNGText_cleanup(LodePNGInfo* info) {
2617   size_t i;
2618   for(i = 0; i != info->text_num; ++i) {
2619     string_cleanup(&info->text_keys[i]);
2620     string_cleanup(&info->text_strings[i]);
2621   }
2622   lodepng_free(info->text_keys);
2623   lodepng_free(info->text_strings);
2624 }
2625 
LodePNGText_copy(LodePNGInfo * dest,const LodePNGInfo * source)2626 static unsigned LodePNGText_copy(LodePNGInfo* dest, const LodePNGInfo* source) {
2627   size_t i = 0;
2628   dest->text_keys = 0;
2629   dest->text_strings = 0;
2630   dest->text_num = 0;
2631   for(i = 0; i != source->text_num; ++i) {
2632     CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i]));
2633   }
2634   return 0;
2635 }
2636 
lodepng_clear_text(LodePNGInfo * info)2637 void lodepng_clear_text(LodePNGInfo* info) {
2638   LodePNGText_cleanup(info);
2639 }
2640 
lodepng_add_text(LodePNGInfo * info,const char * key,const char * str)2641 unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str) {
2642   char** new_keys = (char**)(lodepng_realloc(info->text_keys, sizeof(char*) * (info->text_num + 1)));
2643   char** new_strings = (char**)(lodepng_realloc(info->text_strings, sizeof(char*) * (info->text_num + 1)));
2644   if(!new_keys || !new_strings) {
2645     lodepng_free(new_keys);
2646     lodepng_free(new_strings);
2647     return 83; /*alloc fail*/
2648   }
2649 
2650   ++info->text_num;
2651   info->text_keys = new_keys;
2652   info->text_strings = new_strings;
2653 
2654   info->text_keys[info->text_num - 1] = alloc_string(key);
2655   info->text_strings[info->text_num - 1] = alloc_string(str);
2656 
2657   return 0;
2658 }
2659 
2660 /******************************************************************************/
2661 
LodePNGIText_init(LodePNGInfo * info)2662 static void LodePNGIText_init(LodePNGInfo* info) {
2663   info->itext_num = 0;
2664   info->itext_keys = NULL;
2665   info->itext_langtags = NULL;
2666   info->itext_transkeys = NULL;
2667   info->itext_strings = NULL;
2668 }
2669 
LodePNGIText_cleanup(LodePNGInfo * info)2670 static void LodePNGIText_cleanup(LodePNGInfo* info) {
2671   size_t i;
2672   for(i = 0; i != info->itext_num; ++i) {
2673     string_cleanup(&info->itext_keys[i]);
2674     string_cleanup(&info->itext_langtags[i]);
2675     string_cleanup(&info->itext_transkeys[i]);
2676     string_cleanup(&info->itext_strings[i]);
2677   }
2678   lodepng_free(info->itext_keys);
2679   lodepng_free(info->itext_langtags);
2680   lodepng_free(info->itext_transkeys);
2681   lodepng_free(info->itext_strings);
2682 }
2683 
LodePNGIText_copy(LodePNGInfo * dest,const LodePNGInfo * source)2684 static unsigned LodePNGIText_copy(LodePNGInfo* dest, const LodePNGInfo* source) {
2685   size_t i = 0;
2686   dest->itext_keys = 0;
2687   dest->itext_langtags = 0;
2688   dest->itext_transkeys = 0;
2689   dest->itext_strings = 0;
2690   dest->itext_num = 0;
2691   for(i = 0; i != source->itext_num; ++i) {
2692     CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i],
2693                                         source->itext_transkeys[i], source->itext_strings[i]));
2694   }
2695   return 0;
2696 }
2697 
lodepng_clear_itext(LodePNGInfo * info)2698 void lodepng_clear_itext(LodePNGInfo* info) {
2699   LodePNGIText_cleanup(info);
2700 }
2701 
lodepng_add_itext(LodePNGInfo * info,const char * key,const char * langtag,const char * transkey,const char * str)2702 unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag,
2703                            const char* transkey, const char* str) {
2704   char** new_keys = (char**)(lodepng_realloc(info->itext_keys, sizeof(char*) * (info->itext_num + 1)));
2705   char** new_langtags = (char**)(lodepng_realloc(info->itext_langtags, sizeof(char*) * (info->itext_num + 1)));
2706   char** new_transkeys = (char**)(lodepng_realloc(info->itext_transkeys, sizeof(char*) * (info->itext_num + 1)));
2707   char** new_strings = (char**)(lodepng_realloc(info->itext_strings, sizeof(char*) * (info->itext_num + 1)));
2708   if(!new_keys || !new_langtags || !new_transkeys || !new_strings) {
2709     lodepng_free(new_keys);
2710     lodepng_free(new_langtags);
2711     lodepng_free(new_transkeys);
2712     lodepng_free(new_strings);
2713     return 83; /*alloc fail*/
2714   }
2715 
2716   ++info->itext_num;
2717   info->itext_keys = new_keys;
2718   info->itext_langtags = new_langtags;
2719   info->itext_transkeys = new_transkeys;
2720   info->itext_strings = new_strings;
2721 
2722   info->itext_keys[info->itext_num - 1] = alloc_string(key);
2723   info->itext_langtags[info->itext_num - 1] = alloc_string(langtag);
2724   info->itext_transkeys[info->itext_num - 1] = alloc_string(transkey);
2725   info->itext_strings[info->itext_num - 1] = alloc_string(str);
2726 
2727   return 0;
2728 }
2729 
2730 /* same as set but does not delete */
lodepng_assign_icc(LodePNGInfo * info,const char * name,const unsigned char * profile,unsigned profile_size)2731 static unsigned lodepng_assign_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size) {
2732   info->iccp_name = alloc_string(name);
2733   info->iccp_profile = (unsigned char*)lodepng_malloc(profile_size);
2734 
2735   if(!info->iccp_name || !info->iccp_profile) return 83; /*alloc fail*/
2736 
2737   lodepng_memcpy(info->iccp_profile, profile, profile_size);
2738   info->iccp_profile_size = profile_size;
2739 
2740   return 0; /*ok*/
2741 }
2742 
lodepng_set_icc(LodePNGInfo * info,const char * name,const unsigned char * profile,unsigned profile_size)2743 unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size) {
2744   if(info->iccp_name) lodepng_clear_icc(info);
2745   info->iccp_defined = 1;
2746 
2747   return lodepng_assign_icc(info, name, profile, profile_size);
2748 }
2749 
lodepng_clear_icc(LodePNGInfo * info)2750 void lodepng_clear_icc(LodePNGInfo* info) {
2751   string_cleanup(&info->iccp_name);
2752   lodepng_free(info->iccp_profile);
2753   info->iccp_profile = NULL;
2754   info->iccp_profile_size = 0;
2755   info->iccp_defined = 0;
2756 }
2757 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
2758 
lodepng_info_init(LodePNGInfo * info)2759 void lodepng_info_init(LodePNGInfo* info) {
2760   lodepng_color_mode_init(&info->color);
2761   info->interlace_method = 0;
2762   info->compression_method = 0;
2763   info->filter_method = 0;
2764 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
2765   info->background_defined = 0;
2766   info->background_r = info->background_g = info->background_b = 0;
2767 
2768   LodePNGText_init(info);
2769   LodePNGIText_init(info);
2770 
2771   info->time_defined = 0;
2772   info->phys_defined = 0;
2773 
2774   info->gama_defined = 0;
2775   info->chrm_defined = 0;
2776   info->srgb_defined = 0;
2777   info->iccp_defined = 0;
2778   info->iccp_name = NULL;
2779   info->iccp_profile = NULL;
2780 
2781   LodePNGUnknownChunks_init(info);
2782 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
2783 }
2784 
lodepng_info_cleanup(LodePNGInfo * info)2785 void lodepng_info_cleanup(LodePNGInfo* info) {
2786   lodepng_color_mode_cleanup(&info->color);
2787 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
2788   LodePNGText_cleanup(info);
2789   LodePNGIText_cleanup(info);
2790 
2791   lodepng_clear_icc(info);
2792 
2793   LodePNGUnknownChunks_cleanup(info);
2794 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
2795 }
2796 
lodepng_info_copy(LodePNGInfo * dest,const LodePNGInfo * source)2797 unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source) {
2798   lodepng_info_cleanup(dest);
2799   *dest = *source;
2800   lodepng_color_mode_init(&dest->color);
2801   CERROR_TRY_RETURN(lodepng_color_mode_copy(&dest->color, &source->color));
2802 
2803 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
2804   CERROR_TRY_RETURN(LodePNGText_copy(dest, source));
2805   CERROR_TRY_RETURN(LodePNGIText_copy(dest, source));
2806   if(source->iccp_defined) {
2807     CERROR_TRY_RETURN(lodepng_assign_icc(dest, source->iccp_name, source->iccp_profile, source->iccp_profile_size));
2808   }
2809 
2810   LodePNGUnknownChunks_init(dest);
2811   CERROR_TRY_RETURN(LodePNGUnknownChunks_copy(dest, source));
2812 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
2813   return 0;
2814 }
2815 
2816 /* ////////////////////////////////////////////////////////////////////////// */
2817 
2818 /*index: bitgroup index, bits: bitgroup size(1, 2 or 4), in: bitgroup value, out: octet array to add bits to*/
addColorBits(unsigned char * out,size_t index,unsigned bits,unsigned in)2819 static void addColorBits(unsigned char* out, size_t index, unsigned bits, unsigned in) {
2820   unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1; /*8 / bits - 1*/
2821   /*p = the partial index in the byte, e.g. with 4 palettebits it is 0 for first half or 1 for second half*/
2822   unsigned p = index & m;
2823   in &= (1u << bits) - 1u; /*filter out any other bits of the input value*/
2824   in = in << (bits * (m - p));
2825   if(p == 0) out[index * bits / 8u] = in;
2826   else out[index * bits / 8u] |= in;
2827 }
2828 
2829 typedef struct ColorTree ColorTree;
2830 
2831 /*
2832 One node of a color tree
2833 This is the data structure used to count the number of unique colors and to get a palette
2834 index for a color. It's like an octree, but because the alpha channel is used too, each
2835 node has 16 instead of 8 children.
2836 */
2837 struct ColorTree {
2838   ColorTree* children[16]; /*up to 16 pointers to ColorTree of next level*/
2839   int index; /*the payload. Only has a meaningful value if this is in the last level*/
2840 };
2841 
color_tree_init(ColorTree * tree)2842 static void color_tree_init(ColorTree* tree) {
2843   int i;
2844   for(i = 0; i != 16; ++i) tree->children[i] = 0;
2845   tree->index = -1;
2846 }
2847 
color_tree_cleanup(ColorTree * tree)2848 static void color_tree_cleanup(ColorTree* tree) {
2849   int i;
2850   for(i = 0; i != 16; ++i) {
2851     if(tree->children[i]) {
2852       color_tree_cleanup(tree->children[i]);
2853       lodepng_free(tree->children[i]);
2854     }
2855   }
2856 }
2857 
2858 /*returns -1 if color not present, its index otherwise*/
color_tree_get(ColorTree * tree,unsigned char r,unsigned char g,unsigned char b,unsigned char a)2859 static int color_tree_get(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
2860   int bit = 0;
2861   for(bit = 0; bit < 8; ++bit) {
2862     int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1);
2863     if(!tree->children[i]) return -1;
2864     else tree = tree->children[i];
2865   }
2866   return tree ? tree->index : -1;
2867 }
2868 
2869 #ifdef LODEPNG_COMPILE_ENCODER
color_tree_has(ColorTree * tree,unsigned char r,unsigned char g,unsigned char b,unsigned char a)2870 static int color_tree_has(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
2871   return color_tree_get(tree, r, g, b, a) >= 0;
2872 }
2873 #endif /*LODEPNG_COMPILE_ENCODER*/
2874 
2875 /*color is not allowed to already exist.
2876 Index should be >= 0 (it's signed to be compatible with using -1 for "doesn't exist")*/
color_tree_add(ColorTree * tree,unsigned char r,unsigned char g,unsigned char b,unsigned char a,unsigned index)2877 static void color_tree_add(ColorTree* tree,
2878                            unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned index) {
2879   int bit;
2880   for(bit = 0; bit < 8; ++bit) {
2881     int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1);
2882     if(!tree->children[i]) {
2883       tree->children[i] = (ColorTree*)lodepng_malloc(sizeof(ColorTree));
2884       color_tree_init(tree->children[i]);
2885     }
2886     tree = tree->children[i];
2887   }
2888   tree->index = (int)index;
2889 }
2890 
2891 /*put a pixel, given its RGBA color, into image of any color type*/
rgba8ToPixel(unsigned char * out,size_t i,const LodePNGColorMode * mode,ColorTree * tree,unsigned char r,unsigned char g,unsigned char b,unsigned char a)2892 static unsigned rgba8ToPixel(unsigned char* out, size_t i,
2893                              const LodePNGColorMode* mode, ColorTree* tree /*for palette*/,
2894                              unsigned char r, unsigned char g, unsigned char b, unsigned char a) {
2895   if(mode->colortype == LCT_GREY) {
2896     unsigned char gray = r; /*((unsigned short)r + g + b) / 3u;*/
2897     if(mode->bitdepth == 8) out[i] = gray;
2898     else if(mode->bitdepth == 16) out[i * 2 + 0] = out[i * 2 + 1] = gray;
2899     else {
2900       /*take the most significant bits of gray*/
2901       gray = (gray >> (8 - mode->bitdepth)) & ((1 << mode->bitdepth) - 1);
2902       addColorBits(out, i, mode->bitdepth, gray);
2903     }
2904   } else if(mode->colortype == LCT_RGB) {
2905     if(mode->bitdepth == 8) {
2906       out[i * 3 + 0] = r;
2907       out[i * 3 + 1] = g;
2908       out[i * 3 + 2] = b;
2909     } else {
2910       out[i * 6 + 0] = out[i * 6 + 1] = r;
2911       out[i * 6 + 2] = out[i * 6 + 3] = g;
2912       out[i * 6 + 4] = out[i * 6 + 5] = b;
2913     }
2914   } else if(mode->colortype == LCT_PALETTE) {
2915     int index = color_tree_get(tree, r, g, b, a);
2916     if(index < 0) return 82; /*color not in palette*/
2917     if(mode->bitdepth == 8) out[i] = index;
2918     else addColorBits(out, i, mode->bitdepth, (unsigned)index);
2919   } else if(mode->colortype == LCT_GREY_ALPHA) {
2920     unsigned char gray = r; /*((unsigned short)r + g + b) / 3u;*/
2921     if(mode->bitdepth == 8) {
2922       out[i * 2 + 0] = gray;
2923       out[i * 2 + 1] = a;
2924     } else if(mode->bitdepth == 16) {
2925       out[i * 4 + 0] = out[i * 4 + 1] = gray;
2926       out[i * 4 + 2] = out[i * 4 + 3] = a;
2927     }
2928   } else if(mode->colortype == LCT_RGBA) {
2929     if(mode->bitdepth == 8) {
2930       out[i * 4 + 0] = r;
2931       out[i * 4 + 1] = g;
2932       out[i * 4 + 2] = b;
2933       out[i * 4 + 3] = a;
2934     } else {
2935       out[i * 8 + 0] = out[i * 8 + 1] = r;
2936       out[i * 8 + 2] = out[i * 8 + 3] = g;
2937       out[i * 8 + 4] = out[i * 8 + 5] = b;
2938       out[i * 8 + 6] = out[i * 8 + 7] = a;
2939     }
2940   }
2941 
2942   return 0; /*no error*/
2943 }
2944 
2945 /*put a pixel, given its RGBA16 color, into image of any color 16-bitdepth type*/
rgba16ToPixel(unsigned char * out,size_t i,const LodePNGColorMode * mode,unsigned short r,unsigned short g,unsigned short b,unsigned short a)2946 static void rgba16ToPixel(unsigned char* out, size_t i,
2947                          const LodePNGColorMode* mode,
2948                          unsigned short r, unsigned short g, unsigned short b, unsigned short a) {
2949   if(mode->colortype == LCT_GREY) {
2950     unsigned short gray = r; /*((unsigned)r + g + b) / 3u;*/
2951     out[i * 2 + 0] = (gray >> 8) & 255;
2952     out[i * 2 + 1] = gray & 255;
2953   } else if(mode->colortype == LCT_RGB) {
2954     out[i * 6 + 0] = (r >> 8) & 255;
2955     out[i * 6 + 1] = r & 255;
2956     out[i * 6 + 2] = (g >> 8) & 255;
2957     out[i * 6 + 3] = g & 255;
2958     out[i * 6 + 4] = (b >> 8) & 255;
2959     out[i * 6 + 5] = b & 255;
2960   } else if(mode->colortype == LCT_GREY_ALPHA) {
2961     unsigned short gray = r; /*((unsigned)r + g + b) / 3u;*/
2962     out[i * 4 + 0] = (gray >> 8) & 255;
2963     out[i * 4 + 1] = gray & 255;
2964     out[i * 4 + 2] = (a >> 8) & 255;
2965     out[i * 4 + 3] = a & 255;
2966   } else if(mode->colortype == LCT_RGBA) {
2967     out[i * 8 + 0] = (r >> 8) & 255;
2968     out[i * 8 + 1] = r & 255;
2969     out[i * 8 + 2] = (g >> 8) & 255;
2970     out[i * 8 + 3] = g & 255;
2971     out[i * 8 + 4] = (b >> 8) & 255;
2972     out[i * 8 + 5] = b & 255;
2973     out[i * 8 + 6] = (a >> 8) & 255;
2974     out[i * 8 + 7] = a & 255;
2975   }
2976 }
2977 
2978 /*Get RGBA8 color of pixel with index i (y * width + x) from the raw image with given color type.*/
getPixelColorRGBA8(unsigned char * r,unsigned char * g,unsigned char * b,unsigned char * a,const unsigned char * in,size_t i,const LodePNGColorMode * mode)2979 static void getPixelColorRGBA8(unsigned char* r, unsigned char* g,
2980                                unsigned char* b, unsigned char* a,
2981                                const unsigned char* in, size_t i,
2982                                const LodePNGColorMode* mode) {
2983   if(mode->colortype == LCT_GREY) {
2984     if(mode->bitdepth == 8) {
2985       *r = *g = *b = in[i];
2986       if(mode->key_defined && *r == mode->key_r) *a = 0;
2987       else *a = 255;
2988     } else if(mode->bitdepth == 16) {
2989       *r = *g = *b = in[i * 2 + 0];
2990       if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0;
2991       else *a = 255;
2992     } else {
2993       unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/
2994       size_t j = i * mode->bitdepth;
2995       unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth);
2996       *r = *g = *b = (value * 255) / highest;
2997       if(mode->key_defined && value == mode->key_r) *a = 0;
2998       else *a = 255;
2999     }
3000   } else if(mode->colortype == LCT_RGB) {
3001     if(mode->bitdepth == 8) {
3002       *r = in[i * 3 + 0]; *g = in[i * 3 + 1]; *b = in[i * 3 + 2];
3003       if(mode->key_defined && *r == mode->key_r && *g == mode->key_g && *b == mode->key_b) *a = 0;
3004       else *a = 255;
3005     } else {
3006       *r = in[i * 6 + 0];
3007       *g = in[i * 6 + 2];
3008       *b = in[i * 6 + 4];
3009       if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r
3010          && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g
3011          && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0;
3012       else *a = 255;
3013     }
3014   } else if(mode->colortype == LCT_PALETTE) {
3015     unsigned index;
3016     if(mode->bitdepth == 8) index = in[i];
3017     else {
3018       size_t j = i * mode->bitdepth;
3019       index = readBitsFromReversedStream(&j, in, mode->bitdepth);
3020     }
3021 
3022     if(index >= mode->palettesize) {
3023       /*This is an error according to the PNG spec, but common PNG decoders make it black instead.
3024       Done here too, slightly faster due to no error handling needed.*/
3025       *r = *g = *b = 0;
3026       *a = 255;
3027     } else {
3028       *r = mode->palette[index * 4 + 0];
3029       *g = mode->palette[index * 4 + 1];
3030       *b = mode->palette[index * 4 + 2];
3031       *a = mode->palette[index * 4 + 3];
3032     }
3033   } else if(mode->colortype == LCT_GREY_ALPHA) {
3034     if(mode->bitdepth == 8) {
3035       *r = *g = *b = in[i * 2 + 0];
3036       *a = in[i * 2 + 1];
3037     } else {
3038       *r = *g = *b = in[i * 4 + 0];
3039       *a = in[i * 4 + 2];
3040     }
3041   } else if(mode->colortype == LCT_RGBA) {
3042     if(mode->bitdepth == 8) {
3043       *r = in[i * 4 + 0];
3044       *g = in[i * 4 + 1];
3045       *b = in[i * 4 + 2];
3046       *a = in[i * 4 + 3];
3047     } else {
3048       *r = in[i * 8 + 0];
3049       *g = in[i * 8 + 2];
3050       *b = in[i * 8 + 4];
3051       *a = in[i * 8 + 6];
3052     }
3053   }
3054 }
3055 
3056 /*Similar to getPixelColorRGBA8, but with all the for loops inside of the color
3057 mode test cases, optimized to convert the colors much faster, when converting
3058 to RGBA or RGB with 8 bit per cannel. buffer must be RGBA or RGB output with
3059 enough memory, if has_alpha is true the output is RGBA. mode has the color mode
3060 of the input buffer.*/
getPixelColorsRGBA8(unsigned char * buffer,size_t numpixels,unsigned has_alpha,const unsigned char * in,const LodePNGColorMode * mode)3061 static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels,
3062                                 unsigned has_alpha, const unsigned char* in,
3063                                 const LodePNGColorMode* mode) {
3064   unsigned num_channels = has_alpha ? 4 : 3;
3065   size_t i;
3066   if(mode->colortype == LCT_GREY) {
3067     if(mode->bitdepth == 8) {
3068       for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3069         buffer[0] = buffer[1] = buffer[2] = in[i];
3070         if(has_alpha) buffer[3] = mode->key_defined && in[i] == mode->key_r ? 0 : 255;
3071       }
3072     } else if(mode->bitdepth == 16) {
3073       for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3074         buffer[0] = buffer[1] = buffer[2] = in[i * 2];
3075         if(has_alpha) buffer[3] = mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r ? 0 : 255;
3076       }
3077     } else {
3078       unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/
3079       size_t j = 0;
3080       for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3081         unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth);
3082         buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest;
3083         if(has_alpha) buffer[3] = mode->key_defined && value == mode->key_r ? 0 : 255;
3084       }
3085     }
3086   } else if(mode->colortype == LCT_RGB) {
3087     if(mode->bitdepth == 8) {
3088       for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3089         buffer[0] = in[i * 3 + 0];
3090         buffer[1] = in[i * 3 + 1];
3091         buffer[2] = in[i * 3 + 2];
3092         if(has_alpha) buffer[3] = mode->key_defined && buffer[0] == mode->key_r
3093            && buffer[1]== mode->key_g && buffer[2] == mode->key_b ? 0 : 255;
3094       }
3095     } else {
3096       for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3097         buffer[0] = in[i * 6 + 0];
3098         buffer[1] = in[i * 6 + 2];
3099         buffer[2] = in[i * 6 + 4];
3100         if(has_alpha) buffer[3] = mode->key_defined
3101            && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r
3102            && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g
3103            && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b ? 0 : 255;
3104       }
3105     }
3106   } else if(mode->colortype == LCT_PALETTE) {
3107     unsigned index;
3108     size_t j = 0;
3109     for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3110       if(mode->bitdepth == 8) index = in[i];
3111       else index = readBitsFromReversedStream(&j, in, mode->bitdepth);
3112 
3113       if(index >= mode->palettesize) {
3114         /*This is an error according to the PNG spec, but most PNG decoders make it black instead.
3115         Done here too, slightly faster due to no error handling needed.*/
3116         buffer[0] = buffer[1] = buffer[2] = 0;
3117         if(has_alpha) buffer[3] = 255;
3118       } else {
3119         buffer[0] = mode->palette[index * 4 + 0];
3120         buffer[1] = mode->palette[index * 4 + 1];
3121         buffer[2] = mode->palette[index * 4 + 2];
3122         if(has_alpha) buffer[3] = mode->palette[index * 4 + 3];
3123       }
3124     }
3125   } else if(mode->colortype == LCT_GREY_ALPHA) {
3126     if(mode->bitdepth == 8) {
3127       for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3128         buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0];
3129         if(has_alpha) buffer[3] = in[i * 2 + 1];
3130       }
3131     } else {
3132       for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3133         buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0];
3134         if(has_alpha) buffer[3] = in[i * 4 + 2];
3135       }
3136     }
3137   } else if(mode->colortype == LCT_RGBA) {
3138     if(mode->bitdepth == 8) {
3139       for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3140         buffer[0] = in[i * 4 + 0];
3141         buffer[1] = in[i * 4 + 1];
3142         buffer[2] = in[i * 4 + 2];
3143         if(has_alpha) buffer[3] = in[i * 4 + 3];
3144       }
3145     } else {
3146       for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3147         buffer[0] = in[i * 8 + 0];
3148         buffer[1] = in[i * 8 + 2];
3149         buffer[2] = in[i * 8 + 4];
3150         if(has_alpha) buffer[3] = in[i * 8 + 6];
3151       }
3152     }
3153   }
3154 }
3155 
3156 /*Get RGBA16 color of pixel with index i (y * width + x) from the raw image with
3157 given color type, but the given color type must be 16-bit itself.*/
getPixelColorRGBA16(unsigned short * r,unsigned short * g,unsigned short * b,unsigned short * a,const unsigned char * in,size_t i,const LodePNGColorMode * mode)3158 static void getPixelColorRGBA16(unsigned short* r, unsigned short* g, unsigned short* b, unsigned short* a,
3159                                 const unsigned char* in, size_t i, const LodePNGColorMode* mode) {
3160   if(mode->colortype == LCT_GREY) {
3161     *r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1];
3162     if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0;
3163     else *a = 65535;
3164   } else if(mode->colortype == LCT_RGB) {
3165     *r = 256u * in[i * 6 + 0] + in[i * 6 + 1];
3166     *g = 256u * in[i * 6 + 2] + in[i * 6 + 3];
3167     *b = 256u * in[i * 6 + 4] + in[i * 6 + 5];
3168     if(mode->key_defined
3169        && 256u * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r
3170        && 256u * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g
3171        && 256u * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0;
3172     else *a = 65535;
3173   } else if(mode->colortype == LCT_GREY_ALPHA) {
3174     *r = *g = *b = 256u * in[i * 4 + 0] + in[i * 4 + 1];
3175     *a = 256u * in[i * 4 + 2] + in[i * 4 + 3];
3176   } else if(mode->colortype == LCT_RGBA) {
3177     *r = 256u * in[i * 8 + 0] + in[i * 8 + 1];
3178     *g = 256u * in[i * 8 + 2] + in[i * 8 + 3];
3179     *b = 256u * in[i * 8 + 4] + in[i * 8 + 5];
3180     *a = 256u * in[i * 8 + 6] + in[i * 8 + 7];
3181   }
3182 }
3183 
lodepng_convert(unsigned char * out,const unsigned char * in,const LodePNGColorMode * mode_out,const LodePNGColorMode * mode_in,unsigned w,unsigned h)3184 unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
3185                          const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in,
3186                          unsigned w, unsigned h) {
3187   size_t i;
3188   ColorTree tree;
3189   size_t numpixels = (size_t)w * (size_t)h;
3190   unsigned error = 0;
3191 
3192   if(lodepng_color_mode_equal(mode_out, mode_in)) {
3193     size_t numbytes = lodepng_get_raw_size(w, h, mode_in);
3194     for(i = 0; i != numbytes; ++i) out[i] = in[i];
3195     return 0;
3196   }
3197 
3198   if(mode_out->colortype == LCT_PALETTE) {
3199     size_t palettesize = mode_out->palettesize;
3200     const unsigned char* palette = mode_out->palette;
3201     size_t palsize = (size_t)1u << mode_out->bitdepth;
3202     /*if the user specified output palette but did not give the values, assume
3203     they want the values of the input color type (assuming that one is palette).
3204     Note that we never create a new palette ourselves.*/
3205     if(palettesize == 0) {
3206       palettesize = mode_in->palettesize;
3207       palette = mode_in->palette;
3208       /*if the input was also palette with same bitdepth, then the color types are also
3209       equal, so copy literally. This to preserve the exact indices that were in the PNG
3210       even in case there are duplicate colors in the palette.*/
3211       if (mode_in->colortype == LCT_PALETTE && mode_in->bitdepth == mode_out->bitdepth) {
3212         size_t numbytes = lodepng_get_raw_size(w, h, mode_in);
3213         for(i = 0; i != numbytes; ++i) out[i] = in[i];
3214         return 0;
3215       }
3216     }
3217     if(palettesize < palsize) palsize = palettesize;
3218     color_tree_init(&tree);
3219     for(i = 0; i != palsize; ++i) {
3220       const unsigned char* p = &palette[i * 4];
3221       color_tree_add(&tree, p[0], p[1], p[2], p[3], (unsigned)i);
3222     }
3223   }
3224 
3225   if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16) {
3226     for(i = 0; i != numpixels; ++i) {
3227       unsigned short r = 0, g = 0, b = 0, a = 0;
3228       getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
3229       rgba16ToPixel(out, i, mode_out, r, g, b, a);
3230     }
3231   } else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA) {
3232     getPixelColorsRGBA8(out, numpixels, 1, in, mode_in);
3233   } else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB) {
3234     getPixelColorsRGBA8(out, numpixels, 0, in, mode_in);
3235   } else {
3236     unsigned char r = 0, g = 0, b = 0, a = 0;
3237     for(i = 0; i != numpixels; ++i) {
3238       getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in);
3239       error = rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a);
3240       if (error) break;
3241     }
3242   }
3243 
3244   if(mode_out->colortype == LCT_PALETTE) {
3245     color_tree_cleanup(&tree);
3246   }
3247 
3248   return error;
3249 }
3250 
3251 
3252 /* Converts a single rgb color without alpha from one type to another, color bits truncated to
3253 their bitdepth. In case of single channel (gray or palette), only the r channel is used. Slow
3254 function, do not use to process all pixels of an image. Alpha channel not supported on purpose:
3255 this is for bKGD, supporting alpha may prevent it from finding a color in the palette, from the
3256 specification it looks like bKGD should ignore the alpha values of the palette since it can use
3257 any palette index but doesn't have an alpha channel. Idem with ignoring color key. */
lodepng_convert_rgb(unsigned * r_out,unsigned * g_out,unsigned * b_out,unsigned r_in,unsigned g_in,unsigned b_in,const LodePNGColorMode * mode_out,const LodePNGColorMode * mode_in)3258 unsigned lodepng_convert_rgb(
3259     unsigned* r_out, unsigned* g_out, unsigned* b_out,
3260     unsigned r_in, unsigned g_in, unsigned b_in,
3261     const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in) {
3262   unsigned r = 0, g = 0, b = 0;
3263   unsigned mul = 65535 / ((1u << mode_in->bitdepth) - 1u); /*65535, 21845, 4369, 257, 1*/
3264   unsigned shift = 16 - mode_out->bitdepth;
3265 
3266   if(mode_in->colortype == LCT_GREY || mode_in->colortype == LCT_GREY_ALPHA) {
3267     r = g = b = r_in * mul;
3268   } else if(mode_in->colortype == LCT_RGB || mode_in->colortype == LCT_RGBA) {
3269     r = r_in * mul;
3270     g = g_in * mul;
3271     b = b_in * mul;
3272   } else if(mode_in->colortype == LCT_PALETTE) {
3273     if(r_in >= mode_in->palettesize) return 82;
3274     r = mode_in->palette[r_in * 4 + 0] * 257u;
3275     g = mode_in->palette[r_in * 4 + 1] * 257u;
3276     b = mode_in->palette[r_in * 4 + 2] * 257u;
3277   } else {
3278     return 31;
3279   }
3280 
3281   /* now convert to output format */
3282   if(mode_out->colortype == LCT_GREY || mode_out->colortype == LCT_GREY_ALPHA) {
3283     *r_out = r >> shift ;
3284   } else if(mode_out->colortype == LCT_RGB || mode_out->colortype == LCT_RGBA) {
3285     *r_out = r >> shift ;
3286     *g_out = g >> shift ;
3287     *b_out = b >> shift ;
3288   } else if(mode_out->colortype == LCT_PALETTE) {
3289     unsigned i;
3290     /* a 16-bit color cannot be in the palette */
3291     if((r >> 8) != (r & 255) || (g >> 8) != (g & 255) || (b >> 8) != (b & 255)) return 82;
3292     for(i = 0; i < mode_out->palettesize; i++) {
3293       unsigned j = i * 4;
3294       if((r >> 8) == mode_out->palette[j + 0] && (g >> 8) == mode_out->palette[j + 1] &&
3295           (b >> 8) == mode_out->palette[j + 2]) {
3296         *r_out = i;
3297         return 0;
3298       }
3299     }
3300     return 82;
3301   } else {
3302     return 31;
3303   }
3304 
3305   return 0;
3306 }
3307 
3308 #ifdef LODEPNG_COMPILE_ENCODER
3309 
lodepng_color_stats_init(LodePNGColorStats * stats)3310 void lodepng_color_stats_init(LodePNGColorStats* stats) {
3311   /*stats*/
3312   stats->colored = 0;
3313   stats->key = 0;
3314   stats->key_r = stats->key_g = stats->key_b = 0;
3315   stats->alpha = 0;
3316   stats->numcolors = 0;
3317   stats->bits = 1;
3318   stats->numpixels = 0;
3319   /*settings*/
3320   stats->allow_palette = 1;
3321   stats->allow_greyscale = 1;
3322 }
3323 
3324 /*function used for debug purposes with C++*/
3325 /*void printColorStats(LodePNGColorStats* p) {
3326   std::cout << "colored: " << (int)p->colored << ", ";
3327   std::cout << "key: " << (int)p->key << ", ";
3328   std::cout << "key_r: " << (int)p->key_r << ", ";
3329   std::cout << "key_g: " << (int)p->key_g << ", ";
3330   std::cout << "key_b: " << (int)p->key_b << ", ";
3331   std::cout << "alpha: " << (int)p->alpha << ", ";
3332   std::cout << "numcolors: " << (int)p->numcolors << ", ";
3333   std::cout << "bits: " << (int)p->bits << std::endl;
3334 }*/
3335 
3336 /*Returns how many bits needed to represent given value (max 8 bit)*/
getValueRequiredBits(unsigned char value)3337 static unsigned getValueRequiredBits(unsigned char value) {
3338   if(value == 0 || value == 255) return 1;
3339   /*The scaling of 2-bit and 4-bit values uses multiples of 85 and 17*/
3340   if(value % 17 == 0) return value % 85 == 0 ? 2 : 4;
3341   return 8;
3342 }
3343 
3344 /*stats must already have been inited. */
lodepng_compute_color_stats(LodePNGColorStats * stats,const unsigned char * in,unsigned w,unsigned h,const LodePNGColorMode * mode_in)3345 void lodepng_compute_color_stats(LodePNGColorStats* stats,
3346                                  const unsigned char* in, unsigned w, unsigned h,
3347                                  const LodePNGColorMode* mode_in) {
3348   size_t i;
3349   ColorTree tree;
3350   size_t numpixels = (size_t)w * (size_t)h;
3351 
3352   /* mark things as done already if it would be impossible to have a more expensive case */
3353   unsigned colored_done = lodepng_is_greyscale_type(mode_in) ? 1 : 0;
3354   unsigned alpha_done = lodepng_can_have_alpha(mode_in) ? 0 : 1;
3355   unsigned numcolors_done = 0;
3356   unsigned bpp = lodepng_get_bpp(mode_in);
3357   unsigned bits_done = (stats->bits == 1 && bpp == 1) ? 1 : 0;
3358   unsigned sixteen = 0; /* whether the input image is 16 bit */
3359   unsigned maxnumcolors = 257;
3360   if(bpp <= 8) maxnumcolors = LODEPNG_MIN(257, stats->numcolors + (1u << bpp));
3361 
3362   stats->numpixels += numpixels;
3363 
3364   /*if palette not allowed, no need to compute numcolors*/
3365   if(!stats->allow_palette) numcolors_done = 1;
3366 
3367   color_tree_init(&tree);
3368 
3369   /*If the stats was already filled in from previous data, fill its palette in tree
3370   and mark things as done already if we know they are the most expensive case already*/
3371   if(stats->alpha) alpha_done = 1;
3372   if(stats->colored) colored_done = 1;
3373   if(stats->bits == 16) numcolors_done = 1;
3374   if(stats->bits >= bpp) bits_done = 1;
3375   if(stats->numcolors >= maxnumcolors) numcolors_done = 1;
3376 
3377   if(!numcolors_done) {
3378     for(i = 0; i < stats->numcolors; i++) {
3379       const unsigned char* color = &stats->palette[i * 4];
3380       color_tree_add(&tree, color[0], color[1], color[2], color[3], i);
3381     }
3382   }
3383 
3384   /*Check if the 16-bit input is truly 16-bit*/
3385   if(mode_in->bitdepth == 16 && !sixteen) {
3386     unsigned short r, g, b, a;
3387     for(i = 0; i != numpixels; ++i) {
3388       getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
3389       if((r & 255) != ((r >> 8) & 255) || (g & 255) != ((g >> 8) & 255) ||
3390          (b & 255) != ((b >> 8) & 255) || (a & 255) != ((a >> 8) & 255)) /*first and second byte differ*/ {
3391         stats->bits = 16;
3392         sixteen = 1;
3393         bits_done = 1;
3394         numcolors_done = 1; /*counting colors no longer useful, palette doesn't support 16-bit*/
3395         break;
3396       }
3397     }
3398   }
3399 
3400   if(sixteen) {
3401     unsigned short r = 0, g = 0, b = 0, a = 0;
3402 
3403     for(i = 0; i != numpixels; ++i) {
3404       getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
3405 
3406       if(!colored_done && (r != g || r != b)) {
3407         stats->colored = 1;
3408         colored_done = 1;
3409       }
3410 
3411       if(!alpha_done) {
3412         unsigned matchkey = (r == stats->key_r && g == stats->key_g && b == stats->key_b);
3413         if(a != 65535 && (a != 0 || (stats->key && !matchkey))) {
3414           stats->alpha = 1;
3415           stats->key = 0;
3416           alpha_done = 1;
3417         } else if(a == 0 && !stats->alpha && !stats->key) {
3418           stats->key = 1;
3419           stats->key_r = r;
3420           stats->key_g = g;
3421           stats->key_b = b;
3422         } else if(a == 65535 && stats->key && matchkey) {
3423           /* Color key cannot be used if an opaque pixel also has that RGB color. */
3424           stats->alpha = 1;
3425           stats->key = 0;
3426           alpha_done = 1;
3427         }
3428       }
3429       if(alpha_done && numcolors_done && colored_done && bits_done) break;
3430     }
3431 
3432     if(stats->key && !stats->alpha) {
3433       for(i = 0; i != numpixels; ++i) {
3434         getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
3435         if(a != 0 && r == stats->key_r && g == stats->key_g && b == stats->key_b) {
3436           /* Color key cannot be used if an opaque pixel also has that RGB color. */
3437           stats->alpha = 1;
3438           stats->key = 0;
3439           alpha_done = 1;
3440         }
3441       }
3442     }
3443   } else /* < 16-bit */ {
3444     unsigned char r = 0, g = 0, b = 0, a = 0;
3445     for(i = 0; i != numpixels; ++i) {
3446       getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in);
3447 
3448       if(!bits_done && stats->bits < 8) {
3449         /*only r is checked, < 8 bits is only relevant for grayscale*/
3450         unsigned bits = getValueRequiredBits(r);
3451         if(bits > stats->bits) stats->bits = bits;
3452       }
3453       bits_done = (stats->bits >= bpp);
3454 
3455       if(!colored_done && (r != g || r != b)) {
3456         stats->colored = 1;
3457         colored_done = 1;
3458         if(stats->bits < 8) stats->bits = 8; /*PNG has no colored modes with less than 8-bit per channel*/
3459       }
3460 
3461       if(!alpha_done) {
3462         unsigned matchkey = (r == stats->key_r && g == stats->key_g && b == stats->key_b);
3463         if(a != 255 && (a != 0 || (stats->key && !matchkey))) {
3464           stats->alpha = 1;
3465           stats->key = 0;
3466           alpha_done = 1;
3467           if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/
3468         } else if(a == 0 && !stats->alpha && !stats->key) {
3469           stats->key = 1;
3470           stats->key_r = r;
3471           stats->key_g = g;
3472           stats->key_b = b;
3473         } else if(a == 255 && stats->key && matchkey) {
3474           /* Color key cannot be used if an opaque pixel also has that RGB color. */
3475           stats->alpha = 1;
3476           stats->key = 0;
3477           alpha_done = 1;
3478           if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/
3479         }
3480       }
3481 
3482       if(!numcolors_done) {
3483         if(!color_tree_has(&tree, r, g, b, a)) {
3484           color_tree_add(&tree, r, g, b, a, stats->numcolors);
3485           if(stats->numcolors < 256) {
3486             unsigned char* p = stats->palette;
3487             unsigned n = stats->numcolors;
3488             p[n * 4 + 0] = r;
3489             p[n * 4 + 1] = g;
3490             p[n * 4 + 2] = b;
3491             p[n * 4 + 3] = a;
3492           }
3493           ++stats->numcolors;
3494           numcolors_done = stats->numcolors >= maxnumcolors;
3495         }
3496       }
3497 
3498       if(alpha_done && numcolors_done && colored_done && bits_done) break;
3499     }
3500 
3501     if(stats->key && !stats->alpha) {
3502       for(i = 0; i != numpixels; ++i) {
3503         getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in);
3504         if(a != 0 && r == stats->key_r && g == stats->key_g && b == stats->key_b) {
3505           /* Color key cannot be used if an opaque pixel also has that RGB color. */
3506           stats->alpha = 1;
3507           stats->key = 0;
3508           alpha_done = 1;
3509           if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/
3510         }
3511       }
3512     }
3513 
3514     /*make the stats's key always 16-bit for consistency - repeat each byte twice*/
3515     stats->key_r += (stats->key_r << 8);
3516     stats->key_g += (stats->key_g << 8);
3517     stats->key_b += (stats->key_b << 8);
3518   }
3519 
3520   color_tree_cleanup(&tree);
3521 }
3522 
3523 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
3524 /*Adds a single color to the color stats. The stats must already have been inited. The color must be given as 16-bit
3525 (with 2 bytes repeating for 8-bit and 65535 for opaque alpha channel). This function is expensive, do not call it for
3526 all pixels of an image but only for a few additional values. */
lodepng_color_stats_add(LodePNGColorStats * stats,unsigned r,unsigned g,unsigned b,unsigned a)3527 static void lodepng_color_stats_add(LodePNGColorStats* stats,
3528                                     unsigned r, unsigned g, unsigned b, unsigned a) {
3529   unsigned char image[8];
3530   LodePNGColorMode mode;
3531   lodepng_color_mode_init(&mode);
3532   image[0] = r >> 8; image[1] = r; image[2] = g >> 8; image[3] = g;
3533   image[4] = b >> 8; image[5] = b; image[6] = a >> 8; image[7] = a;
3534   mode.bitdepth = 16;
3535   mode.colortype = LCT_RGBA;
3536   lodepng_compute_color_stats(stats, image, 1, 1, &mode);
3537   lodepng_color_mode_cleanup(&mode);
3538 }
3539 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
3540 
auto_choose_color(LodePNGColorMode * mode_out,const LodePNGColorMode * mode_in,const LodePNGColorStats * stats)3541 unsigned auto_choose_color(LodePNGColorMode* mode_out,
3542                            const LodePNGColorMode* mode_in,
3543                            const LodePNGColorStats* stats) {
3544   unsigned error = 0;
3545   unsigned palettebits;
3546   size_t i, n;
3547   size_t numpixels = stats->numpixels;
3548   unsigned palette_ok, gray_ok;
3549 
3550   unsigned alpha = stats->alpha;
3551   unsigned key = stats->key;
3552   unsigned bits = stats->bits;
3553 
3554   mode_out->key_defined = 0;
3555 
3556   if(key && numpixels <= 16) {
3557     alpha = 1; /*too few pixels to justify tRNS chunk overhead*/
3558     key = 0;
3559     if(bits < 8) bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/
3560   }
3561 
3562   gray_ok = !stats->colored;
3563   if(!stats->allow_greyscale) gray_ok = 0;
3564   if(!gray_ok && bits < 8) bits = 8;
3565 
3566   n = stats->numcolors;
3567   palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8));
3568   palette_ok = n <= 256 && bits <= 8 && n != 0; /*n==0 means likely numcolors wasn't computed*/
3569   if(numpixels < n * 2) palette_ok = 0; /*don't add palette overhead if image has only a few pixels*/
3570   if(gray_ok && bits <= palettebits) palette_ok = 0; /*gray is less overhead*/
3571   if(!stats->allow_palette) palette_ok = 0;
3572 
3573   if(palette_ok) {
3574     const unsigned char* p = stats->palette;
3575     lodepng_palette_clear(mode_out); /*remove potential earlier palette*/
3576     for(i = 0; i != stats->numcolors; ++i) {
3577       error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]);
3578       if(error) break;
3579     }
3580 
3581     mode_out->colortype = LCT_PALETTE;
3582     mode_out->bitdepth = palettebits;
3583 
3584     if(mode_in->colortype == LCT_PALETTE && mode_in->palettesize >= mode_out->palettesize
3585         && mode_in->bitdepth == mode_out->bitdepth) {
3586       /*If input should have same palette colors, keep original to preserve its order and prevent conversion*/
3587       lodepng_color_mode_cleanup(mode_out);
3588       lodepng_color_mode_copy(mode_out, mode_in);
3589     }
3590   } else /*8-bit or 16-bit per channel*/ {
3591     mode_out->bitdepth = bits;
3592     mode_out->colortype = alpha ? (gray_ok ? LCT_GREY_ALPHA : LCT_RGBA)
3593                                 : (gray_ok ? LCT_GREY : LCT_RGB);
3594     if(key) {
3595       unsigned mask = (1u << mode_out->bitdepth) - 1u; /*stats always uses 16-bit, mask converts it*/
3596       mode_out->key_r = stats->key_r & mask;
3597       mode_out->key_g = stats->key_g & mask;
3598       mode_out->key_b = stats->key_b & mask;
3599       mode_out->key_defined = 1;
3600     }
3601   }
3602 
3603   return error;
3604 }
3605 
3606 #endif /* #ifdef LODEPNG_COMPILE_ENCODER */
3607 
3608 /*
3609 Paeth predicter, used by PNG filter type 4
3610 The parameters are of type short, but should come from unsigned chars, the shorts
3611 are only needed to make the paeth calculation correct.
3612 */
paethPredictor(short a,short b,short c)3613 static unsigned char paethPredictor(short a, short b, short c) {
3614   short pa = LODEPNG_ABS(b - c);
3615   short pb = LODEPNG_ABS(a - c);
3616   short pc = LODEPNG_ABS(a + b - c - c);
3617   /* return input value associated with smallest of pa, pb, pc (with certain priority if equal) */
3618   if(pb < pa) { a = b; pa = pb; }
3619   return (pc < pa) ? c : a;
3620 }
3621 
3622 /*shared values used by multiple Adam7 related functions*/
3623 
3624 static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/
3625 static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/
3626 static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/
3627 static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/
3628 
3629 /*
3630 Outputs various dimensions and positions in the image related to the Adam7 reduced images.
3631 passw: output containing the width of the 7 passes
3632 passh: output containing the height of the 7 passes
3633 filter_passstart: output containing the index of the start and end of each
3634  reduced image with filter bytes
3635 padded_passstart output containing the index of the start and end of each
3636  reduced image when without filter bytes but with padded scanlines
3637 passstart: output containing the index of the start and end of each reduced
3638  image without padding between scanlines, but still padding between the images
3639 w, h: width and height of non-interlaced image
3640 bpp: bits per pixel
3641 "padded" is only relevant if bpp is less than 8 and a scanline or image does not
3642  end at a full byte
3643 */
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)3644 static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8],
3645                                 size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp) {
3646   /*the passstart values have 8 values: the 8th one indicates the byte after the end of the 7th (= last) pass*/
3647   unsigned i;
3648 
3649   /*calculate width and height in pixels of each pass*/
3650   for(i = 0; i != 7; ++i) {
3651     passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i];
3652     passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i];
3653     if(passw[i] == 0) passh[i] = 0;
3654     if(passh[i] == 0) passw[i] = 0;
3655   }
3656 
3657   filter_passstart[0] = padded_passstart[0] = passstart[0] = 0;
3658   for(i = 0; i != 7; ++i) {
3659     /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/
3660     filter_passstart[i + 1] = filter_passstart[i]
3661                             + ((passw[i] && passh[i]) ? passh[i] * (1u + (passw[i] * bpp + 7u) / 8u) : 0);
3662     /*bits padded if needed to fill full byte at end of each scanline*/
3663     padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7u) / 8u);
3664     /*only padded at end of reduced image*/
3665     passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7u) / 8u;
3666   }
3667 }
3668 
3669 #ifdef LODEPNG_COMPILE_DECODER
3670 
3671 /* ////////////////////////////////////////////////////////////////////////// */
3672 /* / PNG Decoder                                                            / */
3673 /* ////////////////////////////////////////////////////////////////////////// */
3674 
3675 /*read the information from the header and store it in the LodePNGInfo. return value is error*/
lodepng_inspect(unsigned * w,unsigned * h,LodePNGState * state,const unsigned char * in,size_t insize)3676 unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state,
3677                          const unsigned char* in, size_t insize) {
3678   unsigned width, height;
3679   LodePNGInfo* info = &state->info_png;
3680   if(insize == 0 || in == 0) {
3681     CERROR_RETURN_ERROR(state->error, 48); /*error: the given data is empty*/
3682   }
3683   if(insize < 33) {
3684     CERROR_RETURN_ERROR(state->error, 27); /*error: the data length is smaller than the length of a PNG header*/
3685   }
3686 
3687   /*when decoding a new PNG image, make sure all parameters created after previous decoding are reset*/
3688   /* TODO: remove this. One should use a new LodePNGState for new sessions */
3689   lodepng_info_cleanup(info);
3690   lodepng_info_init(info);
3691 
3692   if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71
3693      || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) {
3694     CERROR_RETURN_ERROR(state->error, 28); /*error: the first 8 bytes are not the correct PNG signature*/
3695   }
3696   if(lodepng_chunk_length(in + 8) != 13) {
3697     CERROR_RETURN_ERROR(state->error, 94); /*error: header size must be 13 bytes*/
3698   }
3699   if(!lodepng_chunk_type_equals(in + 8, "IHDR")) {
3700     CERROR_RETURN_ERROR(state->error, 29); /*error: it doesn't start with a IHDR chunk!*/
3701   }
3702 
3703   /*read the values given in the header*/
3704   width = lodepng_read32bitInt(&in[16]);
3705   height = lodepng_read32bitInt(&in[20]);
3706   /*TODO: remove the undocumented feature that allows to give null pointers to width or height*/
3707   if(w) *w = width;
3708   if(h) *h = height;
3709   info->color.bitdepth = in[24];
3710   info->color.colortype = (LodePNGColorType)in[25];
3711   info->compression_method = in[26];
3712   info->filter_method = in[27];
3713   info->interlace_method = in[28];
3714 
3715   /*errors returned only after the parsing so other values are still output*/
3716 
3717   /*error: invalid image size*/
3718   if(width == 0 || height == 0) CERROR_RETURN_ERROR(state->error, 93);
3719   /*error: invalid colortype or bitdepth combination*/
3720   state->error = checkColorValidity(info->color.colortype, info->color.bitdepth);
3721   if(state->error) return state->error;
3722   /*error: only compression method 0 is allowed in the specification*/
3723   if(info->compression_method != 0) CERROR_RETURN_ERROR(state->error, 32);
3724   /*error: only filter method 0 is allowed in the specification*/
3725   if(info->filter_method != 0) CERROR_RETURN_ERROR(state->error, 33);
3726   /*error: only interlace methods 0 and 1 exist in the specification*/
3727   if(info->interlace_method > 1) CERROR_RETURN_ERROR(state->error, 34);
3728 
3729   if(!state->decoder.ignore_crc) {
3730     unsigned CRC = lodepng_read32bitInt(&in[29]);
3731     unsigned checksum = lodepng_crc32(&in[12], 17);
3732     if(CRC != checksum) {
3733       CERROR_RETURN_ERROR(state->error, 57); /*invalid CRC*/
3734     }
3735   }
3736 
3737   return state->error;
3738 }
3739 
unfilterScanline(unsigned char * recon,const unsigned char * scanline,const unsigned char * precon,size_t bytewidth,unsigned char filterType,size_t length)3740 static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon,
3741                                  size_t bytewidth, unsigned char filterType, size_t length) {
3742   /*
3743   For PNG filter method 0
3744   unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte,
3745   the filter works byte per byte (bytewidth = 1)
3746   precon is the previous unfiltered scanline, recon the result, scanline the current one
3747   the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead
3748   recon and scanline MAY be the same memory address! precon must be disjoint.
3749   */
3750 
3751   size_t i;
3752   switch(filterType) {
3753     case 0:
3754       for(i = 0; i != length; ++i) recon[i] = scanline[i];
3755       break;
3756     case 1:
3757       for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
3758       for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth];
3759       break;
3760     case 2:
3761       if(precon) {
3762         for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i];
3763       } else {
3764         for(i = 0; i != length; ++i) recon[i] = scanline[i];
3765       }
3766       break;
3767     case 3:
3768       if(precon) {
3769         for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1u);
3770         for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1u);
3771       } else {
3772         for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
3773         for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1u);
3774       }
3775       break;
3776     case 4:
3777       if(precon) {
3778         for(i = 0; i != bytewidth; ++i) {
3779           recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/
3780         }
3781         for(i = bytewidth; i < length; ++i) {
3782           recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
3783         }
3784       } else {
3785         for(i = 0; i != bytewidth; ++i) {
3786           recon[i] = scanline[i];
3787         }
3788         for(i = bytewidth; i < length; ++i) {
3789           /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/
3790           recon[i] = (scanline[i] + recon[i - bytewidth]);
3791         }
3792       }
3793       break;
3794     default: return 36; /*error: unexisting filter type given*/
3795   }
3796   return 0;
3797 }
3798 
unfilter(unsigned char * out,const unsigned char * in,unsigned w,unsigned h,unsigned bpp)3799 static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) {
3800   /*
3801   For PNG filter method 0
3802   this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 seven times)
3803   out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline
3804   w and h are image dimensions or dimensions of reduced image, bpp is bits per pixel
3805   in and out are allowed to be the same memory address (but aren't the same size since in has the extra filter bytes)
3806   */
3807 
3808   unsigned y;
3809   unsigned char* prevline = 0;
3810 
3811   /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/
3812   size_t bytewidth = (bpp + 7u) / 8u;
3813   size_t linebytes = (w * bpp + 7u) / 8u;
3814 
3815   for(y = 0; y < h; ++y) {
3816     size_t outindex = linebytes * y;
3817     size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
3818     unsigned char filterType = in[inindex];
3819 
3820     CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes));
3821 
3822     prevline = &out[outindex];
3823   }
3824 
3825   return 0;
3826 }
3827 
3828 /*
3829 in: Adam7 interlaced image, with no padding bits between scanlines, but between
3830  reduced images so that each reduced image starts at a byte.
3831 out: the same pixels, but re-ordered so that they're now a non-interlaced image with size w*h
3832 bpp: bits per pixel
3833 out has the following size in bits: w * h * bpp.
3834 in is possibly bigger due to padding bits between reduced images.
3835 out must be big enough AND must be 0 everywhere if bpp < 8 in the current implementation
3836 (because that's likely a little bit faster)
3837 NOTE: comments about padding bits are only relevant if bpp < 8
3838 */
Adam7_deinterlace(unsigned char * out,const unsigned char * in,unsigned w,unsigned h,unsigned bpp)3839 static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) {
3840   unsigned passw[7], passh[7];
3841   size_t filter_passstart[8], padded_passstart[8], passstart[8];
3842   unsigned i;
3843 
3844   Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
3845 
3846   if(bpp >= 8) {
3847     for(i = 0; i != 7; ++i) {
3848       unsigned x, y, b;
3849       size_t bytewidth = bpp / 8u;
3850       for(y = 0; y < passh[i]; ++y)
3851       for(x = 0; x < passw[i]; ++x) {
3852         size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth;
3853         size_t pixeloutstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth;
3854         for(b = 0; b < bytewidth; ++b) {
3855           out[pixeloutstart + b] = in[pixelinstart + b];
3856         }
3857       }
3858     }
3859   } else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ {
3860     for(i = 0; i != 7; ++i) {
3861       unsigned x, y, b;
3862       unsigned ilinebits = bpp * passw[i];
3863       unsigned olinebits = bpp * w;
3864       size_t obp, ibp; /*bit pointers (for out and in buffer)*/
3865       for(y = 0; y < passh[i]; ++y)
3866       for(x = 0; x < passw[i]; ++x) {
3867         ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp);
3868         obp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp;
3869         for(b = 0; b < bpp; ++b) {
3870           unsigned char bit = readBitFromReversedStream(&ibp, in);
3871           setBitOfReversedStream(&obp, out, bit);
3872         }
3873       }
3874     }
3875   }
3876 }
3877 
removePaddingBits(unsigned char * out,const unsigned char * in,size_t olinebits,size_t ilinebits,unsigned h)3878 static void removePaddingBits(unsigned char* out, const unsigned char* in,
3879                               size_t olinebits, size_t ilinebits, unsigned h) {
3880   /*
3881   After filtering there are still padding bits if scanlines have non multiple of 8 bit amounts. They need
3882   to be removed (except at last scanline of (Adam7-reduced) image) before working with pure image buffers
3883   for the Adam7 code, the color convert code and the output to the user.
3884   in and out are allowed to be the same buffer, in may also be higher but still overlapping; in must
3885   have >= ilinebits*h bits, out must have >= olinebits*h bits, olinebits must be <= ilinebits
3886   also used to move bits after earlier such operations happened, e.g. in a sequence of reduced images from Adam7
3887   only useful if (ilinebits - olinebits) is a value in the range 1..7
3888   */
3889   unsigned y;
3890   size_t diff = ilinebits - olinebits;
3891   size_t ibp = 0, obp = 0; /*input and output bit pointers*/
3892   for(y = 0; y < h; ++y) {
3893     size_t x;
3894     for(x = 0; x < olinebits; ++x) {
3895       unsigned char bit = readBitFromReversedStream(&ibp, in);
3896       setBitOfReversedStream(&obp, out, bit);
3897     }
3898     ibp += diff;
3899   }
3900 }
3901 
3902 /*out must be buffer big enough to contain full image, and in must contain the full decompressed data from
3903 the IDAT chunks (with filter index bytes and possible padding bits)
3904 return value is error*/
postProcessScanlines(unsigned char * out,unsigned char * in,unsigned w,unsigned h,const LodePNGInfo * info_png)3905 static unsigned postProcessScanlines(unsigned char* out, unsigned char* in,
3906                                      unsigned w, unsigned h, const LodePNGInfo* info_png) {
3907   /*
3908   This function converts the filtered-padded-interlaced data into pure 2D image buffer with the PNG's colortype.
3909   Steps:
3910   *) if no Adam7: 1) unfilter 2) remove padding bits (= posible extra bits per scanline if bpp < 8)
3911   *) if adam7: 1) 7x unfilter 2) 7x remove padding bits 3) Adam7_deinterlace
3912   NOTE: the in buffer will be overwritten with intermediate data!
3913   */
3914   unsigned bpp = lodepng_get_bpp(&info_png->color);
3915   if(bpp == 0) return 31; /*error: invalid colortype*/
3916 
3917   if(info_png->interlace_method == 0) {
3918     if(bpp < 8 && w * bpp != ((w * bpp + 7u) / 8u) * 8u) {
3919       CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp));
3920       removePaddingBits(out, in, w * bpp, ((w * bpp + 7u) / 8u) * 8u, h);
3921     }
3922     /*we can immediately filter into the out buffer, no other steps needed*/
3923     else CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp));
3924   } else /*interlace_method is 1 (Adam7)*/ {
3925     unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8];
3926     unsigned i;
3927 
3928     Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
3929 
3930     for(i = 0; i != 7; ++i) {
3931       CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp));
3932       /*TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline,
3933       move bytes instead of bits or move not at all*/
3934       if(bpp < 8) {
3935         /*remove padding bits in scanlines; after this there still may be padding
3936         bits between the different reduced images: each reduced image still starts nicely at a byte*/
3937         removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp,
3938                           ((passw[i] * bpp + 7u) / 8u) * 8u, passh[i]);
3939       }
3940     }
3941 
3942     Adam7_deinterlace(out, in, w, h, bpp);
3943   }
3944 
3945   return 0;
3946 }
3947 
readChunk_PLTE(LodePNGColorMode * color,const unsigned char * data,size_t chunkLength)3948 static unsigned readChunk_PLTE(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) {
3949   unsigned pos = 0, i;
3950   if(color->palette) lodepng_free(color->palette);
3951   color->palettesize = chunkLength / 3u;
3952   color->palette = (unsigned char*)lodepng_malloc(4 * color->palettesize);
3953   if(!color->palette && color->palettesize) {
3954     color->palettesize = 0;
3955     return 83; /*alloc fail*/
3956   }
3957   if(color->palettesize > 256) return 38; /*error: palette too big*/
3958 
3959   for(i = 0; i != color->palettesize; ++i) {
3960     color->palette[4 * i + 0] = data[pos++]; /*R*/
3961     color->palette[4 * i + 1] = data[pos++]; /*G*/
3962     color->palette[4 * i + 2] = data[pos++]; /*B*/
3963     color->palette[4 * i + 3] = 255; /*alpha*/
3964   }
3965 
3966   return 0; /* OK */
3967 }
3968 
readChunk_tRNS(LodePNGColorMode * color,const unsigned char * data,size_t chunkLength)3969 static unsigned readChunk_tRNS(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) {
3970   unsigned i;
3971   if(color->colortype == LCT_PALETTE) {
3972     /*error: more alpha values given than there are palette entries*/
3973     if(chunkLength > color->palettesize) return 39;
3974 
3975     for(i = 0; i != chunkLength; ++i) color->palette[4 * i + 3] = data[i];
3976   } else if(color->colortype == LCT_GREY) {
3977     /*error: this chunk must be 2 bytes for grayscale image*/
3978     if(chunkLength != 2) return 30;
3979 
3980     color->key_defined = 1;
3981     color->key_r = color->key_g = color->key_b = 256u * data[0] + data[1];
3982   } else if(color->colortype == LCT_RGB) {
3983     /*error: this chunk must be 6 bytes for RGB image*/
3984     if(chunkLength != 6) return 41;
3985 
3986     color->key_defined = 1;
3987     color->key_r = 256u * data[0] + data[1];
3988     color->key_g = 256u * data[2] + data[3];
3989     color->key_b = 256u * data[4] + data[5];
3990   }
3991   else return 42; /*error: tRNS chunk not allowed for other color models*/
3992 
3993   return 0; /* OK */
3994 }
3995 
3996 
3997 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
3998 /*background color chunk (bKGD)*/
readChunk_bKGD(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)3999 static unsigned readChunk_bKGD(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) {
4000   if(info->color.colortype == LCT_PALETTE) {
4001     /*error: this chunk must be 1 byte for indexed color image*/
4002     if(chunkLength != 1) return 43;
4003 
4004     /*error: invalid palette index, or maybe this chunk appeared before PLTE*/
4005     if(data[0] >= info->color.palettesize) return 103;
4006 
4007     info->background_defined = 1;
4008     info->background_r = info->background_g = info->background_b = data[0];
4009   } else if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) {
4010     /*error: this chunk must be 2 bytes for grayscale image*/
4011     if(chunkLength != 2) return 44;
4012 
4013     /*the values are truncated to bitdepth in the PNG file*/
4014     info->background_defined = 1;
4015     info->background_r = info->background_g = info->background_b = 256u * data[0] + data[1];
4016   } else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) {
4017     /*error: this chunk must be 6 bytes for grayscale image*/
4018     if(chunkLength != 6) return 45;
4019 
4020     /*the values are truncated to bitdepth in the PNG file*/
4021     info->background_defined = 1;
4022     info->background_r = 256u * data[0] + data[1];
4023     info->background_g = 256u * data[2] + data[3];
4024     info->background_b = 256u * data[4] + data[5];
4025   }
4026 
4027   return 0; /* OK */
4028 }
4029 
4030 /*text chunk (tEXt)*/
readChunk_tEXt(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)4031 static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) {
4032   unsigned error = 0;
4033   char *key = 0, *str = 0;
4034   unsigned i;
4035 
4036   while(!error) /*not really a while loop, only used to break on error*/ {
4037     unsigned length, string2_begin;
4038 
4039     length = 0;
4040     while(length < chunkLength && data[length] != 0) ++length;
4041     /*even though it's not allowed by the standard, no error is thrown if
4042     there's no null termination char, if the text is empty*/
4043     if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/
4044 
4045     key = (char*)lodepng_malloc(length + 1);
4046     if(!key) CERROR_BREAK(error, 83); /*alloc fail*/
4047 
4048     key[length] = 0;
4049     for(i = 0; i != length; ++i) key[i] = (char)data[i];
4050 
4051     string2_begin = length + 1; /*skip keyword null terminator*/
4052 
4053     length = (unsigned)(chunkLength < string2_begin ? 0 : chunkLength - string2_begin);
4054     str = (char*)lodepng_malloc(length + 1);
4055     if(!str) CERROR_BREAK(error, 83); /*alloc fail*/
4056 
4057     str[length] = 0;
4058     for(i = 0; i != length; ++i) str[i] = (char)data[string2_begin + i];
4059 
4060     error = lodepng_add_text(info, key, str);
4061 
4062     break;
4063   }
4064 
4065   lodepng_free(key);
4066   lodepng_free(str);
4067 
4068   return error;
4069 }
4070 
4071 /*compressed text chunk (zTXt)*/
readChunk_zTXt(LodePNGInfo * info,const LodePNGDecompressSettings * zlibsettings,const unsigned char * data,size_t chunkLength)4072 static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings,
4073                                const unsigned char* data, size_t chunkLength) {
4074   unsigned error = 0;
4075   unsigned i;
4076 
4077   unsigned length, string2_begin;
4078   char *key = 0;
4079   ucvector decoded;
4080 
4081   ucvector_init(&decoded);
4082 
4083   while(!error) /*not really a while loop, only used to break on error*/ {
4084     for(length = 0; length < chunkLength && data[length] != 0; ++length) ;
4085     if(length + 2 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/
4086     if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/
4087 
4088     key = (char*)lodepng_malloc(length + 1);
4089     if(!key) CERROR_BREAK(error, 83); /*alloc fail*/
4090 
4091     key[length] = 0;
4092     for(i = 0; i != length; ++i) key[i] = (char)data[i];
4093 
4094     if(data[length + 1] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/
4095 
4096     string2_begin = length + 2;
4097     if(string2_begin > chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/
4098 
4099     length = (unsigned)chunkLength - string2_begin;
4100     /*will fail if zlib error, e.g. if length is too small*/
4101     error = zlib_decompress(&decoded.data, &decoded.size,
4102                             &data[string2_begin],
4103                             length, zlibsettings);
4104     if(error) break;
4105     ucvector_push_back(&decoded, 0);
4106 
4107     error = lodepng_add_text(info, key, (char*)decoded.data);
4108 
4109     break;
4110   }
4111 
4112   lodepng_free(key);
4113   ucvector_cleanup(&decoded);
4114 
4115   return error;
4116 }
4117 
4118 /*international text chunk (iTXt)*/
readChunk_iTXt(LodePNGInfo * info,const LodePNGDecompressSettings * zlibsettings,const unsigned char * data,size_t chunkLength)4119 static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings,
4120                                const unsigned char* data, size_t chunkLength) {
4121   unsigned error = 0;
4122   unsigned i;
4123 
4124   unsigned length, begin, compressed;
4125   char *key = 0, *langtag = 0, *transkey = 0;
4126   ucvector decoded;
4127   ucvector_init(&decoded); /* TODO: only use in case of compressed text */
4128 
4129   while(!error) /*not really a while loop, only used to break on error*/ {
4130     /*Quick check if the chunk length isn't too small. Even without check
4131     it'd still fail with other error checks below if it's too short. This just gives a different error code.*/
4132     if(chunkLength < 5) CERROR_BREAK(error, 30); /*iTXt chunk too short*/
4133 
4134     /*read the key*/
4135     for(length = 0; length < chunkLength && data[length] != 0; ++length) ;
4136     if(length + 3 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination char, corrupt?*/
4137     if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/
4138 
4139     key = (char*)lodepng_malloc(length + 1);
4140     if(!key) CERROR_BREAK(error, 83); /*alloc fail*/
4141 
4142     key[length] = 0;
4143     for(i = 0; i != length; ++i) key[i] = (char)data[i];
4144 
4145     /*read the compression method*/
4146     compressed = data[length + 1];
4147     if(data[length + 2] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/
4148 
4149     /*even though it's not allowed by the standard, no error is thrown if
4150     there's no null termination char, if the text is empty for the next 3 texts*/
4151 
4152     /*read the langtag*/
4153     begin = length + 3;
4154     length = 0;
4155     for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length;
4156 
4157     langtag = (char*)lodepng_malloc(length + 1);
4158     if(!langtag) CERROR_BREAK(error, 83); /*alloc fail*/
4159 
4160     langtag[length] = 0;
4161     for(i = 0; i != length; ++i) langtag[i] = (char)data[begin + i];
4162 
4163     /*read the transkey*/
4164     begin += length + 1;
4165     length = 0;
4166     for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length;
4167 
4168     transkey = (char*)lodepng_malloc(length + 1);
4169     if(!transkey) CERROR_BREAK(error, 83); /*alloc fail*/
4170 
4171     transkey[length] = 0;
4172     for(i = 0; i != length; ++i) transkey[i] = (char)data[begin + i];
4173 
4174     /*read the actual text*/
4175     begin += length + 1;
4176 
4177     length = (unsigned)chunkLength < begin ? 0 : (unsigned)chunkLength - begin;
4178 
4179     if(compressed) {
4180       /*will fail if zlib error, e.g. if length is too small*/
4181       error = zlib_decompress(&decoded.data, &decoded.size,
4182                               &data[begin],
4183                               length, zlibsettings);
4184       if(error) break;
4185       if(decoded.allocsize < decoded.size) decoded.allocsize = decoded.size;
4186       ucvector_push_back(&decoded, 0);
4187     } else {
4188       if(!ucvector_resize(&decoded, length + 1)) CERROR_BREAK(error, 83 /*alloc fail*/);
4189 
4190       decoded.data[length] = 0;
4191       for(i = 0; i != length; ++i) decoded.data[i] = data[begin + i];
4192     }
4193 
4194     error = lodepng_add_itext(info, key, langtag, transkey, (char*)decoded.data);
4195 
4196     break;
4197   }
4198 
4199   lodepng_free(key);
4200   lodepng_free(langtag);
4201   lodepng_free(transkey);
4202   ucvector_cleanup(&decoded);
4203 
4204   return error;
4205 }
4206 
readChunk_tIME(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)4207 static unsigned readChunk_tIME(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) {
4208   if(chunkLength != 7) return 73; /*invalid tIME chunk size*/
4209 
4210   info->time_defined = 1;
4211   info->time.year = 256u * data[0] + data[1];
4212   info->time.month = data[2];
4213   info->time.day = data[3];
4214   info->time.hour = data[4];
4215   info->time.minute = data[5];
4216   info->time.second = data[6];
4217 
4218   return 0; /* OK */
4219 }
4220 
readChunk_pHYs(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)4221 static unsigned readChunk_pHYs(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) {
4222   if(chunkLength != 9) return 74; /*invalid pHYs chunk size*/
4223 
4224   info->phys_defined = 1;
4225   info->phys_x = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3];
4226   info->phys_y = 16777216u * data[4] + 65536u * data[5] + 256u * data[6] + data[7];
4227   info->phys_unit = data[8];
4228 
4229   return 0; /* OK */
4230 }
4231 
readChunk_gAMA(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)4232 static unsigned readChunk_gAMA(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) {
4233   if(chunkLength != 4) return 96; /*invalid gAMA chunk size*/
4234 
4235   info->gama_defined = 1;
4236   info->gama_gamma = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3];
4237 
4238   return 0; /* OK */
4239 }
4240 
readChunk_cHRM(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)4241 static unsigned readChunk_cHRM(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) {
4242   if(chunkLength != 32) return 97; /*invalid cHRM chunk size*/
4243 
4244   info->chrm_defined = 1;
4245   info->chrm_white_x = 16777216u * data[ 0] + 65536u * data[ 1] + 256u * data[ 2] + data[ 3];
4246   info->chrm_white_y = 16777216u * data[ 4] + 65536u * data[ 5] + 256u * data[ 6] + data[ 7];
4247   info->chrm_red_x   = 16777216u * data[ 8] + 65536u * data[ 9] + 256u * data[10] + data[11];
4248   info->chrm_red_y   = 16777216u * data[12] + 65536u * data[13] + 256u * data[14] + data[15];
4249   info->chrm_green_x = 16777216u * data[16] + 65536u * data[17] + 256u * data[18] + data[19];
4250   info->chrm_green_y = 16777216u * data[20] + 65536u * data[21] + 256u * data[22] + data[23];
4251   info->chrm_blue_x  = 16777216u * data[24] + 65536u * data[25] + 256u * data[26] + data[27];
4252   info->chrm_blue_y  = 16777216u * data[28] + 65536u * data[29] + 256u * data[30] + data[31];
4253 
4254   return 0; /* OK */
4255 }
4256 
readChunk_sRGB(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)4257 static unsigned readChunk_sRGB(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) {
4258   if(chunkLength != 1) return 98; /*invalid sRGB chunk size (this one is never ignored)*/
4259 
4260   info->srgb_defined = 1;
4261   info->srgb_intent = data[0];
4262 
4263   return 0; /* OK */
4264 }
4265 
readChunk_iCCP(LodePNGInfo * info,const LodePNGDecompressSettings * zlibsettings,const unsigned char * data,size_t chunkLength)4266 static unsigned readChunk_iCCP(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings,
4267                                const unsigned char* data, size_t chunkLength) {
4268   unsigned error = 0;
4269   unsigned i;
4270 
4271   unsigned length, string2_begin;
4272   ucvector decoded;
4273 
4274   info->iccp_defined = 1;
4275   if(info->iccp_name) lodepng_clear_icc(info);
4276 
4277   for(length = 0; length < chunkLength && data[length] != 0; ++length) ;
4278   if(length + 2 >= chunkLength) return 75; /*no null termination, corrupt?*/
4279   if(length < 1 || length > 79) return 89; /*keyword too short or long*/
4280 
4281   info->iccp_name = (char*)lodepng_malloc(length + 1);
4282   if(!info->iccp_name) return 83; /*alloc fail*/
4283 
4284   info->iccp_name[length] = 0;
4285   for(i = 0; i != length; ++i) info->iccp_name[i] = (char)data[i];
4286 
4287   if(data[length + 1] != 0) return 72; /*the 0 byte indicating compression must be 0*/
4288 
4289   string2_begin = length + 2;
4290   if(string2_begin > chunkLength) return 75; /*no null termination, corrupt?*/
4291 
4292   length = (unsigned)chunkLength - string2_begin;
4293   ucvector_init(&decoded);
4294   error = zlib_decompress(&decoded.data, &decoded.size,
4295                           &data[string2_begin],
4296                           length, zlibsettings);
4297   if(!error) {
4298     info->iccp_profile_size = decoded.size;
4299     info->iccp_profile = (unsigned char*)lodepng_malloc(decoded.size);
4300     if(info->iccp_profile) {
4301       lodepng_memcpy(info->iccp_profile, decoded.data, decoded.size);
4302     } else {
4303       error = 83; /* alloc fail */
4304     }
4305   }
4306   ucvector_cleanup(&decoded);
4307   return error;
4308 }
4309 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
4310 
lodepng_inspect_chunk(LodePNGState * state,size_t pos,const unsigned char * in,size_t insize)4311 unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos,
4312                                const unsigned char* in, size_t insize) {
4313   const unsigned char* chunk = in + pos;
4314   unsigned chunkLength;
4315   const unsigned char* data;
4316   unsigned unhandled = 0;
4317   unsigned error = 0;
4318 
4319   if (pos + 4 > insize) return 30;
4320   chunkLength = lodepng_chunk_length(chunk);
4321   if(chunkLength > 2147483647) return 63;
4322   data = lodepng_chunk_data_const(chunk);
4323   if(data + chunkLength + 4 > in + insize) return 30;
4324 
4325   if(lodepng_chunk_type_equals(chunk, "PLTE")) {
4326     error = readChunk_PLTE(&state->info_png.color, data, chunkLength);
4327   } else if(lodepng_chunk_type_equals(chunk, "tRNS")) {
4328     error = readChunk_tRNS(&state->info_png.color, data, chunkLength);
4329 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4330   } else if(lodepng_chunk_type_equals(chunk, "bKGD")) {
4331     error = readChunk_bKGD(&state->info_png, data, chunkLength);
4332   } else if(lodepng_chunk_type_equals(chunk, "tEXt")) {
4333     error = readChunk_tEXt(&state->info_png, data, chunkLength);
4334   } else if(lodepng_chunk_type_equals(chunk, "zTXt")) {
4335     error = readChunk_zTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
4336   } else if(lodepng_chunk_type_equals(chunk, "iTXt")) {
4337     error = readChunk_iTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
4338   } else if(lodepng_chunk_type_equals(chunk, "tIME")) {
4339     error = readChunk_tIME(&state->info_png, data, chunkLength);
4340   } else if(lodepng_chunk_type_equals(chunk, "pHYs")) {
4341     error = readChunk_pHYs(&state->info_png, data, chunkLength);
4342   } else if(lodepng_chunk_type_equals(chunk, "gAMA")) {
4343     error = readChunk_gAMA(&state->info_png, data, chunkLength);
4344   } else if(lodepng_chunk_type_equals(chunk, "cHRM")) {
4345     error = readChunk_cHRM(&state->info_png, data, chunkLength);
4346   } else if(lodepng_chunk_type_equals(chunk, "sRGB")) {
4347     error = readChunk_sRGB(&state->info_png, data, chunkLength);
4348   } else if(lodepng_chunk_type_equals(chunk, "iCCP")) {
4349     error = readChunk_iCCP(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
4350 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
4351   } else {
4352     /* unhandled chunk is ok (is not an error) */
4353     unhandled = 1;
4354   }
4355 
4356   if(!error && !unhandled && !state->decoder.ignore_crc) {
4357     if(lodepng_chunk_check_crc(chunk)) return 57; /*invalid CRC*/
4358   }
4359 
4360   return error;
4361 }
4362 
4363 /*read a PNG, the result will be in the same color type as the PNG (hence "generic")*/
decodeGeneric(unsigned char ** out,unsigned * w,unsigned * h,LodePNGState * state,const unsigned char * in,size_t insize)4364 static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
4365                           LodePNGState* state,
4366                           const unsigned char* in, size_t insize) {
4367   unsigned char IEND = 0;
4368   const unsigned char* chunk;
4369   size_t i;
4370   ucvector idat; /*the data from idat chunks*/
4371   ucvector scanlines;
4372   size_t predict;
4373   size_t outsize = 0;
4374 
4375   /*for unknown chunk order*/
4376   unsigned unknown = 0;
4377 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4378   unsigned critical_pos = 1; /*1 = after IHDR, 2 = after PLTE, 3 = after IDAT*/
4379 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
4380 
4381 
4382   /* safe output values in case error happens */
4383   *out = 0;
4384   *w = *h = 0;
4385 
4386   state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/
4387   if(state->error) return;
4388 
4389   if(lodepng_pixel_overflow(*w, *h, &state->info_png.color, &state->info_raw)) {
4390     CERROR_RETURN(state->error, 92); /*overflow possible due to amount of pixels*/
4391   }
4392 
4393   ucvector_init(&idat);
4394   chunk = &in[33]; /*first byte of the first chunk after the header*/
4395 
4396   /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk.
4397   IDAT data is put at the start of the in buffer*/
4398   while(!IEND && !state->error) {
4399     unsigned chunkLength;
4400     const unsigned char* data; /*the data in the chunk*/
4401 
4402     /*error: size of the in buffer too small to contain next chunk*/
4403     if((size_t)((chunk - in) + 12) > insize || chunk < in) {
4404       if(state->decoder.ignore_end) break; /*other errors may still happen though*/
4405       CERROR_BREAK(state->error, 30);
4406     }
4407 
4408     /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/
4409     chunkLength = lodepng_chunk_length(chunk);
4410     /*error: chunk length larger than the max PNG chunk size*/
4411     if(chunkLength > 2147483647) {
4412       if(state->decoder.ignore_end) break; /*other errors may still happen though*/
4413       CERROR_BREAK(state->error, 63);
4414     }
4415 
4416     if((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in) {
4417       CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk*/
4418     }
4419 
4420     data = lodepng_chunk_data_const(chunk);
4421 
4422     unknown = 0;
4423 
4424     /*IDAT chunk, containing compressed image data*/
4425     if(lodepng_chunk_type_equals(chunk, "IDAT")) {
4426       size_t oldsize = idat.size;
4427       size_t newsize;
4428       if(lodepng_addofl(oldsize, chunkLength, &newsize)) CERROR_BREAK(state->error, 95);
4429       if(!ucvector_resize(&idat, newsize)) CERROR_BREAK(state->error, 83 /*alloc fail*/);
4430       for(i = 0; i != chunkLength; ++i) idat.data[oldsize + i] = data[i];
4431 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4432       critical_pos = 3;
4433 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
4434     } else if(lodepng_chunk_type_equals(chunk, "IEND")) {
4435       /*IEND chunk*/
4436       IEND = 1;
4437     } else if(lodepng_chunk_type_equals(chunk, "PLTE")) {
4438       /*palette chunk (PLTE)*/
4439       state->error = readChunk_PLTE(&state->info_png.color, data, chunkLength);
4440       if(state->error) break;
4441 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4442       critical_pos = 2;
4443 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
4444     } else if(lodepng_chunk_type_equals(chunk, "tRNS")) {
4445       /*palette transparency chunk (tRNS). Even though this one is an ancillary chunk , it is still compiled
4446       in without 'LODEPNG_COMPILE_ANCILLARY_CHUNKS' because it contains essential color information that
4447       affects the alpha channel of pixels. */
4448       state->error = readChunk_tRNS(&state->info_png.color, data, chunkLength);
4449       if(state->error) break;
4450 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4451       /*background color chunk (bKGD)*/
4452     } else if(lodepng_chunk_type_equals(chunk, "bKGD")) {
4453       state->error = readChunk_bKGD(&state->info_png, data, chunkLength);
4454       if(state->error) break;
4455     } else if(lodepng_chunk_type_equals(chunk, "tEXt")) {
4456       /*text chunk (tEXt)*/
4457       if(state->decoder.read_text_chunks) {
4458         state->error = readChunk_tEXt(&state->info_png, data, chunkLength);
4459         if(state->error) break;
4460       }
4461     } else if(lodepng_chunk_type_equals(chunk, "zTXt")) {
4462       /*compressed text chunk (zTXt)*/
4463       if(state->decoder.read_text_chunks) {
4464         state->error = readChunk_zTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
4465         if(state->error) break;
4466       }
4467     } else if(lodepng_chunk_type_equals(chunk, "iTXt")) {
4468       /*international text chunk (iTXt)*/
4469       if(state->decoder.read_text_chunks) {
4470         state->error = readChunk_iTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
4471         if(state->error) break;
4472       }
4473     } else if(lodepng_chunk_type_equals(chunk, "tIME")) {
4474       state->error = readChunk_tIME(&state->info_png, data, chunkLength);
4475       if(state->error) break;
4476     } else if(lodepng_chunk_type_equals(chunk, "pHYs")) {
4477       state->error = readChunk_pHYs(&state->info_png, data, chunkLength);
4478       if(state->error) break;
4479     } else if(lodepng_chunk_type_equals(chunk, "gAMA")) {
4480       state->error = readChunk_gAMA(&state->info_png, data, chunkLength);
4481       if(state->error) break;
4482     } else if(lodepng_chunk_type_equals(chunk, "cHRM")) {
4483       state->error = readChunk_cHRM(&state->info_png, data, chunkLength);
4484       if(state->error) break;
4485     } else if(lodepng_chunk_type_equals(chunk, "sRGB")) {
4486       state->error = readChunk_sRGB(&state->info_png, data, chunkLength);
4487       if(state->error) break;
4488     } else if(lodepng_chunk_type_equals(chunk, "iCCP")) {
4489       state->error = readChunk_iCCP(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
4490       if(state->error) break;
4491 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
4492     } else /*it's not an implemented chunk type, so ignore it: skip over the data*/ {
4493       /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/
4494       if(!state->decoder.ignore_critical && !lodepng_chunk_ancillary(chunk)) {
4495         CERROR_BREAK(state->error, 69);
4496       }
4497 
4498       unknown = 1;
4499 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4500       if(state->decoder.remember_unknown_chunks) {
4501         state->error = lodepng_chunk_append(&state->info_png.unknown_chunks_data[critical_pos - 1],
4502                                             &state->info_png.unknown_chunks_size[critical_pos - 1], chunk);
4503         if(state->error) break;
4504       }
4505 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
4506     }
4507 
4508     if(!state->decoder.ignore_crc && !unknown) /*check CRC if wanted, only on known chunk types*/ {
4509       if(lodepng_chunk_check_crc(chunk)) CERROR_BREAK(state->error, 57); /*invalid CRC*/
4510     }
4511 
4512     if(!IEND) chunk = lodepng_chunk_next_const(chunk);
4513   }
4514 
4515   ucvector_init(&scanlines);
4516   /*predict output size, to allocate exact size for output buffer to avoid more dynamic allocation.
4517   If the decompressed size does not match the prediction, the image must be corrupt.*/
4518   if(state->info_png.interlace_method == 0) {
4519     predict = lodepng_get_raw_size_idat(*w, *h, &state->info_png.color);
4520   } else {
4521     /*Adam-7 interlaced: predicted size is the sum of the 7 sub-images sizes*/
4522     const LodePNGColorMode* color = &state->info_png.color;
4523     predict = 0;
4524     predict += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, color);
4525     if(*w > 4) predict += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, color);
4526     predict += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, color);
4527     if(*w > 2) predict += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, color);
4528     predict += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, color);
4529     if(*w > 1) predict += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, color);
4530     predict += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, color);
4531   }
4532   if(!state->error && !ucvector_reserve(&scanlines, predict)) state->error = 83; /*alloc fail*/
4533   if(!state->error) {
4534     state->error = zlib_decompress(&scanlines.data, &scanlines.size, idat.data,
4535                                    idat.size, &state->decoder.zlibsettings);
4536     if(!state->error && scanlines.size != predict) state->error = 91; /*decompressed size doesn't match prediction*/
4537   }
4538   ucvector_cleanup(&idat);
4539 
4540   if(!state->error) {
4541     outsize = lodepng_get_raw_size(*w, *h, &state->info_png.color);
4542     *out = (unsigned char*)lodepng_malloc(outsize);
4543     if(!*out) state->error = 83; /*alloc fail*/
4544   }
4545   if(!state->error) {
4546     for(i = 0; i < outsize; i++) (*out)[i] = 0;
4547     state->error = postProcessScanlines(*out, scanlines.data, *w, *h, &state->info_png);
4548   }
4549   ucvector_cleanup(&scanlines);
4550 }
4551 
lodepng_decode(unsigned char ** out,unsigned * w,unsigned * h,LodePNGState * state,const unsigned char * in,size_t insize)4552 unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h,
4553                         LodePNGState* state,
4554                         const unsigned char* in, size_t insize) {
4555   *out = 0;
4556   decodeGeneric(out, w, h, state, in, insize);
4557   if(state->error) return state->error;
4558   if(!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color)) {
4559     /*same color type, no copying or converting of data needed*/
4560     /*store the info_png color settings on the info_raw so that the info_raw still reflects what colortype
4561     the raw image has to the end user*/
4562     if(!state->decoder.color_convert) {
4563       state->error = lodepng_color_mode_copy(&state->info_raw, &state->info_png.color);
4564       if(state->error) return state->error;
4565     }
4566   } else {
4567     /*color conversion needed; sort of copy of the data*/
4568     unsigned char* data = *out;
4569     size_t outsize;
4570 
4571     /*TODO: check if this works according to the statement in the documentation: "The converter can convert
4572     from grayscale input color type, to 8-bit grayscale or grayscale with alpha"*/
4573     if(!(state->info_raw.colortype == LCT_RGB || state->info_raw.colortype == LCT_RGBA)
4574        && !(state->info_raw.bitdepth == 8)) {
4575       return 56; /*unsupported color mode conversion*/
4576     }
4577 
4578     outsize = lodepng_get_raw_size(*w, *h, &state->info_raw);
4579     *out = (unsigned char*)lodepng_malloc(outsize);
4580     if(!(*out)) {
4581       state->error = 83; /*alloc fail*/
4582     }
4583     else state->error = lodepng_convert(*out, data, &state->info_raw,
4584                                         &state->info_png.color, *w, *h);
4585     lodepng_free(data);
4586   }
4587   return state->error;
4588 }
4589 
lodepng_decode_memory(unsigned char ** out,unsigned * w,unsigned * h,const unsigned char * in,size_t insize,LodePNGColorType colortype,unsigned bitdepth)4590 unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in,
4591                                size_t insize, LodePNGColorType colortype, unsigned bitdepth) {
4592   unsigned error;
4593   LodePNGState state;
4594   lodepng_state_init(&state);
4595   state.info_raw.colortype = colortype;
4596   state.info_raw.bitdepth = bitdepth;
4597   error = lodepng_decode(out, w, h, &state, in, insize);
4598   lodepng_state_cleanup(&state);
4599   return error;
4600 }
4601 
lodepng_decode32(unsigned char ** out,unsigned * w,unsigned * h,const unsigned char * in,size_t insize)4602 unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) {
4603   return lodepng_decode_memory(out, w, h, in, insize, LCT_RGBA, 8);
4604 }
4605 
lodepng_decode24(unsigned char ** out,unsigned * w,unsigned * h,const unsigned char * in,size_t insize)4606 unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) {
4607   return lodepng_decode_memory(out, w, h, in, insize, LCT_RGB, 8);
4608 }
4609 
4610 #ifdef LODEPNG_COMPILE_DISK
lodepng_decode_file(unsigned char ** out,unsigned * w,unsigned * h,const char * filename,LodePNGColorType colortype,unsigned bitdepth)4611 unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename,
4612                              LodePNGColorType colortype, unsigned bitdepth) {
4613   unsigned char* buffer = 0;
4614   size_t buffersize;
4615   unsigned error;
4616   /* safe output values in case error happens */
4617   *out = 0;
4618   *w = *h = 0;
4619   error = lodepng_load_file(&buffer, &buffersize, filename);
4620   if(!error) error = lodepng_decode_memory(out, w, h, buffer, buffersize, colortype, bitdepth);
4621   lodepng_free(buffer);
4622   return error;
4623 }
4624 
lodepng_decode32_file(unsigned char ** out,unsigned * w,unsigned * h,const char * filename)4625 unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) {
4626   return lodepng_decode_file(out, w, h, filename, LCT_RGBA, 8);
4627 }
4628 
lodepng_decode24_file(unsigned char ** out,unsigned * w,unsigned * h,const char * filename)4629 unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) {
4630   return lodepng_decode_file(out, w, h, filename, LCT_RGB, 8);
4631 }
4632 #endif /*LODEPNG_COMPILE_DISK*/
4633 
lodepng_decoder_settings_init(LodePNGDecoderSettings * settings)4634 void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings) {
4635   settings->color_convert = 1;
4636 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4637   settings->read_text_chunks = 1;
4638   settings->remember_unknown_chunks = 0;
4639 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
4640   settings->ignore_crc = 0;
4641   settings->ignore_critical = 0;
4642   settings->ignore_end = 0;
4643   lodepng_decompress_settings_init(&settings->zlibsettings);
4644 }
4645 
4646 #endif /*LODEPNG_COMPILE_DECODER*/
4647 
4648 #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER)
4649 
lodepng_state_init(LodePNGState * state)4650 void lodepng_state_init(LodePNGState* state) {
4651 #ifdef LODEPNG_COMPILE_DECODER
4652   lodepng_decoder_settings_init(&state->decoder);
4653 #endif /*LODEPNG_COMPILE_DECODER*/
4654 #ifdef LODEPNG_COMPILE_ENCODER
4655   lodepng_encoder_settings_init(&state->encoder);
4656 #endif /*LODEPNG_COMPILE_ENCODER*/
4657   lodepng_color_mode_init(&state->info_raw);
4658   lodepng_info_init(&state->info_png);
4659   state->error = 1;
4660 }
4661 
lodepng_state_cleanup(LodePNGState * state)4662 void lodepng_state_cleanup(LodePNGState* state) {
4663   lodepng_color_mode_cleanup(&state->info_raw);
4664   lodepng_info_cleanup(&state->info_png);
4665 }
4666 
lodepng_state_copy(LodePNGState * dest,const LodePNGState * source)4667 void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source) {
4668   lodepng_state_cleanup(dest);
4669   *dest = *source;
4670   lodepng_color_mode_init(&dest->info_raw);
4671   lodepng_info_init(&dest->info_png);
4672   dest->error = lodepng_color_mode_copy(&dest->info_raw, &source->info_raw); if(dest->error) return;
4673   dest->error = lodepng_info_copy(&dest->info_png, &source->info_png); if(dest->error) return;
4674 }
4675 
4676 #endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */
4677 
4678 #ifdef LODEPNG_COMPILE_ENCODER
4679 
4680 /* ////////////////////////////////////////////////////////////////////////// */
4681 /* / PNG Encoder                                                            / */
4682 /* ////////////////////////////////////////////////////////////////////////// */
4683 
4684 /*chunkName must be string of 4 characters*/
addChunk(ucvector * out,const char * chunkName,const unsigned char * data,size_t length)4685 static unsigned addChunk(ucvector* out, const char* chunkName, const unsigned char* data, size_t length) {
4686   CERROR_TRY_RETURN(lodepng_chunk_create(&out->data, &out->size, (unsigned)length, chunkName, data));
4687   out->allocsize = out->size; /*fix the allocsize again*/
4688   return 0;
4689 }
4690 
writeSignature(ucvector * out)4691 static void writeSignature(ucvector* out) {
4692   /*8 bytes PNG signature, aka the magic bytes*/
4693   ucvector_push_back(out, 137);
4694   ucvector_push_back(out, 80);
4695   ucvector_push_back(out, 78);
4696   ucvector_push_back(out, 71);
4697   ucvector_push_back(out, 13);
4698   ucvector_push_back(out, 10);
4699   ucvector_push_back(out, 26);
4700   ucvector_push_back(out, 10);
4701 }
4702 
addChunk_IHDR(ucvector * out,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth,unsigned interlace_method)4703 static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h,
4704                               LodePNGColorType colortype, unsigned bitdepth, unsigned interlace_method) {
4705   unsigned error = 0;
4706   ucvector header;
4707   ucvector_init(&header);
4708 
4709   lodepng_add32bitInt(&header, w); /*width*/
4710   lodepng_add32bitInt(&header, h); /*height*/
4711   ucvector_push_back(&header, (unsigned char)bitdepth); /*bit depth*/
4712   ucvector_push_back(&header, (unsigned char)colortype); /*color type*/
4713   ucvector_push_back(&header, 0); /*compression method*/
4714   ucvector_push_back(&header, 0); /*filter method*/
4715   ucvector_push_back(&header, interlace_method); /*interlace method*/
4716 
4717   error = addChunk(out, "IHDR", header.data, header.size);
4718   ucvector_cleanup(&header);
4719 
4720   return error;
4721 }
4722 
addChunk_PLTE(ucvector * out,const LodePNGColorMode * info)4723 static unsigned addChunk_PLTE(ucvector* out, const LodePNGColorMode* info) {
4724   unsigned error = 0;
4725   size_t i;
4726   ucvector PLTE;
4727   ucvector_init(&PLTE);
4728   for(i = 0; i != info->palettesize * 4; ++i) {
4729     /*add all channels except alpha channel*/
4730     if(i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]);
4731   }
4732   error = addChunk(out, "PLTE", PLTE.data, PLTE.size);
4733   ucvector_cleanup(&PLTE);
4734 
4735   return error;
4736 }
4737 
addChunk_tRNS(ucvector * out,const LodePNGColorMode * info)4738 static unsigned addChunk_tRNS(ucvector* out, const LodePNGColorMode* info) {
4739   unsigned error = 0;
4740   size_t i;
4741   ucvector tRNS;
4742   ucvector_init(&tRNS);
4743   if(info->colortype == LCT_PALETTE) {
4744     size_t amount = info->palettesize;
4745     /*the tail of palette values that all have 255 as alpha, does not have to be encoded*/
4746     for(i = info->palettesize; i != 0; --i) {
4747       if(info->palette[4 * (i - 1) + 3] == 255) --amount;
4748       else break;
4749     }
4750     /*add only alpha channel*/
4751     for(i = 0; i != amount; ++i) ucvector_push_back(&tRNS, info->palette[4 * i + 3]);
4752   } else if(info->colortype == LCT_GREY) {
4753     if(info->key_defined) {
4754       ucvector_push_back(&tRNS, (unsigned char)(info->key_r >> 8));
4755       ucvector_push_back(&tRNS, (unsigned char)(info->key_r & 255));
4756     }
4757   } else if(info->colortype == LCT_RGB) {
4758     if(info->key_defined) {
4759       ucvector_push_back(&tRNS, (unsigned char)(info->key_r >> 8));
4760       ucvector_push_back(&tRNS, (unsigned char)(info->key_r & 255));
4761       ucvector_push_back(&tRNS, (unsigned char)(info->key_g >> 8));
4762       ucvector_push_back(&tRNS, (unsigned char)(info->key_g & 255));
4763       ucvector_push_back(&tRNS, (unsigned char)(info->key_b >> 8));
4764       ucvector_push_back(&tRNS, (unsigned char)(info->key_b & 255));
4765     }
4766   }
4767 
4768   error = addChunk(out, "tRNS", tRNS.data, tRNS.size);
4769   ucvector_cleanup(&tRNS);
4770 
4771   return error;
4772 }
4773 
addChunk_IDAT(ucvector * out,const unsigned char * data,size_t datasize,LodePNGCompressSettings * zlibsettings)4774 static unsigned addChunk_IDAT(ucvector* out, const unsigned char* data, size_t datasize,
4775                               LodePNGCompressSettings* zlibsettings) {
4776   ucvector zlibdata;
4777   unsigned error = 0;
4778 
4779   /*compress with the Zlib compressor*/
4780   ucvector_init(&zlibdata);
4781   error = zlib_compress(&zlibdata.data, &zlibdata.size, data, datasize, zlibsettings);
4782   if(!error) error = addChunk(out, "IDAT", zlibdata.data, zlibdata.size);
4783   ucvector_cleanup(&zlibdata);
4784 
4785   return error;
4786 }
4787 
addChunk_IEND(ucvector * out)4788 static unsigned addChunk_IEND(ucvector* out) {
4789   unsigned error = 0;
4790   error = addChunk(out, "IEND", 0, 0);
4791   return error;
4792 }
4793 
4794 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4795 
addChunk_tEXt(ucvector * out,const char * keyword,const char * textstring)4796 static unsigned addChunk_tEXt(ucvector* out, const char* keyword, const char* textstring) {
4797   unsigned error = 0;
4798   size_t i;
4799   ucvector text;
4800   ucvector_init(&text);
4801   for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&text, (unsigned char)keyword[i]);
4802   if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/
4803   ucvector_push_back(&text, 0); /*0 termination char*/
4804   for(i = 0; textstring[i] != 0; ++i) ucvector_push_back(&text, (unsigned char)textstring[i]);
4805   error = addChunk(out, "tEXt", text.data, text.size);
4806   ucvector_cleanup(&text);
4807 
4808   return error;
4809 }
4810 
addChunk_zTXt(ucvector * out,const char * keyword,const char * textstring,LodePNGCompressSettings * zlibsettings)4811 static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* textstring,
4812                               LodePNGCompressSettings* zlibsettings) {
4813   unsigned error = 0;
4814   ucvector data, compressed;
4815   size_t i, textsize = lodepng_strlen(textstring);
4816 
4817   ucvector_init(&data);
4818   ucvector_init(&compressed);
4819   for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)keyword[i]);
4820   if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/
4821   ucvector_push_back(&data, 0); /*0 termination char*/
4822   ucvector_push_back(&data, 0); /*compression method: 0*/
4823 
4824   error = zlib_compress(&compressed.data, &compressed.size,
4825                         (const unsigned char*)textstring, textsize, zlibsettings);
4826   if(!error) {
4827     for(i = 0; i != compressed.size; ++i) ucvector_push_back(&data, compressed.data[i]);
4828     error = addChunk(out, "zTXt", data.data, data.size);
4829   }
4830 
4831   ucvector_cleanup(&compressed);
4832   ucvector_cleanup(&data);
4833   return error;
4834 }
4835 
addChunk_iTXt(ucvector * out,unsigned compressed,const char * keyword,const char * langtag,const char * transkey,const char * textstring,LodePNGCompressSettings * zlibsettings)4836 static unsigned addChunk_iTXt(ucvector* out, unsigned compressed, const char* keyword, const char* langtag,
4837                               const char* transkey, const char* textstring, LodePNGCompressSettings* zlibsettings) {
4838   unsigned error = 0;
4839   ucvector data;
4840   size_t i, textsize = lodepng_strlen(textstring);
4841 
4842   ucvector_init(&data);
4843 
4844   for(i = 0; keyword[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)keyword[i]);
4845   if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/
4846   ucvector_push_back(&data, 0); /*null termination char*/
4847   ucvector_push_back(&data, compressed ? 1 : 0); /*compression flag*/
4848   ucvector_push_back(&data, 0); /*compression method*/
4849   for(i = 0; langtag[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)langtag[i]);
4850   ucvector_push_back(&data, 0); /*null termination char*/
4851   for(i = 0; transkey[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)transkey[i]);
4852   ucvector_push_back(&data, 0); /*null termination char*/
4853 
4854   if(compressed) {
4855     ucvector compressed_data;
4856     ucvector_init(&compressed_data);
4857     error = zlib_compress(&compressed_data.data, &compressed_data.size,
4858                           (const unsigned char*)textstring, textsize, zlibsettings);
4859     if(!error) {
4860       for(i = 0; i != compressed_data.size; ++i) ucvector_push_back(&data, compressed_data.data[i]);
4861     }
4862     ucvector_cleanup(&compressed_data);
4863   } else /*not compressed*/ {
4864     for(i = 0; textstring[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)textstring[i]);
4865   }
4866 
4867   if(!error) error = addChunk(out, "iTXt", data.data, data.size);
4868   ucvector_cleanup(&data);
4869   return error;
4870 }
4871 
addChunk_bKGD(ucvector * out,const LodePNGInfo * info)4872 static unsigned addChunk_bKGD(ucvector* out, const LodePNGInfo* info) {
4873   unsigned error = 0;
4874   ucvector bKGD;
4875   ucvector_init(&bKGD);
4876   if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) {
4877     ucvector_push_back(&bKGD, (unsigned char)(info->background_r >> 8));
4878     ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255));
4879   } else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) {
4880     ucvector_push_back(&bKGD, (unsigned char)(info->background_r >> 8));
4881     ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255));
4882     ucvector_push_back(&bKGD, (unsigned char)(info->background_g >> 8));
4883     ucvector_push_back(&bKGD, (unsigned char)(info->background_g & 255));
4884     ucvector_push_back(&bKGD, (unsigned char)(info->background_b >> 8));
4885     ucvector_push_back(&bKGD, (unsigned char)(info->background_b & 255));
4886   } else if(info->color.colortype == LCT_PALETTE) {
4887     ucvector_push_back(&bKGD, (unsigned char)(info->background_r & 255)); /*palette index*/
4888   }
4889 
4890   error = addChunk(out, "bKGD", bKGD.data, bKGD.size);
4891   ucvector_cleanup(&bKGD);
4892 
4893   return error;
4894 }
4895 
addChunk_tIME(ucvector * out,const LodePNGTime * time)4896 static unsigned addChunk_tIME(ucvector* out, const LodePNGTime* time) {
4897   unsigned error = 0;
4898   unsigned char* data = (unsigned char*)lodepng_malloc(7);
4899   if(!data) return 83; /*alloc fail*/
4900   data[0] = (unsigned char)(time->year >> 8);
4901   data[1] = (unsigned char)(time->year & 255);
4902   data[2] = (unsigned char)time->month;
4903   data[3] = (unsigned char)time->day;
4904   data[4] = (unsigned char)time->hour;
4905   data[5] = (unsigned char)time->minute;
4906   data[6] = (unsigned char)time->second;
4907   error = addChunk(out, "tIME", data, 7);
4908   lodepng_free(data);
4909   return error;
4910 }
4911 
addChunk_pHYs(ucvector * out,const LodePNGInfo * info)4912 static unsigned addChunk_pHYs(ucvector* out, const LodePNGInfo* info) {
4913   unsigned error = 0;
4914   ucvector data;
4915   ucvector_init(&data);
4916 
4917   lodepng_add32bitInt(&data, info->phys_x);
4918   lodepng_add32bitInt(&data, info->phys_y);
4919   ucvector_push_back(&data, info->phys_unit);
4920 
4921   error = addChunk(out, "pHYs", data.data, data.size);
4922   ucvector_cleanup(&data);
4923 
4924   return error;
4925 }
4926 
addChunk_gAMA(ucvector * out,const LodePNGInfo * info)4927 static unsigned addChunk_gAMA(ucvector* out, const LodePNGInfo* info) {
4928   unsigned error = 0;
4929   ucvector data;
4930   ucvector_init(&data);
4931 
4932   lodepng_add32bitInt(&data, info->gama_gamma);
4933 
4934   error = addChunk(out, "gAMA", data.data, data.size);
4935   ucvector_cleanup(&data);
4936 
4937   return error;
4938 }
4939 
addChunk_cHRM(ucvector * out,const LodePNGInfo * info)4940 static unsigned addChunk_cHRM(ucvector* out, const LodePNGInfo* info) {
4941   unsigned error = 0;
4942   ucvector data;
4943   ucvector_init(&data);
4944 
4945   lodepng_add32bitInt(&data, info->chrm_white_x);
4946   lodepng_add32bitInt(&data, info->chrm_white_y);
4947   lodepng_add32bitInt(&data, info->chrm_red_x);
4948   lodepng_add32bitInt(&data, info->chrm_red_y);
4949   lodepng_add32bitInt(&data, info->chrm_green_x);
4950   lodepng_add32bitInt(&data, info->chrm_green_y);
4951   lodepng_add32bitInt(&data, info->chrm_blue_x);
4952   lodepng_add32bitInt(&data, info->chrm_blue_y);
4953 
4954   error = addChunk(out, "cHRM", data.data, data.size);
4955   ucvector_cleanup(&data);
4956 
4957   return error;
4958 }
4959 
addChunk_sRGB(ucvector * out,const LodePNGInfo * info)4960 static unsigned addChunk_sRGB(ucvector* out, const LodePNGInfo* info) {
4961   unsigned char data = info->srgb_intent;
4962   return addChunk(out, "sRGB", &data, 1);
4963 }
4964 
addChunk_iCCP(ucvector * out,const LodePNGInfo * info,LodePNGCompressSettings * zlibsettings)4965 static unsigned addChunk_iCCP(ucvector* out, const LodePNGInfo* info, LodePNGCompressSettings* zlibsettings) {
4966   unsigned error = 0;
4967   ucvector data, compressed;
4968   size_t i;
4969 
4970   ucvector_init(&data);
4971   ucvector_init(&compressed);
4972   for(i = 0; info->iccp_name[i] != 0; ++i) ucvector_push_back(&data, (unsigned char)info->iccp_name[i]);
4973   if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/
4974   ucvector_push_back(&data, 0); /*0 termination char*/
4975   ucvector_push_back(&data, 0); /*compression method: 0*/
4976 
4977   error = zlib_compress(&compressed.data, &compressed.size,
4978                         info->iccp_profile, info->iccp_profile_size, zlibsettings);
4979   if(!error) {
4980     for(i = 0; i != compressed.size; ++i) ucvector_push_back(&data, compressed.data[i]);
4981     error = addChunk(out, "iCCP", data.data, data.size);
4982   }
4983 
4984   ucvector_cleanup(&compressed);
4985   ucvector_cleanup(&data);
4986   return error;
4987 }
4988 
4989 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
4990 
filterScanline(unsigned char * out,const unsigned char * scanline,const unsigned char * prevline,size_t length,size_t bytewidth,unsigned char filterType)4991 static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline,
4992                            size_t length, size_t bytewidth, unsigned char filterType) {
4993   size_t i;
4994   switch(filterType) {
4995     case 0: /*None*/
4996       for(i = 0; i != length; ++i) out[i] = scanline[i];
4997       break;
4998     case 1: /*Sub*/
4999       for(i = 0; i != bytewidth; ++i) out[i] = scanline[i];
5000       for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth];
5001       break;
5002     case 2: /*Up*/
5003       if(prevline) {
5004         for(i = 0; i != length; ++i) out[i] = scanline[i] - prevline[i];
5005       } else {
5006         for(i = 0; i != length; ++i) out[i] = scanline[i];
5007       }
5008       break;
5009     case 3: /*Average*/
5010       if(prevline) {
5011         for(i = 0; i != bytewidth; ++i) out[i] = scanline[i] - (prevline[i] >> 1);
5012         for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) >> 1);
5013       } else {
5014         for(i = 0; i != bytewidth; ++i) out[i] = scanline[i];
5015         for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - (scanline[i - bytewidth] >> 1);
5016       }
5017       break;
5018     case 4: /*Paeth*/
5019       if(prevline) {
5020         /*paethPredictor(0, prevline[i], 0) is always prevline[i]*/
5021         for(i = 0; i != bytewidth; ++i) out[i] = (scanline[i] - prevline[i]);
5022         for(i = bytewidth; i < length; ++i) {
5023           out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth]));
5024         }
5025       } else {
5026         for(i = 0; i != bytewidth; ++i) out[i] = scanline[i];
5027         /*paethPredictor(scanline[i - bytewidth], 0, 0) is always scanline[i - bytewidth]*/
5028         for(i = bytewidth; i < length; ++i) out[i] = (scanline[i] - scanline[i - bytewidth]);
5029       }
5030       break;
5031     default: return; /*unexisting filter type given*/
5032   }
5033 }
5034 
5035 /* TODO: remove the usage of float */
5036 /* log2 approximation. A slight bit faster than std::log. */
flog2(float f)5037 static float flog2(float f) {
5038   float result = 0;
5039   while(f > 32) { result += 4; f /= 16; }
5040   while(f > 2) { ++result; f /= 2; }
5041   return result + 1.442695f * (f * f * f / 3 - 3 * f * f / 2 + 3 * f - 1.83333f);
5042 }
5043 
filter(unsigned char * out,const unsigned char * in,unsigned w,unsigned h,const LodePNGColorMode * info,const LodePNGEncoderSettings * settings)5044 static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h,
5045                        const LodePNGColorMode* info, const LodePNGEncoderSettings* settings) {
5046   /*
5047   For PNG filter method 0
5048   out must be a buffer with as size: h + (w * h * bpp + 7u) / 8u, because there are
5049   the scanlines with 1 extra byte per scanline
5050   */
5051 
5052   unsigned bpp = lodepng_get_bpp(info);
5053   /*the width of a scanline in bytes, not including the filter type*/
5054   size_t linebytes = (w * bpp + 7u) / 8u;
5055   /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/
5056   size_t bytewidth = (bpp + 7u) / 8u;
5057   const unsigned char* prevline = 0;
5058   unsigned x, y;
5059   unsigned error = 0;
5060   LodePNGFilterStrategy strategy = settings->filter_strategy;
5061 
5062   /*
5063   There is a heuristic called the minimum sum of absolute differences heuristic, suggested by the PNG standard:
5064    *  If the image type is Palette, or the bit depth is smaller than 8, then do not filter the image (i.e.
5065       use fixed filtering, with the filter None).
5066    * (The other case) If the image type is Grayscale or RGB (with or without Alpha), and the bit depth is
5067      not smaller than 8, then use adaptive filtering heuristic as follows: independently for each row, apply
5068      all five filters and select the filter that produces the smallest sum of absolute values per row.
5069   This heuristic is used if filter strategy is LFS_MINSUM and filter_palette_zero is true.
5070 
5071   If filter_palette_zero is true and filter_strategy is not LFS_MINSUM, the above heuristic is followed,
5072   but for "the other case", whatever strategy filter_strategy is set to instead of the minimum sum
5073   heuristic is used.
5074   */
5075   if(settings->filter_palette_zero &&
5076      (info->colortype == LCT_PALETTE || info->bitdepth < 8)) strategy = LFS_ZERO;
5077 
5078   if(bpp == 0) return 31; /*error: invalid color type*/
5079 
5080   if(strategy >= LFS_ZERO && strategy <= LFS_FOUR) {
5081     unsigned char type = (unsigned char)strategy;
5082     for(y = 0; y != h; ++y) {
5083       size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
5084       size_t inindex = linebytes * y;
5085       out[outindex] = type; /*filter type byte*/
5086       filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type);
5087       prevline = &in[inindex];
5088     }
5089   } else if(strategy == LFS_MINSUM) {
5090     /*adaptive filtering*/
5091     size_t sum[5];
5092     unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/
5093     size_t smallest = 0;
5094     unsigned char type, bestType = 0;
5095 
5096     for(type = 0; type != 5; ++type) {
5097       attempt[type] = (unsigned char*)lodepng_malloc(linebytes);
5098       if(!attempt[type]) return 83; /*alloc fail*/
5099     }
5100 
5101     if(!error) {
5102       for(y = 0; y != h; ++y) {
5103         /*try the 5 filter types*/
5104         for(type = 0; type != 5; ++type) {
5105           filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type);
5106 
5107           /*calculate the sum of the result*/
5108           sum[type] = 0;
5109           if(type == 0) {
5110             for(x = 0; x != linebytes; ++x) sum[type] += (unsigned char)(attempt[type][x]);
5111           } else {
5112             for(x = 0; x != linebytes; ++x) {
5113               /*For differences, each byte should be treated as signed, values above 127 are negative
5114               (converted to signed char). Filtertype 0 isn't a difference though, so use unsigned there.
5115               This means filtertype 0 is almost never chosen, but that is justified.*/
5116               unsigned char s = attempt[type][x];
5117               sum[type] += s < 128 ? s : (255U - s);
5118             }
5119           }
5120 
5121           /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/
5122           if(type == 0 || sum[type] < smallest) {
5123             bestType = type;
5124             smallest = sum[type];
5125           }
5126         }
5127 
5128         prevline = &in[y * linebytes];
5129 
5130         /*now fill the out values*/
5131         out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
5132         for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x];
5133       }
5134     }
5135 
5136     for(type = 0; type != 5; ++type) lodepng_free(attempt[type]);
5137   } else if(strategy == LFS_ENTROPY) {
5138     float sum[5];
5139     unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/
5140     float smallest = 0;
5141     unsigned type, bestType = 0;
5142     unsigned count[256];
5143 
5144     for(type = 0; type != 5; ++type) {
5145       attempt[type] = (unsigned char*)lodepng_malloc(linebytes);
5146       if(!attempt[type]) return 83; /*alloc fail*/
5147     }
5148 
5149     for(y = 0; y != h; ++y) {
5150       /*try the 5 filter types*/
5151       for(type = 0; type != 5; ++type) {
5152         filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type);
5153         for(x = 0; x != 256; ++x) count[x] = 0;
5154         for(x = 0; x != linebytes; ++x) ++count[attempt[type][x]];
5155         ++count[type]; /*the filter type itself is part of the scanline*/
5156         sum[type] = 0;
5157         for(x = 0; x != 256; ++x) {
5158           float p = count[x] / (float)(linebytes + 1);
5159           sum[type] += count[x] == 0 ? 0 : flog2(1 / p) * p;
5160         }
5161         /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/
5162         if(type == 0 || sum[type] < smallest) {
5163           bestType = type;
5164           smallest = sum[type];
5165         }
5166       }
5167 
5168       prevline = &in[y * linebytes];
5169 
5170       /*now fill the out values*/
5171       out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
5172       for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x];
5173     }
5174 
5175     for(type = 0; type != 5; ++type) lodepng_free(attempt[type]);
5176   } else if(strategy == LFS_PREDEFINED) {
5177     for(y = 0; y != h; ++y) {
5178       size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
5179       size_t inindex = linebytes * y;
5180       unsigned char type = settings->predefined_filters[y];
5181       out[outindex] = type; /*filter type byte*/
5182       filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type);
5183       prevline = &in[inindex];
5184     }
5185   } else if(strategy == LFS_BRUTE_FORCE) {
5186     /*brute force filter chooser.
5187     deflate the scanline after every filter attempt to see which one deflates best.
5188     This is very slow and gives only slightly smaller, sometimes even larger, result*/
5189     size_t size[5];
5190     unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/
5191     size_t smallest = 0;
5192     unsigned type = 0, bestType = 0;
5193     unsigned char* dummy;
5194     LodePNGCompressSettings zlibsettings = settings->zlibsettings;
5195     /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose,
5196     to simulate the true case where the tree is the same for the whole image. Sometimes it gives
5197     better result with dynamic tree anyway. Using the fixed tree sometimes gives worse, but in rare
5198     cases better compression. It does make this a bit less slow, so it's worth doing this.*/
5199     zlibsettings.btype = 1;
5200     /*a custom encoder likely doesn't read the btype setting and is optimized for complete PNG
5201     images only, so disable it*/
5202     zlibsettings.custom_zlib = 0;
5203     zlibsettings.custom_deflate = 0;
5204     for(type = 0; type != 5; ++type) {
5205       attempt[type] = (unsigned char*)lodepng_malloc(linebytes);
5206       if(!attempt[type]) return 83; /*alloc fail*/
5207     }
5208     for(y = 0; y != h; ++y) /*try the 5 filter types*/ {
5209       for(type = 0; type != 5; ++type) {
5210         unsigned testsize = (unsigned)linebytes;
5211         /*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/
5212 
5213         filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type);
5214         size[type] = 0;
5215         dummy = 0;
5216         zlib_compress(&dummy, &size[type], attempt[type], testsize, &zlibsettings);
5217         lodepng_free(dummy);
5218         /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/
5219         if(type == 0 || size[type] < smallest) {
5220           bestType = type;
5221           smallest = size[type];
5222         }
5223       }
5224       prevline = &in[y * linebytes];
5225       out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
5226       for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x];
5227     }
5228     for(type = 0; type != 5; ++type) lodepng_free(attempt[type]);
5229   }
5230   else return 88; /* unknown filter strategy */
5231 
5232   return error;
5233 }
5234 
addPaddingBits(unsigned char * out,const unsigned char * in,size_t olinebits,size_t ilinebits,unsigned h)5235 static void addPaddingBits(unsigned char* out, const unsigned char* in,
5236                            size_t olinebits, size_t ilinebits, unsigned h) {
5237   /*The opposite of the removePaddingBits function
5238   olinebits must be >= ilinebits*/
5239   unsigned y;
5240   size_t diff = olinebits - ilinebits;
5241   size_t obp = 0, ibp = 0; /*bit pointers*/
5242   for(y = 0; y != h; ++y) {
5243     size_t x;
5244     for(x = 0; x < ilinebits; ++x) {
5245       unsigned char bit = readBitFromReversedStream(&ibp, in);
5246       setBitOfReversedStream(&obp, out, bit);
5247     }
5248     /*obp += diff; --> no, fill in some value in the padding bits too, to avoid
5249     "Use of uninitialised value of size ###" warning from valgrind*/
5250     for(x = 0; x != diff; ++x) setBitOfReversedStream(&obp, out, 0);
5251   }
5252 }
5253 
5254 /*
5255 in: non-interlaced image with size w*h
5256 out: the same pixels, but re-ordered according to PNG's Adam7 interlacing, with
5257  no padding bits between scanlines, but between reduced images so that each
5258  reduced image starts at a byte.
5259 bpp: bits per pixel
5260 there are no padding bits, not between scanlines, not between reduced images
5261 in has the following size in bits: w * h * bpp.
5262 out is possibly bigger due to padding bits between reduced images
5263 NOTE: comments about padding bits are only relevant if bpp < 8
5264 */
Adam7_interlace(unsigned char * out,const unsigned char * in,unsigned w,unsigned h,unsigned bpp)5265 static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) {
5266   unsigned passw[7], passh[7];
5267   size_t filter_passstart[8], padded_passstart[8], passstart[8];
5268   unsigned i;
5269 
5270   Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
5271 
5272   if(bpp >= 8) {
5273     for(i = 0; i != 7; ++i) {
5274       unsigned x, y, b;
5275       size_t bytewidth = bpp / 8u;
5276       for(y = 0; y < passh[i]; ++y)
5277       for(x = 0; x < passw[i]; ++x) {
5278         size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth;
5279         size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth;
5280         for(b = 0; b < bytewidth; ++b) {
5281           out[pixeloutstart + b] = in[pixelinstart + b];
5282         }
5283       }
5284     }
5285   } else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ {
5286     for(i = 0; i != 7; ++i) {
5287       unsigned x, y, b;
5288       unsigned ilinebits = bpp * passw[i];
5289       unsigned olinebits = bpp * w;
5290       size_t obp, ibp; /*bit pointers (for out and in buffer)*/
5291       for(y = 0; y < passh[i]; ++y)
5292       for(x = 0; x < passw[i]; ++x) {
5293         ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp;
5294         obp = (8 * passstart[i]) + (y * ilinebits + x * bpp);
5295         for(b = 0; b < bpp; ++b) {
5296           unsigned char bit = readBitFromReversedStream(&ibp, in);
5297           setBitOfReversedStream(&obp, out, bit);
5298         }
5299       }
5300     }
5301   }
5302 }
5303 
5304 /*out must be buffer big enough to contain uncompressed IDAT chunk data, and in must contain the full image.
5305 return value is error**/
preProcessScanlines(unsigned char ** out,size_t * outsize,const unsigned char * in,unsigned w,unsigned h,const LodePNGInfo * info_png,const LodePNGEncoderSettings * settings)5306 static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const unsigned char* in,
5307                                     unsigned w, unsigned h,
5308                                     const LodePNGInfo* info_png, const LodePNGEncoderSettings* settings) {
5309   /*
5310   This function converts the pure 2D image with the PNG's colortype, into filtered-padded-interlaced data. Steps:
5311   *) if no Adam7: 1) add padding bits (= posible extra bits per scanline if bpp < 8) 2) filter
5312   *) if adam7: 1) Adam7_interlace 2) 7x add padding bits 3) 7x filter
5313   */
5314   unsigned bpp = lodepng_get_bpp(&info_png->color);
5315   unsigned error = 0;
5316 
5317   if(info_png->interlace_method == 0) {
5318     *outsize = h + (h * ((w * bpp + 7u) / 8u)); /*image size plus an extra byte per scanline + possible padding bits*/
5319     *out = (unsigned char*)lodepng_malloc(*outsize);
5320     if(!(*out) && (*outsize)) error = 83; /*alloc fail*/
5321 
5322     if(!error) {
5323       /*non multiple of 8 bits per scanline, padding bits needed per scanline*/
5324       if(bpp < 8 && w * bpp != ((w * bpp + 7u) / 8u) * 8u) {
5325         unsigned char* padded = (unsigned char*)lodepng_malloc(h * ((w * bpp + 7u) / 8u));
5326         if(!padded) error = 83; /*alloc fail*/
5327         if(!error) {
5328           addPaddingBits(padded, in, ((w * bpp + 7u) / 8u) * 8u, w * bpp, h);
5329           error = filter(*out, padded, w, h, &info_png->color, settings);
5330         }
5331         lodepng_free(padded);
5332       } else {
5333         /*we can immediately filter into the out buffer, no other steps needed*/
5334         error = filter(*out, in, w, h, &info_png->color, settings);
5335       }
5336     }
5337   } else /*interlace_method is 1 (Adam7)*/ {
5338     unsigned passw[7], passh[7];
5339     size_t filter_passstart[8], padded_passstart[8], passstart[8];
5340     unsigned char* adam7;
5341 
5342     Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
5343 
5344     *outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/
5345     *out = (unsigned char*)lodepng_malloc(*outsize);
5346     if(!(*out)) error = 83; /*alloc fail*/
5347 
5348     adam7 = (unsigned char*)lodepng_malloc(passstart[7]);
5349     if(!adam7 && passstart[7]) error = 83; /*alloc fail*/
5350 
5351     if(!error) {
5352       unsigned i;
5353 
5354       Adam7_interlace(adam7, in, w, h, bpp);
5355       for(i = 0; i != 7; ++i) {
5356         if(bpp < 8) {
5357           unsigned char* padded = (unsigned char*)lodepng_malloc(padded_passstart[i + 1] - padded_passstart[i]);
5358           if(!padded) ERROR_BREAK(83); /*alloc fail*/
5359           addPaddingBits(padded, &adam7[passstart[i]],
5360                          ((passw[i] * bpp + 7u) / 8u) * 8u, passw[i] * bpp, passh[i]);
5361           error = filter(&(*out)[filter_passstart[i]], padded,
5362                          passw[i], passh[i], &info_png->color, settings);
5363           lodepng_free(padded);
5364         } else {
5365           error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]],
5366                          passw[i], passh[i], &info_png->color, settings);
5367         }
5368 
5369         if(error) break;
5370       }
5371     }
5372 
5373     lodepng_free(adam7);
5374   }
5375 
5376   return error;
5377 }
5378 
5379 /*
5380 palette must have 4 * palettesize bytes allocated, and given in format RGBARGBARGBARGBA...
5381 returns 0 if the palette is opaque,
5382 returns 1 if the palette has a single color with alpha 0 ==> color key
5383 returns 2 if the palette is semi-translucent.
5384 */
getPaletteTranslucency(const unsigned char * palette,size_t palettesize)5385 static unsigned getPaletteTranslucency(const unsigned char* palette, size_t palettesize) {
5386   size_t i;
5387   unsigned key = 0;
5388   unsigned r = 0, g = 0, b = 0; /*the value of the color with alpha 0, so long as color keying is possible*/
5389   for(i = 0; i != palettesize; ++i) {
5390     if(!key && palette[4 * i + 3] == 0) {
5391       r = palette[4 * i + 0]; g = palette[4 * i + 1]; b = palette[4 * i + 2];
5392       key = 1;
5393       i = (size_t)(-1); /*restart from beginning, to detect earlier opaque colors with key's value*/
5394     }
5395     else if(palette[4 * i + 3] != 255) return 2;
5396     /*when key, no opaque RGB may have key's RGB*/
5397     else if(key && r == palette[i * 4 + 0] && g == palette[i * 4 + 1] && b == palette[i * 4 + 2]) return 2;
5398   }
5399   return key;
5400 }
5401 
5402 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
addUnknownChunks(ucvector * out,unsigned char * data,size_t datasize)5403 static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t datasize) {
5404   unsigned char* inchunk = data;
5405   while((size_t)(inchunk - data) < datasize) {
5406     CERROR_TRY_RETURN(lodepng_chunk_append(&out->data, &out->size, inchunk));
5407     out->allocsize = out->size; /*fix the allocsize again*/
5408     inchunk = lodepng_chunk_next(inchunk);
5409   }
5410   return 0;
5411 }
5412 
isGrayICCProfile(const unsigned char * profile,unsigned size)5413 static unsigned isGrayICCProfile(const unsigned char* profile, unsigned size) {
5414   /*
5415   It is a gray profile if bytes 16-19 are "GRAY", rgb profile if bytes 16-19
5416   are "RGB ". We do not perform any full parsing of the ICC profile here, other
5417   than check those 4 bytes to grayscale profile. Other than that, validity of
5418   the profile is not checked. This is needed only because the PNG specification
5419   requires using a non-gray color model if there is an ICC profile with "RGB "
5420   (sadly limiting compression opportunities if the input data is grayscale RGB
5421   data), and requires using a gray color model if it is "GRAY".
5422   */
5423   if(size < 20) return 0;
5424   return profile[16] == 'G' &&  profile[17] == 'R' &&  profile[18] == 'A' &&  profile[19] == 'Y';
5425 }
5426 
isRGBICCProfile(const unsigned char * profile,unsigned size)5427 static unsigned isRGBICCProfile(const unsigned char* profile, unsigned size) {
5428   /* See comment in isGrayICCProfile*/
5429   if(size < 20) return 0;
5430   return profile[16] == 'R' &&  profile[17] == 'G' &&  profile[18] == 'B' &&  profile[19] == ' ';
5431 }
5432 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5433 
lodepng_encode(unsigned char ** out,size_t * outsize,const unsigned char * image,unsigned w,unsigned h,LodePNGState * state)5434 unsigned lodepng_encode(unsigned char** out, size_t* outsize,
5435                         const unsigned char* image, unsigned w, unsigned h,
5436                         LodePNGState* state) {
5437   unsigned char* data = 0; /*uncompressed version of the IDAT chunk data*/
5438   size_t datasize = 0;
5439   ucvector outv;
5440   LodePNGInfo info;
5441   const LodePNGInfo* info_png = &state->info_png;
5442 
5443   ucvector_init(&outv);
5444   lodepng_info_init(&info);
5445 
5446   /*provide some proper output values if error will happen*/
5447   *out = 0;
5448   *outsize = 0;
5449   state->error = 0;
5450 
5451   /*check input values validity*/
5452   if((info_png->color.colortype == LCT_PALETTE || state->encoder.force_palette)
5453       && (info_png->color.palettesize == 0 || info_png->color.palettesize > 256)) {
5454     state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/
5455     goto cleanup;
5456   }
5457   if(state->encoder.zlibsettings.btype > 2) {
5458     state->error = 61; /*error: unexisting btype*/
5459     goto cleanup;
5460   }
5461   if(info_png->interlace_method > 1) {
5462     state->error = 71; /*error: unexisting interlace mode*/
5463     goto cleanup;
5464   }
5465   state->error = checkColorValidity(info_png->color.colortype, info_png->color.bitdepth);
5466   if(state->error) goto cleanup; /*error: unexisting color type given*/
5467   state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth);
5468   if(state->error) goto cleanup; /*error: unexisting color type given*/
5469 
5470   /* color convert and compute scanline filter types */
5471   lodepng_info_copy(&info, &state->info_png);
5472   if(state->encoder.auto_convert) {
5473     LodePNGColorStats stats;
5474     lodepng_color_stats_init(&stats);
5475 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5476     if(info_png->iccp_defined &&
5477         isGrayICCProfile(info_png->iccp_profile, info_png->iccp_profile_size)) {
5478       /*the PNG specification does not allow to use palette with a GRAY ICC profile, even
5479       if the palette has only gray colors, so disallow it.*/
5480       stats.allow_palette = 0;
5481     }
5482     if(info_png->iccp_defined &&
5483         isRGBICCProfile(info_png->iccp_profile, info_png->iccp_profile_size)) {
5484       /*the PNG specification does not allow to use grayscale color with RGB ICC profile, so disallow gray.*/
5485       stats.allow_greyscale = 0;
5486     }
5487 #endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */
5488     lodepng_compute_color_stats(&stats, image, w, h, &state->info_raw);
5489 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5490     if(info_png->background_defined) {
5491       /*the background chunk's color must be taken into account as well*/
5492       unsigned r = 0, g = 0, b = 0;
5493       LodePNGColorMode mode16 = lodepng_color_mode_make(LCT_RGB, 16);
5494       lodepng_convert_rgb(&r, &g, &b, info_png->background_r, info_png->background_g, info_png->background_b, &mode16, &info_png->color);
5495       lodepng_color_stats_add(&stats, r, g, b, 65535);
5496     }
5497 #endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */
5498     state->error = auto_choose_color(&info.color, &state->info_raw, &stats);
5499     if(state->error) goto cleanup;
5500 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5501     /*also convert the background chunk*/
5502     if(info_png->background_defined) {
5503       if(lodepng_convert_rgb(&info.background_r, &info.background_g, &info.background_b,
5504           info_png->background_r, info_png->background_g, info_png->background_b, &info.color, &info_png->color)) {
5505         state->error = 104;
5506         goto cleanup;
5507       }
5508     }
5509 #endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */
5510   }
5511 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5512   if(info_png->iccp_defined) {
5513     unsigned gray_icc = isGrayICCProfile(info_png->iccp_profile, info_png->iccp_profile_size);
5514     unsigned rgb_icc = isRGBICCProfile(info_png->iccp_profile, info_png->iccp_profile_size);
5515     unsigned gray_png = info.color.colortype == LCT_GREY || info.color.colortype == LCT_GREY_ALPHA;
5516     if(!gray_icc && !rgb_icc) {
5517       state->error = 100; /* Disallowed profile color type for PNG */
5518       goto cleanup;
5519     }
5520     if(gray_icc != gray_png) {
5521       /*Not allowed to use RGB/RGBA/palette with GRAY ICC profile or vice versa,
5522       or in case of auto_convert, it wasn't possible to find appropriate model*/
5523       state->error = state->encoder.auto_convert ? 102 : 101;
5524       goto cleanup;
5525     }
5526   }
5527 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5528   if(!lodepng_color_mode_equal(&state->info_raw, &info.color)) {
5529     unsigned char* converted;
5530     size_t size = ((size_t)w * (size_t)h * (size_t)lodepng_get_bpp(&info.color) + 7u) / 8u;
5531 
5532     converted = (unsigned char*)lodepng_malloc(size);
5533     if(!converted && size) state->error = 83; /*alloc fail*/
5534     if(!state->error) {
5535       state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h);
5536     }
5537     if(!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder);
5538     lodepng_free(converted);
5539     if(state->error) goto cleanup;
5540   }
5541   else preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder);
5542 
5543   /* output all PNG chunks */ {
5544 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5545     size_t i;
5546 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5547     /*write signature and chunks*/
5548     writeSignature(&outv);
5549     /*IHDR*/
5550     addChunk_IHDR(&outv, w, h, info.color.colortype, info.color.bitdepth, info.interlace_method);
5551 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5552     /*unknown chunks between IHDR and PLTE*/
5553     if(info.unknown_chunks_data[0]) {
5554       state->error = addUnknownChunks(&outv, info.unknown_chunks_data[0], info.unknown_chunks_size[0]);
5555       if(state->error) goto cleanup;
5556     }
5557     /*color profile chunks must come before PLTE */
5558     if(info.iccp_defined) addChunk_iCCP(&outv, &info, &state->encoder.zlibsettings);
5559     if(info.srgb_defined) addChunk_sRGB(&outv, &info);
5560     if(info.gama_defined) addChunk_gAMA(&outv, &info);
5561     if(info.chrm_defined) addChunk_cHRM(&outv, &info);
5562 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5563     /*PLTE*/
5564     if(info.color.colortype == LCT_PALETTE) {
5565       addChunk_PLTE(&outv, &info.color);
5566     }
5567     if(state->encoder.force_palette && (info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA)) {
5568       addChunk_PLTE(&outv, &info.color);
5569     }
5570     /*tRNS*/
5571     if(info.color.colortype == LCT_PALETTE && getPaletteTranslucency(info.color.palette, info.color.palettesize) != 0) {
5572       addChunk_tRNS(&outv, &info.color);
5573     }
5574     if((info.color.colortype == LCT_GREY || info.color.colortype == LCT_RGB) && info.color.key_defined) {
5575       addChunk_tRNS(&outv, &info.color);
5576     }
5577 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5578     /*bKGD (must come between PLTE and the IDAt chunks*/
5579     if(info.background_defined) {
5580       state->error = addChunk_bKGD(&outv, &info);
5581       if(state->error) goto cleanup;
5582     }
5583     /*pHYs (must come before the IDAT chunks)*/
5584     if(info.phys_defined) addChunk_pHYs(&outv, &info);
5585 
5586     /*unknown chunks between PLTE and IDAT*/
5587     if(info.unknown_chunks_data[1]) {
5588       state->error = addUnknownChunks(&outv, info.unknown_chunks_data[1], info.unknown_chunks_size[1]);
5589       if(state->error) goto cleanup;
5590     }
5591 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5592     /*IDAT (multiple IDAT chunks must be consecutive)*/
5593     state->error = addChunk_IDAT(&outv, data, datasize, &state->encoder.zlibsettings);
5594     if(state->error) goto cleanup;
5595 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5596     /*tIME*/
5597     if(info.time_defined) addChunk_tIME(&outv, &info.time);
5598     /*tEXt and/or zTXt*/
5599     for(i = 0; i != info.text_num; ++i) {
5600       if(lodepng_strlen(info.text_keys[i]) > 79) {
5601         state->error = 66; /*text chunk too large*/
5602         goto cleanup;
5603       }
5604       if(lodepng_strlen(info.text_keys[i]) < 1) {
5605         state->error = 67; /*text chunk too small*/
5606         goto cleanup;
5607       }
5608       if(state->encoder.text_compression) {
5609         addChunk_zTXt(&outv, info.text_keys[i], info.text_strings[i], &state->encoder.zlibsettings);
5610       } else {
5611         addChunk_tEXt(&outv, info.text_keys[i], info.text_strings[i]);
5612       }
5613     }
5614     /*LodePNG version id in text chunk*/
5615     if(state->encoder.add_id) {
5616       unsigned already_added_id_text = 0;
5617       for(i = 0; i != info.text_num; ++i) {
5618         const char* k = info.text_keys[i];
5619         /* Could use strcmp, but we're not calling or reimplementing this C library function for this use only */
5620         if(k[0] == 'L' && k[1] == 'o' && k[2] == 'd' && k[3] == 'e' &&
5621            k[4] == 'P' && k[5] == 'N' && k[6] == 'G' && k[7] == '\0') {
5622           already_added_id_text = 1;
5623           break;
5624         }
5625       }
5626       if(already_added_id_text == 0) {
5627         addChunk_tEXt(&outv, "LodePNG", LODEPNG_VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/
5628       }
5629     }
5630     /*iTXt*/
5631     for(i = 0; i != info.itext_num; ++i) {
5632       if(lodepng_strlen(info.itext_keys[i]) > 79) {
5633         state->error = 66; /*text chunk too large*/
5634         goto cleanup;
5635       }
5636       if(lodepng_strlen(info.itext_keys[i]) < 1) {
5637         state->error = 67; /*text chunk too small*/
5638         goto cleanup;
5639       }
5640       addChunk_iTXt(&outv, state->encoder.text_compression,
5641                     info.itext_keys[i], info.itext_langtags[i], info.itext_transkeys[i], info.itext_strings[i],
5642                     &state->encoder.zlibsettings);
5643     }
5644 
5645     /*unknown chunks between IDAT and IEND*/
5646     if(info.unknown_chunks_data[2]) {
5647       state->error = addUnknownChunks(&outv, info.unknown_chunks_data[2], info.unknown_chunks_size[2]);
5648       if(state->error) goto cleanup;
5649     }
5650 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5651     addChunk_IEND(&outv);
5652   }
5653 
5654 cleanup:
5655   lodepng_info_cleanup(&info);
5656   lodepng_free(data);
5657 
5658   /*instead of cleaning the vector up, give it to the output*/
5659   *out = outv.data;
5660   *outsize = outv.size;
5661 
5662   return state->error;
5663 }
5664 
lodepng_encode_memory(unsigned char ** out,size_t * outsize,const unsigned char * image,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)5665 unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, const unsigned char* image,
5666                                unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) {
5667   unsigned error;
5668   LodePNGState state;
5669   lodepng_state_init(&state);
5670   state.info_raw.colortype = colortype;
5671   state.info_raw.bitdepth = bitdepth;
5672   state.info_png.color.colortype = colortype;
5673   state.info_png.color.bitdepth = bitdepth;
5674   lodepng_encode(out, outsize, image, w, h, &state);
5675   error = state.error;
5676   lodepng_state_cleanup(&state);
5677   return error;
5678 }
5679 
lodepng_encode32(unsigned char ** out,size_t * outsize,const unsigned char * image,unsigned w,unsigned h)5680 unsigned lodepng_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) {
5681   return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGBA, 8);
5682 }
5683 
lodepng_encode24(unsigned char ** out,size_t * outsize,const unsigned char * image,unsigned w,unsigned h)5684 unsigned lodepng_encode24(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) {
5685   return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGB, 8);
5686 }
5687 
5688 #ifdef LODEPNG_COMPILE_DISK
lodepng_encode_file(const char * filename,const unsigned char * image,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)5689 unsigned lodepng_encode_file(const char* filename, const unsigned char* image, unsigned w, unsigned h,
5690                              LodePNGColorType colortype, unsigned bitdepth) {
5691   unsigned char* buffer;
5692   size_t buffersize;
5693   unsigned error = lodepng_encode_memory(&buffer, &buffersize, image, w, h, colortype, bitdepth);
5694   if(!error) error = lodepng_save_file(buffer, buffersize, filename);
5695   lodepng_free(buffer);
5696   return error;
5697 }
5698 
lodepng_encode32_file(const char * filename,const unsigned char * image,unsigned w,unsigned h)5699 unsigned lodepng_encode32_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) {
5700   return lodepng_encode_file(filename, image, w, h, LCT_RGBA, 8);
5701 }
5702 
lodepng_encode24_file(const char * filename,const unsigned char * image,unsigned w,unsigned h)5703 unsigned lodepng_encode24_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) {
5704   return lodepng_encode_file(filename, image, w, h, LCT_RGB, 8);
5705 }
5706 #endif /*LODEPNG_COMPILE_DISK*/
5707 
lodepng_encoder_settings_init(LodePNGEncoderSettings * settings)5708 void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings) {
5709   lodepng_compress_settings_init(&settings->zlibsettings);
5710   settings->filter_palette_zero = 1;
5711   settings->filter_strategy = LFS_MINSUM;
5712   settings->auto_convert = 1;
5713   settings->force_palette = 0;
5714   settings->predefined_filters = 0;
5715 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5716   settings->add_id = 0;
5717   settings->text_compression = 1;
5718 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5719 }
5720 
5721 #endif /*LODEPNG_COMPILE_ENCODER*/
5722 #endif /*LODEPNG_COMPILE_PNG*/
5723 
5724 #ifdef LODEPNG_COMPILE_ERROR_TEXT
5725 /*
5726 This returns the description of a numerical error code in English. This is also
5727 the documentation of all the error codes.
5728 */
lodepng_error_text(unsigned code)5729 const char* lodepng_error_text(unsigned code) {
5730   switch(code) {
5731     case 0: return "no error, everything went ok";
5732     case 1: return "nothing done yet"; /*the Encoder/Decoder has done nothing yet, error checking makes no sense yet*/
5733     case 10: return "end of input memory reached without huffman end code"; /*while huffman decoding*/
5734     case 11: return "error in code tree made it jump outside of huffman tree"; /*while huffman decoding*/
5735     case 13: return "problem while processing dynamic deflate block";
5736     case 14: return "problem while processing dynamic deflate block";
5737     case 15: return "problem while processing dynamic deflate block";
5738     case 16: return "unexisting code while processing dynamic deflate block";
5739     case 17: return "end of out buffer memory reached while inflating";
5740     case 18: return "invalid distance code while inflating";
5741     case 19: return "end of out buffer memory reached while inflating";
5742     case 20: return "invalid deflate block BTYPE encountered while decoding";
5743     case 21: return "NLEN is not ones complement of LEN in a deflate block";
5744 
5745     /*end of out buffer memory reached while inflating:
5746     This can happen if the inflated deflate data is longer than the amount of bytes required to fill up
5747     all the pixels of the image, given the color depth and image dimensions. Something that doesn't
5748     happen in a normal, well encoded, PNG image.*/
5749     case 22: return "end of out buffer memory reached while inflating";
5750     case 23: return "end of in buffer memory reached while inflating";
5751     case 24: return "invalid FCHECK in zlib header";
5752     case 25: return "invalid compression method in zlib header";
5753     case 26: return "FDICT encountered in zlib header while it's not used for PNG";
5754     case 27: return "PNG file is smaller than a PNG header";
5755     /*Checks the magic file header, the first 8 bytes of the PNG file*/
5756     case 28: return "incorrect PNG signature, it's no PNG or corrupted";
5757     case 29: return "first chunk is not the header chunk";
5758     case 30: return "chunk length too large, chunk broken off at end of file";
5759     case 31: return "illegal PNG color type or bpp";
5760     case 32: return "illegal PNG compression method";
5761     case 33: return "illegal PNG filter method";
5762     case 34: return "illegal PNG interlace method";
5763     case 35: return "chunk length of a chunk is too large or the chunk too small";
5764     case 36: return "illegal PNG filter type encountered";
5765     case 37: return "illegal bit depth for this color type given";
5766     case 38: return "the palette is too big"; /*more than 256 colors*/
5767     case 39: return "tRNS chunk before PLTE or has more entries than palette size";
5768     case 40: return "tRNS chunk has wrong size for grayscale image";
5769     case 41: return "tRNS chunk has wrong size for RGB image";
5770     case 42: return "tRNS chunk appeared while it was not allowed for this color type";
5771     case 43: return "bKGD chunk has wrong size for palette image";
5772     case 44: return "bKGD chunk has wrong size for grayscale image";
5773     case 45: return "bKGD chunk has wrong size for RGB image";
5774     case 48: return "empty input buffer given to decoder. Maybe caused by non-existing file?";
5775     case 49: return "jumped past memory while generating dynamic huffman tree";
5776     case 50: return "jumped past memory while generating dynamic huffman tree";
5777     case 51: return "jumped past memory while inflating huffman block";
5778     case 52: return "jumped past memory while inflating";
5779     case 53: return "size of zlib data too small";
5780     case 54: return "repeat symbol in tree while there was no value symbol yet";
5781     /*jumped past tree while generating huffman tree, this could be when the
5782     tree will have more leaves than symbols after generating it out of the
5783     given lenghts. They call this an oversubscribed dynamic bit lengths tree in zlib.*/
5784     case 55: return "jumped past tree while generating huffman tree";
5785     case 56: return "given output image colortype or bitdepth not supported for color conversion";
5786     case 57: return "invalid CRC encountered (checking CRC can be disabled)";
5787     case 58: return "invalid ADLER32 encountered (checking ADLER32 can be disabled)";
5788     case 59: return "requested color conversion not supported";
5789     case 60: return "invalid window size given in the settings of the encoder (must be 0-32768)";
5790     case 61: return "invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)";
5791     /*LodePNG leaves the choice of RGB to grayscale conversion formula to the user.*/
5792     case 62: return "conversion from color to grayscale not supported";
5793     /*(2^31-1)*/
5794     case 63: return "length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk";
5795     /*this would result in the inability of a deflated block to ever contain an end code. It must be at least 1.*/
5796     case 64: return "the length of the END symbol 256 in the Huffman tree is 0";
5797     case 66: return "the length of a text chunk keyword given to the encoder is longer than the maximum of 79 bytes";
5798     case 67: return "the length of a text chunk keyword given to the encoder is smaller than the minimum of 1 byte";
5799     case 68: return "tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors";
5800     case 69: return "unknown chunk type with 'critical' flag encountered by the decoder";
5801     case 71: return "unexisting interlace mode given to encoder (must be 0 or 1)";
5802     case 72: return "while decoding, unexisting compression method encountering in zTXt or iTXt chunk (it must be 0)";
5803     case 73: return "invalid tIME chunk size";
5804     case 74: return "invalid pHYs chunk size";
5805     /*length could be wrong, or data chopped off*/
5806     case 75: return "no null termination char found while decoding text chunk";
5807     case 76: return "iTXt chunk too short to contain required bytes";
5808     case 77: return "integer overflow in buffer size";
5809     case 78: return "failed to open file for reading"; /*file doesn't exist or couldn't be opened for reading*/
5810     case 79: return "failed to open file for writing";
5811     case 80: return "tried creating a tree of 0 symbols";
5812     case 81: return "lazy matching at pos 0 is impossible";
5813     case 82: return "color conversion to palette requested while a color isn't in palette, or index out of bounds";
5814     case 83: return "memory allocation failed";
5815     case 84: return "given image too small to contain all pixels to be encoded";
5816     case 86: return "impossible offset in lz77 encoding (internal bug)";
5817     case 87: return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined";
5818     case 88: return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy";
5819     case 89: return "text chunk keyword too short or long: must have size 1-79";
5820     /*the windowsize in the LodePNGCompressSettings. Requiring POT(==> & instead of %) makes encoding 12% faster.*/
5821     case 90: return "windowsize must be a power of two";
5822     case 91: return "invalid decompressed idat size";
5823     case 92: return "integer overflow due to too many pixels";
5824     case 93: return "zero width or height is invalid";
5825     case 94: return "header chunk must have a size of 13 bytes";
5826     case 95: return "integer overflow with combined idat chunk size";
5827     case 96: return "invalid gAMA chunk size";
5828     case 97: return "invalid cHRM chunk size";
5829     case 98: return "invalid sRGB chunk size";
5830     case 99: return "invalid sRGB rendering intent";
5831     case 100: return "invalid ICC profile color type, the PNG specification only allows RGB or GRAY";
5832     case 101: return "PNG specification does not allow RGB ICC profile on gray color types and vice versa";
5833     case 102: return "not allowed to set grayscale ICC profile with colored pixels by PNG specification";
5834     case 103: return "invalid palette index in bKGD chunk. Maybe it came before PLTE chunk?";
5835     case 104: return "invalid bKGD color while encoding (e.g. palette index out of range)";
5836   }
5837   return "unknown error code";
5838 }
5839 #endif /*LODEPNG_COMPILE_ERROR_TEXT*/
5840 
5841 /* ////////////////////////////////////////////////////////////////////////// */
5842 /* ////////////////////////////////////////////////////////////////////////// */
5843 /* // C++ Wrapper                                                          // */
5844 /* ////////////////////////////////////////////////////////////////////////// */
5845 /* ////////////////////////////////////////////////////////////////////////// */
5846 
5847 #ifdef LODEPNG_COMPILE_CPP
5848 namespace lodepng {
5849 
5850 #ifdef LODEPNG_COMPILE_DISK
load_file(std::vector<unsigned char> & buffer,const std::string & filename)5851 unsigned load_file(std::vector<unsigned char>& buffer, const std::string& filename) {
5852   long size = lodepng_filesize(filename.c_str());
5853   if(size < 0) return 78;
5854   buffer.resize((size_t)size);
5855   return size == 0 ? 0 : lodepng_buffer_file(&buffer[0], (size_t)size, filename.c_str());
5856 }
5857 
5858 /*write given buffer to the file, overwriting the file, it doesn't append to it.*/
save_file(const std::vector<unsigned char> & buffer,const std::string & filename)5859 unsigned save_file(const std::vector<unsigned char>& buffer, const std::string& filename) {
5860   return lodepng_save_file(buffer.empty() ? 0 : &buffer[0], buffer.size(), filename.c_str());
5861 }
5862 #endif /* LODEPNG_COMPILE_DISK */
5863 
5864 #ifdef LODEPNG_COMPILE_ZLIB
5865 #ifdef LODEPNG_COMPILE_DECODER
decompress(std::vector<unsigned char> & out,const unsigned char * in,size_t insize,const LodePNGDecompressSettings & settings)5866 unsigned decompress(std::vector<unsigned char>& out, const unsigned char* in, size_t insize,
5867                     const LodePNGDecompressSettings& settings) {
5868   unsigned char* buffer = 0;
5869   size_t buffersize = 0;
5870   unsigned error = zlib_decompress(&buffer, &buffersize, in, insize, &settings);
5871   if(buffer) {
5872     out.insert(out.end(), &buffer[0], &buffer[buffersize]);
5873     lodepng_free(buffer);
5874   }
5875   return error;
5876 }
5877 
decompress(std::vector<unsigned char> & out,const std::vector<unsigned char> & in,const LodePNGDecompressSettings & settings)5878 unsigned decompress(std::vector<unsigned char>& out, const std::vector<unsigned char>& in,
5879                     const LodePNGDecompressSettings& settings) {
5880   return decompress(out, in.empty() ? 0 : &in[0], in.size(), settings);
5881 }
5882 #endif /* LODEPNG_COMPILE_DECODER */
5883 
5884 #ifdef LODEPNG_COMPILE_ENCODER
compress(std::vector<unsigned char> & out,const unsigned char * in,size_t insize,const LodePNGCompressSettings & settings)5885 unsigned compress(std::vector<unsigned char>& out, const unsigned char* in, size_t insize,
5886                   const LodePNGCompressSettings& settings) {
5887   unsigned char* buffer = 0;
5888   size_t buffersize = 0;
5889   unsigned error = zlib_compress(&buffer, &buffersize, in, insize, &settings);
5890   if(buffer) {
5891     out.insert(out.end(), &buffer[0], &buffer[buffersize]);
5892     lodepng_free(buffer);
5893   }
5894   return error;
5895 }
5896 
compress(std::vector<unsigned char> & out,const std::vector<unsigned char> & in,const LodePNGCompressSettings & settings)5897 unsigned compress(std::vector<unsigned char>& out, const std::vector<unsigned char>& in,
5898                   const LodePNGCompressSettings& settings) {
5899   return compress(out, in.empty() ? 0 : &in[0], in.size(), settings);
5900 }
5901 #endif /* LODEPNG_COMPILE_ENCODER */
5902 #endif /* LODEPNG_COMPILE_ZLIB */
5903 
5904 
5905 #ifdef LODEPNG_COMPILE_PNG
5906 
State()5907 State::State() {
5908   lodepng_state_init(this);
5909 }
5910 
State(const State & other)5911 State::State(const State& other) {
5912   lodepng_state_init(this);
5913   lodepng_state_copy(this, &other);
5914 }
5915 
~State()5916 State::~State() {
5917   lodepng_state_cleanup(this);
5918 }
5919 
operator =(const State & other)5920 State& State::operator=(const State& other) {
5921   lodepng_state_copy(this, &other);
5922   return *this;
5923 }
5924 
5925 #ifdef LODEPNG_COMPILE_DECODER
5926 
decode(std::vector<unsigned char> & out,unsigned & w,unsigned & h,const unsigned char * in,size_t insize,LodePNGColorType colortype,unsigned bitdepth)5927 unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h, const unsigned char* in,
5928                 size_t insize, LodePNGColorType colortype, unsigned bitdepth) {
5929   unsigned char* buffer;
5930   unsigned error = lodepng_decode_memory(&buffer, &w, &h, in, insize, colortype, bitdepth);
5931   if(buffer && !error) {
5932     State state;
5933     state.info_raw.colortype = colortype;
5934     state.info_raw.bitdepth = bitdepth;
5935     size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw);
5936     out.insert(out.end(), &buffer[0], &buffer[buffersize]);
5937     lodepng_free(buffer);
5938   }
5939   return error;
5940 }
5941 
decode(std::vector<unsigned char> & out,unsigned & w,unsigned & h,const std::vector<unsigned char> & in,LodePNGColorType colortype,unsigned bitdepth)5942 unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
5943                 const std::vector<unsigned char>& in, LodePNGColorType colortype, unsigned bitdepth) {
5944   return decode(out, w, h, in.empty() ? 0 : &in[0], (unsigned)in.size(), colortype, bitdepth);
5945 }
5946 
decode(std::vector<unsigned char> & out,unsigned & w,unsigned & h,State & state,const unsigned char * in,size_t insize)5947 unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
5948                 State& state,
5949                 const unsigned char* in, size_t insize) {
5950   unsigned char* buffer = NULL;
5951   unsigned error = lodepng_decode(&buffer, &w, &h, &state, in, insize);
5952   if(buffer && !error) {
5953     size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw);
5954     out.insert(out.end(), &buffer[0], &buffer[buffersize]);
5955   }
5956   lodepng_free(buffer);
5957   return error;
5958 }
5959 
decode(std::vector<unsigned char> & out,unsigned & w,unsigned & h,State & state,const std::vector<unsigned char> & in)5960 unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
5961                 State& state,
5962                 const std::vector<unsigned char>& in) {
5963   return decode(out, w, h, state, in.empty() ? 0 : &in[0], in.size());
5964 }
5965 
5966 #ifdef LODEPNG_COMPILE_DISK
decode(std::vector<unsigned char> & out,unsigned & w,unsigned & h,const std::string & filename,LodePNGColorType colortype,unsigned bitdepth)5967 unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h, const std::string& filename,
5968                 LodePNGColorType colortype, unsigned bitdepth) {
5969   std::vector<unsigned char> buffer;
5970   /* safe output values in case error happens */
5971   w = h = 0;
5972   unsigned error = load_file(buffer, filename);
5973   if(error) return error;
5974   return decode(out, w, h, buffer, colortype, bitdepth);
5975 }
5976 #endif /* LODEPNG_COMPILE_DECODER */
5977 #endif /* LODEPNG_COMPILE_DISK */
5978 
5979 #ifdef LODEPNG_COMPILE_ENCODER
encode(std::vector<unsigned char> & out,const unsigned char * in,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)5980 unsigned encode(std::vector<unsigned char>& out, const unsigned char* in, unsigned w, unsigned h,
5981                 LodePNGColorType colortype, unsigned bitdepth) {
5982   unsigned char* buffer;
5983   size_t buffersize;
5984   unsigned error = lodepng_encode_memory(&buffer, &buffersize, in, w, h, colortype, bitdepth);
5985   if(buffer) {
5986     out.insert(out.end(), &buffer[0], &buffer[buffersize]);
5987     lodepng_free(buffer);
5988   }
5989   return error;
5990 }
5991 
encode(std::vector<unsigned char> & out,const std::vector<unsigned char> & in,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)5992 unsigned encode(std::vector<unsigned char>& out,
5993                 const std::vector<unsigned char>& in, unsigned w, unsigned h,
5994                 LodePNGColorType colortype, unsigned bitdepth) {
5995   if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84;
5996   return encode(out, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth);
5997 }
5998 
encode(std::vector<unsigned char> & out,const unsigned char * in,unsigned w,unsigned h,State & state)5999 unsigned encode(std::vector<unsigned char>& out,
6000                 const unsigned char* in, unsigned w, unsigned h,
6001                 State& state) {
6002   unsigned char* buffer;
6003   size_t buffersize;
6004   unsigned error = lodepng_encode(&buffer, &buffersize, in, w, h, &state);
6005   if(buffer) {
6006     out.insert(out.end(), &buffer[0], &buffer[buffersize]);
6007     lodepng_free(buffer);
6008   }
6009   return error;
6010 }
6011 
encode(std::vector<unsigned char> & out,const std::vector<unsigned char> & in,unsigned w,unsigned h,State & state)6012 unsigned encode(std::vector<unsigned char>& out,
6013                 const std::vector<unsigned char>& in, unsigned w, unsigned h,
6014                 State& state) {
6015   if(lodepng_get_raw_size(w, h, &state.info_raw) > in.size()) return 84;
6016   return encode(out, in.empty() ? 0 : &in[0], w, h, state);
6017 }
6018 
6019 #ifdef LODEPNG_COMPILE_DISK
encode(const std::string & filename,const unsigned char * in,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)6020 unsigned encode(const std::string& filename,
6021                 const unsigned char* in, unsigned w, unsigned h,
6022                 LodePNGColorType colortype, unsigned bitdepth) {
6023   std::vector<unsigned char> buffer;
6024   unsigned error = encode(buffer, in, w, h, colortype, bitdepth);
6025   if(!error) error = save_file(buffer, filename);
6026   return error;
6027 }
6028 
encode(const std::string & filename,const std::vector<unsigned char> & in,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)6029 unsigned encode(const std::string& filename,
6030                 const std::vector<unsigned char>& in, unsigned w, unsigned h,
6031                 LodePNGColorType colortype, unsigned bitdepth) {
6032   if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84;
6033   return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth);
6034 }
6035 #endif /* LODEPNG_COMPILE_DISK */
6036 #endif /* LODEPNG_COMPILE_ENCODER */
6037 #endif /* LODEPNG_COMPILE_PNG */
6038 } /* namespace lodepng */
6039 #endif /*LODEPNG_COMPILE_CPP*/
6040