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