1 /*
2 LodePNG version 20230410
3
4 Copyright (c) 2005-2023 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 #if LV_USE_LODEPNG
33 #include "../../core/lv_global.h"
34
35 #define image_cache_draw_buf_handlers &(LV_GLOBAL_DEFAULT()->image_cache_draw_buf_handlers)
36
37 #ifdef LODEPNG_COMPILE_DISK
38 #include <limits.h> /* LONG_MAX */
39 #include <stdio.h> /* file handling */
40 #endif /* LODEPNG_COMPILE_DISK */
41
42 #ifdef LODEPNG_COMPILE_ALLOCATORS
43 #include <stdlib.h> /* allocations */
44 #endif /* LODEPNG_COMPILE_ALLOCATORS */
45
46 #if defined(_MSC_VER) && (_MSC_VER >= 1310) /*Visual Studio: A few warning types are not desired here.*/
47 #pragma warning( disable : 4244 ) /*implicit conversions: not warned by gcc -Wall -Wextra and requires too much casts*/
48 #pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/
49 #endif /*_MSC_VER */
50
51 const char * LODEPNG_VERSION_STRING = "20230410";
52
53 /*
54 This source file is divided into the following large parts. The code sections
55 with the "LODEPNG_COMPILE_" #defines divide this up further in an intermixed way.
56 -Tools for C and common code for PNG and Zlib
57 -C Code for Zlib (huffman, deflate, ...)
58 -C Code for PNG (file format chunks, adam7, PNG filters, color conversions, ...)
59 -The C++ wrapper around all of the above
60 */
61
62 /* ////////////////////////////////////////////////////////////////////////// */
63 /* ////////////////////////////////////////////////////////////////////////// */
64 /* // Tools for C, and common code for PNG and Zlib. // */
65 /* ////////////////////////////////////////////////////////////////////////// */
66 /* ////////////////////////////////////////////////////////////////////////// */
67
68 /*The malloc, realloc and free functions defined here with "lodepng_" in front
69 of the name, so that you can easily change them to others related to your
70 platform if needed. Everything else in the code calls these. Pass
71 -DLODEPNG_NO_COMPILE_ALLOCATORS to the compiler, or comment out
72 #define LODEPNG_COMPILE_ALLOCATORS in the header, to disable the ones here and
73 define them in your own project's source files without needing to change
74 lodepng source code. Don't forget to remove "static" if you copypaste them
75 from here.*/
76
77 #ifdef LODEPNG_COMPILE_ALLOCATORS
lodepng_malloc(size_t size)78 static void * lodepng_malloc(size_t size)
79 {
80 #ifdef LODEPNG_MAX_ALLOC
81 if(size > LODEPNG_MAX_ALLOC) return 0;
82 #endif
83 return lv_malloc(size);
84 }
85
86 /* NOTE: when realloc returns NULL, it leaves the original memory untouched */
lodepng_realloc(void * ptr,size_t new_size)87 static void * lodepng_realloc(void * ptr, size_t new_size)
88 {
89 #ifdef LODEPNG_MAX_ALLOC
90 if(new_size > LODEPNG_MAX_ALLOC) return 0;
91 #endif
92 return lv_realloc(ptr, new_size);
93 }
94
lodepng_free(void * ptr)95 static void lodepng_free(void * ptr)
96 {
97 lv_free(ptr);
98 }
99 #else /*LODEPNG_COMPILE_ALLOCATORS*/
100 /* TODO: support giving additional void* payload to the custom allocators */
101 void * lodepng_malloc(size_t size);
102 void * lodepng_realloc(void * ptr, size_t new_size);
103 void lodepng_free(void * ptr);
104 #endif /*LODEPNG_COMPILE_ALLOCATORS*/
105
106 /* convince the compiler to inline a function, for use when this measurably improves performance */
107 /* inline is not available in C90, but use it when supported by the compiler */
108 #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined(__cplusplus) && (__cplusplus >= 199711L))
109 #define LODEPNG_INLINE inline
110 #else
111 #define LODEPNG_INLINE /* not available */
112 #endif
113
114 /* restrict is not available in C90, but use it when supported by the compiler */
115 #if (defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) ||\
116 (defined(_MSC_VER) && (_MSC_VER >= 1400)) || \
117 (defined(__WATCOMC__) && (__WATCOMC__ >= 1250) && !defined(__cplusplus))
118 #define LODEPNG_RESTRICT __restrict
119 #else
120 #define LODEPNG_RESTRICT /* not available */
121 #endif
122
123 /* Replacements for C library functions such as memcpy and strlen, to support platforms
124 where a full C library is not available. The compiler can recognize them and compile
125 to something as fast. */
126
lodepng_memcpy(void * LODEPNG_RESTRICT dst,const void * LODEPNG_RESTRICT src,size_t size)127 static void lodepng_memcpy(void * LODEPNG_RESTRICT dst,
128 const void * LODEPNG_RESTRICT src, size_t size)
129 {
130 lv_memcpy(dst, src, size);
131 }
132
lodepng_memset(void * LODEPNG_RESTRICT dst,int value,size_t num)133 static void lodepng_memset(void * LODEPNG_RESTRICT dst,
134 int value, size_t num)
135 {
136 lv_memset(dst, value, num);
137 }
138
139 /* does not check memory out of bounds, do not use on untrusted data */
lodepng_strlen(const char * a)140 static size_t lodepng_strlen(const char * a)
141 {
142 const char * orig = a;
143 /* avoid warning about unused function in case of disabled COMPILE... macros */
144 (void)(&lodepng_strlen);
145 while(*a) a++;
146 return (size_t)(a - orig);
147 }
148
149 #define LODEPNG_MAX(a, b) (((a) > (b)) ? (a) : (b))
150 #define LODEPNG_MIN(a, b) (((a) < (b)) ? (a) : (b))
151
152 #if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_DECODER)
153 /* Safely check if adding two integers will overflow (no undefined
154 behavior, compiler removing the code, etc...) and output result. */
lodepng_addofl(size_t a,size_t b,size_t * result)155 static int lodepng_addofl(size_t a, size_t b, size_t * result)
156 {
157 *result = a + b; /* Unsigned addition is well defined and safe in C90 */
158 return *result < a;
159 }
160 #endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_DECODER)*/
161
162 #ifdef LODEPNG_COMPILE_DECODER
163 /* Safely check if multiplying two integers will overflow (no undefined
164 behavior, compiler removing the code, etc...) and output result. */
lodepng_mulofl(size_t a,size_t b,size_t * result)165 static int lodepng_mulofl(size_t a, size_t b, size_t * result)
166 {
167 *result = a * b; /* Unsigned multiplication is well defined and safe in C90 */
168 return (a != 0 && *result / a != b);
169 }
170
171 #ifdef LODEPNG_COMPILE_ZLIB
172 /* Safely check if a + b > c, even if overflow could happen. */
lodepng_gtofl(size_t a,size_t b,size_t c)173 static int lodepng_gtofl(size_t a, size_t b, size_t c)
174 {
175 size_t d;
176 if(lodepng_addofl(a, b, &d)) return 1;
177 return d > c;
178 }
179 #endif /*LODEPNG_COMPILE_ZLIB*/
180 #endif /*LODEPNG_COMPILE_DECODER*/
181
182
183 /*
184 Often in case of an error a value is assigned to a variable and then it breaks
185 out of a loop (to go to the cleanup phase of a function). This macro does that.
186 It makes the error handling code shorter and more readable.
187
188 Example: if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83);
189 */
190 #define CERROR_BREAK(errorvar, code){\
191 errorvar = code;\
192 break;\
193 }
194
195 /*version of CERROR_BREAK that assumes the common case where the error variable is named "error"*/
196 #define ERROR_BREAK(code) CERROR_BREAK(error, code)
197
198 /*Set error var to the error code, and return it.*/
199 #define CERROR_RETURN_ERROR(errorvar, code){\
200 errorvar = code;\
201 return code;\
202 }
203
204 /*Try the code, if it returns error, also return the error.*/
205 #define CERROR_TRY_RETURN(call){\
206 unsigned error = call;\
207 if(error) return error;\
208 }
209
210 /*Set error var to the error code, and return from the void function.*/
211 #define CERROR_RETURN(errorvar, code){\
212 errorvar = code;\
213 return;\
214 }
215
216 /*
217 About uivector, ucvector and string:
218 -All of them wrap dynamic arrays or text strings in a similar way.
219 -LodePNG was originally written in C++. The vectors replace the std::vectors that were used in the C++ version.
220 -The string tools are made to avoid problems with compilers that declare things like strncat as deprecated.
221 -They're not used in the interface, only internally in this file as static functions.
222 -As with many other structs in this file, the init and cleanup functions serve as ctor and dtor.
223 */
224
225 #ifdef LODEPNG_COMPILE_ZLIB
226 #ifdef LODEPNG_COMPILE_ENCODER
227 /*dynamic vector of unsigned ints*/
228 typedef struct uivector {
229 unsigned * data;
230 size_t size; /*size in number of unsigned longs*/
231 size_t allocsize; /*allocated size in bytes*/
232 } uivector;
233
uivector_cleanup(void * p)234 static void uivector_cleanup(void * p)
235 {
236 ((uivector *)p)->size = ((uivector *)p)->allocsize = 0;
237 lodepng_free(((uivector *)p)->data);
238 ((uivector *)p)->data = NULL;
239 }
240
241 /*returns 1 if success, 0 if failure ==> nothing done*/
uivector_resize(uivector * p,size_t size)242 static unsigned uivector_resize(uivector * p, size_t size)
243 {
244 size_t allocsize = size * sizeof(unsigned);
245 if(allocsize > p->allocsize) {
246 size_t newsize = allocsize + (p->allocsize >> 1u);
247 void * data = lodepng_realloc(p->data, newsize);
248 if(data) {
249 p->allocsize = newsize;
250 p->data = (unsigned *)data;
251 }
252 else return 0; /*error: not enough memory*/
253 }
254 p->size = size;
255 return 1; /*success*/
256 }
257
uivector_init(uivector * p)258 static void uivector_init(uivector * p)
259 {
260 p->data = NULL;
261 p->size = p->allocsize = 0;
262 }
263
264 /*returns 1 if success, 0 if failure ==> nothing done*/
uivector_push_back(uivector * p,unsigned c)265 static unsigned uivector_push_back(uivector * p, unsigned c)
266 {
267 if(!uivector_resize(p, p->size + 1)) return 0;
268 p->data[p->size - 1] = c;
269 return 1;
270 }
271 #endif /*LODEPNG_COMPILE_ENCODER*/
272 #endif /*LODEPNG_COMPILE_ZLIB*/
273
274 /* /////////////////////////////////////////////////////////////////////////// */
275
276 /*dynamic vector of unsigned chars*/
277 typedef struct ucvector {
278 unsigned char * data;
279 size_t size; /*used size*/
280 size_t allocsize; /*allocated size*/
281 } ucvector;
282
283 /*returns 1 if success, 0 if failure ==> nothing done*/
ucvector_reserve(ucvector * p,size_t size)284 static unsigned ucvector_reserve(ucvector * p, size_t size)
285 {
286 if(size > p->allocsize) {
287 size_t newsize = size + (p->allocsize >> 1u);
288 void * data = lodepng_realloc(p->data, newsize);
289 if(data) {
290 p->allocsize = newsize;
291 p->data = (unsigned char *)data;
292 }
293 else return 0; /*error: not enough memory*/
294 }
295 return 1; /*success*/
296 }
297
298 /*returns 1 if success, 0 if failure ==> nothing done*/
ucvector_resize(ucvector * p,size_t size)299 static unsigned ucvector_resize(ucvector * p, size_t size)
300 {
301 p->size = size;
302 return ucvector_reserve(p, size);
303 }
304
ucvector_init(unsigned char * buffer,size_t size)305 static ucvector ucvector_init(unsigned char * buffer, size_t size)
306 {
307 ucvector v;
308 v.data = buffer;
309 v.allocsize = v.size = size;
310 return v;
311 }
312
313 /* ////////////////////////////////////////////////////////////////////////// */
314
315 #ifdef LODEPNG_COMPILE_PNG
316 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
317
318 /*free string pointer and set it to NULL*/
string_cleanup(char ** out)319 static void string_cleanup(char ** out)
320 {
321 lodepng_free(*out);
322 *out = NULL;
323 }
324
325 /*also appends null termination character*/
alloc_string_sized(const char * in,size_t insize)326 static char * alloc_string_sized(const char * in, size_t insize)
327 {
328 char * out = (char *)lodepng_malloc(insize + 1);
329 if(out) {
330 lodepng_memcpy(out, in, insize);
331 out[insize] = 0;
332 }
333 return out;
334 }
335
336 /* dynamically allocates a new string with a copy of the null terminated input text */
alloc_string(const char * in)337 static char * alloc_string(const char * in)
338 {
339 return alloc_string_sized(in, lodepng_strlen(in));
340 }
341 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
342 #endif /*LODEPNG_COMPILE_PNG*/
343
344 /* ////////////////////////////////////////////////////////////////////////// */
345
346 #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_PNG)
lodepng_read32bitInt(const unsigned char * buffer)347 static unsigned lodepng_read32bitInt(const unsigned char * buffer)
348 {
349 return (((unsigned)buffer[0] << 24u) | ((unsigned)buffer[1] << 16u) |
350 ((unsigned)buffer[2] << 8u) | (unsigned)buffer[3]);
351 }
352 #endif /*defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_PNG)*/
353
354 #if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)
355 /*buffer must have at least 4 allocated bytes available*/
lodepng_set32bitInt(unsigned char * buffer,unsigned value)356 static void lodepng_set32bitInt(unsigned char * buffer, unsigned value)
357 {
358 buffer[0] = (unsigned char)((value >> 24) & 0xff);
359 buffer[1] = (unsigned char)((value >> 16) & 0xff);
360 buffer[2] = (unsigned char)((value >> 8) & 0xff);
361 buffer[3] = (unsigned char)((value) & 0xff);
362 }
363 #endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/
364
365 /* ////////////////////////////////////////////////////////////////////////// */
366 /* / File IO / */
367 /* ////////////////////////////////////////////////////////////////////////// */
368
369 #ifdef LODEPNG_COMPILE_DISK
370
371 /* returns negative value on error. This should be pure C compatible, so no fstat. */
lodepng_filesize(const char * filename)372 static long lodepng_filesize(const char * filename)
373 {
374 lv_fs_file_t f;
375 lv_fs_res_t res = lv_fs_open(&f, filename, LV_FS_MODE_RD);
376 if(res != LV_FS_RES_OK) return -1;
377 uint32_t size = 0;
378 if(lv_fs_seek(&f, 0, LV_FS_SEEK_END) != 0) {
379 lv_fs_close(&f);
380 return -1;
381 }
382
383 lv_fs_tell(&f, &size);
384 lv_fs_close(&f);
385 return size;
386 }
387
388 /* 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)389 static unsigned lodepng_buffer_file(unsigned char * out, size_t size, const char * filename)
390 {
391 lv_fs_file_t f;
392 lv_fs_res_t res = lv_fs_open(&f, filename, LV_FS_MODE_RD);
393 if(res != LV_FS_RES_OK) return 78;
394
395 uint32_t br;
396 res = lv_fs_read(&f, out, size, &br);
397 lv_fs_close(&f);
398
399 if(res != LV_FS_RES_OK) return 78;
400 if(br != size) return 78;
401
402 return 0;
403 }
404
lodepng_load_file(unsigned char ** out,size_t * outsize,const char * filename)405 unsigned lodepng_load_file(unsigned char ** out, size_t * outsize, const char * filename)
406 {
407 long size = lodepng_filesize(filename);
408 if(size < 0) return 78;
409 *outsize = (size_t)size;
410
411 *out = (unsigned char *)lodepng_malloc((size_t)size);
412 if(!(*out) && size > 0) return 83; /*the above malloc failed*/
413
414 return lodepng_buffer_file(*out, (size_t)size, filename);
415 }
416
417 /*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)418 unsigned lodepng_save_file(const unsigned char * buffer, size_t buffersize, const char * filename)
419 {
420 lv_fs_file_t f;
421 lv_fs_res_t res = lv_fs_open(&f, filename, LV_FS_MODE_WR);
422 if(res != LV_FS_RES_OK) return 79;
423
424 uint32_t bw;
425 res = lv_fs_write(&f, buffer, buffersize, &bw);
426 lv_fs_close(&f);
427 return 0;
428 }
429
430 #endif /*LODEPNG_COMPILE_DISK*/
431
432 /* ////////////////////////////////////////////////////////////////////////// */
433 /* ////////////////////////////////////////////////////////////////////////// */
434 /* // End of common code and tools. Begin of Zlib related code. // */
435 /* ////////////////////////////////////////////////////////////////////////// */
436 /* ////////////////////////////////////////////////////////////////////////// */
437
438 #ifdef LODEPNG_COMPILE_ZLIB
439 #ifdef LODEPNG_COMPILE_ENCODER
440
441 typedef struct {
442 ucvector * data;
443 unsigned char bp; /*ok to overflow, indicates bit pos inside byte*/
444 } LodePNGBitWriter;
445
LodePNGBitWriter_init(LodePNGBitWriter * writer,ucvector * data)446 static void LodePNGBitWriter_init(LodePNGBitWriter * writer, ucvector * data)
447 {
448 writer->data = data;
449 writer->bp = 0;
450 }
451
452 /*TODO: this ignores potential out of memory errors*/
453 #define WRITEBIT(writer, bit){\
454 /* append new byte */\
455 if(((writer->bp) & 7u) == 0) {\
456 if(!ucvector_resize(writer->data, writer->data->size + 1)) return;\
457 writer->data->data[writer->data->size - 1] = 0;\
458 }\
459 (writer->data->data[writer->data->size - 1]) |= (bit << ((writer->bp) & 7u));\
460 ++writer->bp;\
461 }
462
463 /* LSB of value is written first, and LSB of bytes is used first */
writeBits(LodePNGBitWriter * writer,unsigned value,size_t nbits)464 static void writeBits(LodePNGBitWriter * writer, unsigned value, size_t nbits)
465 {
466 if(nbits == 1) { /* compiler should statically compile this case if nbits == 1 */
467 WRITEBIT(writer, value);
468 }
469 else {
470 /* TODO: increase output size only once here rather than in each WRITEBIT */
471 size_t i;
472 for(i = 0; i != nbits; ++i) {
473 WRITEBIT(writer, (unsigned char)((value >> i) & 1));
474 }
475 }
476 }
477
478 /* This one is to use for adding huffman symbol, the value bits are written MSB first */
writeBitsReversed(LodePNGBitWriter * writer,unsigned value,size_t nbits)479 static void writeBitsReversed(LodePNGBitWriter * writer, unsigned value, size_t nbits)
480 {
481 size_t i;
482 for(i = 0; i != nbits; ++i) {
483 /* TODO: increase output size only once here rather than in each WRITEBIT */
484 WRITEBIT(writer, (unsigned char)((value >> (nbits - 1u - i)) & 1u));
485 }
486 }
487 #endif /*LODEPNG_COMPILE_ENCODER*/
488
489 #ifdef LODEPNG_COMPILE_DECODER
490
491 typedef struct {
492 const unsigned char * data;
493 size_t size; /*size of data in bytes*/
494 size_t bitsize; /*size of data in bits, end of valid bp values, should be 8*size*/
495 size_t bp;
496 unsigned buffer; /*buffer for reading bits. NOTE: 'unsigned' must support at least 32 bits*/
497 } LodePNGBitReader;
498
499 /* data size argument is in bytes. Returns error if size too large causing overflow */
LodePNGBitReader_init(LodePNGBitReader * reader,const unsigned char * data,size_t size)500 static unsigned LodePNGBitReader_init(LodePNGBitReader * reader, const unsigned char * data, size_t size)
501 {
502 size_t temp;
503 reader->data = data;
504 reader->size = size;
505 /* size in bits, return error if overflow (if size_t is 32 bit this supports up to 500MB) */
506 if(lodepng_mulofl(size, 8u, &reader->bitsize)) return 105;
507 /*ensure incremented bp can be compared to bitsize without overflow even when it would be incremented 32 too much and
508 trying to ensure 32 more bits*/
509 if(lodepng_addofl(reader->bitsize, 64u, &temp)) return 105;
510 reader->bp = 0;
511 reader->buffer = 0;
512 return 0; /*ok*/
513 }
514
515 /*
516 ensureBits functions:
517 Ensures the reader can at least read nbits bits in one or more readBits calls,
518 safely even if not enough bits are available.
519 The nbits parameter is unused but is given for documentation purposes, error
520 checking for amount of bits must be done beforehand.
521 */
522
523 /*See ensureBits documentation above. This one ensures up to 9 bits */
ensureBits9(LodePNGBitReader * reader,size_t nbits)524 static LODEPNG_INLINE void ensureBits9(LodePNGBitReader * reader, size_t nbits)
525 {
526 size_t start = reader->bp >> 3u;
527 size_t size = reader->size;
528 if(start + 1u < size) {
529 reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u);
530 reader->buffer >>= (reader->bp & 7u);
531 }
532 else {
533 reader->buffer = 0;
534 if(start + 0u < size) reader->buffer = reader->data[start + 0];
535 reader->buffer >>= (reader->bp & 7u);
536 }
537 (void)nbits;
538 }
539
540 /*See ensureBits documentation above. This one ensures up to 17 bits */
ensureBits17(LodePNGBitReader * reader,size_t nbits)541 static LODEPNG_INLINE void ensureBits17(LodePNGBitReader * reader, size_t nbits)
542 {
543 size_t start = reader->bp >> 3u;
544 size_t size = reader->size;
545 if(start + 2u < size) {
546 reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) |
547 ((unsigned)reader->data[start + 2] << 16u);
548 reader->buffer >>= (reader->bp & 7u);
549 }
550 else {
551 reader->buffer = 0;
552 if(start + 0u < size) reader->buffer |= reader->data[start + 0];
553 if(start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u);
554 reader->buffer >>= (reader->bp & 7u);
555 }
556 (void)nbits;
557 }
558
559 /*See ensureBits documentation above. This one ensures up to 25 bits */
ensureBits25(LodePNGBitReader * reader,size_t nbits)560 static LODEPNG_INLINE void ensureBits25(LodePNGBitReader * reader, size_t nbits)
561 {
562 size_t start = reader->bp >> 3u;
563 size_t size = reader->size;
564 if(start + 3u < size) {
565 reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) |
566 ((unsigned)reader->data[start + 2] << 16u) | ((unsigned)reader->data[start + 3] << 24u);
567 reader->buffer >>= (reader->bp & 7u);
568 }
569 else {
570 reader->buffer = 0;
571 if(start + 0u < size) reader->buffer |= reader->data[start + 0];
572 if(start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u);
573 if(start + 2u < size) reader->buffer |= ((unsigned)reader->data[start + 2] << 16u);
574 reader->buffer >>= (reader->bp & 7u);
575 }
576 (void)nbits;
577 }
578
579 /*See ensureBits documentation above. This one ensures up to 32 bits */
ensureBits32(LodePNGBitReader * reader,size_t nbits)580 static LODEPNG_INLINE void ensureBits32(LodePNGBitReader * reader, size_t nbits)
581 {
582 size_t start = reader->bp >> 3u;
583 size_t size = reader->size;
584 if(start + 4u < size) {
585 reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) |
586 ((unsigned)reader->data[start + 2] << 16u) | ((unsigned)reader->data[start + 3] << 24u);
587 reader->buffer >>= (reader->bp & 7u);
588 reader->buffer |= (((unsigned)reader->data[start + 4] << 24u) << (8u - (reader->bp & 7u)));
589 }
590 else {
591 reader->buffer = 0;
592 if(start + 0u < size) reader->buffer |= reader->data[start + 0];
593 if(start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u);
594 if(start + 2u < size) reader->buffer |= ((unsigned)reader->data[start + 2] << 16u);
595 if(start + 3u < size) reader->buffer |= ((unsigned)reader->data[start + 3] << 24u);
596 reader->buffer >>= (reader->bp & 7u);
597 }
598 (void)nbits;
599 }
600
601 /* Get bits without advancing the bit pointer. Must have enough bits available with ensureBits. Max nbits is 31. */
peekBits(LodePNGBitReader * reader,size_t nbits)602 static LODEPNG_INLINE unsigned peekBits(LodePNGBitReader * reader, size_t nbits)
603 {
604 /* The shift allows nbits to be only up to 31. */
605 return reader->buffer & ((1u << nbits) - 1u);
606 }
607
608 /* Must have enough bits available with ensureBits */
advanceBits(LodePNGBitReader * reader,size_t nbits)609 static LODEPNG_INLINE void advanceBits(LodePNGBitReader * reader, size_t nbits)
610 {
611 reader->buffer >>= nbits;
612 reader->bp += nbits;
613 }
614
615 /* Must have enough bits available with ensureBits */
readBits(LodePNGBitReader * reader,size_t nbits)616 static LODEPNG_INLINE unsigned readBits(LodePNGBitReader * reader, size_t nbits)
617 {
618 unsigned result = peekBits(reader, nbits);
619 advanceBits(reader, nbits);
620 return result;
621 }
622 #endif /*LODEPNG_COMPILE_DECODER*/
623
reverseBits(unsigned bits,unsigned num)624 static unsigned reverseBits(unsigned bits, unsigned num)
625 {
626 /*TODO: implement faster lookup table based version when needed*/
627 unsigned i, result = 0;
628 for(i = 0; i < num; i++) result |= ((bits >> (num - i - 1u)) & 1u) << i;
629 return result;
630 }
631
632 /* ////////////////////////////////////////////////////////////////////////// */
633 /* / Deflate - Huffman / */
634 /* ////////////////////////////////////////////////////////////////////////// */
635
636 #define FIRST_LENGTH_CODE_INDEX 257
637 #define LAST_LENGTH_CODE_INDEX 285
638 /*256 literals, the end code, some length codes, and 2 unused codes*/
639 #define NUM_DEFLATE_CODE_SYMBOLS 288
640 /*the distance codes have their own symbols, 30 used, 2 unused*/
641 #define NUM_DISTANCE_SYMBOLS 32
642 /*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/
643 #define NUM_CODE_LENGTH_CODES 19
644
645 /*the base lengths represented by codes 257-285*/
646 static const unsigned LENGTHBASE[29]
647 = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
648 67, 83, 99, 115, 131, 163, 195, 227, 258
649 };
650
651 /*the extra bits used by codes 257-285 (added to base length)*/
652 static const unsigned LENGTHEXTRA[29]
653 = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
654 4, 4, 4, 4, 5, 5, 5, 5, 0
655 };
656
657 /*the base backwards distances (the bits of distance codes appear after length codes and use their own huffman tree)*/
658 static const unsigned DISTANCEBASE[30]
659 = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513,
660 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
661 };
662
663 /*the extra bits of backwards distances (added to base)*/
664 static const unsigned DISTANCEEXTRA[30]
665 = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
666 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13
667 };
668
669 /*the order in which "code length alphabet code lengths" are stored as specified by deflate, out of this the huffman
670 tree of the dynamic huffman tree lengths is generated*/
671 static const unsigned CLCL_ORDER[NUM_CODE_LENGTH_CODES]
672 = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
673
674 /* ////////////////////////////////////////////////////////////////////////// */
675
676 /*
677 Huffman tree struct, containing multiple representations of the tree
678 */
679 typedef struct HuffmanTree {
680 unsigned * codes; /*the huffman codes (bit patterns representing the symbols)*/
681 unsigned * lengths; /*the lengths of the huffman codes*/
682 unsigned maxbitlen; /*maximum number of bits a single code can get*/
683 unsigned numcodes; /*number of symbols in the alphabet = number of codes*/
684 /* for reading only */
685 unsigned char * table_len; /*length of symbol from lookup table, or max length if secondary lookup needed*/
686 unsigned short * table_value; /*value of symbol from lookup table, or pointer to secondary table if needed*/
687 } HuffmanTree;
688
HuffmanTree_init(HuffmanTree * tree)689 static void HuffmanTree_init(HuffmanTree * tree)
690 {
691 tree->codes = 0;
692 tree->lengths = 0;
693 tree->table_len = 0;
694 tree->table_value = 0;
695 }
696
HuffmanTree_cleanup(HuffmanTree * tree)697 static void HuffmanTree_cleanup(HuffmanTree * tree)
698 {
699 lodepng_free(tree->codes);
700 lodepng_free(tree->lengths);
701 lodepng_free(tree->table_len);
702 lodepng_free(tree->table_value);
703 }
704
705 /* amount of bits for first huffman table lookup (aka root bits), see HuffmanTree_makeTable and huffmanDecodeSymbol.*/
706 /* values 8u and 9u work the fastest */
707 #define FIRSTBITS 9u
708
709 /* a symbol value too big to represent any valid symbol, to indicate reading disallowed huffman bits combination,
710 which is possible in case of only 0 or 1 present symbols. */
711 #define INVALIDSYMBOL 65535u
712
713 /* make table for huffman decoding */
HuffmanTree_makeTable(HuffmanTree * tree)714 static unsigned HuffmanTree_makeTable(HuffmanTree * tree)
715 {
716 static const unsigned headsize = 1u << FIRSTBITS; /*size of the first table*/
717 static const unsigned mask = (1u << FIRSTBITS) /*headsize*/ - 1u;
718 size_t i, numpresent, pointer, size; /*total table size*/
719 unsigned * maxlens = (unsigned *)lodepng_malloc(headsize * sizeof(unsigned));
720 if(!maxlens) return 83; /*alloc fail*/
721
722 /* compute maxlens: max total bit length of symbols sharing prefix in the first table*/
723 lodepng_memset(maxlens, 0, headsize * sizeof(*maxlens));
724 for(i = 0; i < tree->numcodes; i++) {
725 unsigned symbol = tree->codes[i];
726 unsigned l = tree->lengths[i];
727 unsigned index;
728 if(l <= FIRSTBITS) continue; /*symbols that fit in first table don't increase secondary table size*/
729 /*get the FIRSTBITS MSBs, the MSBs of the symbol are encoded first. See later comment about the reversing*/
730 index = reverseBits(symbol >> (l - FIRSTBITS), FIRSTBITS);
731 maxlens[index] = LODEPNG_MAX(maxlens[index], l);
732 }
733 /* compute total table size: size of first table plus all secondary tables for symbols longer than FIRSTBITS */
734 size = headsize;
735 for(i = 0; i < headsize; ++i) {
736 unsigned l = maxlens[i];
737 if(l > FIRSTBITS) size += (((size_t)1) << (l - FIRSTBITS));
738 }
739 tree->table_len = (unsigned char *)lodepng_malloc(size * sizeof(*tree->table_len));
740 tree->table_value = (unsigned short *)lodepng_malloc(size * sizeof(*tree->table_value));
741 if(!tree->table_len || !tree->table_value) {
742 lodepng_free(maxlens);
743 /* freeing tree->table values is done at a higher scope */
744 return 83; /*alloc fail*/
745 }
746 /*initialize with an invalid length to indicate unused entries*/
747 for(i = 0; i < size; ++i) tree->table_len[i] = 16;
748
749 /*fill in the first table for long symbols: max prefix size and pointer to secondary tables*/
750 pointer = headsize;
751 for(i = 0; i < headsize; ++i) {
752 unsigned l = maxlens[i];
753 if(l <= FIRSTBITS) continue;
754 tree->table_len[i] = l;
755 tree->table_value[i] = (unsigned short)pointer;
756 pointer += (((size_t)1) << (l - FIRSTBITS));
757 }
758 lodepng_free(maxlens);
759
760 /*fill in the first table for short symbols, or secondary table for long symbols*/
761 numpresent = 0;
762 for(i = 0; i < tree->numcodes; ++i) {
763 unsigned l = tree->lengths[i];
764 unsigned symbol, reverse;
765 if(l == 0) continue;
766 symbol = tree->codes[i]; /*the huffman bit pattern. i itself is the value.*/
767 /*reverse bits, because the huffman bits are given in MSB first order but the bit reader reads LSB first*/
768 reverse = reverseBits(symbol, l);
769 numpresent++;
770
771 if(l <= FIRSTBITS) {
772 /*short symbol, fully in first table, replicated num times if l < FIRSTBITS*/
773 unsigned num = 1u << (FIRSTBITS - l);
774 unsigned j;
775 for(j = 0; j < num; ++j) {
776 /*bit reader will read the l bits of symbol first, the remaining FIRSTBITS - l bits go to the MSB's*/
777 unsigned index = reverse | (j << l);
778 if(tree->table_len[index] != 16) return 55; /*invalid tree: long symbol shares prefix with short symbol*/
779 tree->table_len[index] = l;
780 tree->table_value[index] = (unsigned short)i;
781 }
782 }
783 else {
784 /*long symbol, shares prefix with other long symbols in first lookup table, needs second lookup*/
785 /*the FIRSTBITS MSBs of the symbol are the first table index*/
786 unsigned index = reverse & mask;
787 unsigned maxlen = tree->table_len[index];
788 /*log2 of secondary table length, should be >= l - FIRSTBITS*/
789 unsigned tablelen = maxlen - FIRSTBITS;
790 unsigned start = tree->table_value[index]; /*starting index in secondary table*/
791 unsigned num = 1u << (tablelen - (l - FIRSTBITS)); /*amount of entries of this symbol in secondary table*/
792 unsigned j;
793 if(maxlen < l) return 55; /*invalid tree: long symbol shares prefix with short symbol*/
794 for(j = 0; j < num; ++j) {
795 unsigned reverse2 = reverse >> FIRSTBITS; /* l - FIRSTBITS bits */
796 unsigned index2 = start + (reverse2 | (j << (l - FIRSTBITS)));
797 tree->table_len[index2] = l;
798 tree->table_value[index2] = (unsigned short)i;
799 }
800 }
801 }
802
803 if(numpresent < 2) {
804 /* In case of exactly 1 symbol, in theory the huffman symbol needs 0 bits,
805 but deflate uses 1 bit instead. In case of 0 symbols, no symbols can
806 appear at all, but such huffman tree could still exist (e.g. if distance
807 codes are never used). In both cases, not all symbols of the table will be
808 filled in. Fill them in with an invalid symbol value so returning them from
809 huffmanDecodeSymbol will cause error. */
810 for(i = 0; i < size; ++i) {
811 if(tree->table_len[i] == 16) {
812 /* As length, use a value smaller than FIRSTBITS for the head table,
813 and a value larger than FIRSTBITS for the secondary table, to ensure
814 valid behavior for advanceBits when reading this symbol. */
815 tree->table_len[i] = (i < headsize) ? 1 : (FIRSTBITS + 1);
816 tree->table_value[i] = INVALIDSYMBOL;
817 }
818 }
819 }
820 else {
821 /* A good huffman tree has N * 2 - 1 nodes, of which N - 1 are internal nodes.
822 If that is not the case (due to too long length codes), the table will not
823 have been fully used, and this is an error (not all bit combinations can be
824 decoded): an oversubscribed huffman tree, indicated by error 55. */
825 for(i = 0; i < size; ++i) {
826 if(tree->table_len[i] == 16) return 55;
827 }
828 }
829
830 return 0;
831 }
832
833 /*
834 Second step for the ...makeFromLengths and ...makeFromFrequencies functions.
835 numcodes, lengths and maxbitlen must already be filled in correctly. return
836 value is error.
837 */
HuffmanTree_makeFromLengths2(HuffmanTree * tree)838 static unsigned HuffmanTree_makeFromLengths2(HuffmanTree * tree)
839 {
840 unsigned * blcount;
841 unsigned * nextcode;
842 unsigned error = 0;
843 unsigned bits, n;
844
845 tree->codes = (unsigned *)lodepng_malloc(tree->numcodes * sizeof(unsigned));
846 blcount = (unsigned *)lodepng_malloc((tree->maxbitlen + 1) * sizeof(unsigned));
847 nextcode = (unsigned *)lodepng_malloc((tree->maxbitlen + 1) * sizeof(unsigned));
848 if(!tree->codes || !blcount || !nextcode) error = 83; /*alloc fail*/
849
850 if(!error) {
851 for(n = 0; n != tree->maxbitlen + 1; n++) blcount[n] = nextcode[n] = 0;
852 /*step 1: count number of instances of each code length*/
853 for(bits = 0; bits != tree->numcodes; ++bits) ++blcount[tree->lengths[bits]];
854 /*step 2: generate the nextcode values*/
855 for(bits = 1; bits <= tree->maxbitlen; ++bits) {
856 nextcode[bits] = (nextcode[bits - 1] + blcount[bits - 1]) << 1u;
857 }
858 /*step 3: generate all the codes*/
859 for(n = 0; n != tree->numcodes; ++n) {
860 if(tree->lengths[n] != 0) {
861 tree->codes[n] = nextcode[tree->lengths[n]]++;
862 /*remove superfluous bits from the code*/
863 tree->codes[n] &= ((1u << tree->lengths[n]) - 1u);
864 }
865 }
866 }
867
868 lodepng_free(blcount);
869 lodepng_free(nextcode);
870
871 if(!error) error = HuffmanTree_makeTable(tree);
872 return error;
873 }
874
875 /*
876 given the code lengths (as stored in the PNG file), generate the tree as defined
877 by Deflate. maxbitlen is the maximum bits that a code in the tree can have.
878 return value is error.
879 */
HuffmanTree_makeFromLengths(HuffmanTree * tree,const unsigned * bitlen,size_t numcodes,unsigned maxbitlen)880 static unsigned HuffmanTree_makeFromLengths(HuffmanTree * tree, const unsigned * bitlen,
881 size_t numcodes, unsigned maxbitlen)
882 {
883 unsigned i;
884 tree->lengths = (unsigned *)lodepng_malloc(numcodes * sizeof(unsigned));
885 if(!tree->lengths) return 83; /*alloc fail*/
886 for(i = 0; i != numcodes; ++i) tree->lengths[i] = bitlen[i];
887 tree->numcodes = (unsigned)numcodes; /*number of symbols*/
888 tree->maxbitlen = maxbitlen;
889 return HuffmanTree_makeFromLengths2(tree);
890 }
891
892 #ifdef LODEPNG_COMPILE_ENCODER
893
894 /*BPM: Boundary Package Merge, see "A Fast and Space-Economical Algorithm for Length-Limited Coding",
895 Jyrki Katajainen, Alistair Moffat, Andrew Turpin, 1995.*/
896
897 /*chain node for boundary package merge*/
898 typedef struct BPMNode {
899 int weight; /*the sum of all weights in this chain*/
900 unsigned index; /*index of this leaf node (called "count" in the paper)*/
901 struct BPMNode * tail; /*the next nodes in this chain (null if last)*/
902 int in_use;
903 } BPMNode;
904
905 /*lists of chains*/
906 typedef struct BPMLists {
907 /*memory pool*/
908 unsigned memsize;
909 BPMNode * memory;
910 unsigned numfree;
911 unsigned nextfree;
912 BPMNode ** freelist;
913 /*two heads of lookahead chains per list*/
914 unsigned listsize;
915 BPMNode ** chains0;
916 BPMNode ** chains1;
917 } BPMLists;
918
919 /*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)920 static BPMNode * bpmnode_create(BPMLists * lists, int weight, unsigned index, BPMNode * tail)
921 {
922 unsigned i;
923 BPMNode * result;
924
925 /*memory full, so garbage collect*/
926 if(lists->nextfree >= lists->numfree) {
927 /*mark only those that are in use*/
928 for(i = 0; i != lists->memsize; ++i) lists->memory[i].in_use = 0;
929 for(i = 0; i != lists->listsize; ++i) {
930 BPMNode * node;
931 for(node = lists->chains0[i]; node != 0; node = node->tail) node->in_use = 1;
932 for(node = lists->chains1[i]; node != 0; node = node->tail) node->in_use = 1;
933 }
934 /*collect those that are free*/
935 lists->numfree = 0;
936 for(i = 0; i != lists->memsize; ++i) {
937 if(!lists->memory[i].in_use) lists->freelist[lists->numfree++] = &lists->memory[i];
938 }
939 lists->nextfree = 0;
940 }
941
942 result = lists->freelist[lists->nextfree++];
943 result->weight = weight;
944 result->index = index;
945 result->tail = tail;
946 return result;
947 }
948
949 /*sort the leaves with stable mergesort*/
bpmnode_sort(BPMNode * leaves,size_t num)950 static void bpmnode_sort(BPMNode * leaves, size_t num)
951 {
952 BPMNode * mem = (BPMNode *)lodepng_malloc(sizeof(*leaves) * num);
953 size_t width, counter = 0;
954 for(width = 1; width < num; width *= 2) {
955 BPMNode * a = (counter & 1) ? mem : leaves;
956 BPMNode * b = (counter & 1) ? leaves : mem;
957 size_t p;
958 for(p = 0; p < num; p += 2 * width) {
959 size_t q = (p + width > num) ? num : (p + width);
960 size_t r = (p + 2 * width > num) ? num : (p + 2 * width);
961 size_t i = p, j = q, k;
962 for(k = p; k < r; k++) {
963 if(i < q && (j >= r || a[i].weight <= a[j].weight)) b[k] = a[i++];
964 else b[k] = a[j++];
965 }
966 }
967 counter++;
968 }
969 if(counter & 1) lodepng_memcpy(leaves, mem, sizeof(*leaves) * num);
970 lodepng_free(mem);
971 }
972
973 /*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)974 static void boundaryPM(BPMLists * lists, BPMNode * leaves, size_t numpresent, int c, int num)
975 {
976 unsigned lastindex = lists->chains1[c]->index;
977
978 if(c == 0) {
979 if(lastindex >= numpresent) return;
980 lists->chains0[c] = lists->chains1[c];
981 lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, 0);
982 }
983 else {
984 /*sum of the weights of the head nodes of the previous lookahead chains.*/
985 int sum = lists->chains0[c - 1]->weight + lists->chains1[c - 1]->weight;
986 lists->chains0[c] = lists->chains1[c];
987 if(lastindex < numpresent && sum > leaves[lastindex].weight) {
988 lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, lists->chains1[c]->tail);
989 return;
990 }
991 lists->chains1[c] = bpmnode_create(lists, sum, lastindex, lists->chains1[c - 1]);
992 /*in the end we are only interested in the chain of the last list, so no
993 need to recurse if we're at the last one (this gives measurable speedup)*/
994 if(num + 1 < (int)(2 * numpresent - 2)) {
995 boundaryPM(lists, leaves, numpresent, c - 1, num);
996 boundaryPM(lists, leaves, numpresent, c - 1, num);
997 }
998 }
999 }
1000
lodepng_huffman_code_lengths(unsigned * lengths,const unsigned * frequencies,size_t numcodes,unsigned maxbitlen)1001 unsigned lodepng_huffman_code_lengths(unsigned * lengths, const unsigned * frequencies,
1002 size_t numcodes, unsigned maxbitlen)
1003 {
1004 unsigned error = 0;
1005 unsigned i;
1006 size_t numpresent = 0; /*number of symbols with non-zero frequency*/
1007 BPMNode * leaves; /*the symbols, only those with > 0 frequency*/
1008
1009 if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/
1010 if((1u << maxbitlen) < (unsigned)numcodes) return 80; /*error: represent all symbols*/
1011
1012 leaves = (BPMNode *)lodepng_malloc(numcodes * sizeof(*leaves));
1013 if(!leaves) return 83; /*alloc fail*/
1014
1015 for(i = 0; i != numcodes; ++i) {
1016 if(frequencies[i] > 0) {
1017 leaves[numpresent].weight = (int)frequencies[i];
1018 leaves[numpresent].index = i;
1019 ++numpresent;
1020 }
1021 }
1022
1023 lodepng_memset(lengths, 0, numcodes * sizeof(*lengths));
1024
1025 /*ensure at least two present symbols. There should be at least one symbol
1026 according to RFC 1951 section 3.2.7. Some decoders incorrectly require two. To
1027 make these work as well ensure there are at least two symbols. The
1028 Package-Merge code below also doesn't work correctly if there's only one
1029 symbol, it'd give it the theoretical 0 bits but in practice zlib wants 1 bit*/
1030 if(numpresent == 0) {
1031 lengths[0] = lengths[1] = 1; /*note that for RFC 1951 section 3.2.7, only lengths[0] = 1 is needed*/
1032 }
1033 else if(numpresent == 1) {
1034 lengths[leaves[0].index] = 1;
1035 lengths[leaves[0].index == 0 ? 1 : 0] = 1;
1036 }
1037 else {
1038 BPMLists lists;
1039 BPMNode * node;
1040
1041 bpmnode_sort(leaves, numpresent);
1042
1043 lists.listsize = maxbitlen;
1044 lists.memsize = 2 * maxbitlen * (maxbitlen + 1);
1045 lists.nextfree = 0;
1046 lists.numfree = lists.memsize;
1047 lists.memory = (BPMNode *)lodepng_malloc(lists.memsize * sizeof(*lists.memory));
1048 lists.freelist = (BPMNode **)lodepng_malloc(lists.memsize * sizeof(BPMNode *));
1049 lists.chains0 = (BPMNode **)lodepng_malloc(lists.listsize * sizeof(BPMNode *));
1050 lists.chains1 = (BPMNode **)lodepng_malloc(lists.listsize * sizeof(BPMNode *));
1051 if(!lists.memory || !lists.freelist || !lists.chains0 || !lists.chains1) error = 83; /*alloc fail*/
1052
1053 if(!error) {
1054 for(i = 0; i != lists.memsize; ++i) lists.freelist[i] = &lists.memory[i];
1055
1056 bpmnode_create(&lists, leaves[0].weight, 1, 0);
1057 bpmnode_create(&lists, leaves[1].weight, 2, 0);
1058
1059 for(i = 0; i != lists.listsize; ++i) {
1060 lists.chains0[i] = &lists.memory[0];
1061 lists.chains1[i] = &lists.memory[1];
1062 }
1063
1064 /*each boundaryPM call adds one chain to the last list, and we need 2 * numpresent - 2 chains.*/
1065 for(i = 2; i != 2 * numpresent - 2; ++i) boundaryPM(&lists, leaves, numpresent, (int)maxbitlen - 1, (int)i);
1066
1067 for(node = lists.chains1[maxbitlen - 1]; node; node = node->tail) {
1068 for(i = 0; i != node->index; ++i) ++lengths[leaves[i].index];
1069 }
1070 }
1071
1072 lodepng_free(lists.memory);
1073 lodepng_free(lists.freelist);
1074 lodepng_free(lists.chains0);
1075 lodepng_free(lists.chains1);
1076 }
1077
1078 lodepng_free(leaves);
1079 return error;
1080 }
1081
1082 /*Create the Huffman tree given the symbol frequencies*/
HuffmanTree_makeFromFrequencies(HuffmanTree * tree,const unsigned * frequencies,size_t mincodes,size_t numcodes,unsigned maxbitlen)1083 static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree * tree, const unsigned * frequencies,
1084 size_t mincodes, size_t numcodes, unsigned maxbitlen)
1085 {
1086 unsigned error = 0;
1087 while(!frequencies[numcodes - 1] && numcodes > mincodes) --numcodes; /*trim zeroes*/
1088 tree->lengths = (unsigned *)lodepng_malloc(numcodes * sizeof(unsigned));
1089 if(!tree->lengths) return 83; /*alloc fail*/
1090 tree->maxbitlen = maxbitlen;
1091 tree->numcodes = (unsigned)numcodes; /*number of symbols*/
1092
1093 error = lodepng_huffman_code_lengths(tree->lengths, frequencies, numcodes, maxbitlen);
1094 if(!error) error = HuffmanTree_makeFromLengths2(tree);
1095 return error;
1096 }
1097 #endif /*LODEPNG_COMPILE_ENCODER*/
1098
1099 /*get the literal and length code tree of a deflated block with fixed tree, as per the deflate specification*/
generateFixedLitLenTree(HuffmanTree * tree)1100 static unsigned generateFixedLitLenTree(HuffmanTree * tree)
1101 {
1102 unsigned i, error = 0;
1103 unsigned * bitlen = (unsigned *)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned));
1104 if(!bitlen) return 83; /*alloc fail*/
1105
1106 /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/
1107 for(i = 0; i <= 143; ++i) bitlen[i] = 8;
1108 for(i = 144; i <= 255; ++i) bitlen[i] = 9;
1109 for(i = 256; i <= 279; ++i) bitlen[i] = 7;
1110 for(i = 280; i <= 287; ++i) bitlen[i] = 8;
1111
1112 error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15);
1113
1114 lodepng_free(bitlen);
1115 return error;
1116 }
1117
1118 /*get the distance code tree of a deflated block with fixed tree, as specified in the deflate specification*/
generateFixedDistanceTree(HuffmanTree * tree)1119 static unsigned generateFixedDistanceTree(HuffmanTree * tree)
1120 {
1121 unsigned i, error = 0;
1122 unsigned * bitlen = (unsigned *)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned));
1123 if(!bitlen) return 83; /*alloc fail*/
1124
1125 /*there are 32 distance codes, but 30-31 are unused*/
1126 for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen[i] = 5;
1127 error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15);
1128
1129 lodepng_free(bitlen);
1130 return error;
1131 }
1132
1133 #ifdef LODEPNG_COMPILE_DECODER
1134
1135 /*
1136 returns the code. The bit reader must already have been ensured at least 15 bits
1137 */
huffmanDecodeSymbol(LodePNGBitReader * reader,const HuffmanTree * codetree)1138 static unsigned huffmanDecodeSymbol(LodePNGBitReader * reader, const HuffmanTree * codetree)
1139 {
1140 unsigned short code = peekBits(reader, FIRSTBITS);
1141 unsigned short l = codetree->table_len[code];
1142 unsigned short value = codetree->table_value[code];
1143 if(l <= FIRSTBITS) {
1144 advanceBits(reader, l);
1145 return value;
1146 }
1147 else {
1148 advanceBits(reader, FIRSTBITS);
1149 value += peekBits(reader, l - FIRSTBITS);
1150 advanceBits(reader, codetree->table_len[value] - FIRSTBITS);
1151 return codetree->table_value[value];
1152 }
1153 }
1154 #endif /*LODEPNG_COMPILE_DECODER*/
1155
1156 #ifdef LODEPNG_COMPILE_DECODER
1157
1158 /* ////////////////////////////////////////////////////////////////////////// */
1159 /* / Inflator (Decompressor) / */
1160 /* ////////////////////////////////////////////////////////////////////////// */
1161
1162 /*get the tree of a deflated block with fixed tree, as specified in the deflate specification
1163 Returns error code.*/
getTreeInflateFixed(HuffmanTree * tree_ll,HuffmanTree * tree_d)1164 static unsigned getTreeInflateFixed(HuffmanTree * tree_ll, HuffmanTree * tree_d)
1165 {
1166 unsigned error = generateFixedLitLenTree(tree_ll);
1167 if(error) return error;
1168 return generateFixedDistanceTree(tree_d);
1169 }
1170
1171 /*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)1172 static unsigned getTreeInflateDynamic(HuffmanTree * tree_ll, HuffmanTree * tree_d,
1173 LodePNGBitReader * reader)
1174 {
1175 /*make sure that length values that aren't filled in will be 0, or a wrong tree will be generated*/
1176 unsigned error = 0;
1177 unsigned n, HLIT, HDIST, HCLEN, i;
1178
1179 /*see comments in deflateDynamic for explanation of the context and these variables, it is analogous*/
1180 unsigned * bitlen_ll = 0; /*lit,len code lengths*/
1181 unsigned * bitlen_d = 0; /*dist code lengths*/
1182 /*code length code lengths ("clcl"), the bit lengths of the huffman tree used to compress bitlen_ll and bitlen_d*/
1183 unsigned * bitlen_cl = 0;
1184 HuffmanTree tree_cl; /*the code tree for code length codes (the huffman tree for compressed huffman trees)*/
1185
1186 if(reader->bitsize - reader->bp < 14) return 49; /*error: the bit pointer is or will go past the memory*/
1187 ensureBits17(reader, 14);
1188
1189 /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/
1190 HLIT = readBits(reader, 5) + 257;
1191 /*number of distance codes. Unlike the spec, the value 1 is added to it here already*/
1192 HDIST = readBits(reader, 5) + 1;
1193 /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/
1194 HCLEN = readBits(reader, 4) + 4;
1195
1196 bitlen_cl = (unsigned *)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(unsigned));
1197 if(!bitlen_cl) return 83 /*alloc fail*/;
1198
1199 HuffmanTree_init(&tree_cl);
1200
1201 while(!error) {
1202 /*read the code length codes out of 3 * (amount of code length codes) bits*/
1203 if(lodepng_gtofl(reader->bp, HCLEN * 3, reader->bitsize)) {
1204 ERROR_BREAK(50); /*error: the bit pointer is or will go past the memory*/
1205 }
1206 for(i = 0; i != HCLEN; ++i) {
1207 ensureBits9(reader, 3); /*out of bounds already checked above */
1208 bitlen_cl[CLCL_ORDER[i]] = readBits(reader, 3);
1209 }
1210 for(i = HCLEN; i != NUM_CODE_LENGTH_CODES; ++i) {
1211 bitlen_cl[CLCL_ORDER[i]] = 0;
1212 }
1213
1214 error = HuffmanTree_makeFromLengths(&tree_cl, bitlen_cl, NUM_CODE_LENGTH_CODES, 7);
1215 if(error) break;
1216
1217 /*now we can use this tree to read the lengths for the tree that this function will return*/
1218 bitlen_ll = (unsigned *)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned));
1219 bitlen_d = (unsigned *)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned));
1220 if(!bitlen_ll || !bitlen_d) ERROR_BREAK(83 /*alloc fail*/);
1221 lodepng_memset(bitlen_ll, 0, NUM_DEFLATE_CODE_SYMBOLS * sizeof(*bitlen_ll));
1222 lodepng_memset(bitlen_d, 0, NUM_DISTANCE_SYMBOLS * sizeof(*bitlen_d));
1223
1224 /*i is the current symbol we're reading in the part that contains the code lengths of lit/len and dist codes*/
1225 i = 0;
1226 while(i < HLIT + HDIST) {
1227 unsigned code;
1228 ensureBits25(reader, 22); /* up to 15 bits for huffman code, up to 7 extra bits below*/
1229 code = huffmanDecodeSymbol(reader, &tree_cl);
1230 if(code <= 15) { /*a length code*/
1231 if(i < HLIT) bitlen_ll[i] = code;
1232 else bitlen_d[i - HLIT] = code;
1233 ++i;
1234 }
1235 else if(code == 16) { /*repeat previous*/
1236 unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/
1237 unsigned value; /*set value to the previous code*/
1238
1239 if(i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/
1240
1241 replength += readBits(reader, 2);
1242
1243 if(i < HLIT + 1) value = bitlen_ll[i - 1];
1244 else value = bitlen_d[i - HLIT - 1];
1245 /*repeat this value in the next lengths*/
1246 for(n = 0; n < replength; ++n) {
1247 if(i >= HLIT + HDIST) ERROR_BREAK(13); /*error: i is larger than the amount of codes*/
1248 if(i < HLIT) bitlen_ll[i] = value;
1249 else bitlen_d[i - HLIT] = value;
1250 ++i;
1251 }
1252 }
1253 else if(code == 17) { /*repeat "0" 3-10 times*/
1254 unsigned replength = 3; /*read in the bits that indicate repeat length*/
1255 replength += readBits(reader, 3);
1256
1257 /*repeat this value in the next lengths*/
1258 for(n = 0; n < replength; ++n) {
1259 if(i >= HLIT + HDIST) ERROR_BREAK(14); /*error: i is larger than the amount of codes*/
1260
1261 if(i < HLIT) bitlen_ll[i] = 0;
1262 else bitlen_d[i - HLIT] = 0;
1263 ++i;
1264 }
1265 }
1266 else if(code == 18) { /*repeat "0" 11-138 times*/
1267 unsigned replength = 11; /*read in the bits that indicate repeat length*/
1268 replength += readBits(reader, 7);
1269
1270 /*repeat this value in the next lengths*/
1271 for(n = 0; n < replength; ++n) {
1272 if(i >= HLIT + HDIST) ERROR_BREAK(15); /*error: i is larger than the amount of codes*/
1273
1274 if(i < HLIT) bitlen_ll[i] = 0;
1275 else bitlen_d[i - HLIT] = 0;
1276 ++i;
1277 }
1278 }
1279 else { /*if(code == INVALIDSYMBOL)*/
1280 ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/
1281 }
1282 /*check if any of the ensureBits above went out of bounds*/
1283 if(reader->bp > reader->bitsize) {
1284 /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol
1285 (10=no endcode, 11=wrong jump outside of tree)*/
1286 /* TODO: revise error codes 10,11,50: the above comment is no longer valid */
1287 ERROR_BREAK(50); /*error, bit pointer jumps past memory*/
1288 }
1289 }
1290 if(error) break;
1291
1292 if(bitlen_ll[256] == 0) ERROR_BREAK(64); /*the length of the end code 256 must be larger than 0*/
1293
1294 /*now we've finally got HLIT and HDIST, so generate the code trees, and the function is done*/
1295 error = HuffmanTree_makeFromLengths(tree_ll, bitlen_ll, NUM_DEFLATE_CODE_SYMBOLS, 15);
1296 if(error) break;
1297 error = HuffmanTree_makeFromLengths(tree_d, bitlen_d, NUM_DISTANCE_SYMBOLS, 15);
1298
1299 break; /*end of error-while*/
1300 }
1301
1302 lodepng_free(bitlen_cl);
1303 lodepng_free(bitlen_ll);
1304 lodepng_free(bitlen_d);
1305 HuffmanTree_cleanup(&tree_cl);
1306
1307 return error;
1308 }
1309
1310 /*inflate a block with dynamic of fixed Huffman tree. btype must be 1 or 2.*/
inflateHuffmanBlock(ucvector * out,LodePNGBitReader * reader,unsigned btype,size_t max_output_size)1311 static unsigned inflateHuffmanBlock(ucvector * out, LodePNGBitReader * reader,
1312 unsigned btype, size_t max_output_size)
1313 {
1314 unsigned error = 0;
1315 HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/
1316 HuffmanTree tree_d; /*the huffman tree for distance codes*/
1317 const size_t reserved_size =
1318 260; /* must be at least 258 for max length, and a few extra for adding a few extra literals */
1319 int done = 0;
1320
1321 if(!ucvector_reserve(out, out->size + reserved_size)) return 83; /*alloc fail*/
1322
1323 HuffmanTree_init(&tree_ll);
1324 HuffmanTree_init(&tree_d);
1325
1326 if(btype == 1) error = getTreeInflateFixed(&tree_ll, &tree_d);
1327 else /*if(btype == 2)*/ error = getTreeInflateDynamic(&tree_ll, &tree_d, reader);
1328
1329
1330 while(!error && !done) { /*decode all symbols until end reached, breaks at end code*/
1331 /*code_ll is literal, length or end code*/
1332 unsigned code_ll;
1333 /* ensure enough bits for 2 huffman code reads (15 bits each): if the first is a literal, a second literal is read at once. This
1334 appears to be slightly faster, than ensuring 20 bits here for 1 huffman symbol and the potential 5 extra bits for the length symbol.*/
1335 ensureBits32(reader, 30);
1336 code_ll = huffmanDecodeSymbol(reader, &tree_ll);
1337 if(code_ll <= 255) {
1338 /*slightly faster code path if multiple literals in a row*/
1339 out->data[out->size++] = (unsigned char)code_ll;
1340 code_ll = huffmanDecodeSymbol(reader, &tree_ll);
1341 }
1342 if(code_ll <= 255) { /*literal symbol*/
1343 out->data[out->size++] = (unsigned char)code_ll;
1344 }
1345 else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) { /*length code*/
1346 unsigned code_d, distance;
1347 unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/
1348 size_t start, backward, length;
1349
1350 /*part 1: get length base*/
1351 length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX];
1352
1353 /*part 2: get extra bits and add the value of that to length*/
1354 numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX];
1355 if(numextrabits_l != 0) {
1356 /* bits already ensured above */
1357 ensureBits25(reader, 5);
1358 length += readBits(reader, numextrabits_l);
1359 }
1360
1361 /*part 3: get distance code*/
1362 ensureBits32(reader, 28); /* up to 15 for the huffman symbol, up to 13 for the extra bits */
1363 code_d = huffmanDecodeSymbol(reader, &tree_d);
1364 if(code_d > 29) {
1365 if(code_d <= 31) {
1366 ERROR_BREAK(18); /*error: invalid distance code (30-31 are never used)*/
1367 }
1368 else { /* if(code_d == INVALIDSYMBOL) */
1369 ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/
1370 }
1371 }
1372 distance = DISTANCEBASE[code_d];
1373
1374 /*part 4: get extra bits from distance*/
1375 numextrabits_d = DISTANCEEXTRA[code_d];
1376 if(numextrabits_d != 0) {
1377 /* bits already ensured above */
1378 distance += readBits(reader, numextrabits_d);
1379 }
1380
1381 /*part 5: fill in all the out[n] values based on the length and dist*/
1382 start = out->size;
1383 if(distance > start) ERROR_BREAK(52); /*too long backward distance*/
1384 backward = start - distance;
1385
1386 out->size += length;
1387 if(distance < length) {
1388 size_t forward;
1389 lodepng_memcpy(out->data + start, out->data + backward, distance);
1390 start += distance;
1391 for(forward = distance; forward < length; ++forward) {
1392 out->data[start++] = out->data[backward++];
1393 }
1394 }
1395 else {
1396 lodepng_memcpy(out->data + start, out->data + backward, length);
1397 }
1398 }
1399 else if(code_ll == 256) {
1400 done = 1; /*end code, finish the loop*/
1401 }
1402 else { /*if(code_ll == INVALIDSYMBOL)*/
1403 ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/
1404 }
1405 if(out->allocsize - out->size < reserved_size) {
1406 if(!ucvector_reserve(out, out->size + reserved_size)) ERROR_BREAK(83); /*alloc fail*/
1407 }
1408 /*check if any of the ensureBits above went out of bounds*/
1409 if(reader->bp > reader->bitsize) {
1410 /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol
1411 (10=no endcode, 11=wrong jump outside of tree)*/
1412 /* TODO: revise error codes 10,11,50: the above comment is no longer valid */
1413 ERROR_BREAK(51); /*error, bit pointer jumps past memory*/
1414 }
1415 if(max_output_size && out->size > max_output_size) {
1416 ERROR_BREAK(109); /*error, larger than max size*/
1417 }
1418 }
1419
1420 HuffmanTree_cleanup(&tree_ll);
1421 HuffmanTree_cleanup(&tree_d);
1422
1423 return error;
1424 }
1425
inflateNoCompression(ucvector * out,LodePNGBitReader * reader,const LodePNGDecompressSettings * settings)1426 static unsigned inflateNoCompression(ucvector * out, LodePNGBitReader * reader,
1427 const LodePNGDecompressSettings * settings)
1428 {
1429 size_t bytepos;
1430 size_t size = reader->size;
1431 unsigned LEN, NLEN, error = 0;
1432
1433 /*go to first boundary of byte*/
1434 bytepos = (reader->bp + 7u) >> 3u;
1435
1436 /*read LEN (2 bytes) and NLEN (2 bytes)*/
1437 if(bytepos + 4 >= size) return 52; /*error, bit pointer will jump past memory*/
1438 LEN = (unsigned)reader->data[bytepos] + ((unsigned)reader->data[bytepos + 1] << 8u);
1439 bytepos += 2;
1440 NLEN = (unsigned)reader->data[bytepos] + ((unsigned)reader->data[bytepos + 1] << 8u);
1441 bytepos += 2;
1442
1443 /*check if 16-bit NLEN is really the one's complement of LEN*/
1444 if(!settings->ignore_nlen && LEN + NLEN != 65535) {
1445 return 21; /*error: NLEN is not one's complement of LEN*/
1446 }
1447
1448 if(!ucvector_resize(out, out->size + LEN)) return 83; /*alloc fail*/
1449
1450 /*read the literal data: LEN bytes are now stored in the out buffer*/
1451 if(bytepos + LEN > size) return 23; /*error: reading outside of in buffer*/
1452
1453 /*out->data can be NULL (when LEN is zero), and arithmetics on NULL ptr is undefined*/
1454 if(LEN) {
1455 lodepng_memcpy(out->data + out->size - LEN, reader->data + bytepos, LEN);
1456 bytepos += LEN;
1457 }
1458
1459 reader->bp = bytepos << 3u;
1460
1461 return error;
1462 }
1463
lodepng_inflatev(ucvector * out,const unsigned char * in,size_t insize,const LodePNGDecompressSettings * settings)1464 static unsigned lodepng_inflatev(ucvector * out,
1465 const unsigned char * in, size_t insize,
1466 const LodePNGDecompressSettings * settings)
1467 {
1468 unsigned BFINAL = 0;
1469 LodePNGBitReader reader;
1470 unsigned error = LodePNGBitReader_init(&reader, in, insize);
1471
1472 if(error) return error;
1473
1474 while(!BFINAL) {
1475 unsigned BTYPE;
1476 if(reader.bitsize - reader.bp < 3) return 52; /*error, bit pointer will jump past memory*/
1477 ensureBits9(&reader, 3);
1478 BFINAL = readBits(&reader, 1);
1479 BTYPE = readBits(&reader, 2);
1480
1481 if(BTYPE == 3) return 20; /*error: invalid BTYPE*/
1482 else if(BTYPE == 0) error = inflateNoCompression(out, &reader, settings); /*no compression*/
1483 else error = inflateHuffmanBlock(out, &reader, BTYPE, settings->max_output_size); /*compression, BTYPE 01 or 10*/
1484 if(!error && settings->max_output_size && out->size > settings->max_output_size) error = 109;
1485 if(error) break;
1486 }
1487
1488 return error;
1489 }
1490
lodepng_inflate(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGDecompressSettings * settings)1491 unsigned lodepng_inflate(unsigned char ** out, size_t * outsize,
1492 const unsigned char * in, size_t insize,
1493 const LodePNGDecompressSettings * settings)
1494 {
1495 ucvector v = ucvector_init(*out, *outsize);
1496 unsigned error = lodepng_inflatev(&v, in, insize, settings);
1497 *out = v.data;
1498 *outsize = v.size;
1499 return error;
1500 }
1501
inflatev(ucvector * out,const unsigned char * in,size_t insize,const LodePNGDecompressSettings * settings)1502 static unsigned inflatev(ucvector * out, const unsigned char * in, size_t insize,
1503 const LodePNGDecompressSettings * settings)
1504 {
1505 if(settings->custom_inflate) {
1506 unsigned error = settings->custom_inflate(&out->data, &out->size, in, insize, settings);
1507 out->allocsize = out->size;
1508 if(error) {
1509 /*the custom inflate is allowed to have its own error codes, however, we translate it to code 110*/
1510 error = 110;
1511 /*if there's a max output size, and the custom zlib returned error, then indicate that error instead*/
1512 if(settings->max_output_size && out->size > settings->max_output_size) error = 109;
1513 }
1514 return error;
1515 }
1516 else {
1517 return lodepng_inflatev(out, in, insize, settings);
1518 }
1519 }
1520
1521 #endif /*LODEPNG_COMPILE_DECODER*/
1522
1523 #ifdef LODEPNG_COMPILE_ENCODER
1524
1525 /* ////////////////////////////////////////////////////////////////////////// */
1526 /* / Deflator (Compressor) / */
1527 /* ////////////////////////////////////////////////////////////////////////// */
1528
1529 static const unsigned MAX_SUPPORTED_DEFLATE_LENGTH = 258;
1530
1531 /*search the index in the array, that has the largest value smaller than or equal to the given value,
1532 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)1533 static size_t searchCodeIndex(const unsigned * array, size_t array_size, size_t value)
1534 {
1535 /*binary search (only small gain over linear). TODO: use CPU log2 instruction for getting symbols instead*/
1536 size_t left = 1;
1537 size_t right = array_size - 1;
1538
1539 while(left <= right) {
1540 size_t mid = (left + right) >> 1;
1541 if(array[mid] >= value) right = mid - 1;
1542 else left = mid + 1;
1543 }
1544 if(left >= array_size || array[left] > value) left--;
1545 return left;
1546 }
1547
addLengthDistance(uivector * values,size_t length,size_t distance)1548 static void addLengthDistance(uivector * values, size_t length, size_t distance)
1549 {
1550 /*values in encoded vector are those used by deflate:
1551 0-255: literal bytes
1552 256: end
1553 257-285: length/distance pair (length code, followed by extra length bits, distance code, extra distance bits)
1554 286-287: invalid*/
1555
1556 unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length);
1557 unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]);
1558 unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance);
1559 unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]);
1560
1561 size_t pos = values->size;
1562 /*TODO: return error when this fails (out of memory)*/
1563 unsigned ok = uivector_resize(values, values->size + 4);
1564 if(ok) {
1565 values->data[pos + 0] = length_code + FIRST_LENGTH_CODE_INDEX;
1566 values->data[pos + 1] = extra_length;
1567 values->data[pos + 2] = dist_code;
1568 values->data[pos + 3] = extra_distance;
1569 }
1570 }
1571
1572 /*3 bytes of data get encoded into two bytes. The hash cannot use more than 3
1573 bytes as input because 3 is the minimum match length for deflate*/
1574 static const unsigned HASH_NUM_VALUES = 65536;
1575 static const unsigned HASH_BIT_MASK = 65535; /*HASH_NUM_VALUES - 1, but C90 does not like that as initializer*/
1576
1577 typedef struct Hash {
1578 int * head; /*hash value to head circular pos - can be outdated if went around window*/
1579 /*circular pos to prev circular pos*/
1580 unsigned short * chain;
1581 int * val; /*circular pos to hash value*/
1582
1583 /*TODO: do this not only for zeros but for any repeated byte. However for PNG
1584 it's always going to be the zeros that dominate, so not important for PNG*/
1585 int * headz; /*similar to head, but for chainz*/
1586 unsigned short * chainz; /*those with same amount of zeros*/
1587 unsigned short * zeros; /*length of zeros streak, used as a second hash chain*/
1588 } Hash;
1589
hash_init(Hash * hash,unsigned windowsize)1590 static unsigned hash_init(Hash * hash, unsigned windowsize)
1591 {
1592 unsigned i;
1593 hash->head = (int *)lodepng_malloc(sizeof(int) * HASH_NUM_VALUES);
1594 hash->val = (int *)lodepng_malloc(sizeof(int) * windowsize);
1595 hash->chain = (unsigned short *)lodepng_malloc(sizeof(unsigned short) * windowsize);
1596
1597 hash->zeros = (unsigned short *)lodepng_malloc(sizeof(unsigned short) * windowsize);
1598 hash->headz = (int *)lodepng_malloc(sizeof(int) * (MAX_SUPPORTED_DEFLATE_LENGTH + 1));
1599 hash->chainz = (unsigned short *)lodepng_malloc(sizeof(unsigned short) * windowsize);
1600
1601 if(!hash->head || !hash->chain || !hash->val || !hash->headz || !hash->chainz || !hash->zeros) {
1602 return 83; /*alloc fail*/
1603 }
1604
1605 /*initialize hash table*/
1606 for(i = 0; i != HASH_NUM_VALUES; ++i) hash->head[i] = -1;
1607 for(i = 0; i != windowsize; ++i) hash->val[i] = -1;
1608 for(i = 0; i != windowsize; ++i) hash->chain[i] = i; /*same value as index indicates uninitialized*/
1609
1610 for(i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; ++i) hash->headz[i] = -1;
1611 for(i = 0; i != windowsize; ++i) hash->chainz[i] = i; /*same value as index indicates uninitialized*/
1612
1613 return 0;
1614 }
1615
hash_cleanup(Hash * hash)1616 static void hash_cleanup(Hash * hash)
1617 {
1618 lodepng_free(hash->head);
1619 lodepng_free(hash->val);
1620 lodepng_free(hash->chain);
1621
1622 lodepng_free(hash->zeros);
1623 lodepng_free(hash->headz);
1624 lodepng_free(hash->chainz);
1625 }
1626
1627
1628
getHash(const unsigned char * data,size_t size,size_t pos)1629 static unsigned getHash(const unsigned char * data, size_t size, size_t pos)
1630 {
1631 unsigned result = 0;
1632 if(pos + 2 < size) {
1633 /*A simple shift and xor hash is used. Since the data of PNGs is dominated
1634 by zeroes due to the filters, a better hash does not have a significant
1635 effect on speed in traversing the chain, and causes more time spend on
1636 calculating the hash.*/
1637 result ^= ((unsigned)data[pos + 0] << 0u);
1638 result ^= ((unsigned)data[pos + 1] << 4u);
1639 result ^= ((unsigned)data[pos + 2] << 8u);
1640 }
1641 else {
1642 size_t amount, i;
1643 if(pos >= size) return 0;
1644 amount = size - pos;
1645 for(i = 0; i != amount; ++i) result ^= ((unsigned)data[pos + i] << (i * 8u));
1646 }
1647 return result & HASH_BIT_MASK;
1648 }
1649
countZeros(const unsigned char * data,size_t size,size_t pos)1650 static unsigned countZeros(const unsigned char * data, size_t size, size_t pos)
1651 {
1652 const unsigned char * start = data + pos;
1653 const unsigned char * end = start + MAX_SUPPORTED_DEFLATE_LENGTH;
1654 if(end > data + size) end = data + size;
1655 data = start;
1656 while(data != end && *data == 0) ++data;
1657 /*subtracting two addresses returned as 32-bit number (max value is MAX_SUPPORTED_DEFLATE_LENGTH)*/
1658 return (unsigned)(data - start);
1659 }
1660
1661 /*wpos = pos & (windowsize - 1)*/
updateHashChain(Hash * hash,size_t wpos,unsigned hashval,unsigned short numzeros)1662 static void updateHashChain(Hash * hash, size_t wpos, unsigned hashval, unsigned short numzeros)
1663 {
1664 hash->val[wpos] = (int)hashval;
1665 if(hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval];
1666 hash->head[hashval] = (int)wpos;
1667
1668 hash->zeros[wpos] = numzeros;
1669 if(hash->headz[numzeros] != -1) hash->chainz[wpos] = hash->headz[numzeros];
1670 hash->headz[numzeros] = (int)wpos;
1671 }
1672
1673 /*
1674 LZ77-encode the data. Return value is error code. The input are raw bytes, the output
1675 is in the form of unsigned integers with codes representing for example literal bytes, or
1676 length/distance pairs.
1677 It uses a hash table technique to let it encode faster. When doing LZ77 encoding, a
1678 sliding window (of windowsize) is used, and all past bytes in that window can be used as
1679 the "dictionary". A brute force search through all possible distances would be slow, and
1680 this hash technique is one out of several ways to speed this up.
1681 */
encodeLZ77(uivector * out,Hash * hash,const unsigned char * in,size_t inpos,size_t insize,unsigned windowsize,unsigned minmatch,unsigned nicematch,unsigned lazymatching)1682 static unsigned encodeLZ77(uivector * out, Hash * hash,
1683 const unsigned char * in, size_t inpos, size_t insize, unsigned windowsize,
1684 unsigned minmatch, unsigned nicematch, unsigned lazymatching)
1685 {
1686 size_t pos;
1687 unsigned i, error = 0;
1688 /*for large window lengths, assume the user wants no compression loss. Otherwise, max hash chain length speedup.*/
1689 unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8u;
1690 unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64;
1691
1692 unsigned usezeros = 1; /*not sure if setting it to false for windowsize < 8192 is better or worse*/
1693 unsigned numzeros = 0;
1694
1695 unsigned offset; /*the offset represents the distance in LZ77 terminology*/
1696 unsigned length;
1697 unsigned lazy = 0;
1698 unsigned lazylength = 0, lazyoffset = 0;
1699 unsigned hashval;
1700 unsigned current_offset, current_length;
1701 unsigned prev_offset;
1702 const unsigned char * lastptr, * foreptr, * backptr;
1703 unsigned hashpos;
1704
1705 if(windowsize == 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/
1706 if((windowsize & (windowsize - 1)) != 0) return 90; /*error: must be power of two*/
1707
1708 if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH;
1709
1710 for(pos = inpos; pos < insize; ++pos) {
1711 size_t wpos = pos & (windowsize - 1); /*position for in 'circular' hash buffers*/
1712 unsigned chainlength = 0;
1713
1714 hashval = getHash(in, insize, pos);
1715
1716 if(usezeros && hashval == 0) {
1717 if(numzeros == 0) numzeros = countZeros(in, insize, pos);
1718 else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros;
1719 }
1720 else {
1721 numzeros = 0;
1722 }
1723
1724 updateHashChain(hash, wpos, hashval, numzeros);
1725
1726 /*the length and offset found for the current position*/
1727 length = 0;
1728 offset = 0;
1729
1730 hashpos = hash->chain[wpos];
1731
1732 lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH];
1733
1734 /*search for the longest string*/
1735 prev_offset = 0;
1736 for(;;) {
1737 if(chainlength++ >= maxchainlength) break;
1738 current_offset = (unsigned)(hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize);
1739
1740 if(current_offset < prev_offset) break; /*stop when went completely around the circular buffer*/
1741 prev_offset = current_offset;
1742 if(current_offset > 0) {
1743 /*test the next characters*/
1744 foreptr = &in[pos];
1745 backptr = &in[pos - current_offset];
1746
1747 /*common case in PNGs is lots of zeros. Quickly skip over them as a speedup*/
1748 if(numzeros >= 3) {
1749 unsigned skip = hash->zeros[hashpos];
1750 if(skip > numzeros) skip = numzeros;
1751 backptr += skip;
1752 foreptr += skip;
1753 }
1754
1755 while(foreptr != lastptr && *backptr == *foreptr) { /*maximum supported length by deflate is max length*/
1756 ++backptr;
1757 ++foreptr;
1758 }
1759 current_length = (unsigned)(foreptr - &in[pos]);
1760
1761 if(current_length > length) {
1762 length = current_length; /*the longest length*/
1763 offset = current_offset; /*the offset that is related to this longest length*/
1764 /*jump out once a length of max length is found (speed gain). This also jumps
1765 out if length is MAX_SUPPORTED_DEFLATE_LENGTH*/
1766 if(current_length >= nicematch) break;
1767 }
1768 }
1769
1770 if(hashpos == hash->chain[hashpos]) break;
1771
1772 if(numzeros >= 3 && length > numzeros) {
1773 hashpos = hash->chainz[hashpos];
1774 if(hash->zeros[hashpos] != numzeros) break;
1775 }
1776 else {
1777 hashpos = hash->chain[hashpos];
1778 /*outdated hash value, happens if particular value was not encountered in whole last window*/
1779 if(hash->val[hashpos] != (int)hashval) break;
1780 }
1781 }
1782
1783 if(lazymatching) {
1784 if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH) {
1785 lazy = 1;
1786 lazylength = length;
1787 lazyoffset = offset;
1788 continue; /*try the next byte*/
1789 }
1790 if(lazy) {
1791 lazy = 0;
1792 if(pos == 0) ERROR_BREAK(81);
1793 if(length > lazylength + 1) {
1794 /*push the previous character as literal*/
1795 if(!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 /*alloc fail*/);
1796 }
1797 else {
1798 length = lazylength;
1799 offset = lazyoffset;
1800 hash->head[hashval] = -1; /*the same hashchain update will be done, this ensures no wrong alteration*/
1801 hash->headz[numzeros] = -1; /*idem*/
1802 --pos;
1803 }
1804 }
1805 }
1806 if(length >= 3 && offset > windowsize) ERROR_BREAK(86 /*too big (or overflown negative) offset*/);
1807
1808 /*encode it as length/distance pair or literal value*/
1809 if(length < 3) { /*only lengths of 3 or higher are supported as length/distance pair*/
1810 if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/);
1811 }
1812 else if(length < minmatch || (length == 3 && offset > 4096)) {
1813 /*compensate for the fact that longer offsets have more extra bits, a
1814 length of only 3 may be not worth it then*/
1815 if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/);
1816 }
1817 else {
1818 addLengthDistance(out, length, offset);
1819 for(i = 1; i < length; ++i) {
1820 ++pos;
1821 wpos = pos & (windowsize - 1);
1822 hashval = getHash(in, insize, pos);
1823 if(usezeros && hashval == 0) {
1824 if(numzeros == 0) numzeros = countZeros(in, insize, pos);
1825 else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros;
1826 }
1827 else {
1828 numzeros = 0;
1829 }
1830 updateHashChain(hash, wpos, hashval, numzeros);
1831 }
1832 }
1833 } /*end of the loop through each character of input*/
1834
1835 return error;
1836 }
1837
1838 /* /////////////////////////////////////////////////////////////////////////// */
1839
deflateNoCompression(ucvector * out,const unsigned char * data,size_t datasize)1840 static unsigned deflateNoCompression(ucvector * out, const unsigned char * data, size_t datasize)
1841 {
1842 /*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte,
1843 2 bytes LEN, 2 bytes NLEN, LEN bytes literal DATA*/
1844
1845 size_t i, numdeflateblocks = (datasize + 65534u) / 65535u;
1846 unsigned datapos = 0;
1847 for(i = 0; i != numdeflateblocks; ++i) {
1848 unsigned BFINAL, BTYPE, LEN, NLEN;
1849 unsigned char firstbyte;
1850 size_t pos = out->size;
1851
1852 BFINAL = (i == numdeflateblocks - 1);
1853 BTYPE = 0;
1854
1855 LEN = 65535;
1856 if(datasize - datapos < 65535u) LEN = (unsigned)datasize - datapos;
1857 NLEN = 65535 - LEN;
1858
1859 if(!ucvector_resize(out, out->size + LEN + 5)) return 83; /*alloc fail*/
1860
1861 firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1u) << 1u) + ((BTYPE & 2u) << 1u));
1862 out->data[pos + 0] = firstbyte;
1863 out->data[pos + 1] = (unsigned char)(LEN & 255);
1864 out->data[pos + 2] = (unsigned char)(LEN >> 8u);
1865 out->data[pos + 3] = (unsigned char)(NLEN & 255);
1866 out->data[pos + 4] = (unsigned char)(NLEN >> 8u);
1867 lodepng_memcpy(out->data + pos + 5, data + datapos, LEN);
1868 datapos += LEN;
1869 }
1870
1871 return 0;
1872 }
1873
1874 /*
1875 write the lz77-encoded data, which has lit, len and dist codes, to compressed stream using huffman trees.
1876 tree_ll: the tree for lit and len codes.
1877 tree_d: the tree for distance codes.
1878 */
writeLZ77data(LodePNGBitWriter * writer,const uivector * lz77_encoded,const HuffmanTree * tree_ll,const HuffmanTree * tree_d)1879 static void writeLZ77data(LodePNGBitWriter * writer, const uivector * lz77_encoded,
1880 const HuffmanTree * tree_ll, const HuffmanTree * tree_d)
1881 {
1882 size_t i = 0;
1883 for(i = 0; i != lz77_encoded->size; ++i) {
1884 unsigned val = lz77_encoded->data[i];
1885 writeBitsReversed(writer, tree_ll->codes[val], tree_ll->lengths[val]);
1886 if(val > 256) { /*for a length code, 3 more things have to be added*/
1887 unsigned length_index = val - FIRST_LENGTH_CODE_INDEX;
1888 unsigned n_length_extra_bits = LENGTHEXTRA[length_index];
1889 unsigned length_extra_bits = lz77_encoded->data[++i];
1890
1891 unsigned distance_code = lz77_encoded->data[++i];
1892
1893 unsigned distance_index = distance_code;
1894 unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index];
1895 unsigned distance_extra_bits = lz77_encoded->data[++i];
1896
1897 writeBits(writer, length_extra_bits, n_length_extra_bits);
1898 writeBitsReversed(writer, tree_d->codes[distance_code], tree_d->lengths[distance_code]);
1899 writeBits(writer, distance_extra_bits, n_distance_extra_bits);
1900 }
1901 }
1902 }
1903
1904 /*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)1905 static unsigned deflateDynamic(LodePNGBitWriter * writer, Hash * hash,
1906 const unsigned char * data, size_t datapos, size_t dataend,
1907 const LodePNGCompressSettings * settings, unsigned final)
1908 {
1909 unsigned error = 0;
1910
1911 /*
1912 A block is compressed as follows: The PNG data is lz77 encoded, resulting in
1913 literal bytes and length/distance pairs. This is then huffman compressed with
1914 two huffman trees. One huffman tree is used for the lit and len values ("ll"),
1915 another huffman tree is used for the dist values ("d"). These two trees are
1916 stored using their code lengths, and to compress even more these code lengths
1917 are also run-length encoded and huffman compressed. This gives a huffman tree
1918 of code lengths "cl". The code lengths used to describe this third tree are
1919 the code length code lengths ("clcl").
1920 */
1921
1922 /*The lz77 encoded data, represented with integers since there will also be length and distance codes in it*/
1923 uivector lz77_encoded;
1924 HuffmanTree tree_ll; /*tree for lit,len values*/
1925 HuffmanTree tree_d; /*tree for distance codes*/
1926 HuffmanTree tree_cl; /*tree for encoding the code lengths representing tree_ll and tree_d*/
1927 unsigned * frequencies_ll = 0; /*frequency of lit,len codes*/
1928 unsigned * frequencies_d = 0; /*frequency of dist codes*/
1929 unsigned * frequencies_cl = 0; /*frequency of code length codes*/
1930 unsigned * bitlen_lld = 0; /*lit,len,dist code lengths (int bits), literally (without repeat codes).*/
1931 unsigned * bitlen_lld_e = 0; /*bitlen_lld encoded with repeat codes (this is a rudimentary run length compression)*/
1932 size_t datasize = dataend - datapos;
1933
1934 /*
1935 If we could call "bitlen_cl" the code length code lengths ("clcl"), that is the bit lengths of codes to represent
1936 tree_cl in CLCL_ORDER, then due to the huffman compression of huffman tree representations ("two levels"), there are
1937 some analogies:
1938 bitlen_lld is to tree_cl what data is to tree_ll and tree_d.
1939 bitlen_lld_e is to bitlen_lld what lz77_encoded is to data.
1940 bitlen_cl is to bitlen_lld_e what bitlen_lld is to lz77_encoded.
1941 */
1942
1943 unsigned BFINAL = final;
1944 size_t i;
1945 size_t numcodes_ll, numcodes_d, numcodes_lld, numcodes_lld_e, numcodes_cl;
1946 unsigned HLIT, HDIST, HCLEN;
1947
1948 uivector_init(&lz77_encoded);
1949 HuffmanTree_init(&tree_ll);
1950 HuffmanTree_init(&tree_d);
1951 HuffmanTree_init(&tree_cl);
1952 /* could fit on stack, but >1KB is on the larger side so allocate instead */
1953 frequencies_ll = (unsigned *)lodepng_malloc(286 * sizeof(*frequencies_ll));
1954 frequencies_d = (unsigned *)lodepng_malloc(30 * sizeof(*frequencies_d));
1955 frequencies_cl = (unsigned *)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(*frequencies_cl));
1956
1957 if(!frequencies_ll || !frequencies_d || !frequencies_cl) error = 83; /*alloc fail*/
1958
1959 /*This while loop never loops due to a break at the end, it is here to
1960 allow breaking out of it to the cleanup phase on error conditions.*/
1961 while(!error) {
1962 lodepng_memset(frequencies_ll, 0, 286 * sizeof(*frequencies_ll));
1963 lodepng_memset(frequencies_d, 0, 30 * sizeof(*frequencies_d));
1964 lodepng_memset(frequencies_cl, 0, NUM_CODE_LENGTH_CODES * sizeof(*frequencies_cl));
1965
1966 if(settings->use_lz77) {
1967 error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize,
1968 settings->minmatch, settings->nicematch, settings->lazymatching);
1969 if(error) break;
1970 }
1971 else {
1972 if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 /*alloc fail*/);
1973 for(i = datapos; i < dataend;
1974 ++i) lz77_encoded.data[i - datapos] = data[i]; /*no LZ77, but still will be Huffman compressed*/
1975 }
1976
1977 /*Count the frequencies of lit, len and dist codes*/
1978 for(i = 0; i != lz77_encoded.size; ++i) {
1979 unsigned symbol = lz77_encoded.data[i];
1980 ++frequencies_ll[symbol];
1981 if(symbol > 256) {
1982 unsigned dist = lz77_encoded.data[i + 2];
1983 ++frequencies_d[dist];
1984 i += 3;
1985 }
1986 }
1987 frequencies_ll[256] = 1; /*there will be exactly 1 end code, at the end of the block*/
1988
1989 /*Make both huffman trees, one for the lit and len codes, one for the dist codes*/
1990 error = HuffmanTree_makeFromFrequencies(&tree_ll, frequencies_ll, 257, 286, 15);
1991 if(error) break;
1992 /*2, not 1, is chosen for mincodes: some buggy PNG decoders require at least 2 symbols in the dist tree*/
1993 error = HuffmanTree_makeFromFrequencies(&tree_d, frequencies_d, 2, 30, 15);
1994 if(error) break;
1995
1996 numcodes_ll = LODEPNG_MIN(tree_ll.numcodes, 286);
1997 numcodes_d = LODEPNG_MIN(tree_d.numcodes, 30);
1998 /*store the code lengths of both generated trees in bitlen_lld*/
1999 numcodes_lld = numcodes_ll + numcodes_d;
2000 bitlen_lld = (unsigned *)lodepng_malloc(numcodes_lld * sizeof(*bitlen_lld));
2001 /*numcodes_lld_e never needs more size than bitlen_lld*/
2002 bitlen_lld_e = (unsigned *)lodepng_malloc(numcodes_lld * sizeof(*bitlen_lld_e));
2003 if(!bitlen_lld || !bitlen_lld_e) ERROR_BREAK(83); /*alloc fail*/
2004 numcodes_lld_e = 0;
2005
2006 for(i = 0; i != numcodes_ll; ++i) bitlen_lld[i] = tree_ll.lengths[i];
2007 for(i = 0; i != numcodes_d; ++i) bitlen_lld[numcodes_ll + i] = tree_d.lengths[i];
2008
2009 /*run-length compress bitlen_ldd into bitlen_lld_e by using repeat codes 16 (copy length 3-6 times),
2010 17 (3-10 zeroes), 18 (11-138 zeroes)*/
2011 for(i = 0; i != numcodes_lld; ++i) {
2012 unsigned j = 0; /*amount of repetitions*/
2013 while(i + j + 1 < numcodes_lld && bitlen_lld[i + j + 1] == bitlen_lld[i]) ++j;
2014
2015 if(bitlen_lld[i] == 0 && j >= 2) { /*repeat code for zeroes*/
2016 ++j; /*include the first zero*/
2017 if(j <= 10) { /*repeat code 17 supports max 10 zeroes*/
2018 bitlen_lld_e[numcodes_lld_e++] = 17;
2019 bitlen_lld_e[numcodes_lld_e++] = j - 3;
2020 }
2021 else { /*repeat code 18 supports max 138 zeroes*/
2022 if(j > 138) j = 138;
2023 bitlen_lld_e[numcodes_lld_e++] = 18;
2024 bitlen_lld_e[numcodes_lld_e++] = j - 11;
2025 }
2026 i += (j - 1);
2027 }
2028 else if(j >= 3) { /*repeat code for value other than zero*/
2029 size_t k;
2030 unsigned num = j / 6u, rest = j % 6u;
2031 bitlen_lld_e[numcodes_lld_e++] = bitlen_lld[i];
2032 for(k = 0; k < num; ++k) {
2033 bitlen_lld_e[numcodes_lld_e++] = 16;
2034 bitlen_lld_e[numcodes_lld_e++] = 6 - 3;
2035 }
2036 if(rest >= 3) {
2037 bitlen_lld_e[numcodes_lld_e++] = 16;
2038 bitlen_lld_e[numcodes_lld_e++] = rest - 3;
2039 }
2040 else j -= rest;
2041 i += j;
2042 }
2043 else { /*too short to benefit from repeat code*/
2044 bitlen_lld_e[numcodes_lld_e++] = bitlen_lld[i];
2045 }
2046 }
2047
2048 /*generate tree_cl, the huffmantree of huffmantrees*/
2049 for(i = 0; i != numcodes_lld_e; ++i) {
2050 ++frequencies_cl[bitlen_lld_e[i]];
2051 /*after a repeat code come the bits that specify the number of repetitions,
2052 those don't need to be in the frequencies_cl calculation*/
2053 if(bitlen_lld_e[i] >= 16) ++i;
2054 }
2055
2056 error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl,
2057 NUM_CODE_LENGTH_CODES, NUM_CODE_LENGTH_CODES, 7);
2058 if(error) break;
2059
2060 /*compute amount of code-length-code-lengths to output*/
2061 numcodes_cl = NUM_CODE_LENGTH_CODES;
2062 /*trim zeros at the end (using CLCL_ORDER), but minimum size must be 4 (see HCLEN below)*/
2063 while(numcodes_cl > 4u && tree_cl.lengths[CLCL_ORDER[numcodes_cl - 1u]] == 0) {
2064 numcodes_cl--;
2065 }
2066
2067 /*
2068 Write everything into the output
2069
2070 After the BFINAL and BTYPE, the dynamic block consists out of the following:
2071 - 5 bits HLIT, 5 bits HDIST, 4 bits HCLEN
2072 - (HCLEN+4)*3 bits code lengths of code length alphabet
2073 - HLIT + 257 code lengths of lit/length alphabet (encoded using the code length
2074 alphabet, + possible repetition codes 16, 17, 18)
2075 - HDIST + 1 code lengths of distance alphabet (encoded using the code length
2076 alphabet, + possible repetition codes 16, 17, 18)
2077 - compressed data
2078 - 256 (end code)
2079 */
2080
2081 /*Write block type*/
2082 writeBits(writer, BFINAL, 1);
2083 writeBits(writer, 0, 1); /*first bit of BTYPE "dynamic"*/
2084 writeBits(writer, 1, 1); /*second bit of BTYPE "dynamic"*/
2085
2086 /*write the HLIT, HDIST and HCLEN values*/
2087 /*all three sizes take trimmed ending zeroes into account, done either by HuffmanTree_makeFromFrequencies
2088 or in the loop for numcodes_cl above, which saves space. */
2089 HLIT = (unsigned)(numcodes_ll - 257);
2090 HDIST = (unsigned)(numcodes_d - 1);
2091 HCLEN = (unsigned)(numcodes_cl - 4);
2092 writeBits(writer, HLIT, 5);
2093 writeBits(writer, HDIST, 5);
2094 writeBits(writer, HCLEN, 4);
2095
2096 /*write the code lengths of the code length alphabet ("bitlen_cl")*/
2097 for(i = 0; i != numcodes_cl; ++i) writeBits(writer, tree_cl.lengths[CLCL_ORDER[i]], 3);
2098
2099 /*write the lengths of the lit/len AND the dist alphabet*/
2100 for(i = 0; i != numcodes_lld_e; ++i) {
2101 writeBitsReversed(writer, tree_cl.codes[bitlen_lld_e[i]], tree_cl.lengths[bitlen_lld_e[i]]);
2102 /*extra bits of repeat codes*/
2103 if(bitlen_lld_e[i] == 16) writeBits(writer, bitlen_lld_e[++i], 2);
2104 else if(bitlen_lld_e[i] == 17) writeBits(writer, bitlen_lld_e[++i], 3);
2105 else if(bitlen_lld_e[i] == 18) writeBits(writer, bitlen_lld_e[++i], 7);
2106 }
2107
2108 /*write the compressed data symbols*/
2109 writeLZ77data(writer, &lz77_encoded, &tree_ll, &tree_d);
2110 /*error: the length of the end code 256 must be larger than 0*/
2111 if(tree_ll.lengths[256] == 0) ERROR_BREAK(64);
2112
2113 /*write the end code*/
2114 writeBitsReversed(writer, tree_ll.codes[256], tree_ll.lengths[256]);
2115
2116 break; /*end of error-while*/
2117 }
2118
2119 /*cleanup*/
2120 uivector_cleanup(&lz77_encoded);
2121 HuffmanTree_cleanup(&tree_ll);
2122 HuffmanTree_cleanup(&tree_d);
2123 HuffmanTree_cleanup(&tree_cl);
2124 lodepng_free(frequencies_ll);
2125 lodepng_free(frequencies_d);
2126 lodepng_free(frequencies_cl);
2127 lodepng_free(bitlen_lld);
2128 lodepng_free(bitlen_lld_e);
2129
2130 return error;
2131 }
2132
deflateFixed(LodePNGBitWriter * writer,Hash * hash,const unsigned char * data,size_t datapos,size_t dataend,const LodePNGCompressSettings * settings,unsigned final)2133 static unsigned deflateFixed(LodePNGBitWriter * writer, Hash * hash,
2134 const unsigned char * data,
2135 size_t datapos, size_t dataend,
2136 const LodePNGCompressSettings * settings, unsigned final)
2137 {
2138 HuffmanTree tree_ll; /*tree for literal values and length codes*/
2139 HuffmanTree tree_d; /*tree for distance codes*/
2140
2141 unsigned BFINAL = final;
2142 unsigned error = 0;
2143 size_t i;
2144
2145 HuffmanTree_init(&tree_ll);
2146 HuffmanTree_init(&tree_d);
2147
2148 error = generateFixedLitLenTree(&tree_ll);
2149 if(!error) error = generateFixedDistanceTree(&tree_d);
2150
2151 if(!error) {
2152 writeBits(writer, BFINAL, 1);
2153 writeBits(writer, 1, 1); /*first bit of BTYPE*/
2154 writeBits(writer, 0, 1); /*second bit of BTYPE*/
2155
2156 if(settings->use_lz77) { /*LZ77 encoded*/
2157 uivector lz77_encoded;
2158 uivector_init(&lz77_encoded);
2159 error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize,
2160 settings->minmatch, settings->nicematch, settings->lazymatching);
2161 if(!error) writeLZ77data(writer, &lz77_encoded, &tree_ll, &tree_d);
2162 uivector_cleanup(&lz77_encoded);
2163 }
2164 else { /*no LZ77, but still will be Huffman compressed*/
2165 for(i = datapos; i < dataend; ++i) {
2166 writeBitsReversed(writer, tree_ll.codes[data[i]], tree_ll.lengths[data[i]]);
2167 }
2168 }
2169 /*add END code*/
2170 if(!error) writeBitsReversed(writer, tree_ll.codes[256], tree_ll.lengths[256]);
2171 }
2172
2173 /*cleanup*/
2174 HuffmanTree_cleanup(&tree_ll);
2175 HuffmanTree_cleanup(&tree_d);
2176
2177 return error;
2178 }
2179
lodepng_deflatev(ucvector * out,const unsigned char * in,size_t insize,const LodePNGCompressSettings * settings)2180 static unsigned lodepng_deflatev(ucvector * out, const unsigned char * in, size_t insize,
2181 const LodePNGCompressSettings * settings)
2182 {
2183 unsigned error = 0;
2184 size_t i, blocksize, numdeflateblocks;
2185 Hash hash;
2186 LodePNGBitWriter writer;
2187
2188 LodePNGBitWriter_init(&writer, out);
2189
2190 if(settings->btype > 2) return 61;
2191 else if(settings->btype == 0) return deflateNoCompression(out, in, insize);
2192 else if(settings->btype == 1) blocksize = insize;
2193 else { /*if(settings->btype == 2)*/
2194 /*on PNGs, deflate blocks of 65-262k seem to give most dense encoding*/
2195 blocksize = insize / 8u + 8;
2196 if(blocksize < 65536) blocksize = 65536;
2197 if(blocksize > 262144) blocksize = 262144;
2198 }
2199
2200 numdeflateblocks = (insize + blocksize - 1) / blocksize;
2201 if(numdeflateblocks == 0) numdeflateblocks = 1;
2202
2203 error = hash_init(&hash, settings->windowsize);
2204
2205 if(!error) {
2206 for(i = 0; i != numdeflateblocks && !error; ++i) {
2207 unsigned final = (i == numdeflateblocks - 1);
2208 size_t start = i * blocksize;
2209 size_t end = start + blocksize;
2210 if(end > insize) end = insize;
2211
2212 if(settings->btype == 1) error = deflateFixed(&writer, &hash, in, start, end, settings, final);
2213 else if(settings->btype == 2) error = deflateDynamic(&writer, &hash, in, start, end, settings, final);
2214 }
2215 }
2216
2217 hash_cleanup(&hash);
2218
2219 return error;
2220 }
2221
lodepng_deflate(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGCompressSettings * settings)2222 unsigned lodepng_deflate(unsigned char ** out, size_t * outsize,
2223 const unsigned char * in, size_t insize,
2224 const LodePNGCompressSettings * settings)
2225 {
2226 ucvector v = ucvector_init(*out, *outsize);
2227 unsigned error = lodepng_deflatev(&v, in, insize, settings);
2228 *out = v.data;
2229 *outsize = v.size;
2230 return error;
2231 }
2232
deflate(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGCompressSettings * settings)2233 static unsigned deflate(unsigned char ** out, size_t * outsize,
2234 const unsigned char * in, size_t insize,
2235 const LodePNGCompressSettings * settings)
2236 {
2237 if(settings->custom_deflate) {
2238 unsigned error = settings->custom_deflate(out, outsize, in, insize, settings);
2239 /*the custom deflate is allowed to have its own error codes, however, we translate it to code 111*/
2240 return error ? 111 : 0;
2241 }
2242 else {
2243 return lodepng_deflate(out, outsize, in, insize, settings);
2244 }
2245 }
2246
2247 #endif /*LODEPNG_COMPILE_DECODER*/
2248
2249 /* ////////////////////////////////////////////////////////////////////////// */
2250 /* / Adler32 / */
2251 /* ////////////////////////////////////////////////////////////////////////// */
2252
update_adler32(unsigned adler,const unsigned char * data,unsigned len)2253 static unsigned update_adler32(unsigned adler, const unsigned char * data, unsigned len)
2254 {
2255 unsigned s1 = adler & 0xffffu;
2256 unsigned s2 = (adler >> 16u) & 0xffffu;
2257
2258 while(len != 0u) {
2259 unsigned i;
2260 /*at least 5552 sums can be done before the sums overflow, saving a lot of module divisions*/
2261 unsigned amount = len > 5552u ? 5552u : len;
2262 len -= amount;
2263 for(i = 0; i != amount; ++i) {
2264 s1 += (*data++);
2265 s2 += s1;
2266 }
2267 s1 %= 65521u;
2268 s2 %= 65521u;
2269 }
2270
2271 return (s2 << 16u) | s1;
2272 }
2273
2274 /*Return the adler32 of the bytes data[0..len-1]*/
adler32(const unsigned char * data,unsigned len)2275 static unsigned adler32(const unsigned char * data, unsigned len)
2276 {
2277 return update_adler32(1u, data, len);
2278 }
2279
2280 /* ////////////////////////////////////////////////////////////////////////// */
2281 /* / Zlib / */
2282 /* ////////////////////////////////////////////////////////////////////////// */
2283
2284 #ifdef LODEPNG_COMPILE_DECODER
2285
lodepng_zlib_decompressv(ucvector * out,const unsigned char * in,size_t insize,const LodePNGDecompressSettings * settings)2286 static unsigned lodepng_zlib_decompressv(ucvector * out,
2287 const unsigned char * in, size_t insize,
2288 const LodePNGDecompressSettings * settings)
2289 {
2290 unsigned error = 0;
2291 unsigned CM, CINFO, FDICT;
2292
2293 if(insize < 2) return 53; /*error, size of zlib data too small*/
2294 /*read information from zlib header*/
2295 if((in[0] * 256 + in[1]) % 31 != 0) {
2296 /*error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way*/
2297 return 24;
2298 }
2299
2300 CM = in[0] & 15;
2301 CINFO = (in[0] >> 4) & 15;
2302 /*FCHECK = in[1] & 31;*/ /*FCHECK is already tested above*/
2303 FDICT = (in[1] >> 5) & 1;
2304 /*FLEVEL = (in[1] >> 6) & 3;*/ /*FLEVEL is not used here*/
2305
2306 if(CM != 8 || CINFO > 7) {
2307 /*error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec*/
2308 return 25;
2309 }
2310 if(FDICT != 0) {
2311 /*error: the specification of PNG says about the zlib stream:
2312 "The additional flags shall not specify a preset dictionary."*/
2313 return 26;
2314 }
2315
2316 error = inflatev(out, in + 2, insize - 2, settings);
2317 if(error) return error;
2318
2319 if(!settings->ignore_adler32) {
2320 unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]);
2321 unsigned checksum = adler32(out->data, (unsigned)(out->size));
2322 if(checksum != ADLER32) return 58; /*error, adler checksum not correct, data must be corrupted*/
2323 }
2324
2325 return 0; /*no error*/
2326 }
2327
2328
lodepng_zlib_decompress(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGDecompressSettings * settings)2329 unsigned lodepng_zlib_decompress(unsigned char ** out, size_t * outsize, const unsigned char * in,
2330 size_t insize, const LodePNGDecompressSettings * settings)
2331 {
2332 ucvector v = ucvector_init(*out, *outsize);
2333 unsigned error = lodepng_zlib_decompressv(&v, in, insize, settings);
2334 *out = v.data;
2335 *outsize = v.size;
2336 return error;
2337 }
2338
2339 /*expected_size is expected output size, to avoid intermediate allocations. Set to 0 if not known. */
zlib_decompress(unsigned char ** out,size_t * outsize,size_t expected_size,const unsigned char * in,size_t insize,const LodePNGDecompressSettings * settings)2340 static unsigned zlib_decompress(unsigned char ** out, size_t * outsize, size_t expected_size,
2341 const unsigned char * in, size_t insize, const LodePNGDecompressSettings * settings)
2342 {
2343 unsigned error;
2344 if(settings->custom_zlib) {
2345 error = settings->custom_zlib(out, outsize, in, insize, settings);
2346 if(error) {
2347 /*the custom zlib is allowed to have its own error codes, however, we translate it to code 110*/
2348 error = 110;
2349 /*if there's a max output size, and the custom zlib returned error, then indicate that error instead*/
2350 if(settings->max_output_size && *outsize > settings->max_output_size) error = 109;
2351 }
2352 }
2353 else {
2354 ucvector v = ucvector_init(*out, *outsize);
2355 if(expected_size) {
2356 /*reserve the memory to avoid intermediate reallocations*/
2357 ucvector_resize(&v, *outsize + expected_size);
2358 v.size = *outsize;
2359 }
2360 error = lodepng_zlib_decompressv(&v, in, insize, settings);
2361 *out = v.data;
2362 *outsize = v.size;
2363 }
2364 return error;
2365 }
2366
2367 #endif /*LODEPNG_COMPILE_DECODER*/
2368
2369 #ifdef LODEPNG_COMPILE_ENCODER
2370
lodepng_zlib_compress(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGCompressSettings * settings)2371 unsigned lodepng_zlib_compress(unsigned char ** out, size_t * outsize, const unsigned char * in,
2372 size_t insize, const LodePNGCompressSettings * settings)
2373 {
2374 size_t i;
2375 unsigned error;
2376 unsigned char * deflatedata = 0;
2377 size_t deflatesize = 0;
2378
2379 error = deflate(&deflatedata, &deflatesize, in, insize, settings);
2380
2381 *out = NULL;
2382 *outsize = 0;
2383 if(!error) {
2384 *outsize = deflatesize + 6;
2385 *out = (unsigned char *)lodepng_malloc(*outsize);
2386 if(!*out) error = 83; /*alloc fail*/
2387 }
2388
2389 if(!error) {
2390 unsigned ADLER32 = adler32(in, (unsigned)insize);
2391 /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/
2392 unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/
2393 unsigned FLEVEL = 0;
2394 unsigned FDICT = 0;
2395 unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64;
2396 unsigned FCHECK = 31 - CMFFLG % 31;
2397 CMFFLG += FCHECK;
2398
2399 (*out)[0] = (unsigned char)(CMFFLG >> 8);
2400 (*out)[1] = (unsigned char)(CMFFLG & 255);
2401 for(i = 0; i != deflatesize; ++i)(*out)[i + 2] = deflatedata[i];
2402 lodepng_set32bitInt(&(*out)[*outsize - 4], ADLER32);
2403 }
2404
2405 lodepng_free(deflatedata);
2406 return error;
2407 }
2408
2409 /* 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)2410 static unsigned zlib_compress(unsigned char ** out, size_t * outsize, const unsigned char * in,
2411 size_t insize, const LodePNGCompressSettings * settings)
2412 {
2413 if(settings->custom_zlib) {
2414 unsigned error = settings->custom_zlib(out, outsize, in, insize, settings);
2415 /*the custom zlib is allowed to have its own error codes, however, we translate it to code 111*/
2416 return error ? 111 : 0;
2417 }
2418 else {
2419 return lodepng_zlib_compress(out, outsize, in, insize, settings);
2420 }
2421 }
2422
2423 #endif /*LODEPNG_COMPILE_ENCODER*/
2424
2425 #else /*no LODEPNG_COMPILE_ZLIB*/
2426
2427 #ifdef LODEPNG_COMPILE_DECODER
zlib_decompress(unsigned char ** out,size_t * outsize,size_t expected_size,const unsigned char * in,size_t insize,const LodePNGDecompressSettings * settings)2428 static unsigned zlib_decompress(unsigned char ** out, size_t * outsize, size_t expected_size,
2429 const unsigned char * in, size_t insize, const LodePNGDecompressSettings * settings)
2430 {
2431 if(!settings->custom_zlib) return 87; /*no custom zlib function provided */
2432 (void)expected_size;
2433 return settings->custom_zlib(out, outsize, in, insize, settings);
2434 }
2435 #endif /*LODEPNG_COMPILE_DECODER*/
2436 #ifdef LODEPNG_COMPILE_ENCODER
zlib_compress(unsigned char ** out,size_t * outsize,const unsigned char * in,size_t insize,const LodePNGCompressSettings * settings)2437 static unsigned zlib_compress(unsigned char ** out, size_t * outsize, const unsigned char * in,
2438 size_t insize, const LodePNGCompressSettings * settings)
2439 {
2440 if(!settings->custom_zlib) return 87; /*no custom zlib function provided */
2441 return settings->custom_zlib(out, outsize, in, insize, settings);
2442 }
2443 #endif /*LODEPNG_COMPILE_ENCODER*/
2444
2445 #endif /*LODEPNG_COMPILE_ZLIB*/
2446
2447 /* ////////////////////////////////////////////////////////////////////////// */
2448
2449 #ifdef LODEPNG_COMPILE_ENCODER
2450
2451 /*this is a good tradeoff between speed and compression ratio*/
2452 #define DEFAULT_WINDOWSIZE 2048
2453
lodepng_compress_settings_init(LodePNGCompressSettings * settings)2454 void lodepng_compress_settings_init(LodePNGCompressSettings * settings)
2455 {
2456 /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/
2457 settings->btype = 2;
2458 settings->use_lz77 = 1;
2459 settings->windowsize = DEFAULT_WINDOWSIZE;
2460 settings->minmatch = 3;
2461 settings->nicematch = 128;
2462 settings->lazymatching = 1;
2463
2464 settings->custom_zlib = 0;
2465 settings->custom_deflate = 0;
2466 settings->custom_context = 0;
2467 }
2468
2469 const LodePNGCompressSettings lodepng_default_compress_settings = {2, 1, DEFAULT_WINDOWSIZE, 3, 128, 1, 0, 0, 0};
2470
2471
2472 #endif /*LODEPNG_COMPILE_ENCODER*/
2473
2474 #ifdef LODEPNG_COMPILE_DECODER
2475
lodepng_decompress_settings_init(LodePNGDecompressSettings * settings)2476 void lodepng_decompress_settings_init(LodePNGDecompressSettings * settings)
2477 {
2478 settings->ignore_adler32 = 0;
2479 settings->ignore_nlen = 0;
2480 settings->max_output_size = 0;
2481
2482 settings->custom_zlib = 0;
2483 settings->custom_inflate = 0;
2484 settings->custom_context = 0;
2485 }
2486
2487 const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, 0, 0, 0};
2488
2489 #endif /*LODEPNG_COMPILE_DECODER*/
2490
2491 /* ////////////////////////////////////////////////////////////////////////// */
2492 /* ////////////////////////////////////////////////////////////////////////// */
2493 /* // End of Zlib related code. Begin of PNG related code. // */
2494 /* ////////////////////////////////////////////////////////////////////////// */
2495 /* ////////////////////////////////////////////////////////////////////////// */
2496
2497 #ifdef LODEPNG_COMPILE_PNG
2498
2499 /* ////////////////////////////////////////////////////////////////////////// */
2500 /* / CRC32 / */
2501 /* ////////////////////////////////////////////////////////////////////////// */
2502
2503
2504 #ifdef LODEPNG_COMPILE_CRC
2505
2506 static const unsigned lodepng_crc32_table0[256] = {
2507 0x00000000u, 0x77073096u, 0xee0e612cu, 0x990951bau, 0x076dc419u, 0x706af48fu, 0xe963a535u, 0x9e6495a3u,
2508 0x0edb8832u, 0x79dcb8a4u, 0xe0d5e91eu, 0x97d2d988u, 0x09b64c2bu, 0x7eb17cbdu, 0xe7b82d07u, 0x90bf1d91u,
2509 0x1db71064u, 0x6ab020f2u, 0xf3b97148u, 0x84be41deu, 0x1adad47du, 0x6ddde4ebu, 0xf4d4b551u, 0x83d385c7u,
2510 0x136c9856u, 0x646ba8c0u, 0xfd62f97au, 0x8a65c9ecu, 0x14015c4fu, 0x63066cd9u, 0xfa0f3d63u, 0x8d080df5u,
2511 0x3b6e20c8u, 0x4c69105eu, 0xd56041e4u, 0xa2677172u, 0x3c03e4d1u, 0x4b04d447u, 0xd20d85fdu, 0xa50ab56bu,
2512 0x35b5a8fau, 0x42b2986cu, 0xdbbbc9d6u, 0xacbcf940u, 0x32d86ce3u, 0x45df5c75u, 0xdcd60dcfu, 0xabd13d59u,
2513 0x26d930acu, 0x51de003au, 0xc8d75180u, 0xbfd06116u, 0x21b4f4b5u, 0x56b3c423u, 0xcfba9599u, 0xb8bda50fu,
2514 0x2802b89eu, 0x5f058808u, 0xc60cd9b2u, 0xb10be924u, 0x2f6f7c87u, 0x58684c11u, 0xc1611dabu, 0xb6662d3du,
2515 0x76dc4190u, 0x01db7106u, 0x98d220bcu, 0xefd5102au, 0x71b18589u, 0x06b6b51fu, 0x9fbfe4a5u, 0xe8b8d433u,
2516 0x7807c9a2u, 0x0f00f934u, 0x9609a88eu, 0xe10e9818u, 0x7f6a0dbbu, 0x086d3d2du, 0x91646c97u, 0xe6635c01u,
2517 0x6b6b51f4u, 0x1c6c6162u, 0x856530d8u, 0xf262004eu, 0x6c0695edu, 0x1b01a57bu, 0x8208f4c1u, 0xf50fc457u,
2518 0x65b0d9c6u, 0x12b7e950u, 0x8bbeb8eau, 0xfcb9887cu, 0x62dd1ddfu, 0x15da2d49u, 0x8cd37cf3u, 0xfbd44c65u,
2519 0x4db26158u, 0x3ab551ceu, 0xa3bc0074u, 0xd4bb30e2u, 0x4adfa541u, 0x3dd895d7u, 0xa4d1c46du, 0xd3d6f4fbu,
2520 0x4369e96au, 0x346ed9fcu, 0xad678846u, 0xda60b8d0u, 0x44042d73u, 0x33031de5u, 0xaa0a4c5fu, 0xdd0d7cc9u,
2521 0x5005713cu, 0x270241aau, 0xbe0b1010u, 0xc90c2086u, 0x5768b525u, 0x206f85b3u, 0xb966d409u, 0xce61e49fu,
2522 0x5edef90eu, 0x29d9c998u, 0xb0d09822u, 0xc7d7a8b4u, 0x59b33d17u, 0x2eb40d81u, 0xb7bd5c3bu, 0xc0ba6cadu,
2523 0xedb88320u, 0x9abfb3b6u, 0x03b6e20cu, 0x74b1d29au, 0xead54739u, 0x9dd277afu, 0x04db2615u, 0x73dc1683u,
2524 0xe3630b12u, 0x94643b84u, 0x0d6d6a3eu, 0x7a6a5aa8u, 0xe40ecf0bu, 0x9309ff9du, 0x0a00ae27u, 0x7d079eb1u,
2525 0xf00f9344u, 0x8708a3d2u, 0x1e01f268u, 0x6906c2feu, 0xf762575du, 0x806567cbu, 0x196c3671u, 0x6e6b06e7u,
2526 0xfed41b76u, 0x89d32be0u, 0x10da7a5au, 0x67dd4accu, 0xf9b9df6fu, 0x8ebeeff9u, 0x17b7be43u, 0x60b08ed5u,
2527 0xd6d6a3e8u, 0xa1d1937eu, 0x38d8c2c4u, 0x4fdff252u, 0xd1bb67f1u, 0xa6bc5767u, 0x3fb506ddu, 0x48b2364bu,
2528 0xd80d2bdau, 0xaf0a1b4cu, 0x36034af6u, 0x41047a60u, 0xdf60efc3u, 0xa867df55u, 0x316e8eefu, 0x4669be79u,
2529 0xcb61b38cu, 0xbc66831au, 0x256fd2a0u, 0x5268e236u, 0xcc0c7795u, 0xbb0b4703u, 0x220216b9u, 0x5505262fu,
2530 0xc5ba3bbeu, 0xb2bd0b28u, 0x2bb45a92u, 0x5cb36a04u, 0xc2d7ffa7u, 0xb5d0cf31u, 0x2cd99e8bu, 0x5bdeae1du,
2531 0x9b64c2b0u, 0xec63f226u, 0x756aa39cu, 0x026d930au, 0x9c0906a9u, 0xeb0e363fu, 0x72076785u, 0x05005713u,
2532 0x95bf4a82u, 0xe2b87a14u, 0x7bb12baeu, 0x0cb61b38u, 0x92d28e9bu, 0xe5d5be0du, 0x7cdcefb7u, 0x0bdbdf21u,
2533 0x86d3d2d4u, 0xf1d4e242u, 0x68ddb3f8u, 0x1fda836eu, 0x81be16cdu, 0xf6b9265bu, 0x6fb077e1u, 0x18b74777u,
2534 0x88085ae6u, 0xff0f6a70u, 0x66063bcau, 0x11010b5cu, 0x8f659effu, 0xf862ae69u, 0x616bffd3u, 0x166ccf45u,
2535 0xa00ae278u, 0xd70dd2eeu, 0x4e048354u, 0x3903b3c2u, 0xa7672661u, 0xd06016f7u, 0x4969474du, 0x3e6e77dbu,
2536 0xaed16a4au, 0xd9d65adcu, 0x40df0b66u, 0x37d83bf0u, 0xa9bcae53u, 0xdebb9ec5u, 0x47b2cf7fu, 0x30b5ffe9u,
2537 0xbdbdf21cu, 0xcabac28au, 0x53b39330u, 0x24b4a3a6u, 0xbad03605u, 0xcdd70693u, 0x54de5729u, 0x23d967bfu,
2538 0xb3667a2eu, 0xc4614ab8u, 0x5d681b02u, 0x2a6f2b94u, 0xb40bbe37u, 0xc30c8ea1u, 0x5a05df1bu, 0x2d02ef8du
2539 };
2540
2541 static const unsigned lodepng_crc32_table1[256] = {
2542 0x00000000u, 0x191b3141u, 0x32366282u, 0x2b2d53c3u, 0x646cc504u, 0x7d77f445u, 0x565aa786u, 0x4f4196c7u,
2543 0xc8d98a08u, 0xd1c2bb49u, 0xfaefe88au, 0xe3f4d9cbu, 0xacb54f0cu, 0xb5ae7e4du, 0x9e832d8eu, 0x87981ccfu,
2544 0x4ac21251u, 0x53d92310u, 0x78f470d3u, 0x61ef4192u, 0x2eaed755u, 0x37b5e614u, 0x1c98b5d7u, 0x05838496u,
2545 0x821b9859u, 0x9b00a918u, 0xb02dfadbu, 0xa936cb9au, 0xe6775d5du, 0xff6c6c1cu, 0xd4413fdfu, 0xcd5a0e9eu,
2546 0x958424a2u, 0x8c9f15e3u, 0xa7b24620u, 0xbea97761u, 0xf1e8e1a6u, 0xe8f3d0e7u, 0xc3de8324u, 0xdac5b265u,
2547 0x5d5daeaau, 0x44469febu, 0x6f6bcc28u, 0x7670fd69u, 0x39316baeu, 0x202a5aefu, 0x0b07092cu, 0x121c386du,
2548 0xdf4636f3u, 0xc65d07b2u, 0xed705471u, 0xf46b6530u, 0xbb2af3f7u, 0xa231c2b6u, 0x891c9175u, 0x9007a034u,
2549 0x179fbcfbu, 0x0e848dbau, 0x25a9de79u, 0x3cb2ef38u, 0x73f379ffu, 0x6ae848beu, 0x41c51b7du, 0x58de2a3cu,
2550 0xf0794f05u, 0xe9627e44u, 0xc24f2d87u, 0xdb541cc6u, 0x94158a01u, 0x8d0ebb40u, 0xa623e883u, 0xbf38d9c2u,
2551 0x38a0c50du, 0x21bbf44cu, 0x0a96a78fu, 0x138d96ceu, 0x5ccc0009u, 0x45d73148u, 0x6efa628bu, 0x77e153cau,
2552 0xbabb5d54u, 0xa3a06c15u, 0x888d3fd6u, 0x91960e97u, 0xded79850u, 0xc7cca911u, 0xece1fad2u, 0xf5facb93u,
2553 0x7262d75cu, 0x6b79e61du, 0x4054b5deu, 0x594f849fu, 0x160e1258u, 0x0f152319u, 0x243870dau, 0x3d23419bu,
2554 0x65fd6ba7u, 0x7ce65ae6u, 0x57cb0925u, 0x4ed03864u, 0x0191aea3u, 0x188a9fe2u, 0x33a7cc21u, 0x2abcfd60u,
2555 0xad24e1afu, 0xb43fd0eeu, 0x9f12832du, 0x8609b26cu, 0xc94824abu, 0xd05315eau, 0xfb7e4629u, 0xe2657768u,
2556 0x2f3f79f6u, 0x362448b7u, 0x1d091b74u, 0x04122a35u, 0x4b53bcf2u, 0x52488db3u, 0x7965de70u, 0x607eef31u,
2557 0xe7e6f3feu, 0xfefdc2bfu, 0xd5d0917cu, 0xcccba03du, 0x838a36fau, 0x9a9107bbu, 0xb1bc5478u, 0xa8a76539u,
2558 0x3b83984bu, 0x2298a90au, 0x09b5fac9u, 0x10aecb88u, 0x5fef5d4fu, 0x46f46c0eu, 0x6dd93fcdu, 0x74c20e8cu,
2559 0xf35a1243u, 0xea412302u, 0xc16c70c1u, 0xd8774180u, 0x9736d747u, 0x8e2de606u, 0xa500b5c5u, 0xbc1b8484u,
2560 0x71418a1au, 0x685abb5bu, 0x4377e898u, 0x5a6cd9d9u, 0x152d4f1eu, 0x0c367e5fu, 0x271b2d9cu, 0x3e001cddu,
2561 0xb9980012u, 0xa0833153u, 0x8bae6290u, 0x92b553d1u, 0xddf4c516u, 0xc4eff457u, 0xefc2a794u, 0xf6d996d5u,
2562 0xae07bce9u, 0xb71c8da8u, 0x9c31de6bu, 0x852aef2au, 0xca6b79edu, 0xd37048acu, 0xf85d1b6fu, 0xe1462a2eu,
2563 0x66de36e1u, 0x7fc507a0u, 0x54e85463u, 0x4df36522u, 0x02b2f3e5u, 0x1ba9c2a4u, 0x30849167u, 0x299fa026u,
2564 0xe4c5aeb8u, 0xfdde9ff9u, 0xd6f3cc3au, 0xcfe8fd7bu, 0x80a96bbcu, 0x99b25afdu, 0xb29f093eu, 0xab84387fu,
2565 0x2c1c24b0u, 0x350715f1u, 0x1e2a4632u, 0x07317773u, 0x4870e1b4u, 0x516bd0f5u, 0x7a468336u, 0x635db277u,
2566 0xcbfad74eu, 0xd2e1e60fu, 0xf9ccb5ccu, 0xe0d7848du, 0xaf96124au, 0xb68d230bu, 0x9da070c8u, 0x84bb4189u,
2567 0x03235d46u, 0x1a386c07u, 0x31153fc4u, 0x280e0e85u, 0x674f9842u, 0x7e54a903u, 0x5579fac0u, 0x4c62cb81u,
2568 0x8138c51fu, 0x9823f45eu, 0xb30ea79du, 0xaa1596dcu, 0xe554001bu, 0xfc4f315au, 0xd7626299u, 0xce7953d8u,
2569 0x49e14f17u, 0x50fa7e56u, 0x7bd72d95u, 0x62cc1cd4u, 0x2d8d8a13u, 0x3496bb52u, 0x1fbbe891u, 0x06a0d9d0u,
2570 0x5e7ef3ecu, 0x4765c2adu, 0x6c48916eu, 0x7553a02fu, 0x3a1236e8u, 0x230907a9u, 0x0824546au, 0x113f652bu,
2571 0x96a779e4u, 0x8fbc48a5u, 0xa4911b66u, 0xbd8a2a27u, 0xf2cbbce0u, 0xebd08da1u, 0xc0fdde62u, 0xd9e6ef23u,
2572 0x14bce1bdu, 0x0da7d0fcu, 0x268a833fu, 0x3f91b27eu, 0x70d024b9u, 0x69cb15f8u, 0x42e6463bu, 0x5bfd777au,
2573 0xdc656bb5u, 0xc57e5af4u, 0xee530937u, 0xf7483876u, 0xb809aeb1u, 0xa1129ff0u, 0x8a3fcc33u, 0x9324fd72u
2574 };
2575
2576 static const unsigned lodepng_crc32_table2[256] = {
2577 0x00000000u, 0x01c26a37u, 0x0384d46eu, 0x0246be59u, 0x0709a8dcu, 0x06cbc2ebu, 0x048d7cb2u, 0x054f1685u,
2578 0x0e1351b8u, 0x0fd13b8fu, 0x0d9785d6u, 0x0c55efe1u, 0x091af964u, 0x08d89353u, 0x0a9e2d0au, 0x0b5c473du,
2579 0x1c26a370u, 0x1de4c947u, 0x1fa2771eu, 0x1e601d29u, 0x1b2f0bacu, 0x1aed619bu, 0x18abdfc2u, 0x1969b5f5u,
2580 0x1235f2c8u, 0x13f798ffu, 0x11b126a6u, 0x10734c91u, 0x153c5a14u, 0x14fe3023u, 0x16b88e7au, 0x177ae44du,
2581 0x384d46e0u, 0x398f2cd7u, 0x3bc9928eu, 0x3a0bf8b9u, 0x3f44ee3cu, 0x3e86840bu, 0x3cc03a52u, 0x3d025065u,
2582 0x365e1758u, 0x379c7d6fu, 0x35dac336u, 0x3418a901u, 0x3157bf84u, 0x3095d5b3u, 0x32d36beau, 0x331101ddu,
2583 0x246be590u, 0x25a98fa7u, 0x27ef31feu, 0x262d5bc9u, 0x23624d4cu, 0x22a0277bu, 0x20e69922u, 0x2124f315u,
2584 0x2a78b428u, 0x2bbade1fu, 0x29fc6046u, 0x283e0a71u, 0x2d711cf4u, 0x2cb376c3u, 0x2ef5c89au, 0x2f37a2adu,
2585 0x709a8dc0u, 0x7158e7f7u, 0x731e59aeu, 0x72dc3399u, 0x7793251cu, 0x76514f2bu, 0x7417f172u, 0x75d59b45u,
2586 0x7e89dc78u, 0x7f4bb64fu, 0x7d0d0816u, 0x7ccf6221u, 0x798074a4u, 0x78421e93u, 0x7a04a0cau, 0x7bc6cafdu,
2587 0x6cbc2eb0u, 0x6d7e4487u, 0x6f38fadeu, 0x6efa90e9u, 0x6bb5866cu, 0x6a77ec5bu, 0x68315202u, 0x69f33835u,
2588 0x62af7f08u, 0x636d153fu, 0x612bab66u, 0x60e9c151u, 0x65a6d7d4u, 0x6464bde3u, 0x662203bau, 0x67e0698du,
2589 0x48d7cb20u, 0x4915a117u, 0x4b531f4eu, 0x4a917579u, 0x4fde63fcu, 0x4e1c09cbu, 0x4c5ab792u, 0x4d98dda5u,
2590 0x46c49a98u, 0x4706f0afu, 0x45404ef6u, 0x448224c1u, 0x41cd3244u, 0x400f5873u, 0x4249e62au, 0x438b8c1du,
2591 0x54f16850u, 0x55330267u, 0x5775bc3eu, 0x56b7d609u, 0x53f8c08cu, 0x523aaabbu, 0x507c14e2u, 0x51be7ed5u,
2592 0x5ae239e8u, 0x5b2053dfu, 0x5966ed86u, 0x58a487b1u, 0x5deb9134u, 0x5c29fb03u, 0x5e6f455au, 0x5fad2f6du,
2593 0xe1351b80u, 0xe0f771b7u, 0xe2b1cfeeu, 0xe373a5d9u, 0xe63cb35cu, 0xe7fed96bu, 0xe5b86732u, 0xe47a0d05u,
2594 0xef264a38u, 0xeee4200fu, 0xeca29e56u, 0xed60f461u, 0xe82fe2e4u, 0xe9ed88d3u, 0xebab368au, 0xea695cbdu,
2595 0xfd13b8f0u, 0xfcd1d2c7u, 0xfe976c9eu, 0xff5506a9u, 0xfa1a102cu, 0xfbd87a1bu, 0xf99ec442u, 0xf85cae75u,
2596 0xf300e948u, 0xf2c2837fu, 0xf0843d26u, 0xf1465711u, 0xf4094194u, 0xf5cb2ba3u, 0xf78d95fau, 0xf64fffcdu,
2597 0xd9785d60u, 0xd8ba3757u, 0xdafc890eu, 0xdb3ee339u, 0xde71f5bcu, 0xdfb39f8bu, 0xddf521d2u, 0xdc374be5u,
2598 0xd76b0cd8u, 0xd6a966efu, 0xd4efd8b6u, 0xd52db281u, 0xd062a404u, 0xd1a0ce33u, 0xd3e6706au, 0xd2241a5du,
2599 0xc55efe10u, 0xc49c9427u, 0xc6da2a7eu, 0xc7184049u, 0xc25756ccu, 0xc3953cfbu, 0xc1d382a2u, 0xc011e895u,
2600 0xcb4dafa8u, 0xca8fc59fu, 0xc8c97bc6u, 0xc90b11f1u, 0xcc440774u, 0xcd866d43u, 0xcfc0d31au, 0xce02b92du,
2601 0x91af9640u, 0x906dfc77u, 0x922b422eu, 0x93e92819u, 0x96a63e9cu, 0x976454abu, 0x9522eaf2u, 0x94e080c5u,
2602 0x9fbcc7f8u, 0x9e7eadcfu, 0x9c381396u, 0x9dfa79a1u, 0x98b56f24u, 0x99770513u, 0x9b31bb4au, 0x9af3d17du,
2603 0x8d893530u, 0x8c4b5f07u, 0x8e0de15eu, 0x8fcf8b69u, 0x8a809decu, 0x8b42f7dbu, 0x89044982u, 0x88c623b5u,
2604 0x839a6488u, 0x82580ebfu, 0x801eb0e6u, 0x81dcdad1u, 0x8493cc54u, 0x8551a663u, 0x8717183au, 0x86d5720du,
2605 0xa9e2d0a0u, 0xa820ba97u, 0xaa6604ceu, 0xaba46ef9u, 0xaeeb787cu, 0xaf29124bu, 0xad6fac12u, 0xacadc625u,
2606 0xa7f18118u, 0xa633eb2fu, 0xa4755576u, 0xa5b73f41u, 0xa0f829c4u, 0xa13a43f3u, 0xa37cfdaau, 0xa2be979du,
2607 0xb5c473d0u, 0xb40619e7u, 0xb640a7beu, 0xb782cd89u, 0xb2cddb0cu, 0xb30fb13bu, 0xb1490f62u, 0xb08b6555u,
2608 0xbbd72268u, 0xba15485fu, 0xb853f606u, 0xb9919c31u, 0xbcde8ab4u, 0xbd1ce083u, 0xbf5a5edau, 0xbe9834edu
2609 };
2610
2611 static const unsigned lodepng_crc32_table3[256] = {
2612 0x00000000u, 0xb8bc6765u, 0xaa09c88bu, 0x12b5afeeu, 0x8f629757u, 0x37def032u, 0x256b5fdcu, 0x9dd738b9u,
2613 0xc5b428efu, 0x7d084f8au, 0x6fbde064u, 0xd7018701u, 0x4ad6bfb8u, 0xf26ad8ddu, 0xe0df7733u, 0x58631056u,
2614 0x5019579fu, 0xe8a530fau, 0xfa109f14u, 0x42acf871u, 0xdf7bc0c8u, 0x67c7a7adu, 0x75720843u, 0xcdce6f26u,
2615 0x95ad7f70u, 0x2d111815u, 0x3fa4b7fbu, 0x8718d09eu, 0x1acfe827u, 0xa2738f42u, 0xb0c620acu, 0x087a47c9u,
2616 0xa032af3eu, 0x188ec85bu, 0x0a3b67b5u, 0xb28700d0u, 0x2f503869u, 0x97ec5f0cu, 0x8559f0e2u, 0x3de59787u,
2617 0x658687d1u, 0xdd3ae0b4u, 0xcf8f4f5au, 0x7733283fu, 0xeae41086u, 0x525877e3u, 0x40edd80du, 0xf851bf68u,
2618 0xf02bf8a1u, 0x48979fc4u, 0x5a22302au, 0xe29e574fu, 0x7f496ff6u, 0xc7f50893u, 0xd540a77du, 0x6dfcc018u,
2619 0x359fd04eu, 0x8d23b72bu, 0x9f9618c5u, 0x272a7fa0u, 0xbafd4719u, 0x0241207cu, 0x10f48f92u, 0xa848e8f7u,
2620 0x9b14583du, 0x23a83f58u, 0x311d90b6u, 0x89a1f7d3u, 0x1476cf6au, 0xaccaa80fu, 0xbe7f07e1u, 0x06c36084u,
2621 0x5ea070d2u, 0xe61c17b7u, 0xf4a9b859u, 0x4c15df3cu, 0xd1c2e785u, 0x697e80e0u, 0x7bcb2f0eu, 0xc377486bu,
2622 0xcb0d0fa2u, 0x73b168c7u, 0x6104c729u, 0xd9b8a04cu, 0x446f98f5u, 0xfcd3ff90u, 0xee66507eu, 0x56da371bu,
2623 0x0eb9274du, 0xb6054028u, 0xa4b0efc6u, 0x1c0c88a3u, 0x81dbb01au, 0x3967d77fu, 0x2bd27891u, 0x936e1ff4u,
2624 0x3b26f703u, 0x839a9066u, 0x912f3f88u, 0x299358edu, 0xb4446054u, 0x0cf80731u, 0x1e4da8dfu, 0xa6f1cfbau,
2625 0xfe92dfecu, 0x462eb889u, 0x549b1767u, 0xec277002u, 0x71f048bbu, 0xc94c2fdeu, 0xdbf98030u, 0x6345e755u,
2626 0x6b3fa09cu, 0xd383c7f9u, 0xc1366817u, 0x798a0f72u, 0xe45d37cbu, 0x5ce150aeu, 0x4e54ff40u, 0xf6e89825u,
2627 0xae8b8873u, 0x1637ef16u, 0x048240f8u, 0xbc3e279du, 0x21e91f24u, 0x99557841u, 0x8be0d7afu, 0x335cb0cau,
2628 0xed59b63bu, 0x55e5d15eu, 0x47507eb0u, 0xffec19d5u, 0x623b216cu, 0xda874609u, 0xc832e9e7u, 0x708e8e82u,
2629 0x28ed9ed4u, 0x9051f9b1u, 0x82e4565fu, 0x3a58313au, 0xa78f0983u, 0x1f336ee6u, 0x0d86c108u, 0xb53aa66du,
2630 0xbd40e1a4u, 0x05fc86c1u, 0x1749292fu, 0xaff54e4au, 0x322276f3u, 0x8a9e1196u, 0x982bbe78u, 0x2097d91du,
2631 0x78f4c94bu, 0xc048ae2eu, 0xd2fd01c0u, 0x6a4166a5u, 0xf7965e1cu, 0x4f2a3979u, 0x5d9f9697u, 0xe523f1f2u,
2632 0x4d6b1905u, 0xf5d77e60u, 0xe762d18eu, 0x5fdeb6ebu, 0xc2098e52u, 0x7ab5e937u, 0x680046d9u, 0xd0bc21bcu,
2633 0x88df31eau, 0x3063568fu, 0x22d6f961u, 0x9a6a9e04u, 0x07bda6bdu, 0xbf01c1d8u, 0xadb46e36u, 0x15080953u,
2634 0x1d724e9au, 0xa5ce29ffu, 0xb77b8611u, 0x0fc7e174u, 0x9210d9cdu, 0x2aacbea8u, 0x38191146u, 0x80a57623u,
2635 0xd8c66675u, 0x607a0110u, 0x72cfaefeu, 0xca73c99bu, 0x57a4f122u, 0xef189647u, 0xfdad39a9u, 0x45115eccu,
2636 0x764dee06u, 0xcef18963u, 0xdc44268du, 0x64f841e8u, 0xf92f7951u, 0x41931e34u, 0x5326b1dau, 0xeb9ad6bfu,
2637 0xb3f9c6e9u, 0x0b45a18cu, 0x19f00e62u, 0xa14c6907u, 0x3c9b51beu, 0x842736dbu, 0x96929935u, 0x2e2efe50u,
2638 0x2654b999u, 0x9ee8defcu, 0x8c5d7112u, 0x34e11677u, 0xa9362eceu, 0x118a49abu, 0x033fe645u, 0xbb838120u,
2639 0xe3e09176u, 0x5b5cf613u, 0x49e959fdu, 0xf1553e98u, 0x6c820621u, 0xd43e6144u, 0xc68bceaau, 0x7e37a9cfu,
2640 0xd67f4138u, 0x6ec3265du, 0x7c7689b3u, 0xc4caeed6u, 0x591dd66fu, 0xe1a1b10au, 0xf3141ee4u, 0x4ba87981u,
2641 0x13cb69d7u, 0xab770eb2u, 0xb9c2a15cu, 0x017ec639u, 0x9ca9fe80u, 0x241599e5u, 0x36a0360bu, 0x8e1c516eu,
2642 0x866616a7u, 0x3eda71c2u, 0x2c6fde2cu, 0x94d3b949u, 0x090481f0u, 0xb1b8e695u, 0xa30d497bu, 0x1bb12e1eu,
2643 0x43d23e48u, 0xfb6e592du, 0xe9dbf6c3u, 0x516791a6u, 0xccb0a91fu, 0x740cce7au, 0x66b96194u, 0xde0506f1u
2644 };
2645
2646 static const unsigned lodepng_crc32_table4[256] = {
2647 0x00000000u, 0x3d6029b0u, 0x7ac05360u, 0x47a07ad0u, 0xf580a6c0u, 0xc8e08f70u, 0x8f40f5a0u, 0xb220dc10u,
2648 0x30704bc1u, 0x0d106271u, 0x4ab018a1u, 0x77d03111u, 0xc5f0ed01u, 0xf890c4b1u, 0xbf30be61u, 0x825097d1u,
2649 0x60e09782u, 0x5d80be32u, 0x1a20c4e2u, 0x2740ed52u, 0x95603142u, 0xa80018f2u, 0xefa06222u, 0xd2c04b92u,
2650 0x5090dc43u, 0x6df0f5f3u, 0x2a508f23u, 0x1730a693u, 0xa5107a83u, 0x98705333u, 0xdfd029e3u, 0xe2b00053u,
2651 0xc1c12f04u, 0xfca106b4u, 0xbb017c64u, 0x866155d4u, 0x344189c4u, 0x0921a074u, 0x4e81daa4u, 0x73e1f314u,
2652 0xf1b164c5u, 0xccd14d75u, 0x8b7137a5u, 0xb6111e15u, 0x0431c205u, 0x3951ebb5u, 0x7ef19165u, 0x4391b8d5u,
2653 0xa121b886u, 0x9c419136u, 0xdbe1ebe6u, 0xe681c256u, 0x54a11e46u, 0x69c137f6u, 0x2e614d26u, 0x13016496u,
2654 0x9151f347u, 0xac31daf7u, 0xeb91a027u, 0xd6f18997u, 0x64d15587u, 0x59b17c37u, 0x1e1106e7u, 0x23712f57u,
2655 0x58f35849u, 0x659371f9u, 0x22330b29u, 0x1f532299u, 0xad73fe89u, 0x9013d739u, 0xd7b3ade9u, 0xead38459u,
2656 0x68831388u, 0x55e33a38u, 0x124340e8u, 0x2f236958u, 0x9d03b548u, 0xa0639cf8u, 0xe7c3e628u, 0xdaa3cf98u,
2657 0x3813cfcbu, 0x0573e67bu, 0x42d39cabu, 0x7fb3b51bu, 0xcd93690bu, 0xf0f340bbu, 0xb7533a6bu, 0x8a3313dbu,
2658 0x0863840au, 0x3503adbau, 0x72a3d76au, 0x4fc3fedau, 0xfde322cau, 0xc0830b7au, 0x872371aau, 0xba43581au,
2659 0x9932774du, 0xa4525efdu, 0xe3f2242du, 0xde920d9du, 0x6cb2d18du, 0x51d2f83du, 0x167282edu, 0x2b12ab5du,
2660 0xa9423c8cu, 0x9422153cu, 0xd3826fecu, 0xeee2465cu, 0x5cc29a4cu, 0x61a2b3fcu, 0x2602c92cu, 0x1b62e09cu,
2661 0xf9d2e0cfu, 0xc4b2c97fu, 0x8312b3afu, 0xbe729a1fu, 0x0c52460fu, 0x31326fbfu, 0x7692156fu, 0x4bf23cdfu,
2662 0xc9a2ab0eu, 0xf4c282beu, 0xb362f86eu, 0x8e02d1deu, 0x3c220dceu, 0x0142247eu, 0x46e25eaeu, 0x7b82771eu,
2663 0xb1e6b092u, 0x8c869922u, 0xcb26e3f2u, 0xf646ca42u, 0x44661652u, 0x79063fe2u, 0x3ea64532u, 0x03c66c82u,
2664 0x8196fb53u, 0xbcf6d2e3u, 0xfb56a833u, 0xc6368183u, 0x74165d93u, 0x49767423u, 0x0ed60ef3u, 0x33b62743u,
2665 0xd1062710u, 0xec660ea0u, 0xabc67470u, 0x96a65dc0u, 0x248681d0u, 0x19e6a860u, 0x5e46d2b0u, 0x6326fb00u,
2666 0xe1766cd1u, 0xdc164561u, 0x9bb63fb1u, 0xa6d61601u, 0x14f6ca11u, 0x2996e3a1u, 0x6e369971u, 0x5356b0c1u,
2667 0x70279f96u, 0x4d47b626u, 0x0ae7ccf6u, 0x3787e546u, 0x85a73956u, 0xb8c710e6u, 0xff676a36u, 0xc2074386u,
2668 0x4057d457u, 0x7d37fde7u, 0x3a978737u, 0x07f7ae87u, 0xb5d77297u, 0x88b75b27u, 0xcf1721f7u, 0xf2770847u,
2669 0x10c70814u, 0x2da721a4u, 0x6a075b74u, 0x576772c4u, 0xe547aed4u, 0xd8278764u, 0x9f87fdb4u, 0xa2e7d404u,
2670 0x20b743d5u, 0x1dd76a65u, 0x5a7710b5u, 0x67173905u, 0xd537e515u, 0xe857cca5u, 0xaff7b675u, 0x92979fc5u,
2671 0xe915e8dbu, 0xd475c16bu, 0x93d5bbbbu, 0xaeb5920bu, 0x1c954e1bu, 0x21f567abu, 0x66551d7bu, 0x5b3534cbu,
2672 0xd965a31au, 0xe4058aaau, 0xa3a5f07au, 0x9ec5d9cau, 0x2ce505dau, 0x11852c6au, 0x562556bau, 0x6b457f0au,
2673 0x89f57f59u, 0xb49556e9u, 0xf3352c39u, 0xce550589u, 0x7c75d999u, 0x4115f029u, 0x06b58af9u, 0x3bd5a349u,
2674 0xb9853498u, 0x84e51d28u, 0xc34567f8u, 0xfe254e48u, 0x4c059258u, 0x7165bbe8u, 0x36c5c138u, 0x0ba5e888u,
2675 0x28d4c7dfu, 0x15b4ee6fu, 0x521494bfu, 0x6f74bd0fu, 0xdd54611fu, 0xe03448afu, 0xa794327fu, 0x9af41bcfu,
2676 0x18a48c1eu, 0x25c4a5aeu, 0x6264df7eu, 0x5f04f6ceu, 0xed242adeu, 0xd044036eu, 0x97e479beu, 0xaa84500eu,
2677 0x4834505du, 0x755479edu, 0x32f4033du, 0x0f942a8du, 0xbdb4f69du, 0x80d4df2du, 0xc774a5fdu, 0xfa148c4du,
2678 0x78441b9cu, 0x4524322cu, 0x028448fcu, 0x3fe4614cu, 0x8dc4bd5cu, 0xb0a494ecu, 0xf704ee3cu, 0xca64c78cu
2679 };
2680
2681 static const unsigned lodepng_crc32_table5[256] = {
2682 0x00000000u, 0xcb5cd3a5u, 0x4dc8a10bu, 0x869472aeu, 0x9b914216u, 0x50cd91b3u, 0xd659e31du, 0x1d0530b8u,
2683 0xec53826du, 0x270f51c8u, 0xa19b2366u, 0x6ac7f0c3u, 0x77c2c07bu, 0xbc9e13deu, 0x3a0a6170u, 0xf156b2d5u,
2684 0x03d6029bu, 0xc88ad13eu, 0x4e1ea390u, 0x85427035u, 0x9847408du, 0x531b9328u, 0xd58fe186u, 0x1ed33223u,
2685 0xef8580f6u, 0x24d95353u, 0xa24d21fdu, 0x6911f258u, 0x7414c2e0u, 0xbf481145u, 0x39dc63ebu, 0xf280b04eu,
2686 0x07ac0536u, 0xccf0d693u, 0x4a64a43du, 0x81387798u, 0x9c3d4720u, 0x57619485u, 0xd1f5e62bu, 0x1aa9358eu,
2687 0xebff875bu, 0x20a354feu, 0xa6372650u, 0x6d6bf5f5u, 0x706ec54du, 0xbb3216e8u, 0x3da66446u, 0xf6fab7e3u,
2688 0x047a07adu, 0xcf26d408u, 0x49b2a6a6u, 0x82ee7503u, 0x9feb45bbu, 0x54b7961eu, 0xd223e4b0u, 0x197f3715u,
2689 0xe82985c0u, 0x23755665u, 0xa5e124cbu, 0x6ebdf76eu, 0x73b8c7d6u, 0xb8e41473u, 0x3e7066ddu, 0xf52cb578u,
2690 0x0f580a6cu, 0xc404d9c9u, 0x4290ab67u, 0x89cc78c2u, 0x94c9487au, 0x5f959bdfu, 0xd901e971u, 0x125d3ad4u,
2691 0xe30b8801u, 0x28575ba4u, 0xaec3290au, 0x659ffaafu, 0x789aca17u, 0xb3c619b2u, 0x35526b1cu, 0xfe0eb8b9u,
2692 0x0c8e08f7u, 0xc7d2db52u, 0x4146a9fcu, 0x8a1a7a59u, 0x971f4ae1u, 0x5c439944u, 0xdad7ebeau, 0x118b384fu,
2693 0xe0dd8a9au, 0x2b81593fu, 0xad152b91u, 0x6649f834u, 0x7b4cc88cu, 0xb0101b29u, 0x36846987u, 0xfdd8ba22u,
2694 0x08f40f5au, 0xc3a8dcffu, 0x453cae51u, 0x8e607df4u, 0x93654d4cu, 0x58399ee9u, 0xdeadec47u, 0x15f13fe2u,
2695 0xe4a78d37u, 0x2ffb5e92u, 0xa96f2c3cu, 0x6233ff99u, 0x7f36cf21u, 0xb46a1c84u, 0x32fe6e2au, 0xf9a2bd8fu,
2696 0x0b220dc1u, 0xc07ede64u, 0x46eaaccau, 0x8db67f6fu, 0x90b34fd7u, 0x5bef9c72u, 0xdd7beedcu, 0x16273d79u,
2697 0xe7718facu, 0x2c2d5c09u, 0xaab92ea7u, 0x61e5fd02u, 0x7ce0cdbau, 0xb7bc1e1fu, 0x31286cb1u, 0xfa74bf14u,
2698 0x1eb014d8u, 0xd5ecc77du, 0x5378b5d3u, 0x98246676u, 0x852156ceu, 0x4e7d856bu, 0xc8e9f7c5u, 0x03b52460u,
2699 0xf2e396b5u, 0x39bf4510u, 0xbf2b37beu, 0x7477e41bu, 0x6972d4a3u, 0xa22e0706u, 0x24ba75a8u, 0xefe6a60du,
2700 0x1d661643u, 0xd63ac5e6u, 0x50aeb748u, 0x9bf264edu, 0x86f75455u, 0x4dab87f0u, 0xcb3ff55eu, 0x006326fbu,
2701 0xf135942eu, 0x3a69478bu, 0xbcfd3525u, 0x77a1e680u, 0x6aa4d638u, 0xa1f8059du, 0x276c7733u, 0xec30a496u,
2702 0x191c11eeu, 0xd240c24bu, 0x54d4b0e5u, 0x9f886340u, 0x828d53f8u, 0x49d1805du, 0xcf45f2f3u, 0x04192156u,
2703 0xf54f9383u, 0x3e134026u, 0xb8873288u, 0x73dbe12du, 0x6eded195u, 0xa5820230u, 0x2316709eu, 0xe84aa33bu,
2704 0x1aca1375u, 0xd196c0d0u, 0x5702b27eu, 0x9c5e61dbu, 0x815b5163u, 0x4a0782c6u, 0xcc93f068u, 0x07cf23cdu,
2705 0xf6999118u, 0x3dc542bdu, 0xbb513013u, 0x700de3b6u, 0x6d08d30eu, 0xa65400abu, 0x20c07205u, 0xeb9ca1a0u,
2706 0x11e81eb4u, 0xdab4cd11u, 0x5c20bfbfu, 0x977c6c1au, 0x8a795ca2u, 0x41258f07u, 0xc7b1fda9u, 0x0ced2e0cu,
2707 0xfdbb9cd9u, 0x36e74f7cu, 0xb0733dd2u, 0x7b2fee77u, 0x662adecfu, 0xad760d6au, 0x2be27fc4u, 0xe0beac61u,
2708 0x123e1c2fu, 0xd962cf8au, 0x5ff6bd24u, 0x94aa6e81u, 0x89af5e39u, 0x42f38d9cu, 0xc467ff32u, 0x0f3b2c97u,
2709 0xfe6d9e42u, 0x35314de7u, 0xb3a53f49u, 0x78f9ececu, 0x65fcdc54u, 0xaea00ff1u, 0x28347d5fu, 0xe368aefau,
2710 0x16441b82u, 0xdd18c827u, 0x5b8cba89u, 0x90d0692cu, 0x8dd55994u, 0x46898a31u, 0xc01df89fu, 0x0b412b3au,
2711 0xfa1799efu, 0x314b4a4au, 0xb7df38e4u, 0x7c83eb41u, 0x6186dbf9u, 0xaada085cu, 0x2c4e7af2u, 0xe712a957u,
2712 0x15921919u, 0xdececabcu, 0x585ab812u, 0x93066bb7u, 0x8e035b0fu, 0x455f88aau, 0xc3cbfa04u, 0x089729a1u,
2713 0xf9c19b74u, 0x329d48d1u, 0xb4093a7fu, 0x7f55e9dau, 0x6250d962u, 0xa90c0ac7u, 0x2f987869u, 0xe4c4abccu
2714 };
2715
2716 static const unsigned lodepng_crc32_table6[256] = {
2717 0x00000000u, 0xa6770bb4u, 0x979f1129u, 0x31e81a9du, 0xf44f2413u, 0x52382fa7u, 0x63d0353au, 0xc5a73e8eu,
2718 0x33ef4e67u, 0x959845d3u, 0xa4705f4eu, 0x020754fau, 0xc7a06a74u, 0x61d761c0u, 0x503f7b5du, 0xf64870e9u,
2719 0x67de9cceu, 0xc1a9977au, 0xf0418de7u, 0x56368653u, 0x9391b8ddu, 0x35e6b369u, 0x040ea9f4u, 0xa279a240u,
2720 0x5431d2a9u, 0xf246d91du, 0xc3aec380u, 0x65d9c834u, 0xa07ef6bau, 0x0609fd0eu, 0x37e1e793u, 0x9196ec27u,
2721 0xcfbd399cu, 0x69ca3228u, 0x582228b5u, 0xfe552301u, 0x3bf21d8fu, 0x9d85163bu, 0xac6d0ca6u, 0x0a1a0712u,
2722 0xfc5277fbu, 0x5a257c4fu, 0x6bcd66d2u, 0xcdba6d66u, 0x081d53e8u, 0xae6a585cu, 0x9f8242c1u, 0x39f54975u,
2723 0xa863a552u, 0x0e14aee6u, 0x3ffcb47bu, 0x998bbfcfu, 0x5c2c8141u, 0xfa5b8af5u, 0xcbb39068u, 0x6dc49bdcu,
2724 0x9b8ceb35u, 0x3dfbe081u, 0x0c13fa1cu, 0xaa64f1a8u, 0x6fc3cf26u, 0xc9b4c492u, 0xf85cde0fu, 0x5e2bd5bbu,
2725 0x440b7579u, 0xe27c7ecdu, 0xd3946450u, 0x75e36fe4u, 0xb044516au, 0x16335adeu, 0x27db4043u, 0x81ac4bf7u,
2726 0x77e43b1eu, 0xd19330aau, 0xe07b2a37u, 0x460c2183u, 0x83ab1f0du, 0x25dc14b9u, 0x14340e24u, 0xb2430590u,
2727 0x23d5e9b7u, 0x85a2e203u, 0xb44af89eu, 0x123df32au, 0xd79acda4u, 0x71edc610u, 0x4005dc8du, 0xe672d739u,
2728 0x103aa7d0u, 0xb64dac64u, 0x87a5b6f9u, 0x21d2bd4du, 0xe47583c3u, 0x42028877u, 0x73ea92eau, 0xd59d995eu,
2729 0x8bb64ce5u, 0x2dc14751u, 0x1c295dccu, 0xba5e5678u, 0x7ff968f6u, 0xd98e6342u, 0xe86679dfu, 0x4e11726bu,
2730 0xb8590282u, 0x1e2e0936u, 0x2fc613abu, 0x89b1181fu, 0x4c162691u, 0xea612d25u, 0xdb8937b8u, 0x7dfe3c0cu,
2731 0xec68d02bu, 0x4a1fdb9fu, 0x7bf7c102u, 0xdd80cab6u, 0x1827f438u, 0xbe50ff8cu, 0x8fb8e511u, 0x29cfeea5u,
2732 0xdf879e4cu, 0x79f095f8u, 0x48188f65u, 0xee6f84d1u, 0x2bc8ba5fu, 0x8dbfb1ebu, 0xbc57ab76u, 0x1a20a0c2u,
2733 0x8816eaf2u, 0x2e61e146u, 0x1f89fbdbu, 0xb9fef06fu, 0x7c59cee1u, 0xda2ec555u, 0xebc6dfc8u, 0x4db1d47cu,
2734 0xbbf9a495u, 0x1d8eaf21u, 0x2c66b5bcu, 0x8a11be08u, 0x4fb68086u, 0xe9c18b32u, 0xd82991afu, 0x7e5e9a1bu,
2735 0xefc8763cu, 0x49bf7d88u, 0x78576715u, 0xde206ca1u, 0x1b87522fu, 0xbdf0599bu, 0x8c184306u, 0x2a6f48b2u,
2736 0xdc27385bu, 0x7a5033efu, 0x4bb82972u, 0xedcf22c6u, 0x28681c48u, 0x8e1f17fcu, 0xbff70d61u, 0x198006d5u,
2737 0x47abd36eu, 0xe1dcd8dau, 0xd034c247u, 0x7643c9f3u, 0xb3e4f77du, 0x1593fcc9u, 0x247be654u, 0x820cede0u,
2738 0x74449d09u, 0xd23396bdu, 0xe3db8c20u, 0x45ac8794u, 0x800bb91au, 0x267cb2aeu, 0x1794a833u, 0xb1e3a387u,
2739 0x20754fa0u, 0x86024414u, 0xb7ea5e89u, 0x119d553du, 0xd43a6bb3u, 0x724d6007u, 0x43a57a9au, 0xe5d2712eu,
2740 0x139a01c7u, 0xb5ed0a73u, 0x840510eeu, 0x22721b5au, 0xe7d525d4u, 0x41a22e60u, 0x704a34fdu, 0xd63d3f49u,
2741 0xcc1d9f8bu, 0x6a6a943fu, 0x5b828ea2u, 0xfdf58516u, 0x3852bb98u, 0x9e25b02cu, 0xafcdaab1u, 0x09baa105u,
2742 0xfff2d1ecu, 0x5985da58u, 0x686dc0c5u, 0xce1acb71u, 0x0bbdf5ffu, 0xadcafe4bu, 0x9c22e4d6u, 0x3a55ef62u,
2743 0xabc30345u, 0x0db408f1u, 0x3c5c126cu, 0x9a2b19d8u, 0x5f8c2756u, 0xf9fb2ce2u, 0xc813367fu, 0x6e643dcbu,
2744 0x982c4d22u, 0x3e5b4696u, 0x0fb35c0bu, 0xa9c457bfu, 0x6c636931u, 0xca146285u, 0xfbfc7818u, 0x5d8b73acu,
2745 0x03a0a617u, 0xa5d7ada3u, 0x943fb73eu, 0x3248bc8au, 0xf7ef8204u, 0x519889b0u, 0x6070932du, 0xc6079899u,
2746 0x304fe870u, 0x9638e3c4u, 0xa7d0f959u, 0x01a7f2edu, 0xc400cc63u, 0x6277c7d7u, 0x539fdd4au, 0xf5e8d6feu,
2747 0x647e3ad9u, 0xc209316du, 0xf3e12bf0u, 0x55962044u, 0x90311ecau, 0x3646157eu, 0x07ae0fe3u, 0xa1d90457u,
2748 0x579174beu, 0xf1e67f0au, 0xc00e6597u, 0x66796e23u, 0xa3de50adu, 0x05a95b19u, 0x34414184u, 0x92364a30u
2749 };
2750
2751 static const unsigned lodepng_crc32_table7[256] = {
2752 0x00000000u, 0xccaa009eu, 0x4225077du, 0x8e8f07e3u, 0x844a0efau, 0x48e00e64u, 0xc66f0987u, 0x0ac50919u,
2753 0xd3e51bb5u, 0x1f4f1b2bu, 0x91c01cc8u, 0x5d6a1c56u, 0x57af154fu, 0x9b0515d1u, 0x158a1232u, 0xd92012acu,
2754 0x7cbb312bu, 0xb01131b5u, 0x3e9e3656u, 0xf23436c8u, 0xf8f13fd1u, 0x345b3f4fu, 0xbad438acu, 0x767e3832u,
2755 0xaf5e2a9eu, 0x63f42a00u, 0xed7b2de3u, 0x21d12d7du, 0x2b142464u, 0xe7be24fau, 0x69312319u, 0xa59b2387u,
2756 0xf9766256u, 0x35dc62c8u, 0xbb53652bu, 0x77f965b5u, 0x7d3c6cacu, 0xb1966c32u, 0x3f196bd1u, 0xf3b36b4fu,
2757 0x2a9379e3u, 0xe639797du, 0x68b67e9eu, 0xa41c7e00u, 0xaed97719u, 0x62737787u, 0xecfc7064u, 0x205670fau,
2758 0x85cd537du, 0x496753e3u, 0xc7e85400u, 0x0b42549eu, 0x01875d87u, 0xcd2d5d19u, 0x43a25afau, 0x8f085a64u,
2759 0x562848c8u, 0x9a824856u, 0x140d4fb5u, 0xd8a74f2bu, 0xd2624632u, 0x1ec846acu, 0x9047414fu, 0x5ced41d1u,
2760 0x299dc2edu, 0xe537c273u, 0x6bb8c590u, 0xa712c50eu, 0xadd7cc17u, 0x617dcc89u, 0xeff2cb6au, 0x2358cbf4u,
2761 0xfa78d958u, 0x36d2d9c6u, 0xb85dde25u, 0x74f7debbu, 0x7e32d7a2u, 0xb298d73cu, 0x3c17d0dfu, 0xf0bdd041u,
2762 0x5526f3c6u, 0x998cf358u, 0x1703f4bbu, 0xdba9f425u, 0xd16cfd3cu, 0x1dc6fda2u, 0x9349fa41u, 0x5fe3fadfu,
2763 0x86c3e873u, 0x4a69e8edu, 0xc4e6ef0eu, 0x084cef90u, 0x0289e689u, 0xce23e617u, 0x40ace1f4u, 0x8c06e16au,
2764 0xd0eba0bbu, 0x1c41a025u, 0x92cea7c6u, 0x5e64a758u, 0x54a1ae41u, 0x980baedfu, 0x1684a93cu, 0xda2ea9a2u,
2765 0x030ebb0eu, 0xcfa4bb90u, 0x412bbc73u, 0x8d81bcedu, 0x8744b5f4u, 0x4beeb56au, 0xc561b289u, 0x09cbb217u,
2766 0xac509190u, 0x60fa910eu, 0xee7596edu, 0x22df9673u, 0x281a9f6au, 0xe4b09ff4u, 0x6a3f9817u, 0xa6959889u,
2767 0x7fb58a25u, 0xb31f8abbu, 0x3d908d58u, 0xf13a8dc6u, 0xfbff84dfu, 0x37558441u, 0xb9da83a2u, 0x7570833cu,
2768 0x533b85dau, 0x9f918544u, 0x111e82a7u, 0xddb48239u, 0xd7718b20u, 0x1bdb8bbeu, 0x95548c5du, 0x59fe8cc3u,
2769 0x80de9e6fu, 0x4c749ef1u, 0xc2fb9912u, 0x0e51998cu, 0x04949095u, 0xc83e900bu, 0x46b197e8u, 0x8a1b9776u,
2770 0x2f80b4f1u, 0xe32ab46fu, 0x6da5b38cu, 0xa10fb312u, 0xabcaba0bu, 0x6760ba95u, 0xe9efbd76u, 0x2545bde8u,
2771 0xfc65af44u, 0x30cfafdau, 0xbe40a839u, 0x72eaa8a7u, 0x782fa1beu, 0xb485a120u, 0x3a0aa6c3u, 0xf6a0a65du,
2772 0xaa4de78cu, 0x66e7e712u, 0xe868e0f1u, 0x24c2e06fu, 0x2e07e976u, 0xe2ade9e8u, 0x6c22ee0bu, 0xa088ee95u,
2773 0x79a8fc39u, 0xb502fca7u, 0x3b8dfb44u, 0xf727fbdau, 0xfde2f2c3u, 0x3148f25du, 0xbfc7f5beu, 0x736df520u,
2774 0xd6f6d6a7u, 0x1a5cd639u, 0x94d3d1dau, 0x5879d144u, 0x52bcd85du, 0x9e16d8c3u, 0x1099df20u, 0xdc33dfbeu,
2775 0x0513cd12u, 0xc9b9cd8cu, 0x4736ca6fu, 0x8b9ccaf1u, 0x8159c3e8u, 0x4df3c376u, 0xc37cc495u, 0x0fd6c40bu,
2776 0x7aa64737u, 0xb60c47a9u, 0x3883404au, 0xf42940d4u, 0xfeec49cdu, 0x32464953u, 0xbcc94eb0u, 0x70634e2eu,
2777 0xa9435c82u, 0x65e95c1cu, 0xeb665bffu, 0x27cc5b61u, 0x2d095278u, 0xe1a352e6u, 0x6f2c5505u, 0xa386559bu,
2778 0x061d761cu, 0xcab77682u, 0x44387161u, 0x889271ffu, 0x825778e6u, 0x4efd7878u, 0xc0727f9bu, 0x0cd87f05u,
2779 0xd5f86da9u, 0x19526d37u, 0x97dd6ad4u, 0x5b776a4au, 0x51b26353u, 0x9d1863cdu, 0x1397642eu, 0xdf3d64b0u,
2780 0x83d02561u, 0x4f7a25ffu, 0xc1f5221cu, 0x0d5f2282u, 0x079a2b9bu, 0xcb302b05u, 0x45bf2ce6u, 0x89152c78u,
2781 0x50353ed4u, 0x9c9f3e4au, 0x121039a9u, 0xdeba3937u, 0xd47f302eu, 0x18d530b0u, 0x965a3753u, 0x5af037cdu,
2782 0xff6b144au, 0x33c114d4u, 0xbd4e1337u, 0x71e413a9u, 0x7b211ab0u, 0xb78b1a2eu, 0x39041dcdu, 0xf5ae1d53u,
2783 0x2c8e0fffu, 0xe0240f61u, 0x6eab0882u, 0xa201081cu, 0xa8c40105u, 0x646e019bu, 0xeae10678u, 0x264b06e6u
2784 };
2785
2786 /* Computes the cyclic redundancy check as used by PNG chunks*/
lodepng_crc32(const unsigned char * data,size_t length)2787 unsigned lodepng_crc32(const unsigned char * data, size_t length)
2788 {
2789 /*Using the Slicing by Eight algorithm*/
2790 unsigned r = 0xffffffffu;
2791 while(length >= 8) {
2792 r = lodepng_crc32_table7[(data[0] ^ (r & 0xffu))] ^
2793 lodepng_crc32_table6[(data[1] ^ ((r >> 8) & 0xffu))] ^
2794 lodepng_crc32_table5[(data[2] ^ ((r >> 16) & 0xffu))] ^
2795 lodepng_crc32_table4[(data[3] ^ ((r >> 24) & 0xffu))] ^
2796 lodepng_crc32_table3[data[4]] ^
2797 lodepng_crc32_table2[data[5]] ^
2798 lodepng_crc32_table1[data[6]] ^
2799 lodepng_crc32_table0[data[7]];
2800 data += 8;
2801 length -= 8;
2802 }
2803 while(length--) {
2804 r = lodepng_crc32_table0[(r ^ *data++) & 0xffu] ^ (r >> 8);
2805 }
2806 return r ^ 0xffffffffu;
2807 }
2808 #else /* LODEPNG_COMPILE_CRC */
2809 /*in this case, the function is only declared here, and must be defined externally
2810 so that it will be linked in.
2811
2812 Example implementation that uses a much smaller lookup table for memory constrained cases:
2813
2814 unsigned lodepng_crc32(const unsigned char* data, size_t length) {
2815 unsigned r = 0xffffffffu;
2816 static const unsigned table[16] = {
2817 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
2818 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
2819 };
2820 while(length--) {
2821 r = table[(r ^ *data) & 0xf] ^ (r >> 4);
2822 r = table[(r ^ (*data >> 4)) & 0xf] ^ (r >> 4);
2823 data++;
2824 }
2825 return r ^ 0xffffffffu;
2826 }
2827 */
2828 unsigned lodepng_crc32(const unsigned char * data, size_t length);
2829 #endif /* LODEPNG_COMPILE_CRC */
2830
2831 /* ////////////////////////////////////////////////////////////////////////// */
2832 /* / Reading and writing PNG color channel bits / */
2833 /* ////////////////////////////////////////////////////////////////////////// */
2834
2835 /* The color channel bits of less-than-8-bit pixels are read with the MSB of bytes first,
2836 so LodePNGBitWriter and LodePNGBitReader can't be used for those. */
2837
readBitFromReversedStream(size_t * bitpointer,const unsigned char * bitstream)2838 static unsigned char readBitFromReversedStream(size_t * bitpointer, const unsigned char * bitstream)
2839 {
2840 unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1);
2841 ++(*bitpointer);
2842 return result;
2843 }
2844
2845 /* TODO: make this faster */
readBitsFromReversedStream(size_t * bitpointer,const unsigned char * bitstream,size_t nbits)2846 static unsigned readBitsFromReversedStream(size_t * bitpointer, const unsigned char * bitstream, size_t nbits)
2847 {
2848 unsigned result = 0;
2849 size_t i;
2850 for(i = 0 ; i < nbits; ++i) {
2851 result <<= 1u;
2852 result |= (unsigned)readBitFromReversedStream(bitpointer, bitstream);
2853 }
2854 return result;
2855 }
2856
setBitOfReversedStream(size_t * bitpointer,unsigned char * bitstream,unsigned char bit)2857 static void setBitOfReversedStream(size_t * bitpointer, unsigned char * bitstream, unsigned char bit)
2858 {
2859 /*the current bit in bitstream may be 0 or 1 for this to work*/
2860 if(bit == 0) bitstream[(*bitpointer) >> 3u] &= (unsigned char)(~(1u << (7u - ((*bitpointer) & 7u))));
2861 else bitstream[(*bitpointer) >> 3u] |= (1u << (7u - ((*bitpointer) & 7u)));
2862 ++(*bitpointer);
2863 }
2864
2865 /* ////////////////////////////////////////////////////////////////////////// */
2866 /* / PNG chunks / */
2867 /* ////////////////////////////////////////////////////////////////////////// */
2868
lodepng_chunk_length(const unsigned char * chunk)2869 unsigned lodepng_chunk_length(const unsigned char * chunk)
2870 {
2871 return lodepng_read32bitInt(chunk);
2872 }
2873
lodepng_chunk_type(char type[5],const unsigned char * chunk)2874 void lodepng_chunk_type(char type[5], const unsigned char * chunk)
2875 {
2876 unsigned i;
2877 for(i = 0; i != 4; ++i) type[i] = (char)chunk[4 + i];
2878 type[4] = 0; /*null termination char*/
2879 }
2880
lodepng_chunk_type_equals(const unsigned char * chunk,const char * type)2881 unsigned char lodepng_chunk_type_equals(const unsigned char * chunk, const char * type)
2882 {
2883 if(lodepng_strlen(type) != 4) return 0;
2884 return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]);
2885 }
2886
lodepng_chunk_ancillary(const unsigned char * chunk)2887 unsigned char lodepng_chunk_ancillary(const unsigned char * chunk)
2888 {
2889 return((chunk[4] & 32) != 0);
2890 }
2891
lodepng_chunk_private(const unsigned char * chunk)2892 unsigned char lodepng_chunk_private(const unsigned char * chunk)
2893 {
2894 return((chunk[6] & 32) != 0);
2895 }
2896
lodepng_chunk_safetocopy(const unsigned char * chunk)2897 unsigned char lodepng_chunk_safetocopy(const unsigned char * chunk)
2898 {
2899 return((chunk[7] & 32) != 0);
2900 }
2901
lodepng_chunk_data(unsigned char * chunk)2902 unsigned char * lodepng_chunk_data(unsigned char * chunk)
2903 {
2904 return &chunk[8];
2905 }
2906
lodepng_chunk_data_const(const unsigned char * chunk)2907 const unsigned char * lodepng_chunk_data_const(const unsigned char * chunk)
2908 {
2909 return &chunk[8];
2910 }
2911
lodepng_chunk_check_crc(const unsigned char * chunk)2912 unsigned lodepng_chunk_check_crc(const unsigned char * chunk)
2913 {
2914 unsigned length = lodepng_chunk_length(chunk);
2915 unsigned CRC = lodepng_read32bitInt(&chunk[length + 8]);
2916 /*the CRC is taken of the data and the 4 chunk type letters, not the length*/
2917 unsigned checksum = lodepng_crc32(&chunk[4], length + 4);
2918 if(CRC != checksum) return 1;
2919 else return 0;
2920 }
2921
lodepng_chunk_generate_crc(unsigned char * chunk)2922 void lodepng_chunk_generate_crc(unsigned char * chunk)
2923 {
2924 unsigned length = lodepng_chunk_length(chunk);
2925 unsigned CRC = lodepng_crc32(&chunk[4], length + 4);
2926 lodepng_set32bitInt(chunk + 8 + length, CRC);
2927 }
2928
lodepng_chunk_next(unsigned char * chunk,unsigned char * end)2929 unsigned char * lodepng_chunk_next(unsigned char * chunk, unsigned char * end)
2930 {
2931 size_t available_size = (size_t)(end - chunk);
2932 if(chunk >= end || available_size < 12) return end; /*too small to contain a chunk*/
2933 if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47
2934 && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) {
2935 /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */
2936 return chunk + 8;
2937 }
2938 else {
2939 size_t total_chunk_length;
2940 if(lodepng_addofl(lodepng_chunk_length(chunk), 12, &total_chunk_length)) return end;
2941 if(total_chunk_length > available_size) return end; /*outside of range*/
2942 return chunk + total_chunk_length;
2943 }
2944 }
2945
lodepng_chunk_next_const(const unsigned char * chunk,const unsigned char * end)2946 const unsigned char * lodepng_chunk_next_const(const unsigned char * chunk, const unsigned char * end)
2947 {
2948 size_t available_size = (size_t)(end - chunk);
2949 if(chunk >= end || available_size < 12) return end; /*too small to contain a chunk*/
2950 if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47
2951 && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) {
2952 /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */
2953 return chunk + 8;
2954 }
2955 else {
2956 size_t total_chunk_length;
2957 if(lodepng_addofl(lodepng_chunk_length(chunk), 12, &total_chunk_length)) return end;
2958 if(total_chunk_length > available_size) return end; /*outside of range*/
2959 return chunk + total_chunk_length;
2960 }
2961 }
2962
lodepng_chunk_find(unsigned char * chunk,unsigned char * end,const char type[5])2963 unsigned char * lodepng_chunk_find(unsigned char * chunk, unsigned char * end, const char type[5])
2964 {
2965 for(;;) {
2966 if(chunk >= end || end - chunk < 12) return 0; /* past file end: chunk + 12 > end */
2967 if(lodepng_chunk_type_equals(chunk, type)) return chunk;
2968 chunk = lodepng_chunk_next(chunk, end);
2969 }
2970 }
2971
lodepng_chunk_find_const(const unsigned char * chunk,const unsigned char * end,const char type[5])2972 const unsigned char * lodepng_chunk_find_const(const unsigned char * chunk, const unsigned char * end,
2973 const char type[5])
2974 {
2975 for(;;) {
2976 if(chunk >= end || end - chunk < 12) return 0; /* past file end: chunk + 12 > end */
2977 if(lodepng_chunk_type_equals(chunk, type)) return chunk;
2978 chunk = lodepng_chunk_next_const(chunk, end);
2979 }
2980 }
2981
lodepng_chunk_append(unsigned char ** out,size_t * outsize,const unsigned char * chunk)2982 unsigned lodepng_chunk_append(unsigned char ** out, size_t * outsize, const unsigned char * chunk)
2983 {
2984 unsigned i;
2985 size_t total_chunk_length, new_length;
2986 unsigned char * chunk_start, * new_buffer;
2987
2988 if(lodepng_addofl(lodepng_chunk_length(chunk), 12, &total_chunk_length)) return 77;
2989 if(lodepng_addofl(*outsize, total_chunk_length, &new_length)) return 77;
2990
2991 new_buffer = (unsigned char *)lodepng_realloc(*out, new_length);
2992 if(!new_buffer) return 83; /*alloc fail*/
2993 (*out) = new_buffer;
2994 (*outsize) = new_length;
2995 chunk_start = &(*out)[new_length - total_chunk_length];
2996
2997 for(i = 0; i != total_chunk_length; ++i) chunk_start[i] = chunk[i];
2998
2999 return 0;
3000 }
3001
3002 /*Sets length and name and allocates the space for data and crc but does not
3003 set data or crc yet. Returns the start of the chunk in chunk. The start of
3004 the data is at chunk + 8. To finalize chunk, add the data, then use
3005 lodepng_chunk_generate_crc */
lodepng_chunk_init(unsigned char ** chunk,ucvector * out,size_t length,const char * type)3006 static unsigned lodepng_chunk_init(unsigned char ** chunk,
3007 ucvector * out,
3008 size_t length, const char * type)
3009 {
3010 size_t new_length = out->size;
3011 if(lodepng_addofl(new_length, length, &new_length)) return 77;
3012 if(lodepng_addofl(new_length, 12, &new_length)) return 77;
3013 if(!ucvector_resize(out, new_length)) return 83; /*alloc fail*/
3014 *chunk = out->data + new_length - length - 12u;
3015
3016 /*1: length*/
3017 lodepng_set32bitInt(*chunk, (unsigned)length);
3018
3019 /*2: chunk name (4 letters)*/
3020 lodepng_memcpy(*chunk + 4, type, 4);
3021
3022 return 0;
3023 }
3024
3025 /* like lodepng_chunk_create but with custom allocsize */
lodepng_chunk_createv(ucvector * out,size_t length,const char * type,const unsigned char * data)3026 static unsigned lodepng_chunk_createv(ucvector * out,
3027 size_t length, const char * type, const unsigned char * data)
3028 {
3029 unsigned char * chunk;
3030 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, length, type));
3031
3032 /*3: the data*/
3033 lodepng_memcpy(chunk + 8, data, length);
3034
3035 /*4: CRC (of the chunkname characters and the data)*/
3036 lodepng_chunk_generate_crc(chunk);
3037
3038 return 0;
3039 }
3040
lodepng_chunk_create(unsigned char ** out,size_t * outsize,size_t length,const char * type,const unsigned char * data)3041 unsigned lodepng_chunk_create(unsigned char ** out, size_t * outsize,
3042 size_t length, const char * type, const unsigned char * data)
3043 {
3044 ucvector v = ucvector_init(*out, *outsize);
3045 unsigned error = lodepng_chunk_createv(&v, length, type, data);
3046 *out = v.data;
3047 *outsize = v.size;
3048 return error;
3049 }
3050
3051 /* ////////////////////////////////////////////////////////////////////////// */
3052 /* / Color types, channels, bits / */
3053 /* ////////////////////////////////////////////////////////////////////////// */
3054
3055 /*checks if the colortype is valid and the bitdepth bd is allowed for this colortype.
3056 Return value is a LodePNG error code.*/
checkColorValidity(LodePNGColorType colortype,unsigned bd)3057 static unsigned checkColorValidity(LodePNGColorType colortype, unsigned bd)
3058 {
3059 switch(colortype) {
3060 case LCT_GREY:
3061 if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37;
3062 break;
3063 case LCT_RGB:
3064 if(!(bd == 8 || bd == 16)) return 37;
3065 break;
3066 case LCT_PALETTE:
3067 if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8)) return 37;
3068 break;
3069 case LCT_GREY_ALPHA:
3070 if(!(bd == 8 || bd == 16)) return 37;
3071 break;
3072 case LCT_RGBA:
3073 if(!(bd == 8 || bd == 16)) return 37;
3074 break;
3075 case LCT_MAX_OCTET_VALUE:
3076 return 31; /* invalid color type */
3077 default:
3078 return 31; /* invalid color type */
3079 }
3080 return 0; /*allowed color type / bits combination*/
3081 }
3082
getNumColorChannels(LodePNGColorType colortype)3083 static unsigned getNumColorChannels(LodePNGColorType colortype)
3084 {
3085 switch(colortype) {
3086 case LCT_GREY:
3087 return 1;
3088 case LCT_RGB:
3089 return 3;
3090 case LCT_PALETTE:
3091 return 1;
3092 case LCT_GREY_ALPHA:
3093 return 2;
3094 case LCT_RGBA:
3095 return 4;
3096 case LCT_MAX_OCTET_VALUE:
3097 return 0; /* invalid color type */
3098 default:
3099 return 0; /*invalid color type*/
3100 }
3101 }
3102
lodepng_get_bpp_lct(LodePNGColorType colortype,unsigned bitdepth)3103 static unsigned lodepng_get_bpp_lct(LodePNGColorType colortype, unsigned bitdepth)
3104 {
3105 /*bits per pixel is amount of channels * bits per channel*/
3106 return getNumColorChannels(colortype) * bitdepth;
3107 }
3108
3109 /* ////////////////////////////////////////////////////////////////////////// */
3110
lodepng_color_mode_init(LodePNGColorMode * info)3111 void lodepng_color_mode_init(LodePNGColorMode * info)
3112 {
3113 info->key_defined = 0;
3114 info->key_r = info->key_g = info->key_b = 0;
3115 info->colortype = LCT_RGBA;
3116 info->bitdepth = 8;
3117 info->palette = 0;
3118 info->palettesize = 0;
3119 }
3120
3121 /*allocates palette memory if needed, and initializes all colors to black*/
lodepng_color_mode_alloc_palette(LodePNGColorMode * info)3122 static void lodepng_color_mode_alloc_palette(LodePNGColorMode * info)
3123 {
3124 size_t i;
3125 /*if the palette is already allocated, it will have size 1024 so no reallocation needed in that case*/
3126 /*the palette must have room for up to 256 colors with 4 bytes each.*/
3127 if(!info->palette) info->palette = (unsigned char *)lodepng_malloc(1024);
3128 if(!info->palette) return; /*alloc fail*/
3129 for(i = 0; i != 256; ++i) {
3130 /*Initialize all unused colors with black, the value used for invalid palette indices.
3131 This is an error according to the PNG spec, but common PNG decoders make it black instead.
3132 That makes color conversion slightly faster due to no error handling needed.*/
3133 info->palette[i * 4 + 0] = 0;
3134 info->palette[i * 4 + 1] = 0;
3135 info->palette[i * 4 + 2] = 0;
3136 info->palette[i * 4 + 3] = 255;
3137 }
3138 }
3139
lodepng_color_mode_cleanup(LodePNGColorMode * info)3140 void lodepng_color_mode_cleanup(LodePNGColorMode * info)
3141 {
3142 lodepng_palette_clear(info);
3143 }
3144
lodepng_color_mode_copy(LodePNGColorMode * dest,const LodePNGColorMode * source)3145 unsigned lodepng_color_mode_copy(LodePNGColorMode * dest, const LodePNGColorMode * source)
3146 {
3147 lodepng_color_mode_cleanup(dest);
3148 lodepng_memcpy(dest, source, sizeof(LodePNGColorMode));
3149 if(source->palette) {
3150 dest->palette = (unsigned char *)lodepng_malloc(1024);
3151 if(!dest->palette && source->palettesize) return 83; /*alloc fail*/
3152 lodepng_memcpy(dest->palette, source->palette, source->palettesize * 4);
3153 }
3154 return 0;
3155 }
3156
lodepng_color_mode_make(LodePNGColorType colortype,unsigned bitdepth)3157 LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth)
3158 {
3159 LodePNGColorMode result;
3160 lodepng_color_mode_init(&result);
3161 result.colortype = colortype;
3162 result.bitdepth = bitdepth;
3163 return result;
3164 }
3165
lodepng_color_mode_equal(const LodePNGColorMode * a,const LodePNGColorMode * b)3166 static int lodepng_color_mode_equal(const LodePNGColorMode * a, const LodePNGColorMode * b)
3167 {
3168 size_t i;
3169 if(a->colortype != b->colortype) return 0;
3170 if(a->bitdepth != b->bitdepth) return 0;
3171 if(a->key_defined != b->key_defined) return 0;
3172 if(a->key_defined) {
3173 if(a->key_r != b->key_r) return 0;
3174 if(a->key_g != b->key_g) return 0;
3175 if(a->key_b != b->key_b) return 0;
3176 }
3177 if(a->palettesize != b->palettesize) return 0;
3178 for(i = 0; i != a->palettesize * 4; ++i) {
3179 if(a->palette[i] != b->palette[i]) return 0;
3180 }
3181 return 1;
3182 }
3183
lodepng_palette_clear(LodePNGColorMode * info)3184 void lodepng_palette_clear(LodePNGColorMode * info)
3185 {
3186 if(info->palette) lodepng_free(info->palette);
3187 info->palette = 0;
3188 info->palettesize = 0;
3189 }
3190
lodepng_palette_add(LodePNGColorMode * info,unsigned char r,unsigned char g,unsigned char b,unsigned char a)3191 unsigned lodepng_palette_add(LodePNGColorMode * info,
3192 unsigned char r, unsigned char g, unsigned char b, unsigned char a)
3193 {
3194 if(!info->palette) { /*allocate palette if empty*/
3195 lodepng_color_mode_alloc_palette(info);
3196 if(!info->palette) return 83; /*alloc fail*/
3197 }
3198 if(info->palettesize >= 256) {
3199 return 108; /*too many palette values*/
3200 }
3201 info->palette[4 * info->palettesize + 0] = r;
3202 info->palette[4 * info->palettesize + 1] = g;
3203 info->palette[4 * info->palettesize + 2] = b;
3204 info->palette[4 * info->palettesize + 3] = a;
3205 ++info->palettesize;
3206 return 0;
3207 }
3208
3209 /*calculate bits per pixel out of colortype and bitdepth*/
lodepng_get_bpp(const LodePNGColorMode * info)3210 unsigned lodepng_get_bpp(const LodePNGColorMode * info)
3211 {
3212 return lodepng_get_bpp_lct(info->colortype, info->bitdepth);
3213 }
3214
lodepng_get_channels(const LodePNGColorMode * info)3215 unsigned lodepng_get_channels(const LodePNGColorMode * info)
3216 {
3217 return getNumColorChannels(info->colortype);
3218 }
3219
lodepng_is_greyscale_type(const LodePNGColorMode * info)3220 unsigned lodepng_is_greyscale_type(const LodePNGColorMode * info)
3221 {
3222 return info->colortype == LCT_GREY || info->colortype == LCT_GREY_ALPHA;
3223 }
3224
lodepng_is_alpha_type(const LodePNGColorMode * info)3225 unsigned lodepng_is_alpha_type(const LodePNGColorMode * info)
3226 {
3227 return (info->colortype & 4) != 0; /*4 or 6*/
3228 }
3229
lodepng_is_palette_type(const LodePNGColorMode * info)3230 unsigned lodepng_is_palette_type(const LodePNGColorMode * info)
3231 {
3232 return info->colortype == LCT_PALETTE;
3233 }
3234
lodepng_has_palette_alpha(const LodePNGColorMode * info)3235 unsigned lodepng_has_palette_alpha(const LodePNGColorMode * info)
3236 {
3237 size_t i;
3238 for(i = 0; i != info->palettesize; ++i) {
3239 if(info->palette[i * 4 + 3] < 255) return 1;
3240 }
3241 return 0;
3242 }
3243
lodepng_can_have_alpha(const LodePNGColorMode * info)3244 unsigned lodepng_can_have_alpha(const LodePNGColorMode * info)
3245 {
3246 return info->key_defined
3247 || lodepng_is_alpha_type(info)
3248 || lodepng_has_palette_alpha(info);
3249 }
3250
lodepng_get_raw_size_lct(unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)3251 static size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth)
3252 {
3253 size_t bpp = lodepng_get_bpp_lct(colortype, bitdepth);
3254 size_t n = (size_t)w * (size_t)h;
3255 return ((n / 8u) * bpp) + ((n & 7u) * bpp + 7u) / 8u;
3256 }
3257
lodepng_get_raw_size(unsigned w,unsigned h,const LodePNGColorMode * color)3258 size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode * color)
3259 {
3260 return lodepng_get_raw_size_lct(w, h, color->colortype, color->bitdepth);
3261 }
3262
3263
3264 #ifdef LODEPNG_COMPILE_PNG
3265
3266 /*in an idat chunk, each scanline is a multiple of 8 bits, unlike the lodepng output buffer,
3267 and in addition has one extra byte per line: the filter byte. So this gives a larger
3268 result than lodepng_get_raw_size. Set h to 1 to get the size of 1 row including filter byte. */
lodepng_get_raw_size_idat(unsigned w,unsigned h,unsigned bpp)3269 static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, unsigned bpp)
3270 {
3271 /* + 1 for the filter byte, and possibly plus padding bits per line. */
3272 /* Ignoring casts, the expression is equal to (w * bpp + 7) / 8 + 1, but avoids overflow of w * bpp */
3273 size_t line = ((size_t)(w / 8u) * bpp) + 1u + ((w & 7u) * bpp + 7u) / 8u;
3274 return (size_t)h * line;
3275 }
3276
3277 #ifdef LODEPNG_COMPILE_DECODER
3278 /*Safely checks whether size_t overflow can be caused due to amount of pixels.
3279 This check is overcautious rather than precise. If this check indicates no overflow,
3280 you can safely compute in a size_t (but not an unsigned):
3281 -(size_t)w * (size_t)h * 8
3282 -amount of bytes in IDAT (including filter, padding and Adam7 bytes)
3283 -amount of bytes in raw color model
3284 Returns 1 if overflow possible, 0 if not.
3285 */
lodepng_pixel_overflow(unsigned w,unsigned h,const LodePNGColorMode * pngcolor,const LodePNGColorMode * rawcolor)3286 static int lodepng_pixel_overflow(unsigned w, unsigned h,
3287 const LodePNGColorMode * pngcolor, const LodePNGColorMode * rawcolor)
3288 {
3289 size_t bpp = LODEPNG_MAX(lodepng_get_bpp(pngcolor), lodepng_get_bpp(rawcolor));
3290 size_t numpixels, total;
3291 size_t line; /* bytes per line in worst case */
3292
3293 if(lodepng_mulofl((size_t)w, (size_t)h, &numpixels)) return 1;
3294 if(lodepng_mulofl(numpixels, 8, &total)) return 1; /* bit pointer with 8-bit color, or 8 bytes per channel color */
3295
3296 /* Bytes per scanline with the expression "(w / 8u) * bpp) + ((w & 7u) * bpp + 7u) / 8u" */
3297 if(lodepng_mulofl((size_t)(w / 8u), bpp, &line)) return 1;
3298 if(lodepng_addofl(line, ((w & 7u) * bpp + 7u) / 8u, &line)) return 1;
3299
3300 if(lodepng_addofl(line, 5, &line)) return 1; /* 5 bytes overhead per line: 1 filterbyte, 4 for Adam7 worst case */
3301 if(lodepng_mulofl(line, h, &total)) return 1; /* Total bytes in worst case */
3302
3303 return 0; /* no overflow */
3304 }
3305 #endif /*LODEPNG_COMPILE_DECODER*/
3306 #endif /*LODEPNG_COMPILE_PNG*/
3307
3308 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
3309
LodePNGUnknownChunks_init(LodePNGInfo * info)3310 static void LodePNGUnknownChunks_init(LodePNGInfo * info)
3311 {
3312 unsigned i;
3313 for(i = 0; i != 3; ++i) info->unknown_chunks_data[i] = 0;
3314 for(i = 0; i != 3; ++i) info->unknown_chunks_size[i] = 0;
3315 }
3316
LodePNGUnknownChunks_cleanup(LodePNGInfo * info)3317 static void LodePNGUnknownChunks_cleanup(LodePNGInfo * info)
3318 {
3319 unsigned i;
3320 for(i = 0; i != 3; ++i) lodepng_free(info->unknown_chunks_data[i]);
3321 }
3322
LodePNGUnknownChunks_copy(LodePNGInfo * dest,const LodePNGInfo * src)3323 static unsigned LodePNGUnknownChunks_copy(LodePNGInfo * dest, const LodePNGInfo * src)
3324 {
3325 unsigned i;
3326
3327 LodePNGUnknownChunks_cleanup(dest);
3328
3329 for(i = 0; i != 3; ++i) {
3330 size_t j;
3331 dest->unknown_chunks_size[i] = src->unknown_chunks_size[i];
3332 dest->unknown_chunks_data[i] = (unsigned char *)lodepng_malloc(src->unknown_chunks_size[i]);
3333 if(!dest->unknown_chunks_data[i] && dest->unknown_chunks_size[i]) return 83; /*alloc fail*/
3334 for(j = 0; j < src->unknown_chunks_size[i]; ++j) {
3335 dest->unknown_chunks_data[i][j] = src->unknown_chunks_data[i][j];
3336 }
3337 }
3338
3339 return 0;
3340 }
3341
3342 /******************************************************************************/
3343
LodePNGText_init(LodePNGInfo * info)3344 static void LodePNGText_init(LodePNGInfo * info)
3345 {
3346 info->text_num = 0;
3347 info->text_keys = NULL;
3348 info->text_strings = NULL;
3349 }
3350
LodePNGText_cleanup(LodePNGInfo * info)3351 static void LodePNGText_cleanup(LodePNGInfo * info)
3352 {
3353 size_t i;
3354 for(i = 0; i != info->text_num; ++i) {
3355 string_cleanup(&info->text_keys[i]);
3356 string_cleanup(&info->text_strings[i]);
3357 }
3358 lodepng_free(info->text_keys);
3359 lodepng_free(info->text_strings);
3360 }
3361
LodePNGText_copy(LodePNGInfo * dest,const LodePNGInfo * source)3362 static unsigned LodePNGText_copy(LodePNGInfo * dest, const LodePNGInfo * source)
3363 {
3364 size_t i = 0;
3365 dest->text_keys = NULL;
3366 dest->text_strings = NULL;
3367 dest->text_num = 0;
3368 for(i = 0; i != source->text_num; ++i) {
3369 CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i]));
3370 }
3371 return 0;
3372 }
3373
lodepng_add_text_sized(LodePNGInfo * info,const char * key,const char * str,size_t size)3374 static unsigned lodepng_add_text_sized(LodePNGInfo * info, const char * key, const char * str, size_t size)
3375 {
3376 char ** new_keys = (char **)(lodepng_realloc(info->text_keys, sizeof(char *) * (info->text_num + 1)));
3377 char ** new_strings = (char **)(lodepng_realloc(info->text_strings, sizeof(char *) * (info->text_num + 1)));
3378
3379 if(new_keys) info->text_keys = new_keys;
3380 if(new_strings) info->text_strings = new_strings;
3381
3382 if(!new_keys || !new_strings) return 83; /*alloc fail*/
3383
3384 ++info->text_num;
3385 info->text_keys[info->text_num - 1] = alloc_string(key);
3386 info->text_strings[info->text_num - 1] = alloc_string_sized(str, size);
3387 if(!info->text_keys[info->text_num - 1] || !info->text_strings[info->text_num - 1]) return 83; /*alloc fail*/
3388
3389 return 0;
3390 }
3391
lodepng_add_text(LodePNGInfo * info,const char * key,const char * str)3392 unsigned lodepng_add_text(LodePNGInfo * info, const char * key, const char * str)
3393 {
3394 return lodepng_add_text_sized(info, key, str, lodepng_strlen(str));
3395 }
3396
lodepng_clear_text(LodePNGInfo * info)3397 void lodepng_clear_text(LodePNGInfo * info)
3398 {
3399 LodePNGText_cleanup(info);
3400 }
3401
3402 /******************************************************************************/
3403
LodePNGIText_init(LodePNGInfo * info)3404 static void LodePNGIText_init(LodePNGInfo * info)
3405 {
3406 info->itext_num = 0;
3407 info->itext_keys = NULL;
3408 info->itext_langtags = NULL;
3409 info->itext_transkeys = NULL;
3410 info->itext_strings = NULL;
3411 }
3412
LodePNGIText_cleanup(LodePNGInfo * info)3413 static void LodePNGIText_cleanup(LodePNGInfo * info)
3414 {
3415 size_t i;
3416 for(i = 0; i != info->itext_num; ++i) {
3417 string_cleanup(&info->itext_keys[i]);
3418 string_cleanup(&info->itext_langtags[i]);
3419 string_cleanup(&info->itext_transkeys[i]);
3420 string_cleanup(&info->itext_strings[i]);
3421 }
3422 lodepng_free(info->itext_keys);
3423 lodepng_free(info->itext_langtags);
3424 lodepng_free(info->itext_transkeys);
3425 lodepng_free(info->itext_strings);
3426 }
3427
LodePNGIText_copy(LodePNGInfo * dest,const LodePNGInfo * source)3428 static unsigned LodePNGIText_copy(LodePNGInfo * dest, const LodePNGInfo * source)
3429 {
3430 size_t i = 0;
3431 dest->itext_keys = NULL;
3432 dest->itext_langtags = NULL;
3433 dest->itext_transkeys = NULL;
3434 dest->itext_strings = NULL;
3435 dest->itext_num = 0;
3436 for(i = 0; i != source->itext_num; ++i) {
3437 CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i],
3438 source->itext_transkeys[i], source->itext_strings[i]));
3439 }
3440 return 0;
3441 }
3442
lodepng_clear_itext(LodePNGInfo * info)3443 void lodepng_clear_itext(LodePNGInfo * info)
3444 {
3445 LodePNGIText_cleanup(info);
3446 }
3447
lodepng_add_itext_sized(LodePNGInfo * info,const char * key,const char * langtag,const char * transkey,const char * str,size_t size)3448 static unsigned lodepng_add_itext_sized(LodePNGInfo * info, const char * key, const char * langtag,
3449 const char * transkey, const char * str, size_t size)
3450 {
3451 char ** new_keys = (char **)(lodepng_realloc(info->itext_keys, sizeof(char *) * (info->itext_num + 1)));
3452 char ** new_langtags = (char **)(lodepng_realloc(info->itext_langtags, sizeof(char *) * (info->itext_num + 1)));
3453 char ** new_transkeys = (char **)(lodepng_realloc(info->itext_transkeys, sizeof(char *) * (info->itext_num + 1)));
3454 char ** new_strings = (char **)(lodepng_realloc(info->itext_strings, sizeof(char *) * (info->itext_num + 1)));
3455
3456 if(new_keys) info->itext_keys = new_keys;
3457 if(new_langtags) info->itext_langtags = new_langtags;
3458 if(new_transkeys) info->itext_transkeys = new_transkeys;
3459 if(new_strings) info->itext_strings = new_strings;
3460
3461 if(!new_keys || !new_langtags || !new_transkeys || !new_strings) return 83; /*alloc fail*/
3462
3463 ++info->itext_num;
3464
3465 info->itext_keys[info->itext_num - 1] = alloc_string(key);
3466 info->itext_langtags[info->itext_num - 1] = alloc_string(langtag);
3467 info->itext_transkeys[info->itext_num - 1] = alloc_string(transkey);
3468 info->itext_strings[info->itext_num - 1] = alloc_string_sized(str, size);
3469
3470 return 0;
3471 }
3472
lodepng_add_itext(LodePNGInfo * info,const char * key,const char * langtag,const char * transkey,const char * str)3473 unsigned lodepng_add_itext(LodePNGInfo * info, const char * key, const char * langtag,
3474 const char * transkey, const char * str)
3475 {
3476 return lodepng_add_itext_sized(info, key, langtag, transkey, str, lodepng_strlen(str));
3477 }
3478
3479 /* same as set but does not delete */
lodepng_assign_icc(LodePNGInfo * info,const char * name,const unsigned char * profile,unsigned profile_size)3480 static unsigned lodepng_assign_icc(LodePNGInfo * info, const char * name, const unsigned char * profile,
3481 unsigned profile_size)
3482 {
3483 if(profile_size == 0) return 100; /*invalid ICC profile size*/
3484
3485 info->iccp_name = alloc_string(name);
3486 info->iccp_profile = (unsigned char *)lodepng_malloc(profile_size);
3487
3488 if(!info->iccp_name || !info->iccp_profile) return 83; /*alloc fail*/
3489
3490 lodepng_memcpy(info->iccp_profile, profile, profile_size);
3491 info->iccp_profile_size = profile_size;
3492
3493 return 0; /*ok*/
3494 }
3495
lodepng_set_icc(LodePNGInfo * info,const char * name,const unsigned char * profile,unsigned profile_size)3496 unsigned lodepng_set_icc(LodePNGInfo * info, const char * name, const unsigned char * profile, unsigned profile_size)
3497 {
3498 if(info->iccp_name) lodepng_clear_icc(info);
3499 info->iccp_defined = 1;
3500
3501 return lodepng_assign_icc(info, name, profile, profile_size);
3502 }
3503
lodepng_clear_icc(LodePNGInfo * info)3504 void lodepng_clear_icc(LodePNGInfo * info)
3505 {
3506 string_cleanup(&info->iccp_name);
3507 lodepng_free(info->iccp_profile);
3508 info->iccp_profile = NULL;
3509 info->iccp_profile_size = 0;
3510 info->iccp_defined = 0;
3511 }
3512 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
3513
lodepng_info_init(LodePNGInfo * info)3514 void lodepng_info_init(LodePNGInfo * info)
3515 {
3516 lodepng_color_mode_init(&info->color);
3517 info->interlace_method = 0;
3518 info->compression_method = 0;
3519 info->filter_method = 0;
3520 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
3521 info->background_defined = 0;
3522 info->background_r = info->background_g = info->background_b = 0;
3523
3524 LodePNGText_init(info);
3525 LodePNGIText_init(info);
3526
3527 info->time_defined = 0;
3528 info->phys_defined = 0;
3529
3530 info->gama_defined = 0;
3531 info->chrm_defined = 0;
3532 info->srgb_defined = 0;
3533 info->iccp_defined = 0;
3534 info->iccp_name = NULL;
3535 info->iccp_profile = NULL;
3536
3537 info->sbit_defined = 0;
3538 info->sbit_r = info->sbit_g = info->sbit_b = info->sbit_a = 0;
3539
3540 LodePNGUnknownChunks_init(info);
3541 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
3542 }
3543
lodepng_info_cleanup(LodePNGInfo * info)3544 void lodepng_info_cleanup(LodePNGInfo * info)
3545 {
3546 lodepng_color_mode_cleanup(&info->color);
3547 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
3548 LodePNGText_cleanup(info);
3549 LodePNGIText_cleanup(info);
3550
3551 lodepng_clear_icc(info);
3552
3553 LodePNGUnknownChunks_cleanup(info);
3554 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
3555 }
3556
lodepng_info_copy(LodePNGInfo * dest,const LodePNGInfo * source)3557 unsigned lodepng_info_copy(LodePNGInfo * dest, const LodePNGInfo * source)
3558 {
3559 lodepng_info_cleanup(dest);
3560 lodepng_memcpy(dest, source, sizeof(LodePNGInfo));
3561 lodepng_color_mode_init(&dest->color);
3562 CERROR_TRY_RETURN(lodepng_color_mode_copy(&dest->color, &source->color));
3563
3564 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
3565 CERROR_TRY_RETURN(LodePNGText_copy(dest, source));
3566 CERROR_TRY_RETURN(LodePNGIText_copy(dest, source));
3567 if(source->iccp_defined) {
3568 CERROR_TRY_RETURN(lodepng_assign_icc(dest, source->iccp_name, source->iccp_profile, source->iccp_profile_size));
3569 }
3570
3571 LodePNGUnknownChunks_init(dest);
3572 CERROR_TRY_RETURN(LodePNGUnknownChunks_copy(dest, source));
3573 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
3574 return 0;
3575 }
3576
3577 /* ////////////////////////////////////////////////////////////////////////// */
3578
3579 /*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)3580 static void addColorBits(unsigned char * out, size_t index, unsigned bits, unsigned in)
3581 {
3582 unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1; /*8 / bits - 1*/
3583 /*p = the partial index in the byte, e.g. with 4 palettebits it is 0 for first half or 1 for second half*/
3584 unsigned p = index & m;
3585 in &= (1u << bits) - 1u; /*filter out any other bits of the input value*/
3586 in = in << (bits * (m - p));
3587 if(p == 0) out[index * bits / 8u] = in;
3588 else out[index * bits / 8u] |= in;
3589 }
3590
3591 typedef struct ColorTree ColorTree;
3592
3593 /*
3594 One node of a color tree
3595 This is the data structure used to count the number of unique colors and to get a palette
3596 index for a color. It's like an octree, but because the alpha channel is used too, each
3597 node has 16 instead of 8 children.
3598 */
3599 struct ColorTree {
3600 ColorTree * children[16]; /*up to 16 pointers to ColorTree of next level*/
3601 int index; /*the payload. Only has a meaningful value if this is in the last level*/
3602 };
3603
color_tree_init(ColorTree * tree)3604 static void color_tree_init(ColorTree * tree)
3605 {
3606 lodepng_memset(tree->children, 0, 16 * sizeof(*tree->children));
3607 tree->index = -1;
3608 }
3609
color_tree_cleanup(ColorTree * tree)3610 static void color_tree_cleanup(ColorTree * tree)
3611 {
3612 int i;
3613 for(i = 0; i != 16; ++i) {
3614 if(tree->children[i]) {
3615 color_tree_cleanup(tree->children[i]);
3616 lodepng_free(tree->children[i]);
3617 }
3618 }
3619 }
3620
3621 /*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)3622 static int color_tree_get(ColorTree * tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
3623 {
3624 int bit = 0;
3625 for(bit = 0; bit < 8; ++bit) {
3626 int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1);
3627 if(!tree->children[i]) return -1;
3628 else tree = tree->children[i];
3629 }
3630 return tree ? tree->index : -1;
3631 }
3632
3633 #ifdef LODEPNG_COMPILE_ENCODER
color_tree_has(ColorTree * tree,unsigned char r,unsigned char g,unsigned char b,unsigned char a)3634 static int color_tree_has(ColorTree * tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
3635 {
3636 return color_tree_get(tree, r, g, b, a) >= 0;
3637 }
3638 #endif /*LODEPNG_COMPILE_ENCODER*/
3639
3640 /*color is not allowed to already exist.
3641 Index should be >= 0 (it's signed to be compatible with using -1 for "doesn't exist")
3642 Returns error code, or 0 if ok*/
color_tree_add(ColorTree * tree,unsigned char r,unsigned char g,unsigned char b,unsigned char a,unsigned index)3643 static unsigned color_tree_add(ColorTree * tree,
3644 unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned index)
3645 {
3646 int bit;
3647 for(bit = 0; bit < 8; ++bit) {
3648 int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1);
3649 if(!tree->children[i]) {
3650 tree->children[i] = (ColorTree *)lodepng_malloc(sizeof(ColorTree));
3651 if(!tree->children[i]) return 83; /*alloc fail*/
3652 color_tree_init(tree->children[i]);
3653 }
3654 tree = tree->children[i];
3655 }
3656 tree->index = (int)index;
3657 return 0;
3658 }
3659
3660 /*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)3661 static unsigned rgba8ToPixel(unsigned char * out, size_t i,
3662 const LodePNGColorMode * mode, ColorTree * tree /*for palette*/,
3663 unsigned char r, unsigned char g, unsigned char b, unsigned char a)
3664 {
3665 if(mode->colortype == LCT_GREY) {
3666 unsigned char gray = r; /*((unsigned short)r + g + b) / 3u;*/
3667 if(mode->bitdepth == 8) out[i] = gray;
3668 else if(mode->bitdepth == 16) out[i * 2 + 0] = out[i * 2 + 1] = gray;
3669 else {
3670 /*take the most significant bits of gray*/
3671 gray = ((unsigned)gray >> (8u - mode->bitdepth)) & ((1u << mode->bitdepth) - 1u);
3672 addColorBits(out, i, mode->bitdepth, gray);
3673 }
3674 }
3675 else if(mode->colortype == LCT_RGB) {
3676 if(mode->bitdepth == 8) {
3677 out[i * 3 + 0] = r;
3678 out[i * 3 + 1] = g;
3679 out[i * 3 + 2] = b;
3680 }
3681 else {
3682 out[i * 6 + 0] = out[i * 6 + 1] = r;
3683 out[i * 6 + 2] = out[i * 6 + 3] = g;
3684 out[i * 6 + 4] = out[i * 6 + 5] = b;
3685 }
3686 }
3687 else if(mode->colortype == LCT_PALETTE) {
3688 int index = color_tree_get(tree, r, g, b, a);
3689 if(index < 0) return 82; /*color not in palette*/
3690 if(mode->bitdepth == 8) out[i] = index;
3691 else addColorBits(out, i, mode->bitdepth, (unsigned)index);
3692 }
3693 else if(mode->colortype == LCT_GREY_ALPHA) {
3694 unsigned char gray = r; /*((unsigned short)r + g + b) / 3u;*/
3695 if(mode->bitdepth == 8) {
3696 out[i * 2 + 0] = gray;
3697 out[i * 2 + 1] = a;
3698 }
3699 else if(mode->bitdepth == 16) {
3700 out[i * 4 + 0] = out[i * 4 + 1] = gray;
3701 out[i * 4 + 2] = out[i * 4 + 3] = a;
3702 }
3703 }
3704 else if(mode->colortype == LCT_RGBA) {
3705 if(mode->bitdepth == 8) {
3706 out[i * 4 + 0] = r;
3707 out[i * 4 + 1] = g;
3708 out[i * 4 + 2] = b;
3709 out[i * 4 + 3] = a;
3710 }
3711 else {
3712 out[i * 8 + 0] = out[i * 8 + 1] = r;
3713 out[i * 8 + 2] = out[i * 8 + 3] = g;
3714 out[i * 8 + 4] = out[i * 8 + 5] = b;
3715 out[i * 8 + 6] = out[i * 8 + 7] = a;
3716 }
3717 }
3718
3719 return 0; /*no error*/
3720 }
3721
3722 /*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)3723 static void rgba16ToPixel(unsigned char * out, size_t i,
3724 const LodePNGColorMode * mode,
3725 unsigned short r, unsigned short g, unsigned short b, unsigned short a)
3726 {
3727 if(mode->colortype == LCT_GREY) {
3728 unsigned short gray = r; /*((unsigned)r + g + b) / 3u;*/
3729 out[i * 2 + 0] = (gray >> 8) & 255;
3730 out[i * 2 + 1] = gray & 255;
3731 }
3732 else if(mode->colortype == LCT_RGB) {
3733 out[i * 6 + 0] = (r >> 8) & 255;
3734 out[i * 6 + 1] = r & 255;
3735 out[i * 6 + 2] = (g >> 8) & 255;
3736 out[i * 6 + 3] = g & 255;
3737 out[i * 6 + 4] = (b >> 8) & 255;
3738 out[i * 6 + 5] = b & 255;
3739 }
3740 else if(mode->colortype == LCT_GREY_ALPHA) {
3741 unsigned short gray = r; /*((unsigned)r + g + b) / 3u;*/
3742 out[i * 4 + 0] = (gray >> 8) & 255;
3743 out[i * 4 + 1] = gray & 255;
3744 out[i * 4 + 2] = (a >> 8) & 255;
3745 out[i * 4 + 3] = a & 255;
3746 }
3747 else if(mode->colortype == LCT_RGBA) {
3748 out[i * 8 + 0] = (r >> 8) & 255;
3749 out[i * 8 + 1] = r & 255;
3750 out[i * 8 + 2] = (g >> 8) & 255;
3751 out[i * 8 + 3] = g & 255;
3752 out[i * 8 + 4] = (b >> 8) & 255;
3753 out[i * 8 + 5] = b & 255;
3754 out[i * 8 + 6] = (a >> 8) & 255;
3755 out[i * 8 + 7] = a & 255;
3756 }
3757 }
3758
3759 /*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)3760 static void getPixelColorRGBA8(unsigned char * r, unsigned char * g,
3761 unsigned char * b, unsigned char * a,
3762 const unsigned char * in, size_t i,
3763 const LodePNGColorMode * mode)
3764 {
3765 if(mode->colortype == LCT_GREY) {
3766 if(mode->bitdepth == 8) {
3767 *r = *g = *b = in[i];
3768 if(mode->key_defined && *r == mode->key_r) *a = 0;
3769 else *a = 255;
3770 }
3771 else if(mode->bitdepth == 16) {
3772 *r = *g = *b = in[i * 2 + 0];
3773 if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0;
3774 else *a = 255;
3775 }
3776 else {
3777 unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/
3778 size_t j = i * mode->bitdepth;
3779 unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth);
3780 *r = *g = *b = (value * 255) / highest;
3781 if(mode->key_defined && value == mode->key_r) *a = 0;
3782 else *a = 255;
3783 }
3784 }
3785 else if(mode->colortype == LCT_RGB) {
3786 if(mode->bitdepth == 8) {
3787 *r = in[i * 3 + 0];
3788 *g = in[i * 3 + 1];
3789 *b = in[i * 3 + 2];
3790 if(mode->key_defined && *r == mode->key_r && *g == mode->key_g && *b == mode->key_b) *a = 0;
3791 else *a = 255;
3792 }
3793 else {
3794 *r = in[i * 6 + 0];
3795 *g = in[i * 6 + 2];
3796 *b = in[i * 6 + 4];
3797 if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r
3798 && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g
3799 && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0;
3800 else *a = 255;
3801 }
3802 }
3803 else if(mode->colortype == LCT_PALETTE) {
3804 unsigned index;
3805 if(mode->bitdepth == 8) index = in[i];
3806 else {
3807 size_t j = i * mode->bitdepth;
3808 index = readBitsFromReversedStream(&j, in, mode->bitdepth);
3809 }
3810 /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/
3811 *r = mode->palette[index * 4 + 0];
3812 *g = mode->palette[index * 4 + 1];
3813 *b = mode->palette[index * 4 + 2];
3814 *a = mode->palette[index * 4 + 3];
3815 }
3816 else if(mode->colortype == LCT_GREY_ALPHA) {
3817 if(mode->bitdepth == 8) {
3818 *r = *g = *b = in[i * 2 + 0];
3819 *a = in[i * 2 + 1];
3820 }
3821 else {
3822 *r = *g = *b = in[i * 4 + 0];
3823 *a = in[i * 4 + 2];
3824 }
3825 }
3826 else if(mode->colortype == LCT_RGBA) {
3827 if(mode->bitdepth == 8) {
3828 *r = in[i * 4 + 0];
3829 *g = in[i * 4 + 1];
3830 *b = in[i * 4 + 2];
3831 *a = in[i * 4 + 3];
3832 }
3833 else {
3834 *r = in[i * 8 + 0];
3835 *g = in[i * 8 + 2];
3836 *b = in[i * 8 + 4];
3837 *a = in[i * 8 + 6];
3838 }
3839 }
3840 }
3841
3842 /*Similar to getPixelColorRGBA8, but with all the for loops inside of the color
3843 mode test cases, optimized to convert the colors much faster, when converting
3844 to the common case of RGBA with 8 bit per channel. buffer must be RGBA with
3845 enough memory.*/
getPixelColorsRGBA8(unsigned char * LODEPNG_RESTRICT buffer,size_t numpixels,const unsigned char * LODEPNG_RESTRICT in,const LodePNGColorMode * mode)3846 static void getPixelColorsRGBA8(unsigned char * LODEPNG_RESTRICT buffer, size_t numpixels,
3847 const unsigned char * LODEPNG_RESTRICT in,
3848 const LodePNGColorMode * mode)
3849 {
3850 unsigned num_channels = 4;
3851 size_t i;
3852 if(mode->colortype == LCT_GREY) {
3853 if(mode->bitdepth == 8) {
3854 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3855 buffer[0] = buffer[1] = buffer[2] = in[i];
3856 buffer[3] = 255;
3857 }
3858 if(mode->key_defined) {
3859 buffer -= numpixels * num_channels;
3860 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3861 if(buffer[0] == mode->key_r) buffer[3] = 0;
3862 }
3863 }
3864 }
3865 else if(mode->bitdepth == 16) {
3866 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3867 buffer[0] = buffer[1] = buffer[2] = in[i * 2];
3868 buffer[3] = mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r ? 0 : 255;
3869 }
3870 }
3871 else {
3872 unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/
3873 size_t j = 0;
3874 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3875 unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth);
3876 buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest;
3877 buffer[3] = mode->key_defined && value == mode->key_r ? 0 : 255;
3878 }
3879 }
3880 }
3881 else if(mode->colortype == LCT_RGB) {
3882 if(mode->bitdepth == 8) {
3883 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3884 lodepng_memcpy(buffer, &in[i * 3], 3);
3885 buffer[3] = 255;
3886 }
3887 if(mode->key_defined) {
3888 buffer -= numpixels * num_channels;
3889 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3890 if(buffer[0] == mode->key_r && buffer[1] == mode->key_g && buffer[2] == mode->key_b) buffer[3] = 0;
3891 }
3892 }
3893 }
3894 else {
3895 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3896 buffer[0] = in[i * 6 + 0];
3897 buffer[1] = in[i * 6 + 2];
3898 buffer[2] = in[i * 6 + 4];
3899 buffer[3] = mode->key_defined
3900 && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r
3901 && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g
3902 && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b ? 0 : 255;
3903 }
3904 }
3905 }
3906 else if(mode->colortype == LCT_PALETTE) {
3907 if(mode->bitdepth == 8) {
3908 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3909 unsigned index = in[i];
3910 /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/
3911 lodepng_memcpy(buffer, &mode->palette[index * 4], 4);
3912 }
3913 }
3914 else {
3915 size_t j = 0;
3916 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3917 unsigned index = readBitsFromReversedStream(&j, in, mode->bitdepth);
3918 /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/
3919 lodepng_memcpy(buffer, &mode->palette[index * 4], 4);
3920 }
3921 }
3922 }
3923 else if(mode->colortype == LCT_GREY_ALPHA) {
3924 if(mode->bitdepth == 8) {
3925 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3926 buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0];
3927 buffer[3] = in[i * 2 + 1];
3928 }
3929 }
3930 else {
3931 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3932 buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0];
3933 buffer[3] = in[i * 4 + 2];
3934 }
3935 }
3936 }
3937 else if(mode->colortype == LCT_RGBA) {
3938 if(mode->bitdepth == 8) {
3939 lodepng_memcpy(buffer, in, numpixels * 4);
3940 }
3941 else {
3942 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3943 buffer[0] = in[i * 8 + 0];
3944 buffer[1] = in[i * 8 + 2];
3945 buffer[2] = in[i * 8 + 4];
3946 buffer[3] = in[i * 8 + 6];
3947 }
3948 }
3949 }
3950 }
3951
3952 /*Similar to getPixelColorsRGBA8, but with 3-channel RGB output.*/
getPixelColorsRGB8(unsigned char * LODEPNG_RESTRICT buffer,size_t numpixels,const unsigned char * LODEPNG_RESTRICT in,const LodePNGColorMode * mode)3953 static void getPixelColorsRGB8(unsigned char * LODEPNG_RESTRICT buffer, size_t numpixels,
3954 const unsigned char * LODEPNG_RESTRICT in,
3955 const LodePNGColorMode * mode)
3956 {
3957 const unsigned num_channels = 3;
3958 size_t i;
3959 if(mode->colortype == LCT_GREY) {
3960 if(mode->bitdepth == 8) {
3961 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3962 buffer[0] = buffer[1] = buffer[2] = in[i];
3963 }
3964 }
3965 else if(mode->bitdepth == 16) {
3966 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3967 buffer[0] = buffer[1] = buffer[2] = in[i * 2];
3968 }
3969 }
3970 else {
3971 unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/
3972 size_t j = 0;
3973 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3974 unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth);
3975 buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest;
3976 }
3977 }
3978 }
3979 else if(mode->colortype == LCT_RGB) {
3980 if(mode->bitdepth == 8) {
3981 lodepng_memcpy(buffer, in, numpixels * 3);
3982 }
3983 else {
3984 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3985 buffer[0] = in[i * 6 + 0];
3986 buffer[1] = in[i * 6 + 2];
3987 buffer[2] = in[i * 6 + 4];
3988 }
3989 }
3990 }
3991 else if(mode->colortype == LCT_PALETTE) {
3992 if(mode->bitdepth == 8) {
3993 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
3994 unsigned index = in[i];
3995 /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/
3996 lodepng_memcpy(buffer, &mode->palette[index * 4], 3);
3997 }
3998 }
3999 else {
4000 size_t j = 0;
4001 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
4002 unsigned index = readBitsFromReversedStream(&j, in, mode->bitdepth);
4003 /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/
4004 lodepng_memcpy(buffer, &mode->palette[index * 4], 3);
4005 }
4006 }
4007 }
4008 else if(mode->colortype == LCT_GREY_ALPHA) {
4009 if(mode->bitdepth == 8) {
4010 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
4011 buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0];
4012 }
4013 }
4014 else {
4015 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
4016 buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0];
4017 }
4018 }
4019 }
4020 else if(mode->colortype == LCT_RGBA) {
4021 if(mode->bitdepth == 8) {
4022 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
4023 lodepng_memcpy(buffer, &in[i * 4], 3);
4024 }
4025 }
4026 else {
4027 for(i = 0; i != numpixels; ++i, buffer += num_channels) {
4028 buffer[0] = in[i * 8 + 0];
4029 buffer[1] = in[i * 8 + 2];
4030 buffer[2] = in[i * 8 + 4];
4031 }
4032 }
4033 }
4034 }
4035
4036 /*Get RGBA16 color of pixel with index i (y * width + x) from the raw image with
4037 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)4038 static void getPixelColorRGBA16(unsigned short * r, unsigned short * g, unsigned short * b, unsigned short * a,
4039 const unsigned char * in, size_t i, const LodePNGColorMode * mode)
4040 {
4041 if(mode->colortype == LCT_GREY) {
4042 *r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1];
4043 if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0;
4044 else *a = 65535;
4045 }
4046 else if(mode->colortype == LCT_RGB) {
4047 *r = 256u * in[i * 6 + 0] + in[i * 6 + 1];
4048 *g = 256u * in[i * 6 + 2] + in[i * 6 + 3];
4049 *b = 256u * in[i * 6 + 4] + in[i * 6 + 5];
4050 if(mode->key_defined
4051 && 256u * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r
4052 && 256u * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g
4053 && 256u * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0;
4054 else *a = 65535;
4055 }
4056 else if(mode->colortype == LCT_GREY_ALPHA) {
4057 *r = *g = *b = 256u * in[i * 4 + 0] + in[i * 4 + 1];
4058 *a = 256u * in[i * 4 + 2] + in[i * 4 + 3];
4059 }
4060 else if(mode->colortype == LCT_RGBA) {
4061 *r = 256u * in[i * 8 + 0] + in[i * 8 + 1];
4062 *g = 256u * in[i * 8 + 2] + in[i * 8 + 3];
4063 *b = 256u * in[i * 8 + 4] + in[i * 8 + 5];
4064 *a = 256u * in[i * 8 + 6] + in[i * 8 + 7];
4065 }
4066 }
4067
lodepng_convert(unsigned char * out,const unsigned char * in,const LodePNGColorMode * mode_out,const LodePNGColorMode * mode_in,unsigned w,unsigned h)4068 unsigned lodepng_convert(unsigned char * out, const unsigned char * in,
4069 const LodePNGColorMode * mode_out, const LodePNGColorMode * mode_in,
4070 unsigned w, unsigned h)
4071 {
4072 size_t i;
4073 ColorTree tree;
4074 size_t numpixels = (size_t)w * (size_t)h;
4075 unsigned error = 0;
4076
4077 if(mode_in->colortype == LCT_PALETTE && !mode_in->palette) {
4078 return 107; /* error: must provide palette if input mode is palette */
4079 }
4080
4081 if(lodepng_color_mode_equal(mode_out, mode_in)) {
4082 size_t numbytes = lodepng_get_raw_size(w, h, mode_in);
4083 lodepng_memcpy(out, in, numbytes);
4084 return 0;
4085 }
4086
4087 if(mode_out->colortype == LCT_PALETTE) {
4088 size_t palettesize = mode_out->palettesize;
4089 const unsigned char * palette = mode_out->palette;
4090 size_t palsize = (size_t)1u << mode_out->bitdepth;
4091 /*if the user specified output palette but did not give the values, assume
4092 they want the values of the input color type (assuming that one is palette).
4093 Note that we never create a new palette ourselves.*/
4094 if(palettesize == 0) {
4095 palettesize = mode_in->palettesize;
4096 palette = mode_in->palette;
4097 /*if the input was also palette with same bitdepth, then the color types are also
4098 equal, so copy literally. This to preserve the exact indices that were in the PNG
4099 even in case there are duplicate colors in the palette.*/
4100 if(mode_in->colortype == LCT_PALETTE && mode_in->bitdepth == mode_out->bitdepth) {
4101 size_t numbytes = lodepng_get_raw_size(w, h, mode_in);
4102 lodepng_memcpy(out, in, numbytes);
4103 return 0;
4104 }
4105 }
4106 if(palettesize < palsize) palsize = palettesize;
4107 color_tree_init(&tree);
4108 for(i = 0; i != palsize; ++i) {
4109 const unsigned char * p = &palette[i * 4];
4110 error = color_tree_add(&tree, p[0], p[1], p[2], p[3], (unsigned)i);
4111 if(error) break;
4112 }
4113 }
4114
4115 if(!error) {
4116 if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16) {
4117 for(i = 0; i != numpixels; ++i) {
4118 unsigned short r = 0, g = 0, b = 0, a = 0;
4119 getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
4120 rgba16ToPixel(out, i, mode_out, r, g, b, a);
4121 }
4122 }
4123 else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA) {
4124 getPixelColorsRGBA8(out, numpixels, in, mode_in);
4125 }
4126 else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB) {
4127 getPixelColorsRGB8(out, numpixels, in, mode_in);
4128 }
4129 else {
4130 unsigned char r = 0, g = 0, b = 0, a = 0;
4131 for(i = 0; i != numpixels; ++i) {
4132 getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in);
4133 error = rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a);
4134 if(error) break;
4135 }
4136 }
4137 }
4138
4139 if(mode_out->colortype == LCT_PALETTE) {
4140 color_tree_cleanup(&tree);
4141 }
4142
4143 return error;
4144 }
4145
4146
4147 /* Converts a single rgb color without alpha from one type to another, color bits truncated to
4148 their bitdepth. In case of single channel (gray or palette), only the r channel is used. Slow
4149 function, do not use to process all pixels of an image. Alpha channel not supported on purpose:
4150 this is for bKGD, supporting alpha may prevent it from finding a color in the palette, from the
4151 specification it looks like bKGD should ignore the alpha values of the palette since it can use
4152 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)4153 static unsigned lodepng_convert_rgb(
4154 unsigned * r_out, unsigned * g_out, unsigned * b_out,
4155 unsigned r_in, unsigned g_in, unsigned b_in,
4156 const LodePNGColorMode * mode_out, const LodePNGColorMode * mode_in)
4157 {
4158 unsigned r = 0, g = 0, b = 0;
4159 unsigned mul = 65535 / ((1u << mode_in->bitdepth) - 1u); /*65535, 21845, 4369, 257, 1*/
4160 unsigned shift = 16 - mode_out->bitdepth;
4161
4162 if(mode_in->colortype == LCT_GREY || mode_in->colortype == LCT_GREY_ALPHA) {
4163 r = g = b = r_in * mul;
4164 }
4165 else if(mode_in->colortype == LCT_RGB || mode_in->colortype == LCT_RGBA) {
4166 r = r_in * mul;
4167 g = g_in * mul;
4168 b = b_in * mul;
4169 }
4170 else if(mode_in->colortype == LCT_PALETTE) {
4171 if(r_in >= mode_in->palettesize) return 82;
4172 r = mode_in->palette[r_in * 4 + 0] * 257u;
4173 g = mode_in->palette[r_in * 4 + 1] * 257u;
4174 b = mode_in->palette[r_in * 4 + 2] * 257u;
4175 }
4176 else {
4177 return 31;
4178 }
4179
4180 /* now convert to output format */
4181 if(mode_out->colortype == LCT_GREY || mode_out->colortype == LCT_GREY_ALPHA) {
4182 *r_out = r >> shift ;
4183 }
4184 else if(mode_out->colortype == LCT_RGB || mode_out->colortype == LCT_RGBA) {
4185 *r_out = r >> shift ;
4186 *g_out = g >> shift ;
4187 *b_out = b >> shift ;
4188 }
4189 else if(mode_out->colortype == LCT_PALETTE) {
4190 unsigned i;
4191 /* a 16-bit color cannot be in the palette */
4192 if((r >> 8) != (r & 255) || (g >> 8) != (g & 255) || (b >> 8) != (b & 255)) return 82;
4193 for(i = 0; i < mode_out->palettesize; i++) {
4194 unsigned j = i * 4;
4195 if((r >> 8) == mode_out->palette[j + 0] && (g >> 8) == mode_out->palette[j + 1] &&
4196 (b >> 8) == mode_out->palette[j + 2]) {
4197 *r_out = i;
4198 return 0;
4199 }
4200 }
4201 return 82;
4202 }
4203 else {
4204 return 31;
4205 }
4206
4207 return 0;
4208 }
4209
4210 #ifdef LODEPNG_COMPILE_ENCODER
4211
lodepng_color_stats_init(LodePNGColorStats * stats)4212 void lodepng_color_stats_init(LodePNGColorStats * stats)
4213 {
4214 /*stats*/
4215 stats->colored = 0;
4216 stats->key = 0;
4217 stats->key_r = stats->key_g = stats->key_b = 0;
4218 stats->alpha = 0;
4219 stats->numcolors = 0;
4220 stats->bits = 1;
4221 stats->numpixels = 0;
4222 /*settings*/
4223 stats->allow_palette = 1;
4224 stats->allow_greyscale = 1;
4225 }
4226
4227 /*function used for debug purposes with C++*/
4228 /*void printColorStats(LodePNGColorStats* p) {
4229 std::cout << "colored: " << (int)p->colored << ", ";
4230 std::cout << "key: " << (int)p->key << ", ";
4231 std::cout << "key_r: " << (int)p->key_r << ", ";
4232 std::cout << "key_g: " << (int)p->key_g << ", ";
4233 std::cout << "key_b: " << (int)p->key_b << ", ";
4234 std::cout << "alpha: " << (int)p->alpha << ", ";
4235 std::cout << "numcolors: " << (int)p->numcolors << ", ";
4236 std::cout << "bits: " << (int)p->bits << std::endl;
4237 }*/
4238
4239 /*Returns how many bits needed to represent given value (max 8 bit)*/
getValueRequiredBits(unsigned char value)4240 static unsigned getValueRequiredBits(unsigned char value)
4241 {
4242 if(value == 0 || value == 255) return 1;
4243 /*The scaling of 2-bit and 4-bit values uses multiples of 85 and 17*/
4244 if(value % 17 == 0) return value % 85 == 0 ? 2 : 4;
4245 return 8;
4246 }
4247
4248 /*stats must already have been inited. */
lodepng_compute_color_stats(LodePNGColorStats * stats,const unsigned char * in,unsigned w,unsigned h,const LodePNGColorMode * mode_in)4249 unsigned lodepng_compute_color_stats(LodePNGColorStats * stats,
4250 const unsigned char * in, unsigned w, unsigned h,
4251 const LodePNGColorMode * mode_in)
4252 {
4253 size_t i;
4254 ColorTree tree;
4255 size_t numpixels = (size_t)w * (size_t)h;
4256 unsigned error = 0;
4257
4258 /* mark things as done already if it would be impossible to have a more expensive case */
4259 unsigned colored_done = lodepng_is_greyscale_type(mode_in) ? 1 : 0;
4260 unsigned alpha_done = lodepng_can_have_alpha(mode_in) ? 0 : 1;
4261 unsigned numcolors_done = 0;
4262 unsigned bpp = lodepng_get_bpp(mode_in);
4263 unsigned bits_done = (stats->bits == 1 && bpp == 1) ? 1 : 0;
4264 unsigned sixteen = 0; /* whether the input image is 16 bit */
4265 unsigned maxnumcolors = 257;
4266 if(bpp <= 8) maxnumcolors = LODEPNG_MIN(257, stats->numcolors + (1u << bpp));
4267
4268 stats->numpixels += numpixels;
4269
4270 /*if palette not allowed, no need to compute numcolors*/
4271 if(!stats->allow_palette) numcolors_done = 1;
4272
4273 color_tree_init(&tree);
4274
4275 /*If the stats was already filled in from previous data, fill its palette in tree
4276 and mark things as done already if we know they are the most expensive case already*/
4277 if(stats->alpha) alpha_done = 1;
4278 if(stats->colored) colored_done = 1;
4279 if(stats->bits == 16) numcolors_done = 1;
4280 if(stats->bits >= bpp) bits_done = 1;
4281 if(stats->numcolors >= maxnumcolors) numcolors_done = 1;
4282
4283 if(!numcolors_done) {
4284 for(i = 0; i < stats->numcolors; i++) {
4285 const unsigned char * color = &stats->palette[i * 4];
4286 error = color_tree_add(&tree, color[0], color[1], color[2], color[3], (unsigned)i);
4287 if(error) goto cleanup;
4288 }
4289 }
4290
4291 /*Check if the 16-bit input is truly 16-bit*/
4292 if(mode_in->bitdepth == 16 && !sixteen) {
4293 unsigned short r = 0, g = 0, b = 0, a = 0;
4294 for(i = 0; i != numpixels; ++i) {
4295 getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
4296 if((r & 255) != ((r >> 8) & 255) || (g & 255) != ((g >> 8) & 255) ||
4297 (b & 255) != ((b >> 8) & 255) || (a & 255) != ((a >> 8) & 255)) { /*first and second byte differ*/
4298 stats->bits = 16;
4299 sixteen = 1;
4300 bits_done = 1;
4301 numcolors_done = 1; /*counting colors no longer useful, palette doesn't support 16-bit*/
4302 break;
4303 }
4304 }
4305 }
4306
4307 if(sixteen) {
4308 unsigned short r = 0, g = 0, b = 0, a = 0;
4309
4310 for(i = 0; i != numpixels; ++i) {
4311 getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
4312
4313 if(!colored_done && (r != g || r != b)) {
4314 stats->colored = 1;
4315 colored_done = 1;
4316 }
4317
4318 if(!alpha_done) {
4319 unsigned matchkey = (r == stats->key_r && g == stats->key_g && b == stats->key_b);
4320 if(a != 65535 && (a != 0 || (stats->key && !matchkey))) {
4321 stats->alpha = 1;
4322 stats->key = 0;
4323 alpha_done = 1;
4324 }
4325 else if(a == 0 && !stats->alpha && !stats->key) {
4326 stats->key = 1;
4327 stats->key_r = r;
4328 stats->key_g = g;
4329 stats->key_b = b;
4330 }
4331 else if(a == 65535 && stats->key && matchkey) {
4332 /* Color key cannot be used if an opaque pixel also has that RGB color. */
4333 stats->alpha = 1;
4334 stats->key = 0;
4335 alpha_done = 1;
4336 }
4337 }
4338 if(alpha_done && numcolors_done && colored_done && bits_done) break;
4339 }
4340
4341 if(stats->key && !stats->alpha) {
4342 for(i = 0; i != numpixels; ++i) {
4343 getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
4344 if(a != 0 && r == stats->key_r && g == stats->key_g && b == stats->key_b) {
4345 /* Color key cannot be used if an opaque pixel also has that RGB color. */
4346 stats->alpha = 1;
4347 stats->key = 0;
4348 alpha_done = 1;
4349 }
4350 }
4351 }
4352 }
4353 else { /* < 16-bit */
4354 unsigned char r = 0, g = 0, b = 0, a = 0;
4355 for(i = 0; i != numpixels; ++i) {
4356 getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in);
4357
4358 if(!bits_done && stats->bits < 8) {
4359 /*only r is checked, < 8 bits is only relevant for grayscale*/
4360 unsigned bits = getValueRequiredBits(r);
4361 if(bits > stats->bits) stats->bits = bits;
4362 }
4363 bits_done = (stats->bits >= bpp);
4364
4365 if(!colored_done && (r != g || r != b)) {
4366 stats->colored = 1;
4367 colored_done = 1;
4368 if(stats->bits < 8) stats->bits = 8; /*PNG has no colored modes with less than 8-bit per channel*/
4369 }
4370
4371 if(!alpha_done) {
4372 unsigned matchkey = (r == stats->key_r && g == stats->key_g && b == stats->key_b);
4373 if(a != 255 && (a != 0 || (stats->key && !matchkey))) {
4374 stats->alpha = 1;
4375 stats->key = 0;
4376 alpha_done = 1;
4377 if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/
4378 }
4379 else if(a == 0 && !stats->alpha && !stats->key) {
4380 stats->key = 1;
4381 stats->key_r = r;
4382 stats->key_g = g;
4383 stats->key_b = b;
4384 }
4385 else if(a == 255 && stats->key && matchkey) {
4386 /* Color key cannot be used if an opaque pixel also has that RGB color. */
4387 stats->alpha = 1;
4388 stats->key = 0;
4389 alpha_done = 1;
4390 if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/
4391 }
4392 }
4393
4394 if(!numcolors_done) {
4395 if(!color_tree_has(&tree, r, g, b, a)) {
4396 error = color_tree_add(&tree, r, g, b, a, stats->numcolors);
4397 if(error) goto cleanup;
4398 if(stats->numcolors < 256) {
4399 unsigned char * p = stats->palette;
4400 unsigned n = stats->numcolors;
4401 p[n * 4 + 0] = r;
4402 p[n * 4 + 1] = g;
4403 p[n * 4 + 2] = b;
4404 p[n * 4 + 3] = a;
4405 }
4406 ++stats->numcolors;
4407 numcolors_done = stats->numcolors >= maxnumcolors;
4408 }
4409 }
4410
4411 if(alpha_done && numcolors_done && colored_done && bits_done) break;
4412 }
4413
4414 if(stats->key && !stats->alpha) {
4415 for(i = 0; i != numpixels; ++i) {
4416 getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in);
4417 if(a != 0 && r == stats->key_r && g == stats->key_g && b == stats->key_b) {
4418 /* Color key cannot be used if an opaque pixel also has that RGB color. */
4419 stats->alpha = 1;
4420 stats->key = 0;
4421 alpha_done = 1;
4422 if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/
4423 }
4424 }
4425 }
4426
4427 /*make the stats's key always 16-bit for consistency - repeat each byte twice*/
4428 stats->key_r += (stats->key_r << 8);
4429 stats->key_g += (stats->key_g << 8);
4430 stats->key_b += (stats->key_b << 8);
4431 }
4432
4433 cleanup:
4434 color_tree_cleanup(&tree);
4435 return error;
4436 }
4437
4438 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
4439 /*Adds a single color to the color stats. The stats must already have been inited. The color must be given as 16-bit
4440 (with 2 bytes repeating for 8-bit and 65535 for opaque alpha channel). This function is expensive, do not call it for
4441 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)4442 static unsigned lodepng_color_stats_add(LodePNGColorStats * stats,
4443 unsigned r, unsigned g, unsigned b, unsigned a)
4444 {
4445 unsigned error = 0;
4446 unsigned char image[8];
4447 LodePNGColorMode mode;
4448 lodepng_color_mode_init(&mode);
4449 image[0] = r >> 8;
4450 image[1] = r;
4451 image[2] = g >> 8;
4452 image[3] = g;
4453 image[4] = b >> 8;
4454 image[5] = b;
4455 image[6] = a >> 8;
4456 image[7] = a;
4457 mode.bitdepth = 16;
4458 mode.colortype = LCT_RGBA;
4459 error = lodepng_compute_color_stats(stats, image, 1, 1, &mode);
4460 lodepng_color_mode_cleanup(&mode);
4461 return error;
4462 }
4463 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
4464
4465 /*Computes a minimal PNG color model that can contain all colors as indicated by the stats.
4466 The stats should be computed with lodepng_compute_color_stats.
4467 mode_in is raw color profile of the image the stats were computed on, to copy palette order from when relevant.
4468 Minimal PNG color model means the color type and bit depth that gives smallest amount of bits in the output image,
4469 e.g. gray if only grayscale pixels, palette if less than 256 colors, color key if only single transparent color, ...
4470 This is used if auto_convert is enabled (it is by default).
4471 */
auto_choose_color(LodePNGColorMode * mode_out,const LodePNGColorMode * mode_in,const LodePNGColorStats * stats)4472 static unsigned auto_choose_color(LodePNGColorMode * mode_out,
4473 const LodePNGColorMode * mode_in,
4474 const LodePNGColorStats * stats)
4475 {
4476 unsigned error = 0;
4477 unsigned palettebits;
4478 size_t i, n;
4479 size_t numpixels = stats->numpixels;
4480 unsigned palette_ok, gray_ok;
4481
4482 unsigned alpha = stats->alpha;
4483 unsigned key = stats->key;
4484 unsigned bits = stats->bits;
4485
4486 mode_out->key_defined = 0;
4487
4488 if(key && numpixels <= 16) {
4489 alpha = 1; /*too few pixels to justify tRNS chunk overhead*/
4490 key = 0;
4491 if(bits < 8) bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/
4492 }
4493
4494 gray_ok = !stats->colored;
4495 if(!stats->allow_greyscale) gray_ok = 0;
4496 if(!gray_ok && bits < 8) bits = 8;
4497
4498 n = stats->numcolors;
4499 palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8));
4500 palette_ok = n <= 256 && bits <= 8 && n != 0; /*n==0 means likely numcolors wasn't computed*/
4501 if(numpixels < n * 2) palette_ok = 0; /*don't add palette overhead if image has only a few pixels*/
4502 if(gray_ok && !alpha && bits <= palettebits) palette_ok = 0; /*gray is less overhead*/
4503 if(!stats->allow_palette) palette_ok = 0;
4504
4505 if(palette_ok) {
4506 const unsigned char * p = stats->palette;
4507 lodepng_palette_clear(mode_out); /*remove potential earlier palette*/
4508 for(i = 0; i != stats->numcolors; ++i) {
4509 error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]);
4510 if(error) break;
4511 }
4512
4513 mode_out->colortype = LCT_PALETTE;
4514 mode_out->bitdepth = palettebits;
4515
4516 if(mode_in->colortype == LCT_PALETTE && mode_in->palettesize >= mode_out->palettesize
4517 && mode_in->bitdepth == mode_out->bitdepth) {
4518 /*If input should have same palette colors, keep original to preserve its order and prevent conversion*/
4519 lodepng_color_mode_cleanup(mode_out); /*clears palette, keeps the above set colortype and bitdepth fields as-is*/
4520 lodepng_color_mode_copy(mode_out, mode_in);
4521 }
4522 }
4523 else { /*8-bit or 16-bit per channel*/
4524 mode_out->bitdepth = bits;
4525 mode_out->colortype = alpha ? (gray_ok ? LCT_GREY_ALPHA : LCT_RGBA)
4526 : (gray_ok ? LCT_GREY : LCT_RGB);
4527 if(key) {
4528 unsigned mask = (1u << mode_out->bitdepth) - 1u; /*stats always uses 16-bit, mask converts it*/
4529 mode_out->key_r = stats->key_r & mask;
4530 mode_out->key_g = stats->key_g & mask;
4531 mode_out->key_b = stats->key_b & mask;
4532 mode_out->key_defined = 1;
4533 }
4534 }
4535
4536 return error;
4537 }
4538
4539 #endif /* #ifdef LODEPNG_COMPILE_ENCODER */
4540
4541 /*Paeth predictor, used by PNG filter type 4*/
paethPredictor(unsigned char a,unsigned char b,unsigned char c)4542 static unsigned char paethPredictor(unsigned char a, unsigned char b, unsigned char c)
4543 {
4544 /* the subtractions of unsigned char cast it to a signed type.
4545 With gcc, short is faster than int, with clang int is as fast (as of april 2023)*/
4546 short pa = (b - c) < 0 ? -(b - c) : (b - c);
4547 short pb = (a - c) < 0 ? -(a - c) : (a - c);
4548 /* writing it out like this compiles to something faster than introducing a temp variable*/
4549 short pc = (a + b - c - c) < 0 ? -(a + b - c - c) : (a + b - c - c);
4550 /* return input value associated with smallest of pa, pb, pc (with certain priority if equal) */
4551 if(pb < pa) {
4552 a = b;
4553 pa = pb;
4554 }
4555 return (pc < pa) ? c : a;
4556 }
4557
4558 /*shared values used by multiple Adam7 related functions*/
4559
4560 static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/
4561 static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/
4562 static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/
4563 static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/
4564
4565 /*
4566 Outputs various dimensions and positions in the image related to the Adam7 reduced images.
4567 passw: output containing the width of the 7 passes
4568 passh: output containing the height of the 7 passes
4569 filter_passstart: output containing the index of the start and end of each
4570 reduced image with filter bytes
4571 padded_passstart output containing the index of the start and end of each
4572 reduced image when without filter bytes but with padded scanlines
4573 passstart: output containing the index of the start and end of each reduced
4574 image without padding between scanlines, but still padding between the images
4575 w, h: width and height of non-interlaced image
4576 bpp: bits per pixel
4577 "padded" is only relevant if bpp is less than 8 and a scanline or image does not
4578 end at a full byte
4579 */
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)4580 static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8],
4581 size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp)
4582 {
4583 /*the passstart values have 8 values: the 8th one indicates the byte after the end of the 7th (= last) pass*/
4584 unsigned i;
4585
4586 /*calculate width and height in pixels of each pass*/
4587 for(i = 0; i != 7; ++i) {
4588 passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i];
4589 passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i];
4590 if(passw[i] == 0) passh[i] = 0;
4591 if(passh[i] == 0) passw[i] = 0;
4592 }
4593
4594 filter_passstart[0] = padded_passstart[0] = passstart[0] = 0;
4595 for(i = 0; i != 7; ++i) {
4596 /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/
4597 filter_passstart[i + 1] = filter_passstart[i]
4598 + ((passw[i] && passh[i]) ? passh[i] * (1u + (passw[i] * bpp + 7u) / 8u) : 0);
4599 /*bits padded if needed to fill full byte at end of each scanline*/
4600 padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7u) / 8u);
4601 /*only padded at end of reduced image*/
4602 passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7u) / 8u;
4603 }
4604 }
4605
4606 #ifdef LODEPNG_COMPILE_DECODER
4607
4608 /* ////////////////////////////////////////////////////////////////////////// */
4609 /* / PNG Decoder / */
4610 /* ////////////////////////////////////////////////////////////////////////// */
4611
4612 /*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)4613 unsigned lodepng_inspect(unsigned * w, unsigned * h, LodePNGState * state,
4614 const unsigned char * in, size_t insize)
4615 {
4616 unsigned width, height;
4617 LodePNGInfo * info = &state->info_png;
4618 if(insize == 0 || in == 0) {
4619 CERROR_RETURN_ERROR(state->error, 48); /*error: the given data is empty*/
4620 }
4621 if(insize < 33) {
4622 CERROR_RETURN_ERROR(state->error, 27); /*error: the data length is smaller than the length of a PNG header*/
4623 }
4624
4625 /*when decoding a new PNG image, make sure all parameters created after previous decoding are reset*/
4626 /* TODO: remove this. One should use a new LodePNGState for new sessions */
4627 lodepng_info_cleanup(info);
4628 lodepng_info_init(info);
4629
4630 if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71
4631 || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) {
4632 CERROR_RETURN_ERROR(state->error, 28); /*error: the first 8 bytes are not the correct PNG signature*/
4633 }
4634 if(lodepng_chunk_length(in + 8) != 13) {
4635 CERROR_RETURN_ERROR(state->error, 94); /*error: header size must be 13 bytes*/
4636 }
4637 if(!lodepng_chunk_type_equals(in + 8, "IHDR")) {
4638 CERROR_RETURN_ERROR(state->error, 29); /*error: it doesn't start with a IHDR chunk!*/
4639 }
4640
4641 /*read the values given in the header*/
4642 width = lodepng_read32bitInt(&in[16]);
4643 height = lodepng_read32bitInt(&in[20]);
4644 /*TODO: remove the undocumented feature that allows to give null pointers to width or height*/
4645 if(w) *w = width;
4646 if(h) *h = height;
4647 info->color.bitdepth = in[24];
4648 info->color.colortype = (LodePNGColorType)in[25];
4649 info->compression_method = in[26];
4650 info->filter_method = in[27];
4651 info->interlace_method = in[28];
4652
4653 /*errors returned only after the parsing so other values are still output*/
4654
4655 /*error: invalid image size*/
4656 if(width == 0 || height == 0) CERROR_RETURN_ERROR(state->error, 93);
4657 /*error: invalid colortype or bitdepth combination*/
4658 state->error = checkColorValidity(info->color.colortype, info->color.bitdepth);
4659 if(state->error) return state->error;
4660 /*error: only compression method 0 is allowed in the specification*/
4661 if(info->compression_method != 0) CERROR_RETURN_ERROR(state->error, 32);
4662 /*error: only filter method 0 is allowed in the specification*/
4663 if(info->filter_method != 0) CERROR_RETURN_ERROR(state->error, 33);
4664 /*error: only interlace methods 0 and 1 exist in the specification*/
4665 if(info->interlace_method > 1) CERROR_RETURN_ERROR(state->error, 34);
4666
4667 if(!state->decoder.ignore_crc) {
4668 unsigned CRC = lodepng_read32bitInt(&in[29]);
4669 unsigned checksum = lodepng_crc32(&in[12], 17);
4670 if(CRC != checksum) {
4671 CERROR_RETURN_ERROR(state->error, 57); /*invalid CRC*/
4672 }
4673 }
4674
4675 return state->error;
4676 }
4677
unfilterScanline(unsigned char * recon,const unsigned char * scanline,const unsigned char * precon,size_t bytewidth,unsigned char filterType,size_t length)4678 static unsigned unfilterScanline(unsigned char * recon, const unsigned char * scanline, const unsigned char * precon,
4679 size_t bytewidth, unsigned char filterType, size_t length)
4680 {
4681 /*
4682 For PNG filter method 0
4683 unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte,
4684 the filter works byte per byte (bytewidth = 1)
4685 precon is the previous unfiltered scanline, recon the result, scanline the current one
4686 the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead
4687 recon and scanline MAY be the same memory address! precon must be disjoint.
4688 */
4689
4690 size_t i;
4691 switch(filterType) {
4692 case 0:
4693 for(i = 0; i != length; ++i) recon[i] = scanline[i];
4694 break;
4695 case 1: {
4696 size_t j = 0;
4697 for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
4698 for(i = bytewidth; i != length; ++i, ++j) recon[i] = scanline[i] + recon[j];
4699 break;
4700 }
4701 case 2:
4702 if(precon) {
4703 for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i];
4704 }
4705 else {
4706 for(i = 0; i != length; ++i) recon[i] = scanline[i];
4707 }
4708 break;
4709 case 3:
4710 if(precon) {
4711 size_t j = 0;
4712 for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1u);
4713 /* Unroll independent paths of this predictor. A 6x and 8x version is also possible but that adds
4714 too much code. Whether this speeds up anything depends on compiler and settings. */
4715 if(bytewidth >= 4) {
4716 for(; i + 3 < length; i += 4, j += 4) {
4717 unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2], s3 = scanline[i + 3];
4718 unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2], r3 = recon[j + 3];
4719 unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2], p3 = precon[i + 3];
4720 recon[i + 0] = s0 + ((r0 + p0) >> 1u);
4721 recon[i + 1] = s1 + ((r1 + p1) >> 1u);
4722 recon[i + 2] = s2 + ((r2 + p2) >> 1u);
4723 recon[i + 3] = s3 + ((r3 + p3) >> 1u);
4724 }
4725 }
4726 else if(bytewidth >= 3) {
4727 for(; i + 2 < length; i += 3, j += 3) {
4728 unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2];
4729 unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2];
4730 unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2];
4731 recon[i + 0] = s0 + ((r0 + p0) >> 1u);
4732 recon[i + 1] = s1 + ((r1 + p1) >> 1u);
4733 recon[i + 2] = s2 + ((r2 + p2) >> 1u);
4734 }
4735 }
4736 else if(bytewidth >= 2) {
4737 for(; i + 1 < length; i += 2, j += 2) {
4738 unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1];
4739 unsigned char r0 = recon[j + 0], r1 = recon[j + 1];
4740 unsigned char p0 = precon[i + 0], p1 = precon[i + 1];
4741 recon[i + 0] = s0 + ((r0 + p0) >> 1u);
4742 recon[i + 1] = s1 + ((r1 + p1) >> 1u);
4743 }
4744 }
4745 for(; i != length; ++i, ++j) recon[i] = scanline[i] + ((recon[j] + precon[i]) >> 1u);
4746 }
4747 else {
4748 size_t j = 0;
4749 for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
4750 for(i = bytewidth; i != length; ++i, ++j) recon[i] = scanline[i] + (recon[j] >> 1u);
4751 }
4752 break;
4753 case 4:
4754 if(precon) {
4755 /* Unroll independent paths of this predictor. Whether this speeds up
4756 anything depends on compiler and settings. */
4757 if(bytewidth == 8) {
4758 unsigned char a0, b0 = 0, c0, d0 = 0, a1, b1 = 0, c1, d1 = 0;
4759 unsigned char a2, b2 = 0, c2, d2 = 0, a3, b3 = 0, c3, d3 = 0;
4760 unsigned char a4, b4 = 0, c4, d4 = 0, a5, b5 = 0, c5, d5 = 0;
4761 unsigned char a6, b6 = 0, c6, d6 = 0, a7, b7 = 0, c7, d7 = 0;
4762 for(i = 0; i + 7 < length; i += 8) {
4763 c0 = b0;
4764 c1 = b1;
4765 c2 = b2;
4766 c3 = b3;
4767 c4 = b4;
4768 c5 = b5;
4769 c6 = b6;
4770 c7 = b7;
4771 b0 = precon[i + 0];
4772 b1 = precon[i + 1];
4773 b2 = precon[i + 2];
4774 b3 = precon[i + 3];
4775 b4 = precon[i + 4];
4776 b5 = precon[i + 5];
4777 b6 = precon[i + 6];
4778 b7 = precon[i + 7];
4779 a0 = d0;
4780 a1 = d1;
4781 a2 = d2;
4782 a3 = d3;
4783 a4 = d4;
4784 a5 = d5;
4785 a6 = d6;
4786 a7 = d7;
4787 d0 = scanline[i + 0] + paethPredictor(a0, b0, c0);
4788 d1 = scanline[i + 1] + paethPredictor(a1, b1, c1);
4789 d2 = scanline[i + 2] + paethPredictor(a2, b2, c2);
4790 d3 = scanline[i + 3] + paethPredictor(a3, b3, c3);
4791 d4 = scanline[i + 4] + paethPredictor(a4, b4, c4);
4792 d5 = scanline[i + 5] + paethPredictor(a5, b5, c5);
4793 d6 = scanline[i + 6] + paethPredictor(a6, b6, c6);
4794 d7 = scanline[i + 7] + paethPredictor(a7, b7, c7);
4795 recon[i + 0] = d0;
4796 recon[i + 1] = d1;
4797 recon[i + 2] = d2;
4798 recon[i + 3] = d3;
4799 recon[i + 4] = d4;
4800 recon[i + 5] = d5;
4801 recon[i + 6] = d6;
4802 recon[i + 7] = d7;
4803 }
4804 }
4805 else if(bytewidth == 6) {
4806 unsigned char a0, b0 = 0, c0, d0 = 0, a1, b1 = 0, c1, d1 = 0;
4807 unsigned char a2, b2 = 0, c2, d2 = 0, a3, b3 = 0, c3, d3 = 0;
4808 unsigned char a4, b4 = 0, c4, d4 = 0, a5, b5 = 0, c5, d5 = 0;
4809 for(i = 0; i + 5 < length; i += 6) {
4810 c0 = b0;
4811 c1 = b1;
4812 c2 = b2;
4813 c3 = b3;
4814 c4 = b4;
4815 c5 = b5;
4816 b0 = precon[i + 0];
4817 b1 = precon[i + 1];
4818 b2 = precon[i + 2];
4819 b3 = precon[i + 3];
4820 b4 = precon[i + 4];
4821 b5 = precon[i + 5];
4822 a0 = d0;
4823 a1 = d1;
4824 a2 = d2;
4825 a3 = d3;
4826 a4 = d4;
4827 a5 = d5;
4828 d0 = scanline[i + 0] + paethPredictor(a0, b0, c0);
4829 d1 = scanline[i + 1] + paethPredictor(a1, b1, c1);
4830 d2 = scanline[i + 2] + paethPredictor(a2, b2, c2);
4831 d3 = scanline[i + 3] + paethPredictor(a3, b3, c3);
4832 d4 = scanline[i + 4] + paethPredictor(a4, b4, c4);
4833 d5 = scanline[i + 5] + paethPredictor(a5, b5, c5);
4834 recon[i + 0] = d0;
4835 recon[i + 1] = d1;
4836 recon[i + 2] = d2;
4837 recon[i + 3] = d3;
4838 recon[i + 4] = d4;
4839 recon[i + 5] = d5;
4840 }
4841 }
4842 else if(bytewidth == 4) {
4843 unsigned char a0, b0 = 0, c0, d0 = 0, a1, b1 = 0, c1, d1 = 0;
4844 unsigned char a2, b2 = 0, c2, d2 = 0, a3, b3 = 0, c3, d3 = 0;
4845 for(i = 0; i + 3 < length; i += 4) {
4846 c0 = b0;
4847 c1 = b1;
4848 c2 = b2;
4849 c3 = b3;
4850 b0 = precon[i + 0];
4851 b1 = precon[i + 1];
4852 b2 = precon[i + 2];
4853 b3 = precon[i + 3];
4854 a0 = d0;
4855 a1 = d1;
4856 a2 = d2;
4857 a3 = d3;
4858 d0 = scanline[i + 0] + paethPredictor(a0, b0, c0);
4859 d1 = scanline[i + 1] + paethPredictor(a1, b1, c1);
4860 d2 = scanline[i + 2] + paethPredictor(a2, b2, c2);
4861 d3 = scanline[i + 3] + paethPredictor(a3, b3, c3);
4862 recon[i + 0] = d0;
4863 recon[i + 1] = d1;
4864 recon[i + 2] = d2;
4865 recon[i + 3] = d3;
4866 }
4867 }
4868 else if(bytewidth == 3) {
4869 unsigned char a0, b0 = 0, c0, d0 = 0;
4870 unsigned char a1, b1 = 0, c1, d1 = 0;
4871 unsigned char a2, b2 = 0, c2, d2 = 0;
4872 for(i = 0; i + 2 < length; i += 3) {
4873 c0 = b0;
4874 c1 = b1;
4875 c2 = b2;
4876 b0 = precon[i + 0];
4877 b1 = precon[i + 1];
4878 b2 = precon[i + 2];
4879 a0 = d0;
4880 a1 = d1;
4881 a2 = d2;
4882 d0 = scanline[i + 0] + paethPredictor(a0, b0, c0);
4883 d1 = scanline[i + 1] + paethPredictor(a1, b1, c1);
4884 d2 = scanline[i + 2] + paethPredictor(a2, b2, c2);
4885 recon[i + 0] = d0;
4886 recon[i + 1] = d1;
4887 recon[i + 2] = d2;
4888 }
4889 }
4890 else if(bytewidth == 2) {
4891 unsigned char a0, b0 = 0, c0, d0 = 0;
4892 unsigned char a1, b1 = 0, c1, d1 = 0;
4893 for(i = 0; i + 1 < length; i += 2) {
4894 c0 = b0;
4895 c1 = b1;
4896 b0 = precon[i + 0];
4897 b1 = precon[i + 1];
4898 a0 = d0;
4899 a1 = d1;
4900 d0 = scanline[i + 0] + paethPredictor(a0, b0, c0);
4901 d1 = scanline[i + 1] + paethPredictor(a1, b1, c1);
4902 recon[i + 0] = d0;
4903 recon[i + 1] = d1;
4904 }
4905 }
4906 else if(bytewidth == 1) {
4907 unsigned char a, b = 0, c, d = 0;
4908 for(i = 0; i != length; ++i) {
4909 c = b;
4910 b = precon[i];
4911 a = d;
4912 d = scanline[i] + paethPredictor(a, b, c);
4913 recon[i] = d;
4914 }
4915 }
4916 else {
4917 /* Normally not a possible case, but this would handle it correctly */
4918 for(i = 0; i != bytewidth; ++i) {
4919 recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/
4920 }
4921 }
4922 /* finish any remaining bytes */
4923 for(; i != length; ++i) {
4924 recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
4925 }
4926 }
4927 else {
4928 size_t j = 0;
4929 for(i = 0; i != bytewidth; ++i) {
4930 recon[i] = scanline[i];
4931 }
4932 for(i = bytewidth; i != length; ++i, ++j) {
4933 /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/
4934 recon[i] = (scanline[i] + recon[j]);
4935 }
4936 }
4937 break;
4938 default:
4939 return 36; /*error: invalid filter type given*/
4940 }
4941 return 0;
4942 }
4943
unfilter(unsigned char * out,const unsigned char * in,unsigned w,unsigned h,unsigned bpp)4944 static unsigned unfilter(unsigned char * out, const unsigned char * in, unsigned w, unsigned h, unsigned bpp)
4945 {
4946 /*
4947 For PNG filter method 0
4948 this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 seven times)
4949 out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline
4950 w and h are image dimensions or dimensions of reduced image, bpp is bits per pixel
4951 in and out are allowed to be the same memory address (but aren't the same size since in has the extra filter bytes)
4952 */
4953
4954 unsigned y;
4955 unsigned char * prevline = 0;
4956
4957 /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/
4958 size_t bytewidth = (bpp + 7u) / 8u;
4959 /*the width of a scanline in bytes, not including the filter type*/
4960 size_t linebytes = lodepng_get_raw_size_idat(w, 1, bpp) - 1u;
4961
4962 for(y = 0; y < h; ++y) {
4963 size_t outindex = linebytes * y;
4964 size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
4965 unsigned char filterType = in[inindex];
4966
4967 CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes));
4968
4969 prevline = &out[outindex];
4970 }
4971
4972 return 0;
4973 }
4974
4975 /*
4976 in: Adam7 interlaced image, with no padding bits between scanlines, but between
4977 reduced images so that each reduced image starts at a byte.
4978 out: the same pixels, but re-ordered so that they're now a non-interlaced image with size w*h
4979 bpp: bits per pixel
4980 out has the following size in bits: w * h * bpp.
4981 in is possibly bigger due to padding bits between reduced images.
4982 out must be big enough AND must be 0 everywhere if bpp < 8 in the current implementation
4983 (because that's likely a little bit faster)
4984 NOTE: comments about padding bits are only relevant if bpp < 8
4985 */
Adam7_deinterlace(unsigned char * out,const unsigned char * in,unsigned w,unsigned h,unsigned bpp)4986 static void Adam7_deinterlace(unsigned char * out, const unsigned char * in, unsigned w, unsigned h, unsigned bpp)
4987 {
4988 unsigned passw[7], passh[7];
4989 size_t filter_passstart[8], padded_passstart[8], passstart[8];
4990 unsigned i;
4991
4992 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
4993
4994 if(bpp >= 8) {
4995 for(i = 0; i != 7; ++i) {
4996 unsigned x, y, b;
4997 size_t bytewidth = bpp / 8u;
4998 for(y = 0; y < passh[i]; ++y)
4999 for(x = 0; x < passw[i]; ++x) {
5000 size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth;
5001 size_t pixeloutstart = ((ADAM7_IY[i] + (size_t)y * ADAM7_DY[i]) * (size_t)w
5002 + ADAM7_IX[i] + (size_t)x * ADAM7_DX[i]) * bytewidth;
5003 for(b = 0; b < bytewidth; ++b) {
5004 out[pixeloutstart + b] = in[pixelinstart + b];
5005 }
5006 }
5007 }
5008 }
5009 else { /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/
5010 for(i = 0; i != 7; ++i) {
5011 unsigned x, y, b;
5012 unsigned ilinebits = bpp * passw[i];
5013 unsigned olinebits = bpp * w;
5014 size_t obp, ibp; /*bit pointers (for out and in buffer)*/
5015 for(y = 0; y < passh[i]; ++y)
5016 for(x = 0; x < passw[i]; ++x) {
5017 ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp);
5018 obp = (ADAM7_IY[i] + (size_t)y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + (size_t)x * ADAM7_DX[i]) * bpp;
5019 for(b = 0; b < bpp; ++b) {
5020 unsigned char bit = readBitFromReversedStream(&ibp, in);
5021 setBitOfReversedStream(&obp, out, bit);
5022 }
5023 }
5024 }
5025 }
5026 }
5027
removePaddingBits(unsigned char * out,const unsigned char * in,size_t olinebits,size_t ilinebits,unsigned h)5028 static void removePaddingBits(unsigned char * out, const unsigned char * in,
5029 size_t olinebits, size_t ilinebits, unsigned h)
5030 {
5031 /*
5032 After filtering there are still padding bits if scanlines have non multiple of 8 bit amounts. They need
5033 to be removed (except at last scanline of (Adam7-reduced) image) before working with pure image buffers
5034 for the Adam7 code, the color convert code and the output to the user.
5035 in and out are allowed to be the same buffer, in may also be higher but still overlapping; in must
5036 have >= ilinebits*h bits, out must have >= olinebits*h bits, olinebits must be <= ilinebits
5037 also used to move bits after earlier such operations happened, e.g. in a sequence of reduced images from Adam7
5038 only useful if (ilinebits - olinebits) is a value in the range 1..7
5039 */
5040 unsigned y;
5041 size_t diff = ilinebits - olinebits;
5042 size_t ibp = 0, obp = 0; /*input and output bit pointers*/
5043 for(y = 0; y < h; ++y) {
5044 size_t x;
5045 for(x = 0; x < olinebits; ++x) {
5046 unsigned char bit = readBitFromReversedStream(&ibp, in);
5047 setBitOfReversedStream(&obp, out, bit);
5048 }
5049 ibp += diff;
5050 }
5051 }
5052
5053 /*out must be buffer big enough to contain full image, and in must contain the full decompressed data from
5054 the IDAT chunks (with filter index bytes and possible padding bits)
5055 return value is error*/
postProcessScanlines(unsigned char * out,unsigned char * in,unsigned w,unsigned h,const LodePNGInfo * info_png)5056 static unsigned postProcessScanlines(unsigned char * out, unsigned char * in,
5057 unsigned w, unsigned h, const LodePNGInfo * info_png)
5058 {
5059 /*
5060 This function converts the filtered-padded-interlaced data into pure 2D image buffer with the PNG's colortype.
5061 Steps:
5062 *) if no Adam7: 1) unfilter 2) remove padding bits (= possible extra bits per scanline if bpp < 8)
5063 *) if adam7: 1) 7x unfilter 2) 7x remove padding bits 3) Adam7_deinterlace
5064 NOTE: the in buffer will be overwritten with intermediate data!
5065 */
5066 unsigned bpp = lodepng_get_bpp(&info_png->color);
5067 if(bpp == 0) return 31; /*error: invalid colortype*/
5068
5069 if(info_png->interlace_method == 0) {
5070 if(bpp < 8 && w * bpp != ((w * bpp + 7u) / 8u) * 8u) {
5071 CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp));
5072 removePaddingBits(out, in, w * bpp, ((w * bpp + 7u) / 8u) * 8u, h);
5073 }
5074 /*we can immediately filter into the out buffer, no other steps needed*/
5075 else CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp));
5076 }
5077 else { /*interlace_method is 1 (Adam7)*/
5078 unsigned passw[7], passh[7];
5079 size_t filter_passstart[8], padded_passstart[8], passstart[8];
5080 unsigned i;
5081
5082 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
5083
5084 for(i = 0; i != 7; ++i) {
5085 CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp));
5086 /*TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline,
5087 move bytes instead of bits or move not at all*/
5088 if(bpp < 8) {
5089 /*remove padding bits in scanlines; after this there still may be padding
5090 bits between the different reduced images: each reduced image still starts nicely at a byte*/
5091 removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp,
5092 ((passw[i] * bpp + 7u) / 8u) * 8u, passh[i]);
5093 }
5094 }
5095
5096 Adam7_deinterlace(out, in, w, h, bpp);
5097 }
5098
5099 return 0;
5100 }
5101
readChunk_PLTE(LodePNGColorMode * color,const unsigned char * data,size_t chunkLength)5102 static unsigned readChunk_PLTE(LodePNGColorMode * color, const unsigned char * data, size_t chunkLength)
5103 {
5104 unsigned pos = 0, i;
5105 color->palettesize = chunkLength / 3u;
5106 if(color->palettesize == 0 || color->palettesize > 256) return 38; /*error: palette too small or big*/
5107 lodepng_color_mode_alloc_palette(color);
5108 if(!color->palette && color->palettesize) {
5109 color->palettesize = 0;
5110 return 83; /*alloc fail*/
5111 }
5112
5113 for(i = 0; i != color->palettesize; ++i) {
5114 color->palette[4 * i + 0] = data[pos++]; /*R*/
5115 color->palette[4 * i + 1] = data[pos++]; /*G*/
5116 color->palette[4 * i + 2] = data[pos++]; /*B*/
5117 color->palette[4 * i + 3] = 255; /*alpha*/
5118 }
5119
5120 return 0; /* OK */
5121 }
5122
readChunk_tRNS(LodePNGColorMode * color,const unsigned char * data,size_t chunkLength)5123 static unsigned readChunk_tRNS(LodePNGColorMode * color, const unsigned char * data, size_t chunkLength)
5124 {
5125 unsigned i;
5126 if(color->colortype == LCT_PALETTE) {
5127 /*error: more alpha values given than there are palette entries*/
5128 if(chunkLength > color->palettesize) return 39;
5129
5130 for(i = 0; i != chunkLength; ++i) color->palette[4 * i + 3] = data[i];
5131 }
5132 else if(color->colortype == LCT_GREY) {
5133 /*error: this chunk must be 2 bytes for grayscale image*/
5134 if(chunkLength != 2) return 30;
5135
5136 color->key_defined = 1;
5137 color->key_r = color->key_g = color->key_b = 256u * data[0] + data[1];
5138 }
5139 else if(color->colortype == LCT_RGB) {
5140 /*error: this chunk must be 6 bytes for RGB image*/
5141 if(chunkLength != 6) return 41;
5142
5143 color->key_defined = 1;
5144 color->key_r = 256u * data[0] + data[1];
5145 color->key_g = 256u * data[2] + data[3];
5146 color->key_b = 256u * data[4] + data[5];
5147 }
5148 else return 42; /*error: tRNS chunk not allowed for other color models*/
5149
5150 return 0; /* OK */
5151 }
5152
5153
5154 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5155 /*background color chunk (bKGD)*/
readChunk_bKGD(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)5156 static unsigned readChunk_bKGD(LodePNGInfo * info, const unsigned char * data, size_t chunkLength)
5157 {
5158 if(info->color.colortype == LCT_PALETTE) {
5159 /*error: this chunk must be 1 byte for indexed color image*/
5160 if(chunkLength != 1) return 43;
5161
5162 /*error: invalid palette index, or maybe this chunk appeared before PLTE*/
5163 if(data[0] >= info->color.palettesize) return 103;
5164
5165 info->background_defined = 1;
5166 info->background_r = info->background_g = info->background_b = data[0];
5167 }
5168 else if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) {
5169 /*error: this chunk must be 2 bytes for grayscale image*/
5170 if(chunkLength != 2) return 44;
5171
5172 /*the values are truncated to bitdepth in the PNG file*/
5173 info->background_defined = 1;
5174 info->background_r = info->background_g = info->background_b = 256u * data[0] + data[1];
5175 }
5176 else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) {
5177 /*error: this chunk must be 6 bytes for grayscale image*/
5178 if(chunkLength != 6) return 45;
5179
5180 /*the values are truncated to bitdepth in the PNG file*/
5181 info->background_defined = 1;
5182 info->background_r = 256u * data[0] + data[1];
5183 info->background_g = 256u * data[2] + data[3];
5184 info->background_b = 256u * data[4] + data[5];
5185 }
5186
5187 return 0; /* OK */
5188 }
5189
5190 /*text chunk (tEXt)*/
readChunk_tEXt(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)5191 static unsigned readChunk_tEXt(LodePNGInfo * info, const unsigned char * data, size_t chunkLength)
5192 {
5193 unsigned error = 0;
5194 char * key = 0, * str = 0;
5195
5196 while(!error) { /*not really a while loop, only used to break on error*/
5197 unsigned length, string2_begin;
5198
5199 length = 0;
5200 while(length < chunkLength && data[length] != 0) ++length;
5201 /*even though it's not allowed by the standard, no error is thrown if
5202 there's no null termination char, if the text is empty*/
5203 if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/
5204
5205 key = (char *)lodepng_malloc(length + 1);
5206 if(!key) CERROR_BREAK(error, 83); /*alloc fail*/
5207
5208 lodepng_memcpy(key, data, length);
5209 key[length] = 0;
5210
5211 string2_begin = length + 1; /*skip keyword null terminator*/
5212
5213 length = (unsigned)(chunkLength < string2_begin ? 0 : chunkLength - string2_begin);
5214 str = (char *)lodepng_malloc(length + 1);
5215 if(!str) CERROR_BREAK(error, 83); /*alloc fail*/
5216
5217 lodepng_memcpy(str, data + string2_begin, length);
5218 str[length] = 0;
5219
5220 error = lodepng_add_text(info, key, str);
5221
5222 break;
5223 }
5224
5225 lodepng_free(key);
5226 lodepng_free(str);
5227
5228 return error;
5229 }
5230
5231 /*compressed text chunk (zTXt)*/
readChunk_zTXt(LodePNGInfo * info,const LodePNGDecoderSettings * decoder,const unsigned char * data,size_t chunkLength)5232 static unsigned readChunk_zTXt(LodePNGInfo * info, const LodePNGDecoderSettings * decoder,
5233 const unsigned char * data, size_t chunkLength)
5234 {
5235 unsigned error = 0;
5236
5237 /*copy the object to change parameters in it*/
5238 LodePNGDecompressSettings zlibsettings = decoder->zlibsettings;
5239
5240 unsigned length, string2_begin;
5241 char * key = 0;
5242 unsigned char * str = 0;
5243 size_t size = 0;
5244
5245 while(!error) { /*not really a while loop, only used to break on error*/
5246 for(length = 0; length < chunkLength && data[length] != 0; ++length) ;
5247 if(length + 2 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/
5248 if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/
5249
5250 key = (char *)lodepng_malloc(length + 1);
5251 if(!key) CERROR_BREAK(error, 83); /*alloc fail*/
5252
5253 lodepng_memcpy(key, data, length);
5254 key[length] = 0;
5255
5256 if(data[length + 1] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/
5257
5258 string2_begin = length + 2;
5259 if(string2_begin > chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/
5260
5261 length = (unsigned)chunkLength - string2_begin;
5262 zlibsettings.max_output_size = decoder->max_text_size;
5263 /*will fail if zlib error, e.g. if length is too small*/
5264 error = zlib_decompress(&str, &size, 0, &data[string2_begin],
5265 length, &zlibsettings);
5266 /*error: compressed text larger than decoder->max_text_size*/
5267 if(error && size > zlibsettings.max_output_size) error = 112;
5268 if(error) break;
5269 error = lodepng_add_text_sized(info, key, (char *)str, size);
5270 break;
5271 }
5272
5273 lodepng_free(key);
5274 lodepng_free(str);
5275
5276 return error;
5277 }
5278
5279 /*international text chunk (iTXt)*/
readChunk_iTXt(LodePNGInfo * info,const LodePNGDecoderSettings * decoder,const unsigned char * data,size_t chunkLength)5280 static unsigned readChunk_iTXt(LodePNGInfo * info, const LodePNGDecoderSettings * decoder,
5281 const unsigned char * data, size_t chunkLength)
5282 {
5283 unsigned error = 0;
5284 unsigned i;
5285
5286 /*copy the object to change parameters in it*/
5287 LodePNGDecompressSettings zlibsettings = decoder->zlibsettings;
5288
5289 unsigned length, begin, compressed;
5290 char * key = 0, * langtag = 0, * transkey = 0;
5291
5292 while(!error) { /*not really a while loop, only used to break on error*/
5293 /*Quick check if the chunk length isn't too small. Even without check
5294 it'd still fail with other error checks below if it's too short. This just gives a different error code.*/
5295 if(chunkLength < 5) CERROR_BREAK(error, 30); /*iTXt chunk too short*/
5296
5297 /*read the key*/
5298 for(length = 0; length < chunkLength && data[length] != 0; ++length) ;
5299 if(length + 3 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination char, corrupt?*/
5300 if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/
5301
5302 key = (char *)lodepng_malloc(length + 1);
5303 if(!key) CERROR_BREAK(error, 83); /*alloc fail*/
5304
5305 lodepng_memcpy(key, data, length);
5306 key[length] = 0;
5307
5308 /*read the compression method*/
5309 compressed = data[length + 1];
5310 if(data[length + 2] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/
5311
5312 /*even though it's not allowed by the standard, no error is thrown if
5313 there's no null termination char, if the text is empty for the next 3 texts*/
5314
5315 /*read the langtag*/
5316 begin = length + 3;
5317 length = 0;
5318 for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length;
5319
5320 langtag = (char *)lodepng_malloc(length + 1);
5321 if(!langtag) CERROR_BREAK(error, 83); /*alloc fail*/
5322
5323 lodepng_memcpy(langtag, data + begin, length);
5324 langtag[length] = 0;
5325
5326 /*read the transkey*/
5327 begin += length + 1;
5328 length = 0;
5329 for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length;
5330
5331 transkey = (char *)lodepng_malloc(length + 1);
5332 if(!transkey) CERROR_BREAK(error, 83); /*alloc fail*/
5333
5334 lodepng_memcpy(transkey, data + begin, length);
5335 transkey[length] = 0;
5336
5337 /*read the actual text*/
5338 begin += length + 1;
5339
5340 length = (unsigned)chunkLength < begin ? 0 : (unsigned)chunkLength - begin;
5341
5342 if(compressed) {
5343 unsigned char * str = 0;
5344 size_t size = 0;
5345 zlibsettings.max_output_size = decoder->max_text_size;
5346 /*will fail if zlib error, e.g. if length is too small*/
5347 error = zlib_decompress(&str, &size, 0, &data[begin],
5348 length, &zlibsettings);
5349 /*error: compressed text larger than decoder->max_text_size*/
5350 if(error && size > zlibsettings.max_output_size) error = 112;
5351 if(!error) error = lodepng_add_itext_sized(info, key, langtag, transkey, (char *)str, size);
5352 lodepng_free(str);
5353 }
5354 else {
5355 error = lodepng_add_itext_sized(info, key, langtag, transkey, (char *)(data + begin), length);
5356 }
5357
5358 break;
5359 }
5360
5361 lodepng_free(key);
5362 lodepng_free(langtag);
5363 lodepng_free(transkey);
5364
5365 return error;
5366 }
5367
readChunk_tIME(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)5368 static unsigned readChunk_tIME(LodePNGInfo * info, const unsigned char * data, size_t chunkLength)
5369 {
5370 if(chunkLength != 7) return 73; /*invalid tIME chunk size*/
5371
5372 info->time_defined = 1;
5373 info->time.year = 256u * data[0] + data[1];
5374 info->time.month = data[2];
5375 info->time.day = data[3];
5376 info->time.hour = data[4];
5377 info->time.minute = data[5];
5378 info->time.second = data[6];
5379
5380 return 0; /* OK */
5381 }
5382
readChunk_pHYs(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)5383 static unsigned readChunk_pHYs(LodePNGInfo * info, const unsigned char * data, size_t chunkLength)
5384 {
5385 if(chunkLength != 9) return 74; /*invalid pHYs chunk size*/
5386
5387 info->phys_defined = 1;
5388 info->phys_x = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3];
5389 info->phys_y = 16777216u * data[4] + 65536u * data[5] + 256u * data[6] + data[7];
5390 info->phys_unit = data[8];
5391
5392 return 0; /* OK */
5393 }
5394
readChunk_gAMA(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)5395 static unsigned readChunk_gAMA(LodePNGInfo * info, const unsigned char * data, size_t chunkLength)
5396 {
5397 if(chunkLength != 4) return 96; /*invalid gAMA chunk size*/
5398
5399 info->gama_defined = 1;
5400 info->gama_gamma = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3];
5401
5402 return 0; /* OK */
5403 }
5404
readChunk_cHRM(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)5405 static unsigned readChunk_cHRM(LodePNGInfo * info, const unsigned char * data, size_t chunkLength)
5406 {
5407 if(chunkLength != 32) return 97; /*invalid cHRM chunk size*/
5408
5409 info->chrm_defined = 1;
5410 info->chrm_white_x = 16777216u * data[ 0] + 65536u * data[ 1] + 256u * data[ 2] + data[ 3];
5411 info->chrm_white_y = 16777216u * data[ 4] + 65536u * data[ 5] + 256u * data[ 6] + data[ 7];
5412 info->chrm_red_x = 16777216u * data[ 8] + 65536u * data[ 9] + 256u * data[10] + data[11];
5413 info->chrm_red_y = 16777216u * data[12] + 65536u * data[13] + 256u * data[14] + data[15];
5414 info->chrm_green_x = 16777216u * data[16] + 65536u * data[17] + 256u * data[18] + data[19];
5415 info->chrm_green_y = 16777216u * data[20] + 65536u * data[21] + 256u * data[22] + data[23];
5416 info->chrm_blue_x = 16777216u * data[24] + 65536u * data[25] + 256u * data[26] + data[27];
5417 info->chrm_blue_y = 16777216u * data[28] + 65536u * data[29] + 256u * data[30] + data[31];
5418
5419 return 0; /* OK */
5420 }
5421
readChunk_sRGB(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)5422 static unsigned readChunk_sRGB(LodePNGInfo * info, const unsigned char * data, size_t chunkLength)
5423 {
5424 if(chunkLength != 1) return 98; /*invalid sRGB chunk size (this one is never ignored)*/
5425
5426 info->srgb_defined = 1;
5427 info->srgb_intent = data[0];
5428
5429 return 0; /* OK */
5430 }
5431
readChunk_iCCP(LodePNGInfo * info,const LodePNGDecoderSettings * decoder,const unsigned char * data,size_t chunkLength)5432 static unsigned readChunk_iCCP(LodePNGInfo * info, const LodePNGDecoderSettings * decoder,
5433 const unsigned char * data, size_t chunkLength)
5434 {
5435 unsigned error = 0;
5436 unsigned i;
5437 size_t size = 0;
5438 /*copy the object to change parameters in it*/
5439 LodePNGDecompressSettings zlibsettings = decoder->zlibsettings;
5440
5441 unsigned length, string2_begin;
5442
5443 info->iccp_defined = 1;
5444 if(info->iccp_name) lodepng_clear_icc(info);
5445
5446 for(length = 0; length < chunkLength && data[length] != 0; ++length) ;
5447 if(length + 2 >= chunkLength) return 75; /*no null termination, corrupt?*/
5448 if(length < 1 || length > 79) return 89; /*keyword too short or long*/
5449
5450 info->iccp_name = (char *)lodepng_malloc(length + 1);
5451 if(!info->iccp_name) return 83; /*alloc fail*/
5452
5453 info->iccp_name[length] = 0;
5454 for(i = 0; i != length; ++i) info->iccp_name[i] = (char)data[i];
5455
5456 if(data[length + 1] != 0) return 72; /*the 0 byte indicating compression must be 0*/
5457
5458 string2_begin = length + 2;
5459 if(string2_begin > chunkLength) return 75; /*no null termination, corrupt?*/
5460
5461 length = (unsigned)chunkLength - string2_begin;
5462 zlibsettings.max_output_size = decoder->max_icc_size;
5463 error = zlib_decompress(&info->iccp_profile, &size, 0,
5464 &data[string2_begin],
5465 length, &zlibsettings);
5466 /*error: ICC profile larger than decoder->max_icc_size*/
5467 if(error && size > zlibsettings.max_output_size) error = 113;
5468 info->iccp_profile_size = (unsigned)size;
5469 if(!error && !info->iccp_profile_size) error = 100; /*invalid ICC profile size*/
5470 return error;
5471 }
5472
5473 /*significant bits chunk (sBIT)*/
readChunk_sBIT(LodePNGInfo * info,const unsigned char * data,size_t chunkLength)5474 static unsigned readChunk_sBIT(LodePNGInfo * info, const unsigned char * data, size_t chunkLength)
5475 {
5476 unsigned bitdepth = (info->color.colortype == LCT_PALETTE) ? 8 : info->color.bitdepth;
5477 if(info->color.colortype == LCT_GREY) {
5478 /*error: this chunk must be 1 bytes for grayscale image*/
5479 if(chunkLength != 1) return 114;
5480 if(data[0] == 0 || data[0] > bitdepth) return 115;
5481 info->sbit_defined = 1;
5482 info->sbit_r = info->sbit_g = info->sbit_b = data[0]; /*setting g and b is not required, but sensible*/
5483 }
5484 else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_PALETTE) {
5485 /*error: this chunk must be 3 bytes for RGB and palette image*/
5486 if(chunkLength != 3) return 114;
5487 if(data[0] == 0 || data[1] == 0 || data[2] == 0) return 115;
5488 if(data[0] > bitdepth || data[1] > bitdepth || data[2] > bitdepth) return 115;
5489 info->sbit_defined = 1;
5490 info->sbit_r = data[0];
5491 info->sbit_g = data[1];
5492 info->sbit_b = data[2];
5493 }
5494 else if(info->color.colortype == LCT_GREY_ALPHA) {
5495 /*error: this chunk must be 2 byte for grayscale with alpha image*/
5496 if(chunkLength != 2) return 114;
5497 if(data[0] == 0 || data[1] == 0) return 115;
5498 if(data[0] > bitdepth || data[1] > bitdepth) return 115;
5499 info->sbit_defined = 1;
5500 info->sbit_r = info->sbit_g = info->sbit_b = data[0]; /*setting g and b is not required, but sensible*/
5501 info->sbit_a = data[1];
5502 }
5503 else if(info->color.colortype == LCT_RGBA) {
5504 /*error: this chunk must be 4 bytes for grayscale image*/
5505 if(chunkLength != 4) return 114;
5506 if(data[0] == 0 || data[1] == 0 || data[2] == 0 || data[3] == 0) return 115;
5507 if(data[0] > bitdepth || data[1] > bitdepth || data[2] > bitdepth || data[3] > bitdepth) return 115;
5508 info->sbit_defined = 1;
5509 info->sbit_r = data[0];
5510 info->sbit_g = data[1];
5511 info->sbit_b = data[2];
5512 info->sbit_a = data[3];
5513 }
5514
5515 return 0; /* OK */
5516 }
5517 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5518
lodepng_inspect_chunk(LodePNGState * state,size_t pos,const unsigned char * in,size_t insize)5519 unsigned lodepng_inspect_chunk(LodePNGState * state, size_t pos,
5520 const unsigned char * in, size_t insize)
5521 {
5522 const unsigned char * chunk = in + pos;
5523 unsigned chunkLength;
5524 const unsigned char * data;
5525 unsigned unhandled = 0;
5526 unsigned error = 0;
5527
5528 if(pos + 4 > insize) return 30;
5529 chunkLength = lodepng_chunk_length(chunk);
5530 if(chunkLength > 2147483647) return 63;
5531 data = lodepng_chunk_data_const(chunk);
5532 if(chunkLength + 12 > insize - pos) return 30;
5533
5534 if(lodepng_chunk_type_equals(chunk, "PLTE")) {
5535 error = readChunk_PLTE(&state->info_png.color, data, chunkLength);
5536 }
5537 else if(lodepng_chunk_type_equals(chunk, "tRNS")) {
5538 error = readChunk_tRNS(&state->info_png.color, data, chunkLength);
5539 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5540 }
5541 else if(lodepng_chunk_type_equals(chunk, "bKGD")) {
5542 error = readChunk_bKGD(&state->info_png, data, chunkLength);
5543 }
5544 else if(lodepng_chunk_type_equals(chunk, "tEXt")) {
5545 error = readChunk_tEXt(&state->info_png, data, chunkLength);
5546 }
5547 else if(lodepng_chunk_type_equals(chunk, "zTXt")) {
5548 error = readChunk_zTXt(&state->info_png, &state->decoder, data, chunkLength);
5549 }
5550 else if(lodepng_chunk_type_equals(chunk, "iTXt")) {
5551 error = readChunk_iTXt(&state->info_png, &state->decoder, data, chunkLength);
5552 }
5553 else if(lodepng_chunk_type_equals(chunk, "tIME")) {
5554 error = readChunk_tIME(&state->info_png, data, chunkLength);
5555 }
5556 else if(lodepng_chunk_type_equals(chunk, "pHYs")) {
5557 error = readChunk_pHYs(&state->info_png, data, chunkLength);
5558 }
5559 else if(lodepng_chunk_type_equals(chunk, "gAMA")) {
5560 error = readChunk_gAMA(&state->info_png, data, chunkLength);
5561 }
5562 else if(lodepng_chunk_type_equals(chunk, "cHRM")) {
5563 error = readChunk_cHRM(&state->info_png, data, chunkLength);
5564 }
5565 else if(lodepng_chunk_type_equals(chunk, "sRGB")) {
5566 error = readChunk_sRGB(&state->info_png, data, chunkLength);
5567 }
5568 else if(lodepng_chunk_type_equals(chunk, "iCCP")) {
5569 error = readChunk_iCCP(&state->info_png, &state->decoder, data, chunkLength);
5570 }
5571 else if(lodepng_chunk_type_equals(chunk, "sBIT")) {
5572 error = readChunk_sBIT(&state->info_png, data, chunkLength);
5573 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5574 }
5575 else {
5576 /* unhandled chunk is ok (is not an error) */
5577 unhandled = 1;
5578 }
5579
5580 if(!error && !unhandled && !state->decoder.ignore_crc) {
5581 if(lodepng_chunk_check_crc(chunk)) return 57; /*invalid CRC*/
5582 }
5583
5584 return error;
5585 }
5586
5587 /*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)5588 static void decodeGeneric(unsigned char ** out, unsigned * w, unsigned * h,
5589 LodePNGState * state,
5590 const unsigned char * in, size_t insize)
5591 {
5592 unsigned char IEND = 0;
5593 const unsigned char * chunk; /*points to beginning of next chunk*/
5594 unsigned char * idat; /*the data from idat chunks, zlib compressed*/
5595 size_t idatsize = 0;
5596 unsigned char * scanlines = 0;
5597 size_t scanlines_size = 0, expected_size = 0;
5598 size_t outsize = 0;
5599
5600 /*for unknown chunk order*/
5601 unsigned unknown = 0;
5602 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5603 unsigned critical_pos = 1; /*1 = after IHDR, 2 = after PLTE, 3 = after IDAT*/
5604 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5605
5606
5607 /* safe output values in case error happens */
5608 *out = 0;
5609 *w = *h = 0;
5610
5611 state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/
5612 if(state->error) return;
5613
5614 if(lodepng_pixel_overflow(*w, *h, &state->info_png.color, &state->info_raw)) {
5615 CERROR_RETURN(state->error, 92); /*overflow possible due to amount of pixels*/
5616 }
5617
5618 /*the input filesize is a safe upper bound for the sum of idat chunks size*/
5619 idat = (unsigned char *)lodepng_malloc(insize);
5620 if(!idat) CERROR_RETURN(state->error, 83); /*alloc fail*/
5621
5622 chunk = &in[33]; /*first byte of the first chunk after the header*/
5623
5624 /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk.
5625 IDAT data is put at the start of the in buffer*/
5626 while(!IEND && !state->error) {
5627 unsigned chunkLength;
5628 const unsigned char * data; /*the data in the chunk*/
5629 size_t pos = (size_t)(chunk - in);
5630
5631 /*error: next chunk out of bounds of the in buffer*/
5632 if(chunk < in || pos + 12 > insize) {
5633 if(state->decoder.ignore_end) break; /*other errors may still happen though*/
5634 CERROR_BREAK(state->error, 30);
5635 }
5636
5637 /*length of the data of the chunk, excluding the 12 bytes for length, chunk type and CRC*/
5638 chunkLength = lodepng_chunk_length(chunk);
5639 /*error: chunk length larger than the max PNG chunk size*/
5640 if(chunkLength > 2147483647) {
5641 if(state->decoder.ignore_end) break; /*other errors may still happen though*/
5642 CERROR_BREAK(state->error, 63);
5643 }
5644
5645 if(pos + (size_t)chunkLength + 12 > insize || pos + (size_t)chunkLength + 12 < pos) {
5646 CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk (or int overflow)*/
5647 }
5648
5649 data = lodepng_chunk_data_const(chunk);
5650
5651 unknown = 0;
5652
5653 /*IDAT chunk, containing compressed image data*/
5654 if(lodepng_chunk_type_equals(chunk, "IDAT")) {
5655 size_t newsize;
5656 if(lodepng_addofl(idatsize, chunkLength, &newsize)) CERROR_BREAK(state->error, 95);
5657 if(newsize > insize) CERROR_BREAK(state->error, 95);
5658 lodepng_memcpy(idat + idatsize, data, chunkLength);
5659 idatsize += chunkLength;
5660 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5661 critical_pos = 3;
5662 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5663 }
5664 else if(lodepng_chunk_type_equals(chunk, "IEND")) {
5665 /*IEND chunk*/
5666 IEND = 1;
5667 }
5668 else if(lodepng_chunk_type_equals(chunk, "PLTE")) {
5669 /*palette chunk (PLTE)*/
5670 state->error = readChunk_PLTE(&state->info_png.color, data, chunkLength);
5671 if(state->error) break;
5672 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5673 critical_pos = 2;
5674 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5675 }
5676 else if(lodepng_chunk_type_equals(chunk, "tRNS")) {
5677 /*palette transparency chunk (tRNS). Even though this one is an ancillary chunk , it is still compiled
5678 in without 'LODEPNG_COMPILE_ANCILLARY_CHUNKS' because it contains essential color information that
5679 affects the alpha channel of pixels. */
5680 state->error = readChunk_tRNS(&state->info_png.color, data, chunkLength);
5681 if(state->error) break;
5682 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5683 /*background color chunk (bKGD)*/
5684 }
5685 else if(lodepng_chunk_type_equals(chunk, "bKGD")) {
5686 state->error = readChunk_bKGD(&state->info_png, data, chunkLength);
5687 if(state->error) break;
5688 }
5689 else if(lodepng_chunk_type_equals(chunk, "tEXt")) {
5690 /*text chunk (tEXt)*/
5691 if(state->decoder.read_text_chunks) {
5692 state->error = readChunk_tEXt(&state->info_png, data, chunkLength);
5693 if(state->error) break;
5694 }
5695 }
5696 else if(lodepng_chunk_type_equals(chunk, "zTXt")) {
5697 /*compressed text chunk (zTXt)*/
5698 if(state->decoder.read_text_chunks) {
5699 state->error = readChunk_zTXt(&state->info_png, &state->decoder, data, chunkLength);
5700 if(state->error) break;
5701 }
5702 }
5703 else if(lodepng_chunk_type_equals(chunk, "iTXt")) {
5704 /*international text chunk (iTXt)*/
5705 if(state->decoder.read_text_chunks) {
5706 state->error = readChunk_iTXt(&state->info_png, &state->decoder, data, chunkLength);
5707 if(state->error) break;
5708 }
5709 }
5710 else if(lodepng_chunk_type_equals(chunk, "tIME")) {
5711 state->error = readChunk_tIME(&state->info_png, data, chunkLength);
5712 if(state->error) break;
5713 }
5714 else if(lodepng_chunk_type_equals(chunk, "pHYs")) {
5715 state->error = readChunk_pHYs(&state->info_png, data, chunkLength);
5716 if(state->error) break;
5717 }
5718 else if(lodepng_chunk_type_equals(chunk, "gAMA")) {
5719 state->error = readChunk_gAMA(&state->info_png, data, chunkLength);
5720 if(state->error) break;
5721 }
5722 else if(lodepng_chunk_type_equals(chunk, "cHRM")) {
5723 state->error = readChunk_cHRM(&state->info_png, data, chunkLength);
5724 if(state->error) break;
5725 }
5726 else if(lodepng_chunk_type_equals(chunk, "sRGB")) {
5727 state->error = readChunk_sRGB(&state->info_png, data, chunkLength);
5728 if(state->error) break;
5729 }
5730 else if(lodepng_chunk_type_equals(chunk, "iCCP")) {
5731 state->error = readChunk_iCCP(&state->info_png, &state->decoder, data, chunkLength);
5732 if(state->error) break;
5733 }
5734 else if(lodepng_chunk_type_equals(chunk, "sBIT")) {
5735 state->error = readChunk_sBIT(&state->info_png, data, chunkLength);
5736 if(state->error) break;
5737 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5738 }
5739 else /*it's not an implemented chunk type, so ignore it: skip over the data*/ {
5740 /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/
5741 if(!state->decoder.ignore_critical && !lodepng_chunk_ancillary(chunk)) {
5742 CERROR_BREAK(state->error, 69);
5743 }
5744
5745 unknown = 1;
5746 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5747 if(state->decoder.remember_unknown_chunks) {
5748 state->error = lodepng_chunk_append(&state->info_png.unknown_chunks_data[critical_pos - 1],
5749 &state->info_png.unknown_chunks_size[critical_pos - 1], chunk);
5750 if(state->error) break;
5751 }
5752 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5753 }
5754
5755 if(!state->decoder.ignore_crc && !unknown) { /*check CRC if wanted, only on known chunk types*/
5756 if(lodepng_chunk_check_crc(chunk)) CERROR_BREAK(state->error, 57); /*invalid CRC*/
5757 }
5758
5759 if(!IEND) chunk = lodepng_chunk_next_const(chunk, in + insize);
5760 }
5761
5762 if(!state->error && state->info_png.color.colortype == LCT_PALETTE && !state->info_png.color.palette) {
5763 state->error = 106; /* error: PNG file must have PLTE chunk if color type is palette */
5764 }
5765
5766 if(!state->error) {
5767 /*predict output size, to allocate exact size for output buffer to avoid more dynamic allocation.
5768 If the decompressed size does not match the prediction, the image must be corrupt.*/
5769 if(state->info_png.interlace_method == 0) {
5770 unsigned bpp = lodepng_get_bpp(&state->info_png.color);
5771 expected_size = lodepng_get_raw_size_idat(*w, *h, bpp);
5772 }
5773 else {
5774 unsigned bpp = lodepng_get_bpp(&state->info_png.color);
5775 /*Adam-7 interlaced: expected size is the sum of the 7 sub-images sizes*/
5776 expected_size = 0;
5777 expected_size += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, bpp);
5778 if(*w > 4) expected_size += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, bpp);
5779 expected_size += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, bpp);
5780 if(*w > 2) expected_size += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, bpp);
5781 expected_size += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, bpp);
5782 if(*w > 1) expected_size += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, bpp);
5783 expected_size += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, bpp);
5784 }
5785
5786 state->error = zlib_decompress(&scanlines, &scanlines_size, expected_size, idat, idatsize,
5787 &state->decoder.zlibsettings);
5788 }
5789 if(!state->error && scanlines_size != expected_size) state->error = 91; /*decompressed size doesn't match prediction*/
5790 lodepng_free(idat);
5791
5792 if(!state->error) {
5793 lv_draw_buf_t * decoded = lv_draw_buf_create_ex(image_cache_draw_buf_handlers, *w, *h, LV_COLOR_FORMAT_ARGB8888, 4 * *w);
5794 if(decoded) {
5795 *out = (unsigned char*)decoded;
5796 outsize = decoded->data_size;
5797 }
5798 else state->error = 83; /*alloc fail*/
5799 }
5800 if(!state->error) {
5801 lv_draw_buf_t * decoded = (lv_draw_buf_t *)*out;
5802 lodepng_memset(decoded->data, 0, outsize);
5803 state->error = postProcessScanlines(decoded->data, scanlines, *w, *h, &state->info_png);
5804 }
5805 lodepng_free(scanlines);
5806 }
5807
lodepng_decode(unsigned char ** out,unsigned * w,unsigned * h,LodePNGState * state,const unsigned char * in,size_t insize)5808 unsigned lodepng_decode(unsigned char ** out, unsigned * w, unsigned * h,
5809 LodePNGState * state,
5810 const unsigned char * in, size_t insize)
5811 {
5812 *out = NULL;
5813 decodeGeneric(out, w, h, state, in, insize);
5814 if(state->error) return state->error;
5815 if(!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color)) {
5816 /*same color type, no copying or converting of data needed*/
5817 /*store the info_png color settings on the info_raw so that the info_raw still reflects what colortype
5818 the raw image has to the end user*/
5819 if(!state->decoder.color_convert) {
5820 state->error = lodepng_color_mode_copy(&state->info_raw, &state->info_png.color);
5821 if(state->error) return state->error;
5822 }
5823 }
5824 else { /*color conversion needed*/
5825 lv_draw_buf_t * old_buf = (lv_draw_buf_t *)*out;
5826
5827 /*TODO: check if this works according to the statement in the documentation: "The converter can convert
5828 from grayscale input color type, to 8-bit grayscale or grayscale with alpha"*/
5829 if(!(state->info_raw.colortype == LCT_RGB || state->info_raw.colortype == LCT_RGBA)
5830 && !(state->info_raw.bitdepth == 8)) {
5831 return 56; /*unsupported color mode conversion*/
5832 }
5833
5834 lv_draw_buf_t * new_buf = lv_draw_buf_create_user(image_cache_draw_buf_handlers,*w, *h, LV_COLOR_FORMAT_ARGB8888, 4 * *w);
5835 if(new_buf == NULL) {
5836 state->error = 83; /*alloc fail*/
5837 }
5838 else {
5839 state->error = lodepng_convert(new_buf->data, old_buf->data,
5840 &state->info_raw, &state->info_png.color, *w, *h);
5841
5842 if (state->error) {
5843 lv_draw_buf_destroy(new_buf);
5844 new_buf = NULL;
5845 }
5846 }
5847
5848 *out = (unsigned char*)new_buf;
5849 lv_draw_buf_destroy(old_buf);
5850 }
5851 return state->error;
5852 }
5853
lodepng_decode_memory(unsigned char ** out,unsigned * w,unsigned * h,const unsigned char * in,size_t insize,LodePNGColorType colortype,unsigned bitdepth)5854 unsigned lodepng_decode_memory(unsigned char ** out, unsigned * w, unsigned * h, const unsigned char * in,
5855 size_t insize, LodePNGColorType colortype, unsigned bitdepth)
5856 {
5857 unsigned error;
5858 LodePNGState state;
5859 lodepng_state_init(&state);
5860 state.info_raw.colortype = colortype;
5861 state.info_raw.bitdepth = bitdepth;
5862 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5863 /*disable reading things that this function doesn't output*/
5864 state.decoder.read_text_chunks = 0;
5865 state.decoder.remember_unknown_chunks = 0;
5866 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5867 error = lodepng_decode(out, w, h, &state, in, insize);
5868 lodepng_state_cleanup(&state);
5869 return error;
5870 }
5871
lodepng_decode32(unsigned char ** out,unsigned * w,unsigned * h,const unsigned char * in,size_t insize)5872 unsigned lodepng_decode32(unsigned char ** out, unsigned * w, unsigned * h, const unsigned char * in, size_t insize)
5873 {
5874 return lodepng_decode_memory(out, w, h, in, insize, LCT_RGBA, 8);
5875 }
5876
lodepng_decode24(unsigned char ** out,unsigned * w,unsigned * h,const unsigned char * in,size_t insize)5877 unsigned lodepng_decode24(unsigned char ** out, unsigned * w, unsigned * h, const unsigned char * in, size_t insize)
5878 {
5879 return lodepng_decode_memory(out, w, h, in, insize, LCT_RGB, 8);
5880 }
5881
5882 #ifdef LODEPNG_COMPILE_DISK
lodepng_decode_file(unsigned char ** out,unsigned * w,unsigned * h,const char * filename,LodePNGColorType colortype,unsigned bitdepth)5883 unsigned lodepng_decode_file(unsigned char ** out, unsigned * w, unsigned * h, const char * filename,
5884 LodePNGColorType colortype, unsigned bitdepth)
5885 {
5886 unsigned char * buffer = 0;
5887 size_t buffersize;
5888 unsigned error;
5889 /* safe output values in case error happens */
5890 *out = 0;
5891 *w = *h = 0;
5892 error = lodepng_load_file(&buffer, &buffersize, filename);
5893 if(!error) error = lodepng_decode_memory(out, w, h, buffer, buffersize, colortype, bitdepth);
5894 lodepng_free(buffer);
5895 return error;
5896 }
5897
lodepng_decode32_file(unsigned char ** out,unsigned * w,unsigned * h,const char * filename)5898 unsigned lodepng_decode32_file(unsigned char ** out, unsigned * w, unsigned * h, const char * filename)
5899 {
5900 return lodepng_decode_file(out, w, h, filename, LCT_RGBA, 8);
5901 }
5902
lodepng_decode24_file(unsigned char ** out,unsigned * w,unsigned * h,const char * filename)5903 unsigned lodepng_decode24_file(unsigned char ** out, unsigned * w, unsigned * h, const char * filename)
5904 {
5905 return lodepng_decode_file(out, w, h, filename, LCT_RGB, 8);
5906 }
5907 #endif /*LODEPNG_COMPILE_DISK*/
5908
lodepng_decoder_settings_init(LodePNGDecoderSettings * settings)5909 void lodepng_decoder_settings_init(LodePNGDecoderSettings * settings)
5910 {
5911 settings->color_convert = 1;
5912 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
5913 settings->read_text_chunks = 1;
5914 settings->remember_unknown_chunks = 0;
5915 settings->max_text_size = 16777216;
5916 settings->max_icc_size = 16777216; /* 16MB is much more than enough for any reasonable ICC profile */
5917 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
5918 settings->ignore_crc = 0;
5919 settings->ignore_critical = 0;
5920 settings->ignore_end = 0;
5921 lodepng_decompress_settings_init(&settings->zlibsettings);
5922 }
5923
5924 #endif /*LODEPNG_COMPILE_DECODER*/
5925
5926 #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER)
5927
lodepng_state_init(LodePNGState * state)5928 void lodepng_state_init(LodePNGState * state)
5929 {
5930 #ifdef LODEPNG_COMPILE_DECODER
5931 lodepng_decoder_settings_init(&state->decoder);
5932 #endif /*LODEPNG_COMPILE_DECODER*/
5933 #ifdef LODEPNG_COMPILE_ENCODER
5934 lodepng_encoder_settings_init(&state->encoder);
5935 #endif /*LODEPNG_COMPILE_ENCODER*/
5936 lodepng_color_mode_init(&state->info_raw);
5937 lodepng_info_init(&state->info_png);
5938 state->error = 1;
5939 }
5940
lodepng_state_cleanup(LodePNGState * state)5941 void lodepng_state_cleanup(LodePNGState * state)
5942 {
5943 lodepng_color_mode_cleanup(&state->info_raw);
5944 lodepng_info_cleanup(&state->info_png);
5945 }
5946
lodepng_state_copy(LodePNGState * dest,const LodePNGState * source)5947 void lodepng_state_copy(LodePNGState * dest, const LodePNGState * source)
5948 {
5949 lodepng_state_cleanup(dest);
5950 *dest = *source;
5951 lodepng_color_mode_init(&dest->info_raw);
5952 lodepng_info_init(&dest->info_png);
5953 dest->error = lodepng_color_mode_copy(&dest->info_raw, &source->info_raw);
5954 if(dest->error) return;
5955 dest->error = lodepng_info_copy(&dest->info_png, &source->info_png);
5956 if(dest->error) return;
5957 }
5958
5959 #endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */
5960
5961 #ifdef LODEPNG_COMPILE_ENCODER
5962
5963 /* ////////////////////////////////////////////////////////////////////////// */
5964 /* / PNG Encoder / */
5965 /* ////////////////////////////////////////////////////////////////////////// */
5966
5967
writeSignature(ucvector * out)5968 static unsigned writeSignature(ucvector * out)
5969 {
5970 size_t pos = out->size;
5971 const unsigned char signature[] = {137, 80, 78, 71, 13, 10, 26, 10};
5972 /*8 bytes PNG signature, aka the magic bytes*/
5973 if(!ucvector_resize(out, out->size + 8)) return 83; /*alloc fail*/
5974 lodepng_memcpy(out->data + pos, signature, 8);
5975 return 0;
5976 }
5977
addChunk_IHDR(ucvector * out,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth,unsigned interlace_method)5978 static unsigned addChunk_IHDR(ucvector * out, unsigned w, unsigned h,
5979 LodePNGColorType colortype, unsigned bitdepth, unsigned interlace_method)
5980 {
5981 unsigned char * chunk, * data;
5982 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 13, "IHDR"));
5983 data = chunk + 8;
5984
5985 lodepng_set32bitInt(data + 0, w); /*width*/
5986 lodepng_set32bitInt(data + 4, h); /*height*/
5987 data[8] = (unsigned char)bitdepth; /*bit depth*/
5988 data[9] = (unsigned char)colortype; /*color type*/
5989 data[10] = 0; /*compression method*/
5990 data[11] = 0; /*filter method*/
5991 data[12] = interlace_method; /*interlace method*/
5992
5993 lodepng_chunk_generate_crc(chunk);
5994 return 0;
5995 }
5996
5997 /* only adds the chunk if needed (there is a key or palette with alpha) */
addChunk_PLTE(ucvector * out,const LodePNGColorMode * info)5998 static unsigned addChunk_PLTE(ucvector * out, const LodePNGColorMode * info)
5999 {
6000 unsigned char * chunk;
6001 size_t i, j = 8;
6002
6003 if(info->palettesize == 0 || info->palettesize > 256) {
6004 return 68; /*invalid palette size, it is only allowed to be 1-256*/
6005 }
6006
6007 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, info->palettesize * 3, "PLTE"));
6008
6009 for(i = 0; i != info->palettesize; ++i) {
6010 /*add all channels except alpha channel*/
6011 chunk[j++] = info->palette[i * 4 + 0];
6012 chunk[j++] = info->palette[i * 4 + 1];
6013 chunk[j++] = info->palette[i * 4 + 2];
6014 }
6015
6016 lodepng_chunk_generate_crc(chunk);
6017 return 0;
6018 }
6019
addChunk_tRNS(ucvector * out,const LodePNGColorMode * info)6020 static unsigned addChunk_tRNS(ucvector * out, const LodePNGColorMode * info)
6021 {
6022 unsigned char * chunk = 0;
6023
6024 if(info->colortype == LCT_PALETTE) {
6025 size_t i, amount = info->palettesize;
6026 /*the tail of palette values that all have 255 as alpha, does not have to be encoded*/
6027 for(i = info->palettesize; i != 0; --i) {
6028 if(info->palette[4 * (i - 1) + 3] != 255) break;
6029 --amount;
6030 }
6031 if(amount) {
6032 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, amount, "tRNS"));
6033 /*add the alpha channel values from the palette*/
6034 for(i = 0; i != amount; ++i) chunk[8 + i] = info->palette[4 * i + 3];
6035 }
6036 }
6037 else if(info->colortype == LCT_GREY) {
6038 if(info->key_defined) {
6039 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 2, "tRNS"));
6040 chunk[8] = (unsigned char)(info->key_r >> 8);
6041 chunk[9] = (unsigned char)(info->key_r & 255);
6042 }
6043 }
6044 else if(info->colortype == LCT_RGB) {
6045 if(info->key_defined) {
6046 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 6, "tRNS"));
6047 chunk[8] = (unsigned char)(info->key_r >> 8);
6048 chunk[9] = (unsigned char)(info->key_r & 255);
6049 chunk[10] = (unsigned char)(info->key_g >> 8);
6050 chunk[11] = (unsigned char)(info->key_g & 255);
6051 chunk[12] = (unsigned char)(info->key_b >> 8);
6052 chunk[13] = (unsigned char)(info->key_b & 255);
6053 }
6054 }
6055
6056 if(chunk) lodepng_chunk_generate_crc(chunk);
6057 return 0;
6058 }
6059
addChunk_IDAT(ucvector * out,const unsigned char * data,size_t datasize,LodePNGCompressSettings * zlibsettings)6060 static unsigned addChunk_IDAT(ucvector * out, const unsigned char * data, size_t datasize,
6061 LodePNGCompressSettings * zlibsettings)
6062 {
6063 unsigned error = 0;
6064 unsigned char * zlib = 0;
6065 size_t zlibsize = 0;
6066
6067 error = zlib_compress(&zlib, &zlibsize, data, datasize, zlibsettings);
6068 if(!error) {
6069 error = lodepng_chunk_createv(out, zlibsize, "IDAT", zlib);
6070 }
6071 lodepng_free(zlib);
6072 return error;
6073 }
6074
addChunk_IEND(ucvector * out)6075 static unsigned addChunk_IEND(ucvector * out)
6076 {
6077 return lodepng_chunk_createv(out, 0, "IEND", 0);
6078 }
6079
6080 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6081
addChunk_tEXt(ucvector * out,const char * keyword,const char * textstring)6082 static unsigned addChunk_tEXt(ucvector * out, const char * keyword, const char * textstring)
6083 {
6084 unsigned char * chunk = 0;
6085 size_t keysize = lodepng_strlen(keyword), textsize = lodepng_strlen(textstring);
6086 size_t size = keysize + 1 + textsize;
6087 if(keysize < 1 || keysize > 79) return 89; /*error: invalid keyword size*/
6088 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, size, "tEXt"));
6089 lodepng_memcpy(chunk + 8, keyword, keysize);
6090 chunk[8 + keysize] = 0; /*null termination char*/
6091 lodepng_memcpy(chunk + 9 + keysize, textstring, textsize);
6092 lodepng_chunk_generate_crc(chunk);
6093 return 0;
6094 }
6095
addChunk_zTXt(ucvector * out,const char * keyword,const char * textstring,LodePNGCompressSettings * zlibsettings)6096 static unsigned addChunk_zTXt(ucvector * out, const char * keyword, const char * textstring,
6097 LodePNGCompressSettings * zlibsettings)
6098 {
6099 unsigned error = 0;
6100 unsigned char * chunk = 0;
6101 unsigned char * compressed = 0;
6102 size_t compressedsize = 0;
6103 size_t textsize = lodepng_strlen(textstring);
6104 size_t keysize = lodepng_strlen(keyword);
6105 if(keysize < 1 || keysize > 79) return 89; /*error: invalid keyword size*/
6106
6107 error = zlib_compress(&compressed, &compressedsize,
6108 (const unsigned char *)textstring, textsize, zlibsettings);
6109 if(!error) {
6110 size_t size = keysize + 2 + compressedsize;
6111 error = lodepng_chunk_init(&chunk, out, size, "zTXt");
6112 }
6113 if(!error) {
6114 lodepng_memcpy(chunk + 8, keyword, keysize);
6115 chunk[8 + keysize] = 0; /*null termination char*/
6116 chunk[9 + keysize] = 0; /*compression method: 0*/
6117 lodepng_memcpy(chunk + 10 + keysize, compressed, compressedsize);
6118 lodepng_chunk_generate_crc(chunk);
6119 }
6120
6121 lodepng_free(compressed);
6122 return error;
6123 }
6124
addChunk_iTXt(ucvector * out,unsigned compress,const char * keyword,const char * langtag,const char * transkey,const char * textstring,LodePNGCompressSettings * zlibsettings)6125 static unsigned addChunk_iTXt(ucvector * out, unsigned compress, const char * keyword, const char * langtag,
6126 const char * transkey, const char * textstring, LodePNGCompressSettings * zlibsettings)
6127 {
6128 unsigned error = 0;
6129 unsigned char * chunk = 0;
6130 unsigned char * compressed = 0;
6131 size_t compressedsize = 0;
6132 size_t textsize = lodepng_strlen(textstring);
6133 size_t keysize = lodepng_strlen(keyword), langsize = lodepng_strlen(langtag), transsize = lodepng_strlen(transkey);
6134
6135 if(keysize < 1 || keysize > 79) return 89; /*error: invalid keyword size*/
6136
6137 if(compress) {
6138 error = zlib_compress(&compressed, &compressedsize,
6139 (const unsigned char *)textstring, textsize, zlibsettings);
6140 }
6141 if(!error) {
6142 size_t size = keysize + 3 + langsize + 1 + transsize + 1 + (compress ? compressedsize : textsize);
6143 error = lodepng_chunk_init(&chunk, out, size, "iTXt");
6144 }
6145 if(!error) {
6146 size_t pos = 8;
6147 lodepng_memcpy(chunk + pos, keyword, keysize);
6148 pos += keysize;
6149 chunk[pos++] = 0; /*null termination char*/
6150 chunk[pos++] = (compress ? 1 : 0); /*compression flag*/
6151 chunk[pos++] = 0; /*compression method: 0*/
6152 lodepng_memcpy(chunk + pos, langtag, langsize);
6153 pos += langsize;
6154 chunk[pos++] = 0; /*null termination char*/
6155 lodepng_memcpy(chunk + pos, transkey, transsize);
6156 pos += transsize;
6157 chunk[pos++] = 0; /*null termination char*/
6158 if(compress) {
6159 lodepng_memcpy(chunk + pos, compressed, compressedsize);
6160 }
6161 else {
6162 lodepng_memcpy(chunk + pos, textstring, textsize);
6163 }
6164 lodepng_chunk_generate_crc(chunk);
6165 }
6166
6167 lodepng_free(compressed);
6168 return error;
6169 }
6170
addChunk_bKGD(ucvector * out,const LodePNGInfo * info)6171 static unsigned addChunk_bKGD(ucvector * out, const LodePNGInfo * info)
6172 {
6173 unsigned char * chunk = 0;
6174 if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) {
6175 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 2, "bKGD"));
6176 chunk[8] = (unsigned char)(info->background_r >> 8);
6177 chunk[9] = (unsigned char)(info->background_r & 255);
6178 }
6179 else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) {
6180 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 6, "bKGD"));
6181 chunk[8] = (unsigned char)(info->background_r >> 8);
6182 chunk[9] = (unsigned char)(info->background_r & 255);
6183 chunk[10] = (unsigned char)(info->background_g >> 8);
6184 chunk[11] = (unsigned char)(info->background_g & 255);
6185 chunk[12] = (unsigned char)(info->background_b >> 8);
6186 chunk[13] = (unsigned char)(info->background_b & 255);
6187 }
6188 else if(info->color.colortype == LCT_PALETTE) {
6189 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 1, "bKGD"));
6190 chunk[8] = (unsigned char)(info->background_r & 255); /*palette index*/
6191 }
6192 if(chunk) lodepng_chunk_generate_crc(chunk);
6193 return 0;
6194 }
6195
addChunk_tIME(ucvector * out,const LodePNGTime * time)6196 static unsigned addChunk_tIME(ucvector * out, const LodePNGTime * time)
6197 {
6198 unsigned char * chunk;
6199 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 7, "tIME"));
6200 chunk[8] = (unsigned char)(time->year >> 8);
6201 chunk[9] = (unsigned char)(time->year & 255);
6202 chunk[10] = (unsigned char)time->month;
6203 chunk[11] = (unsigned char)time->day;
6204 chunk[12] = (unsigned char)time->hour;
6205 chunk[13] = (unsigned char)time->minute;
6206 chunk[14] = (unsigned char)time->second;
6207 lodepng_chunk_generate_crc(chunk);
6208 return 0;
6209 }
6210
addChunk_pHYs(ucvector * out,const LodePNGInfo * info)6211 static unsigned addChunk_pHYs(ucvector * out, const LodePNGInfo * info)
6212 {
6213 unsigned char * chunk;
6214 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 9, "pHYs"));
6215 lodepng_set32bitInt(chunk + 8, info->phys_x);
6216 lodepng_set32bitInt(chunk + 12, info->phys_y);
6217 chunk[16] = info->phys_unit;
6218 lodepng_chunk_generate_crc(chunk);
6219 return 0;
6220 }
6221
addChunk_gAMA(ucvector * out,const LodePNGInfo * info)6222 static unsigned addChunk_gAMA(ucvector * out, const LodePNGInfo * info)
6223 {
6224 unsigned char * chunk;
6225 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 4, "gAMA"));
6226 lodepng_set32bitInt(chunk + 8, info->gama_gamma);
6227 lodepng_chunk_generate_crc(chunk);
6228 return 0;
6229 }
6230
addChunk_cHRM(ucvector * out,const LodePNGInfo * info)6231 static unsigned addChunk_cHRM(ucvector * out, const LodePNGInfo * info)
6232 {
6233 unsigned char * chunk;
6234 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 32, "cHRM"));
6235 lodepng_set32bitInt(chunk + 8, info->chrm_white_x);
6236 lodepng_set32bitInt(chunk + 12, info->chrm_white_y);
6237 lodepng_set32bitInt(chunk + 16, info->chrm_red_x);
6238 lodepng_set32bitInt(chunk + 20, info->chrm_red_y);
6239 lodepng_set32bitInt(chunk + 24, info->chrm_green_x);
6240 lodepng_set32bitInt(chunk + 28, info->chrm_green_y);
6241 lodepng_set32bitInt(chunk + 32, info->chrm_blue_x);
6242 lodepng_set32bitInt(chunk + 36, info->chrm_blue_y);
6243 lodepng_chunk_generate_crc(chunk);
6244 return 0;
6245 }
6246
addChunk_sRGB(ucvector * out,const LodePNGInfo * info)6247 static unsigned addChunk_sRGB(ucvector * out, const LodePNGInfo * info)
6248 {
6249 unsigned char data = info->srgb_intent;
6250 return lodepng_chunk_createv(out, 1, "sRGB", &data);
6251 }
6252
addChunk_iCCP(ucvector * out,const LodePNGInfo * info,LodePNGCompressSettings * zlibsettings)6253 static unsigned addChunk_iCCP(ucvector * out, const LodePNGInfo * info, LodePNGCompressSettings * zlibsettings)
6254 {
6255 unsigned error = 0;
6256 unsigned char * chunk = 0;
6257 unsigned char * compressed = 0;
6258 size_t compressedsize = 0;
6259 size_t keysize = lodepng_strlen(info->iccp_name);
6260
6261 if(keysize < 1 || keysize > 79) return 89; /*error: invalid keyword size*/
6262 error = zlib_compress(&compressed, &compressedsize,
6263 info->iccp_profile, info->iccp_profile_size, zlibsettings);
6264 if(!error) {
6265 size_t size = keysize + 2 + compressedsize;
6266 error = lodepng_chunk_init(&chunk, out, size, "iCCP");
6267 }
6268 if(!error) {
6269 lodepng_memcpy(chunk + 8, info->iccp_name, keysize);
6270 chunk[8 + keysize] = 0; /*null termination char*/
6271 chunk[9 + keysize] = 0; /*compression method: 0*/
6272 lodepng_memcpy(chunk + 10 + keysize, compressed, compressedsize);
6273 lodepng_chunk_generate_crc(chunk);
6274 }
6275
6276 lodepng_free(compressed);
6277 return error;
6278 }
6279
addChunk_sBIT(ucvector * out,const LodePNGInfo * info)6280 static unsigned addChunk_sBIT(ucvector * out, const LodePNGInfo * info)
6281 {
6282 unsigned bitdepth = (info->color.colortype == LCT_PALETTE) ? 8 : info->color.bitdepth;
6283 unsigned char * chunk = 0;
6284 if(info->color.colortype == LCT_GREY) {
6285 if(info->sbit_r == 0 || info->sbit_r > bitdepth) return 115;
6286 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 1, "sBIT"));
6287 chunk[8] = info->sbit_r;
6288 }
6289 else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_PALETTE) {
6290 if(info->sbit_r == 0 || info->sbit_g == 0 || info->sbit_b == 0) return 115;
6291 if(info->sbit_r > bitdepth || info->sbit_g > bitdepth || info->sbit_b > bitdepth) return 115;
6292 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 3, "sBIT"));
6293 chunk[8] = info->sbit_r;
6294 chunk[9] = info->sbit_g;
6295 chunk[10] = info->sbit_b;
6296 }
6297 else if(info->color.colortype == LCT_GREY_ALPHA) {
6298 if(info->sbit_r == 0 || info->sbit_a == 0) return 115;
6299 if(info->sbit_r > bitdepth || info->sbit_a > bitdepth) return 115;
6300 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 2, "sBIT"));
6301 chunk[8] = info->sbit_r;
6302 chunk[9] = info->sbit_a;
6303 }
6304 else if(info->color.colortype == LCT_RGBA) {
6305 if(info->sbit_r == 0 || info->sbit_g == 0 || info->sbit_b == 0 || info->sbit_a == 0 ||
6306 info->sbit_r > bitdepth || info->sbit_g > bitdepth ||
6307 info->sbit_b > bitdepth || info->sbit_a > bitdepth) {
6308 return 115;
6309 }
6310 CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 4, "sBIT"));
6311 chunk[8] = info->sbit_r;
6312 chunk[9] = info->sbit_g;
6313 chunk[10] = info->sbit_b;
6314 chunk[11] = info->sbit_a;
6315 }
6316 if(chunk) lodepng_chunk_generate_crc(chunk);
6317 return 0;
6318 }
6319
6320 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
6321
filterScanline(unsigned char * out,const unsigned char * scanline,const unsigned char * prevline,size_t length,size_t bytewidth,unsigned char filterType)6322 static void filterScanline(unsigned char * out, const unsigned char * scanline, const unsigned char * prevline,
6323 size_t length, size_t bytewidth, unsigned char filterType)
6324 {
6325 size_t i;
6326 switch(filterType) {
6327 case 0: /*None*/
6328 for(i = 0; i != length; ++i) out[i] = scanline[i];
6329 break;
6330 case 1: /*Sub*/
6331 for(i = 0; i != bytewidth; ++i) out[i] = scanline[i];
6332 for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth];
6333 break;
6334 case 2: /*Up*/
6335 if(prevline) {
6336 for(i = 0; i != length; ++i) out[i] = scanline[i] - prevline[i];
6337 }
6338 else {
6339 for(i = 0; i != length; ++i) out[i] = scanline[i];
6340 }
6341 break;
6342 case 3: /*Average*/
6343 if(prevline) {
6344 for(i = 0; i != bytewidth; ++i) out[i] = scanline[i] - (prevline[i] >> 1);
6345 for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) >> 1);
6346 }
6347 else {
6348 for(i = 0; i != bytewidth; ++i) out[i] = scanline[i];
6349 for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - (scanline[i - bytewidth] >> 1);
6350 }
6351 break;
6352 case 4: /*Paeth*/
6353 if(prevline) {
6354 /*paethPredictor(0, prevline[i], 0) is always prevline[i]*/
6355 for(i = 0; i != bytewidth; ++i) out[i] = (scanline[i] - prevline[i]);
6356 for(i = bytewidth; i < length; ++i) {
6357 out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth]));
6358 }
6359 }
6360 else {
6361 for(i = 0; i != bytewidth; ++i) out[i] = scanline[i];
6362 /*paethPredictor(scanline[i - bytewidth], 0, 0) is always scanline[i - bytewidth]*/
6363 for(i = bytewidth; i < length; ++i) out[i] = (scanline[i] - scanline[i - bytewidth]);
6364 }
6365 break;
6366 default:
6367 return; /*invalid filter type given*/
6368 }
6369 }
6370
6371 /* integer binary logarithm, max return value is 31 */
ilog2(size_t i)6372 static size_t ilog2(size_t i)
6373 {
6374 size_t result = 0;
6375 if(i >= 65536) {
6376 result += 16;
6377 i >>= 16;
6378 }
6379 if(i >= 256) {
6380 result += 8;
6381 i >>= 8;
6382 }
6383 if(i >= 16) {
6384 result += 4;
6385 i >>= 4;
6386 }
6387 if(i >= 4) {
6388 result += 2;
6389 i >>= 2;
6390 }
6391 if(i >= 2) {
6392 result += 1; /*i >>= 1;*/
6393 }
6394 return result;
6395 }
6396
6397 /* integer approximation for i * log2(i), helper function for LFS_ENTROPY */
ilog2i(size_t i)6398 static size_t ilog2i(size_t i)
6399 {
6400 size_t l;
6401 if(i == 0) return 0;
6402 l = ilog2(i);
6403 /* approximate i*log2(i): l is integer logarithm, ((i - (1u << l)) << 1u)
6404 linearly approximates the missing fractional part multiplied by i */
6405 return i * l + ((i - (((size_t)1) << l)) << 1u);
6406 }
6407
filter(unsigned char * out,const unsigned char * in,unsigned w,unsigned h,const LodePNGColorMode * color,const LodePNGEncoderSettings * settings)6408 static unsigned filter(unsigned char * out, const unsigned char * in, unsigned w, unsigned h,
6409 const LodePNGColorMode * color, const LodePNGEncoderSettings * settings)
6410 {
6411 /*
6412 For PNG filter method 0
6413 out must be a buffer with as size: h + (w * h * bpp + 7u) / 8u, because there are
6414 the scanlines with 1 extra byte per scanline
6415 */
6416
6417 unsigned bpp = lodepng_get_bpp(color);
6418 /*the width of a scanline in bytes, not including the filter type*/
6419 size_t linebytes = lodepng_get_raw_size_idat(w, 1, bpp) - 1u;
6420
6421 /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/
6422 size_t bytewidth = (bpp + 7u) / 8u;
6423 const unsigned char * prevline = 0;
6424 unsigned x, y;
6425 unsigned error = 0;
6426 LodePNGFilterStrategy strategy = settings->filter_strategy;
6427
6428 /*
6429 There is a heuristic called the minimum sum of absolute differences heuristic, suggested by the PNG standard:
6430 * If the image type is Palette, or the bit depth is smaller than 8, then do not filter the image (i.e.
6431 use fixed filtering, with the filter None).
6432 * (The other case) If the image type is Grayscale or RGB (with or without Alpha), and the bit depth is
6433 not smaller than 8, then use adaptive filtering heuristic as follows: independently for each row, apply
6434 all five filters and select the filter that produces the smallest sum of absolute values per row.
6435 This heuristic is used if filter strategy is LFS_MINSUM and filter_palette_zero is true.
6436
6437 If filter_palette_zero is true and filter_strategy is not LFS_MINSUM, the above heuristic is followed,
6438 but for "the other case", whatever strategy filter_strategy is set to instead of the minimum sum
6439 heuristic is used.
6440 */
6441 if(settings->filter_palette_zero &&
6442 (color->colortype == LCT_PALETTE || color->bitdepth < 8)) strategy = LFS_ZERO;
6443
6444 if(bpp == 0) return 31; /*error: invalid color type*/
6445
6446 if(strategy >= LFS_ZERO && strategy <= LFS_FOUR) {
6447 unsigned char type = (unsigned char)strategy;
6448 for(y = 0; y != h; ++y) {
6449 size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
6450 size_t inindex = linebytes * y;
6451 out[outindex] = type; /*filter type byte*/
6452 filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type);
6453 prevline = &in[inindex];
6454 }
6455 }
6456 else if(strategy == LFS_MINSUM) {
6457 /*adaptive filtering*/
6458 unsigned char * attempt[5]; /*five filtering attempts, one for each filter type*/
6459 size_t smallest = 0;
6460 unsigned char type, bestType = 0;
6461
6462 for(type = 0; type != 5; ++type) {
6463 attempt[type] = (unsigned char *)lodepng_malloc(linebytes);
6464 if(!attempt[type]) error = 83; /*alloc fail*/
6465 }
6466
6467 if(!error) {
6468 for(y = 0; y != h; ++y) {
6469 /*try the 5 filter types*/
6470 for(type = 0; type != 5; ++type) {
6471 size_t sum = 0;
6472 filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type);
6473
6474 /*calculate the sum of the result*/
6475 if(type == 0) {
6476 for(x = 0; x != linebytes; ++x) sum += (unsigned char)(attempt[type][x]);
6477 }
6478 else {
6479 for(x = 0; x != linebytes; ++x) {
6480 /*For differences, each byte should be treated as signed, values above 127 are negative
6481 (converted to signed char). Filtertype 0 isn't a difference though, so use unsigned there.
6482 This means filtertype 0 is almost never chosen, but that is justified.*/
6483 unsigned char s = attempt[type][x];
6484 sum += s < 128 ? s : (255U - s);
6485 }
6486 }
6487
6488 /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/
6489 if(type == 0 || sum < smallest) {
6490 bestType = type;
6491 smallest = sum;
6492 }
6493 }
6494
6495 prevline = &in[y * linebytes];
6496
6497 /*now fill the out values*/
6498 out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
6499 for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x];
6500 }
6501 }
6502
6503 for(type = 0; type != 5; ++type) lodepng_free(attempt[type]);
6504 }
6505 else if(strategy == LFS_ENTROPY) {
6506 unsigned char * attempt[5]; /*five filtering attempts, one for each filter type*/
6507 size_t bestSum = 0;
6508 unsigned type, bestType = 0;
6509 unsigned count[256];
6510
6511 for(type = 0; type != 5; ++type) {
6512 attempt[type] = (unsigned char *)lodepng_malloc(linebytes);
6513 if(!attempt[type]) error = 83; /*alloc fail*/
6514 }
6515
6516 if(!error) {
6517 for(y = 0; y != h; ++y) {
6518 /*try the 5 filter types*/
6519 for(type = 0; type != 5; ++type) {
6520 size_t sum = 0;
6521 filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type);
6522 lodepng_memset(count, 0, 256 * sizeof(*count));
6523 for(x = 0; x != linebytes; ++x) ++count[attempt[type][x]];
6524 ++count[type]; /*the filter type itself is part of the scanline*/
6525 for(x = 0; x != 256; ++x) {
6526 sum += ilog2i(count[x]);
6527 }
6528 /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/
6529 if(type == 0 || sum > bestSum) {
6530 bestType = type;
6531 bestSum = sum;
6532 }
6533 }
6534
6535 prevline = &in[y * linebytes];
6536
6537 /*now fill the out values*/
6538 out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
6539 for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x];
6540 }
6541 }
6542
6543 for(type = 0; type != 5; ++type) lodepng_free(attempt[type]);
6544 }
6545 else if(strategy == LFS_PREDEFINED) {
6546 for(y = 0; y != h; ++y) {
6547 size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/
6548 size_t inindex = linebytes * y;
6549 unsigned char type = settings->predefined_filters[y];
6550 out[outindex] = type; /*filter type byte*/
6551 filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type);
6552 prevline = &in[inindex];
6553 }
6554 }
6555 else if(strategy == LFS_BRUTE_FORCE) {
6556 /*brute force filter chooser.
6557 deflate the scanline after every filter attempt to see which one deflates best.
6558 This is very slow and gives only slightly smaller, sometimes even larger, result*/
6559 size_t size[5];
6560 unsigned char * attempt[5]; /*five filtering attempts, one for each filter type*/
6561 size_t smallest = 0;
6562 unsigned type = 0, bestType = 0;
6563 unsigned char * dummy;
6564 LodePNGCompressSettings zlibsettings;
6565 lodepng_memcpy(&zlibsettings, &settings->zlibsettings, sizeof(LodePNGCompressSettings));
6566 /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose,
6567 to simulate the true case where the tree is the same for the whole image. Sometimes it gives
6568 better result with dynamic tree anyway. Using the fixed tree sometimes gives worse, but in rare
6569 cases better compression. It does make this a bit less slow, so it's worth doing this.*/
6570 zlibsettings.btype = 1;
6571 /*a custom encoder likely doesn't read the btype setting and is optimized for complete PNG
6572 images only, so disable it*/
6573 zlibsettings.custom_zlib = 0;
6574 zlibsettings.custom_deflate = 0;
6575 for(type = 0; type != 5; ++type) {
6576 attempt[type] = (unsigned char *)lodepng_malloc(linebytes);
6577 if(!attempt[type]) error = 83; /*alloc fail*/
6578 }
6579 if(!error) {
6580 for(y = 0; y != h; ++y) { /*try the 5 filter types*/
6581 for(type = 0; type != 5; ++type) {
6582 unsigned testsize = (unsigned)linebytes;
6583 /*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/
6584
6585 filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type);
6586 size[type] = 0;
6587 dummy = 0;
6588 zlib_compress(&dummy, &size[type], attempt[type], testsize, &zlibsettings);
6589 lodepng_free(dummy);
6590 /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/
6591 if(type == 0 || size[type] < smallest) {
6592 bestType = type;
6593 smallest = size[type];
6594 }
6595 }
6596 prevline = &in[y * linebytes];
6597 out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/
6598 for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x];
6599 }
6600 }
6601 for(type = 0; type != 5; ++type) lodepng_free(attempt[type]);
6602 }
6603 else return 88; /* unknown filter strategy */
6604
6605 return error;
6606 }
6607
addPaddingBits(unsigned char * out,const unsigned char * in,size_t olinebits,size_t ilinebits,unsigned h)6608 static void addPaddingBits(unsigned char * out, const unsigned char * in,
6609 size_t olinebits, size_t ilinebits, unsigned h)
6610 {
6611 /*The opposite of the removePaddingBits function
6612 olinebits must be >= ilinebits*/
6613 unsigned y;
6614 size_t diff = olinebits - ilinebits;
6615 size_t obp = 0, ibp = 0; /*bit pointers*/
6616 for(y = 0; y != h; ++y) {
6617 size_t x;
6618 for(x = 0; x < ilinebits; ++x) {
6619 unsigned char bit = readBitFromReversedStream(&ibp, in);
6620 setBitOfReversedStream(&obp, out, bit);
6621 }
6622 /*obp += diff; --> no, fill in some value in the padding bits too, to avoid
6623 "Use of uninitialised value of size ###" warning from valgrind*/
6624 for(x = 0; x != diff; ++x) setBitOfReversedStream(&obp, out, 0);
6625 }
6626 }
6627
6628 /*
6629 in: non-interlaced image with size w*h
6630 out: the same pixels, but re-ordered according to PNG's Adam7 interlacing, with
6631 no padding bits between scanlines, but between reduced images so that each
6632 reduced image starts at a byte.
6633 bpp: bits per pixel
6634 there are no padding bits, not between scanlines, not between reduced images
6635 in has the following size in bits: w * h * bpp.
6636 out is possibly bigger due to padding bits between reduced images
6637 NOTE: comments about padding bits are only relevant if bpp < 8
6638 */
Adam7_interlace(unsigned char * out,const unsigned char * in,unsigned w,unsigned h,unsigned bpp)6639 static void Adam7_interlace(unsigned char * out, const unsigned char * in, unsigned w, unsigned h, unsigned bpp)
6640 {
6641 unsigned passw[7], passh[7];
6642 size_t filter_passstart[8], padded_passstart[8], passstart[8];
6643 unsigned i;
6644
6645 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
6646
6647 if(bpp >= 8) {
6648 for(i = 0; i != 7; ++i) {
6649 unsigned x, y, b;
6650 size_t bytewidth = bpp / 8u;
6651 for(y = 0; y < passh[i]; ++y)
6652 for(x = 0; x < passw[i]; ++x) {
6653 size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth;
6654 size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth;
6655 for(b = 0; b < bytewidth; ++b) {
6656 out[pixeloutstart + b] = in[pixelinstart + b];
6657 }
6658 }
6659 }
6660 }
6661 else { /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/
6662 for(i = 0; i != 7; ++i) {
6663 unsigned x, y, b;
6664 unsigned ilinebits = bpp * passw[i];
6665 unsigned olinebits = bpp * w;
6666 size_t obp, ibp; /*bit pointers (for out and in buffer)*/
6667 for(y = 0; y < passh[i]; ++y)
6668 for(x = 0; x < passw[i]; ++x) {
6669 ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp;
6670 obp = (8 * passstart[i]) + (y * ilinebits + x * bpp);
6671 for(b = 0; b < bpp; ++b) {
6672 unsigned char bit = readBitFromReversedStream(&ibp, in);
6673 setBitOfReversedStream(&obp, out, bit);
6674 }
6675 }
6676 }
6677 }
6678 }
6679
6680 /*out must be buffer big enough to contain uncompressed IDAT chunk data, and in must contain the full image.
6681 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)6682 static unsigned preProcessScanlines(unsigned char ** out, size_t * outsize, const unsigned char * in,
6683 unsigned w, unsigned h,
6684 const LodePNGInfo * info_png, const LodePNGEncoderSettings * settings)
6685 {
6686 /*
6687 This function converts the pure 2D image with the PNG's colortype, into filtered-padded-interlaced data. Steps:
6688 *) if no Adam7: 1) add padding bits (= possible extra bits per scanline if bpp < 8) 2) filter
6689 *) if adam7: 1) Adam7_interlace 2) 7x add padding bits 3) 7x filter
6690 */
6691 unsigned bpp = lodepng_get_bpp(&info_png->color);
6692 unsigned error = 0;
6693
6694 if(info_png->interlace_method == 0) {
6695 *outsize = h + (h * ((w * bpp + 7u) / 8u)); /*image size plus an extra byte per scanline + possible padding bits*/
6696 *out = (unsigned char *)lodepng_malloc(*outsize);
6697 if(!(*out) && (*outsize)) error = 83; /*alloc fail*/
6698
6699 if(!error) {
6700 /*non multiple of 8 bits per scanline, padding bits needed per scanline*/
6701 if(bpp < 8 && w * bpp != ((w * bpp + 7u) / 8u) * 8u) {
6702 unsigned char * padded = (unsigned char *)lodepng_malloc(h * ((w * bpp + 7u) / 8u));
6703 if(!padded) error = 83; /*alloc fail*/
6704 if(!error) {
6705 addPaddingBits(padded, in, ((w * bpp + 7u) / 8u) * 8u, w * bpp, h);
6706 error = filter(*out, padded, w, h, &info_png->color, settings);
6707 }
6708 lodepng_free(padded);
6709 }
6710 else {
6711 /*we can immediately filter into the out buffer, no other steps needed*/
6712 error = filter(*out, in, w, h, &info_png->color, settings);
6713 }
6714 }
6715 }
6716 else { /*interlace_method is 1 (Adam7)*/
6717 unsigned passw[7], passh[7];
6718 size_t filter_passstart[8], padded_passstart[8], passstart[8];
6719 unsigned char * adam7;
6720
6721 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
6722
6723 *outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/
6724 *out = (unsigned char *)lodepng_malloc(*outsize);
6725 if(!(*out)) error = 83; /*alloc fail*/
6726
6727 adam7 = (unsigned char *)lodepng_malloc(passstart[7]);
6728 if(!adam7 && passstart[7]) error = 83; /*alloc fail*/
6729
6730 if(!error) {
6731 unsigned i;
6732
6733 Adam7_interlace(adam7, in, w, h, bpp);
6734 for(i = 0; i != 7; ++i) {
6735 if(bpp < 8) {
6736 unsigned char * padded = (unsigned char *)lodepng_malloc(padded_passstart[i + 1] - padded_passstart[i]);
6737 if(!padded) ERROR_BREAK(83); /*alloc fail*/
6738 addPaddingBits(padded, &adam7[passstart[i]],
6739 ((passw[i] * bpp + 7u) / 8u) * 8u, passw[i] * bpp, passh[i]);
6740 error = filter(&(*out)[filter_passstart[i]], padded,
6741 passw[i], passh[i], &info_png->color, settings);
6742 lodepng_free(padded);
6743 }
6744 else {
6745 error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]],
6746 passw[i], passh[i], &info_png->color, settings);
6747 }
6748
6749 if(error) break;
6750 }
6751 }
6752
6753 lodepng_free(adam7);
6754 }
6755
6756 return error;
6757 }
6758
6759 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
addUnknownChunks(ucvector * out,unsigned char * data,size_t datasize)6760 static unsigned addUnknownChunks(ucvector * out, unsigned char * data, size_t datasize)
6761 {
6762 unsigned char * inchunk = data;
6763 while((size_t)(inchunk - data) < datasize) {
6764 CERROR_TRY_RETURN(lodepng_chunk_append(&out->data, &out->size, inchunk));
6765 out->allocsize = out->size; /*fix the allocsize again*/
6766 inchunk = lodepng_chunk_next(inchunk, data + datasize);
6767 }
6768 return 0;
6769 }
6770
isGrayICCProfile(const unsigned char * profile,unsigned size)6771 static unsigned isGrayICCProfile(const unsigned char * profile, unsigned size)
6772 {
6773 /*
6774 It is a gray profile if bytes 16-19 are "GRAY", rgb profile if bytes 16-19
6775 are "RGB ". We do not perform any full parsing of the ICC profile here, other
6776 than check those 4 bytes to grayscale profile. Other than that, validity of
6777 the profile is not checked. This is needed only because the PNG specification
6778 requires using a non-gray color model if there is an ICC profile with "RGB "
6779 (sadly limiting compression opportunities if the input data is grayscale RGB
6780 data), and requires using a gray color model if it is "GRAY".
6781 */
6782 if(size < 20) return 0;
6783 return profile[16] == 'G' && profile[17] == 'R' && profile[18] == 'A' && profile[19] == 'Y';
6784 }
6785
isRGBICCProfile(const unsigned char * profile,unsigned size)6786 static unsigned isRGBICCProfile(const unsigned char * profile, unsigned size)
6787 {
6788 /* See comment in isGrayICCProfile*/
6789 if(size < 20) return 0;
6790 return profile[16] == 'R' && profile[17] == 'G' && profile[18] == 'B' && profile[19] == ' ';
6791 }
6792 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
6793
lodepng_encode(unsigned char ** out,size_t * outsize,const unsigned char * image,unsigned w,unsigned h,LodePNGState * state)6794 unsigned lodepng_encode(unsigned char ** out, size_t * outsize,
6795 const unsigned char * image, unsigned w, unsigned h,
6796 LodePNGState * state)
6797 {
6798 unsigned char * data = 0; /*uncompressed version of the IDAT chunk data*/
6799 size_t datasize = 0;
6800 ucvector outv = ucvector_init(NULL, 0);
6801 LodePNGInfo info;
6802 const LodePNGInfo * info_png = &state->info_png;
6803 LodePNGColorMode auto_color;
6804
6805 lodepng_info_init(&info);
6806 lodepng_color_mode_init(&auto_color);
6807
6808 /*provide some proper output values if error will happen*/
6809 *out = 0;
6810 *outsize = 0;
6811 state->error = 0;
6812
6813 /*check input values validity*/
6814 if((info_png->color.colortype == LCT_PALETTE || state->encoder.force_palette)
6815 && (info_png->color.palettesize == 0 || info_png->color.palettesize > 256)) {
6816 /*this error is returned even if auto_convert is enabled and thus encoder could
6817 generate the palette by itself: while allowing this could be possible in theory,
6818 it may complicate the code or edge cases, and always requiring to give a palette
6819 when setting this color type is a simpler contract*/
6820 state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/
6821 goto cleanup;
6822 }
6823 if(state->encoder.zlibsettings.btype > 2) {
6824 state->error = 61; /*error: invalid btype*/
6825 goto cleanup;
6826 }
6827 if(info_png->interlace_method > 1) {
6828 state->error = 71; /*error: invalid interlace mode*/
6829 goto cleanup;
6830 }
6831 state->error = checkColorValidity(info_png->color.colortype, info_png->color.bitdepth);
6832 if(state->error) goto cleanup; /*error: invalid color type given*/
6833 state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth);
6834 if(state->error) goto cleanup; /*error: invalid color type given*/
6835
6836 /* color convert and compute scanline filter types */
6837 lodepng_info_copy(&info, &state->info_png);
6838 if(state->encoder.auto_convert) {
6839 LodePNGColorStats stats;
6840 unsigned allow_convert = 1;
6841 lodepng_color_stats_init(&stats);
6842 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6843 if(info_png->iccp_defined &&
6844 isGrayICCProfile(info_png->iccp_profile, info_png->iccp_profile_size)) {
6845 /*the PNG specification does not allow to use palette with a GRAY ICC profile, even
6846 if the palette has only gray colors, so disallow it.*/
6847 stats.allow_palette = 0;
6848 }
6849 if(info_png->iccp_defined &&
6850 isRGBICCProfile(info_png->iccp_profile, info_png->iccp_profile_size)) {
6851 /*the PNG specification does not allow to use grayscale color with RGB ICC profile, so disallow gray.*/
6852 stats.allow_greyscale = 0;
6853 }
6854 #endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */
6855 state->error = lodepng_compute_color_stats(&stats, image, w, h, &state->info_raw);
6856 if(state->error) goto cleanup;
6857 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6858 if(info_png->background_defined) {
6859 /*the background chunk's color must be taken into account as well*/
6860 unsigned r = 0, g = 0, b = 0;
6861 LodePNGColorMode mode16 = lodepng_color_mode_make(LCT_RGB, 16);
6862 lodepng_convert_rgb(&r, &g, &b,
6863 info_png->background_r, info_png->background_g, info_png->background_b, &mode16, &info_png->color);
6864 state->error = lodepng_color_stats_add(&stats, r, g, b, 65535);
6865 if(state->error) goto cleanup;
6866 }
6867 #endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */
6868 state->error = auto_choose_color(&auto_color, &state->info_raw, &stats);
6869 if(state->error) goto cleanup;
6870 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6871 if(info_png->sbit_defined) {
6872 /*if sbit is defined, due to strict requirements of which sbit values can be present for which color modes,
6873 auto_convert can't be done in many cases. However, do support a few cases here.
6874 TODO: more conversions may be possible, and it may also be possible to get a more appropriate color type out of
6875 auto_choose_color if knowledge about sbit is used beforehand
6876 */
6877 unsigned sbit_max = LODEPNG_MAX(LODEPNG_MAX(LODEPNG_MAX(info_png->sbit_r, info_png->sbit_g),
6878 info_png->sbit_b), info_png->sbit_a);
6879 unsigned equal = (!info_png->sbit_g || info_png->sbit_g == info_png->sbit_r)
6880 && (!info_png->sbit_b || info_png->sbit_b == info_png->sbit_r)
6881 && (!info_png->sbit_a || info_png->sbit_a == info_png->sbit_r);
6882 allow_convert = 0;
6883 if(info.color.colortype == LCT_PALETTE &&
6884 auto_color.colortype == LCT_PALETTE) {
6885 /* input and output are palette, and in this case it may happen that palette data is
6886 expected to be copied from info_raw into the info_png */
6887 allow_convert = 1;
6888 }
6889 /*going from 8-bit RGB to palette (or 16-bit as long as sbit_max <= 8) is possible
6890 since both are 8-bit RGB for sBIT's purposes*/
6891 if(info.color.colortype == LCT_RGB &&
6892 auto_color.colortype == LCT_PALETTE && sbit_max <= 8) {
6893 allow_convert = 1;
6894 }
6895 /*going from 8-bit RGBA to palette is also ok but only if sbit_a is exactly 8*/
6896 if(info.color.colortype == LCT_RGBA && auto_color.colortype == LCT_PALETTE &&
6897 info_png->sbit_a == 8 && sbit_max <= 8) {
6898 allow_convert = 1;
6899 }
6900 /*going from 16-bit RGB(A) to 8-bit RGB(A) is ok if all sbit values are <= 8*/
6901 if((info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA) && info.color.bitdepth == 16 &&
6902 auto_color.colortype == info.color.colortype && auto_color.bitdepth == 8 &&
6903 sbit_max <= 8) {
6904 allow_convert = 1;
6905 }
6906 /*going to less channels is ok if all bit values are equal (all possible values in sbit,
6907 as well as the chosen bitdepth of the result). Due to how auto_convert works,
6908 we already know that auto_color.colortype has less than or equal amount of channels than
6909 info.colortype. Palette is not used here. This conversion is not allowed if
6910 info_png->sbit_r < auto_color.bitdepth, because specifically for alpha, non-presence of
6911 an sbit value heavily implies that alpha's bit depth is equal to the PNG bit depth (rather
6912 than the bit depths set in the r, g and b sbit values, by how the PNG specification describes
6913 handling tRNS chunk case with sBIT), so be conservative here about ignoring user input.*/
6914 if(info.color.colortype != LCT_PALETTE && auto_color.colortype != LCT_PALETTE &&
6915 equal && info_png->sbit_r == auto_color.bitdepth) {
6916 allow_convert = 1;
6917 }
6918 }
6919 #endif
6920 if(state->encoder.force_palette) {
6921 if(info.color.colortype != LCT_GREY && info.color.colortype != LCT_GREY_ALPHA &&
6922 (auto_color.colortype == LCT_GREY || auto_color.colortype == LCT_GREY_ALPHA)) {
6923 /*user speficially forced a PLTE palette, so cannot convert to grayscale types because
6924 the PNG specification only allows writing a suggested palette in PLTE for truecolor types*/
6925 allow_convert = 0;
6926 }
6927 }
6928 if(allow_convert) {
6929 lodepng_color_mode_copy(&info.color, &auto_color);
6930 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6931 /*also convert the background chunk*/
6932 if(info_png->background_defined) {
6933 if(lodepng_convert_rgb(&info.background_r, &info.background_g, &info.background_b,
6934 info_png->background_r, info_png->background_g, info_png->background_b, &info.color, &info_png->color)) {
6935 state->error = 104;
6936 goto cleanup;
6937 }
6938 }
6939 #endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */
6940 }
6941 }
6942 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6943 if(info_png->iccp_defined) {
6944 unsigned gray_icc = isGrayICCProfile(info_png->iccp_profile, info_png->iccp_profile_size);
6945 unsigned rgb_icc = isRGBICCProfile(info_png->iccp_profile, info_png->iccp_profile_size);
6946 unsigned gray_png = info.color.colortype == LCT_GREY || info.color.colortype == LCT_GREY_ALPHA;
6947 if(!gray_icc && !rgb_icc) {
6948 state->error = 100; /* Disallowed profile color type for PNG */
6949 goto cleanup;
6950 }
6951 if(gray_icc != gray_png) {
6952 /*Not allowed to use RGB/RGBA/palette with GRAY ICC profile or vice versa,
6953 or in case of auto_convert, it wasn't possible to find appropriate model*/
6954 state->error = state->encoder.auto_convert ? 102 : 101;
6955 goto cleanup;
6956 }
6957 }
6958 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
6959 if(!lodepng_color_mode_equal(&state->info_raw, &info.color)) {
6960 unsigned char * converted;
6961 size_t size = ((size_t)w * (size_t)h * (size_t)lodepng_get_bpp(&info.color) + 7u) / 8u;
6962
6963 converted = (unsigned char *)lodepng_malloc(size);
6964 if(!converted && size) state->error = 83; /*alloc fail*/
6965 if(!state->error) {
6966 state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h);
6967 }
6968 if(!state->error) {
6969 state->error = preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder);
6970 }
6971 lodepng_free(converted);
6972 if(state->error) goto cleanup;
6973 }
6974 else {
6975 state->error = preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder);
6976 if(state->error) goto cleanup;
6977 }
6978
6979 /* output all PNG chunks */ {
6980 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6981 size_t i;
6982 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
6983 /*write signature and chunks*/
6984 state->error = writeSignature(&outv);
6985 if(state->error) goto cleanup;
6986 /*IHDR*/
6987 state->error = addChunk_IHDR(&outv, w, h, info.color.colortype, info.color.bitdepth, info.interlace_method);
6988 if(state->error) goto cleanup;
6989 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
6990 /*unknown chunks between IHDR and PLTE*/
6991 if(info.unknown_chunks_data[0]) {
6992 state->error = addUnknownChunks(&outv, info.unknown_chunks_data[0], info.unknown_chunks_size[0]);
6993 if(state->error) goto cleanup;
6994 }
6995 /*color profile chunks must come before PLTE */
6996 if(info.iccp_defined) {
6997 state->error = addChunk_iCCP(&outv, &info, &state->encoder.zlibsettings);
6998 if(state->error) goto cleanup;
6999 }
7000 if(info.srgb_defined) {
7001 state->error = addChunk_sRGB(&outv, &info);
7002 if(state->error) goto cleanup;
7003 }
7004 if(info.gama_defined) {
7005 state->error = addChunk_gAMA(&outv, &info);
7006 if(state->error) goto cleanup;
7007 }
7008 if(info.chrm_defined) {
7009 state->error = addChunk_cHRM(&outv, &info);
7010 if(state->error) goto cleanup;
7011 }
7012 if(info_png->sbit_defined) {
7013 state->error = addChunk_sBIT(&outv, &info);
7014 if(state->error) goto cleanup;
7015 }
7016 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
7017 /*PLTE*/
7018 if(info.color.colortype == LCT_PALETTE) {
7019 state->error = addChunk_PLTE(&outv, &info.color);
7020 if(state->error) goto cleanup;
7021 }
7022 if(state->encoder.force_palette && (info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA)) {
7023 /*force_palette means: write suggested palette for truecolor in PLTE chunk*/
7024 state->error = addChunk_PLTE(&outv, &info.color);
7025 if(state->error) goto cleanup;
7026 }
7027 /*tRNS (this will only add if when necessary) */
7028 state->error = addChunk_tRNS(&outv, &info.color);
7029 if(state->error) goto cleanup;
7030 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
7031 /*bKGD (must come between PLTE and the IDAt chunks*/
7032 if(info.background_defined) {
7033 state->error = addChunk_bKGD(&outv, &info);
7034 if(state->error) goto cleanup;
7035 }
7036 /*pHYs (must come before the IDAT chunks)*/
7037 if(info.phys_defined) {
7038 state->error = addChunk_pHYs(&outv, &info);
7039 if(state->error) goto cleanup;
7040 }
7041
7042 /*unknown chunks between PLTE and IDAT*/
7043 if(info.unknown_chunks_data[1]) {
7044 state->error = addUnknownChunks(&outv, info.unknown_chunks_data[1], info.unknown_chunks_size[1]);
7045 if(state->error) goto cleanup;
7046 }
7047 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
7048 /*IDAT (multiple IDAT chunks must be consecutive)*/
7049 state->error = addChunk_IDAT(&outv, data, datasize, &state->encoder.zlibsettings);
7050 if(state->error) goto cleanup;
7051 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
7052 /*tIME*/
7053 if(info.time_defined) {
7054 state->error = addChunk_tIME(&outv, &info.time);
7055 if(state->error) goto cleanup;
7056 }
7057 /*tEXt and/or zTXt*/
7058 for(i = 0; i != info.text_num; ++i) {
7059 if(lodepng_strlen(info.text_keys[i]) > 79) {
7060 state->error = 66; /*text chunk too large*/
7061 goto cleanup;
7062 }
7063 if(lodepng_strlen(info.text_keys[i]) < 1) {
7064 state->error = 67; /*text chunk too small*/
7065 goto cleanup;
7066 }
7067 if(state->encoder.text_compression) {
7068 state->error = addChunk_zTXt(&outv, info.text_keys[i], info.text_strings[i], &state->encoder.zlibsettings);
7069 if(state->error) goto cleanup;
7070 }
7071 else {
7072 state->error = addChunk_tEXt(&outv, info.text_keys[i], info.text_strings[i]);
7073 if(state->error) goto cleanup;
7074 }
7075 }
7076 /*LodePNG version id in text chunk*/
7077 if(state->encoder.add_id) {
7078 unsigned already_added_id_text = 0;
7079 for(i = 0; i != info.text_num; ++i) {
7080 const char * k = info.text_keys[i];
7081 /* Could use strcmp, but we're not calling or reimplementing this C library function for this use only */
7082 if(k[0] == 'L' && k[1] == 'o' && k[2] == 'd' && k[3] == 'e' &&
7083 k[4] == 'P' && k[5] == 'N' && k[6] == 'G' && k[7] == '\0') {
7084 already_added_id_text = 1;
7085 break;
7086 }
7087 }
7088 if(already_added_id_text == 0) {
7089 state->error = addChunk_tEXt(&outv, "LodePNG", LODEPNG_VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/
7090 if(state->error) goto cleanup;
7091 }
7092 }
7093 /*iTXt*/
7094 for(i = 0; i != info.itext_num; ++i) {
7095 if(lodepng_strlen(info.itext_keys[i]) > 79) {
7096 state->error = 66; /*text chunk too large*/
7097 goto cleanup;
7098 }
7099 if(lodepng_strlen(info.itext_keys[i]) < 1) {
7100 state->error = 67; /*text chunk too small*/
7101 goto cleanup;
7102 }
7103 state->error = addChunk_iTXt(
7104 &outv, state->encoder.text_compression,
7105 info.itext_keys[i], info.itext_langtags[i], info.itext_transkeys[i], info.itext_strings[i],
7106 &state->encoder.zlibsettings);
7107 if(state->error) goto cleanup;
7108 }
7109
7110 /*unknown chunks between IDAT and IEND*/
7111 if(info.unknown_chunks_data[2]) {
7112 state->error = addUnknownChunks(&outv, info.unknown_chunks_data[2], info.unknown_chunks_size[2]);
7113 if(state->error) goto cleanup;
7114 }
7115 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
7116 state->error = addChunk_IEND(&outv);
7117 if(state->error) goto cleanup;
7118 }
7119
7120 cleanup:
7121 lodepng_info_cleanup(&info);
7122 lodepng_free(data);
7123 lodepng_color_mode_cleanup(&auto_color);
7124
7125 /*instead of cleaning the vector up, give it to the output*/
7126 *out = outv.data;
7127 *outsize = outv.size;
7128
7129 return state->error;
7130 }
7131
lodepng_encode_memory(unsigned char ** out,size_t * outsize,const unsigned char * image,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)7132 unsigned lodepng_encode_memory(unsigned char ** out, size_t * outsize, const unsigned char * image,
7133 unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth)
7134 {
7135 unsigned error;
7136 LodePNGState state;
7137 lodepng_state_init(&state);
7138 state.info_raw.colortype = colortype;
7139 state.info_raw.bitdepth = bitdepth;
7140 state.info_png.color.colortype = colortype;
7141 state.info_png.color.bitdepth = bitdepth;
7142 lodepng_encode(out, outsize, image, w, h, &state);
7143 error = state.error;
7144 lodepng_state_cleanup(&state);
7145 return error;
7146 }
7147
lodepng_encode32(unsigned char ** out,size_t * outsize,const unsigned char * image,unsigned w,unsigned h)7148 unsigned lodepng_encode32(unsigned char ** out, size_t * outsize, const unsigned char * image, unsigned w, unsigned h)
7149 {
7150 return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGBA, 8);
7151 }
7152
lodepng_encode24(unsigned char ** out,size_t * outsize,const unsigned char * image,unsigned w,unsigned h)7153 unsigned lodepng_encode24(unsigned char ** out, size_t * outsize, const unsigned char * image, unsigned w, unsigned h)
7154 {
7155 return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGB, 8);
7156 }
7157
7158 #ifdef LODEPNG_COMPILE_DISK
lodepng_encode_file(const char * filename,const unsigned char * image,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)7159 unsigned lodepng_encode_file(const char * filename, const unsigned char * image, unsigned w, unsigned h,
7160 LodePNGColorType colortype, unsigned bitdepth)
7161 {
7162 unsigned char * buffer;
7163 size_t buffersize;
7164 unsigned error = lodepng_encode_memory(&buffer, &buffersize, image, w, h, colortype, bitdepth);
7165 if(!error) error = lodepng_save_file(buffer, buffersize, filename);
7166 lodepng_free(buffer);
7167 return error;
7168 }
7169
lodepng_encode32_file(const char * filename,const unsigned char * image,unsigned w,unsigned h)7170 unsigned lodepng_encode32_file(const char * filename, const unsigned char * image, unsigned w, unsigned h)
7171 {
7172 return lodepng_encode_file(filename, image, w, h, LCT_RGBA, 8);
7173 }
7174
lodepng_encode24_file(const char * filename,const unsigned char * image,unsigned w,unsigned h)7175 unsigned lodepng_encode24_file(const char * filename, const unsigned char * image, unsigned w, unsigned h)
7176 {
7177 return lodepng_encode_file(filename, image, w, h, LCT_RGB, 8);
7178 }
7179 #endif /*LODEPNG_COMPILE_DISK*/
7180
lodepng_encoder_settings_init(LodePNGEncoderSettings * settings)7181 void lodepng_encoder_settings_init(LodePNGEncoderSettings * settings)
7182 {
7183 lodepng_compress_settings_init(&settings->zlibsettings);
7184 settings->filter_palette_zero = 1;
7185 settings->filter_strategy = LFS_MINSUM;
7186 settings->auto_convert = 1;
7187 settings->force_palette = 0;
7188 settings->predefined_filters = 0;
7189 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
7190 settings->add_id = 0;
7191 settings->text_compression = 1;
7192 #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
7193 }
7194
7195 #endif /*LODEPNG_COMPILE_ENCODER*/
7196 #endif /*LODEPNG_COMPILE_PNG*/
7197
7198 #ifdef LODEPNG_COMPILE_ERROR_TEXT
7199 /*
7200 This returns the description of a numerical error code in English. This is also
7201 the documentation of all the error codes.
7202 */
lodepng_error_text(unsigned code)7203 const char * lodepng_error_text(unsigned code)
7204 {
7205 switch(code) {
7206 case 0:
7207 return "no error, everything went ok";
7208 case 1:
7209 return "nothing done yet"; /*the Encoder/Decoder has done nothing yet, error checking makes no sense yet*/
7210 case 10:
7211 return "end of input memory reached without huffman end code"; /*while huffman decoding*/
7212 case 11:
7213 return "error in code tree made it jump outside of huffman tree"; /*while huffman decoding*/
7214 case 13:
7215 return "problem while processing dynamic deflate block";
7216 case 14:
7217 return "problem while processing dynamic deflate block";
7218 case 15:
7219 return "problem while processing dynamic deflate block";
7220 /*this error could happen if there are only 0 or 1 symbols present in the huffman code:*/
7221 case 16:
7222 return "invalid code while processing dynamic deflate block";
7223 case 17:
7224 return "end of out buffer memory reached while inflating";
7225 case 18:
7226 return "invalid distance code while inflating";
7227 case 19:
7228 return "end of out buffer memory reached while inflating";
7229 case 20:
7230 return "invalid deflate block BTYPE encountered while decoding";
7231 case 21:
7232 return "NLEN is not ones complement of LEN in a deflate block";
7233
7234 /*end of out buffer memory reached while inflating:
7235 This can happen if the inflated deflate data is longer than the amount of bytes required to fill up
7236 all the pixels of the image, given the color depth and image dimensions. Something that doesn't
7237 happen in a normal, well encoded, PNG image.*/
7238 case 22:
7239 return "end of out buffer memory reached while inflating";
7240 case 23:
7241 return "end of in buffer memory reached while inflating";
7242 case 24:
7243 return "invalid FCHECK in zlib header";
7244 case 25:
7245 return "invalid compression method in zlib header";
7246 case 26:
7247 return "FDICT encountered in zlib header while it's not used for PNG";
7248 case 27:
7249 return "PNG file is smaller than a PNG header";
7250 /*Checks the magic file header, the first 8 bytes of the PNG file*/
7251 case 28:
7252 return "incorrect PNG signature, it's no PNG or corrupted";
7253 case 29:
7254 return "first chunk is not the header chunk";
7255 case 30:
7256 return "chunk length too large, chunk broken off at end of file";
7257 case 31:
7258 return "illegal PNG color type or bpp";
7259 case 32:
7260 return "illegal PNG compression method";
7261 case 33:
7262 return "illegal PNG filter method";
7263 case 34:
7264 return "illegal PNG interlace method";
7265 case 35:
7266 return "chunk length of a chunk is too large or the chunk too small";
7267 case 36:
7268 return "illegal PNG filter type encountered";
7269 case 37:
7270 return "illegal bit depth for this color type given";
7271 case 38:
7272 return "the palette is too small or too big"; /*0, or more than 256 colors*/
7273 case 39:
7274 return "tRNS chunk before PLTE or has more entries than palette size";
7275 case 40:
7276 return "tRNS chunk has wrong size for grayscale image";
7277 case 41:
7278 return "tRNS chunk has wrong size for RGB image";
7279 case 42:
7280 return "tRNS chunk appeared while it was not allowed for this color type";
7281 case 43:
7282 return "bKGD chunk has wrong size for palette image";
7283 case 44:
7284 return "bKGD chunk has wrong size for grayscale image";
7285 case 45:
7286 return "bKGD chunk has wrong size for RGB image";
7287 case 48:
7288 return "empty input buffer given to decoder. Maybe caused by non-existing file?";
7289 case 49:
7290 return "jumped past memory while generating dynamic huffman tree";
7291 case 50:
7292 return "jumped past memory while generating dynamic huffman tree";
7293 case 51:
7294 return "jumped past memory while inflating huffman block";
7295 case 52:
7296 return "jumped past memory while inflating";
7297 case 53:
7298 return "size of zlib data too small";
7299 case 54:
7300 return "repeat symbol in tree while there was no value symbol yet";
7301 /*jumped past tree while generating huffman tree, this could be when the
7302 tree will have more leaves than symbols after generating it out of the
7303 given lengths. They call this an oversubscribed dynamic bit lengths tree in zlib.*/
7304 case 55:
7305 return "jumped past tree while generating huffman tree";
7306 case 56:
7307 return "given output image colortype or bitdepth not supported for color conversion";
7308 case 57:
7309 return "invalid CRC encountered (checking CRC can be disabled)";
7310 case 58:
7311 return "invalid ADLER32 encountered (checking ADLER32 can be disabled)";
7312 case 59:
7313 return "requested color conversion not supported";
7314 case 60:
7315 return "invalid window size given in the settings of the encoder (must be 0-32768)";
7316 case 61:
7317 return "invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)";
7318 /*LodePNG leaves the choice of RGB to grayscale conversion formula to the user.*/
7319 case 62:
7320 return "conversion from color to grayscale not supported";
7321 /*(2^31-1)*/
7322 case 63:
7323 return "length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk";
7324 /*this would result in the inability of a deflated block to ever contain an end code. It must be at least 1.*/
7325 case 64:
7326 return "the length of the END symbol 256 in the Huffman tree is 0";
7327 case 66:
7328 return "the length of a text chunk keyword given to the encoder is longer than the maximum of 79 bytes";
7329 case 67:
7330 return "the length of a text chunk keyword given to the encoder is smaller than the minimum of 1 byte";
7331 case 68:
7332 return "tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors";
7333 case 69:
7334 return "unknown chunk type with 'critical' flag encountered by the decoder";
7335 case 71:
7336 return "invalid interlace mode given to encoder (must be 0 or 1)";
7337 case 72:
7338 return "while decoding, invalid compression method encountering in zTXt or iTXt chunk (it must be 0)";
7339 case 73:
7340 return "invalid tIME chunk size";
7341 case 74:
7342 return "invalid pHYs chunk size";
7343 /*length could be wrong, or data chopped off*/
7344 case 75:
7345 return "no null termination char found while decoding text chunk";
7346 case 76:
7347 return "iTXt chunk too short to contain required bytes";
7348 case 77:
7349 return "integer overflow in buffer size";
7350 case 78:
7351 return "failed to open file for reading"; /*file doesn't exist or couldn't be opened for reading*/
7352 case 79:
7353 return "failed to open file for writing";
7354 case 80:
7355 return "tried creating a tree of 0 symbols";
7356 case 81:
7357 return "lazy matching at pos 0 is impossible";
7358 case 82:
7359 return "color conversion to palette requested while a color isn't in palette, or index out of bounds";
7360 case 83:
7361 return "memory allocation failed";
7362 case 84:
7363 return "given image too small to contain all pixels to be encoded";
7364 case 86:
7365 return "impossible offset in lz77 encoding (internal bug)";
7366 case 87:
7367 return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined";
7368 case 88:
7369 return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy";
7370 case 89:
7371 return "text chunk keyword too short or long: must have size 1-79";
7372 /*the windowsize in the LodePNGCompressSettings. Requiring POT(==> & instead of %) makes encoding 12% faster.*/
7373 case 90:
7374 return "windowsize must be a power of two";
7375 case 91:
7376 return "invalid decompressed idat size";
7377 case 92:
7378 return "integer overflow due to too many pixels";
7379 case 93:
7380 return "zero width or height is invalid";
7381 case 94:
7382 return "header chunk must have a size of 13 bytes";
7383 case 95:
7384 return "integer overflow with combined idat chunk size";
7385 case 96:
7386 return "invalid gAMA chunk size";
7387 case 97:
7388 return "invalid cHRM chunk size";
7389 case 98:
7390 return "invalid sRGB chunk size";
7391 case 99:
7392 return "invalid sRGB rendering intent";
7393 case 100:
7394 return "invalid ICC profile color type, the PNG specification only allows RGB or GRAY";
7395 case 101:
7396 return "PNG specification does not allow RGB ICC profile on gray color types and vice versa";
7397 case 102:
7398 return "not allowed to set grayscale ICC profile with colored pixels by PNG specification";
7399 case 103:
7400 return "invalid palette index in bKGD chunk. Maybe it came before PLTE chunk?";
7401 case 104:
7402 return "invalid bKGD color while encoding (e.g. palette index out of range)";
7403 case 105:
7404 return "integer overflow of bitsize";
7405 case 106:
7406 return "PNG file must have PLTE chunk if color type is palette";
7407 case 107:
7408 return "color convert from palette mode requested without setting the palette data in it";
7409 case 108:
7410 return "tried to add more than 256 values to a palette";
7411 /*this limit can be configured in LodePNGDecompressSettings*/
7412 case 109:
7413 return "tried to decompress zlib or deflate data larger than desired max_output_size";
7414 case 110:
7415 return "custom zlib or inflate decompression failed";
7416 case 111:
7417 return "custom zlib or deflate compression failed";
7418 /*max text size limit can be configured in LodePNGDecoderSettings. This error prevents
7419 unreasonable memory consumption when decoding due to impossibly large text sizes.*/
7420 case 112:
7421 return "compressed text unreasonably large";
7422 /*max ICC size limit can be configured in LodePNGDecoderSettings. This error prevents
7423 unreasonable memory consumption when decoding due to impossibly large ICC profile*/
7424 case 113:
7425 return "ICC profile unreasonably large";
7426 case 114:
7427 return "sBIT chunk has wrong size for the color type of the image";
7428 case 115:
7429 return "sBIT value out of range";
7430 }
7431 return "unknown error code";
7432 }
7433 #endif /*LODEPNG_COMPILE_ERROR_TEXT*/
7434
7435 /* ////////////////////////////////////////////////////////////////////////// */
7436 /* ////////////////////////////////////////////////////////////////////////// */
7437 /* // C++ Wrapper // */
7438 /* ////////////////////////////////////////////////////////////////////////// */
7439 /* ////////////////////////////////////////////////////////////////////////// */
7440
7441 #ifdef LODEPNG_COMPILE_CPP
7442 namespace lodepng
7443 {
7444
7445 #ifdef LODEPNG_COMPILE_DISK
load_file(std::vector<unsigned char> & buffer,const std::string & filename)7446 unsigned load_file(std::vector<unsigned char> & buffer, const std::string & filename)
7447 {
7448 long size = lodepng_filesize(filename.c_str());
7449 if(size < 0) return 78;
7450 buffer.resize((size_t)size);
7451 return size == 0 ? 0 : lodepng_buffer_file(&buffer[0], (size_t)size, filename.c_str());
7452 }
7453
7454 /*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)7455 unsigned save_file(const std::vector<unsigned char> & buffer, const std::string & filename)
7456 {
7457 return lodepng_save_file(buffer.empty() ? 0 : &buffer[0], buffer.size(), filename.c_str());
7458 }
7459 #endif /* LODEPNG_COMPILE_DISK */
7460
7461 #ifdef LODEPNG_COMPILE_ZLIB
7462 #ifdef LODEPNG_COMPILE_DECODER
decompress(std::vector<unsigned char> & out,const unsigned char * in,size_t insize,const LodePNGDecompressSettings & settings)7463 unsigned decompress(std::vector<unsigned char> & out, const unsigned char * in, size_t insize,
7464 const LodePNGDecompressSettings & settings)
7465 {
7466 unsigned char * buffer = 0;
7467 size_t buffersize = 0;
7468 unsigned error = zlib_decompress(&buffer, &buffersize, 0, in, insize, &settings);
7469 if(buffer) {
7470 out.insert(out.end(), buffer, &buffer[buffersize]);
7471 lodepng_free(buffer);
7472 }
7473 return error;
7474 }
7475
decompress(std::vector<unsigned char> & out,const std::vector<unsigned char> & in,const LodePNGDecompressSettings & settings)7476 unsigned decompress(std::vector<unsigned char> & out, const std::vector<unsigned char> & in,
7477 const LodePNGDecompressSettings & settings)
7478 {
7479 return decompress(out, in.empty() ? 0 : &in[0], in.size(), settings);
7480 }
7481 #endif /* LODEPNG_COMPILE_DECODER */
7482
7483 #ifdef LODEPNG_COMPILE_ENCODER
compress(std::vector<unsigned char> & out,const unsigned char * in,size_t insize,const LodePNGCompressSettings & settings)7484 unsigned compress(std::vector<unsigned char> & out, const unsigned char * in, size_t insize,
7485 const LodePNGCompressSettings & settings)
7486 {
7487 unsigned char * buffer = 0;
7488 size_t buffersize = 0;
7489 unsigned error = zlib_compress(&buffer, &buffersize, in, insize, &settings);
7490 if(buffer) {
7491 out.insert(out.end(), buffer, &buffer[buffersize]);
7492 lodepng_free(buffer);
7493 }
7494 return error;
7495 }
7496
compress(std::vector<unsigned char> & out,const std::vector<unsigned char> & in,const LodePNGCompressSettings & settings)7497 unsigned compress(std::vector<unsigned char> & out, const std::vector<unsigned char> & in,
7498 const LodePNGCompressSettings & settings)
7499 {
7500 return compress(out, in.empty() ? 0 : &in[0], in.size(), settings);
7501 }
7502 #endif /* LODEPNG_COMPILE_ENCODER */
7503 #endif /* LODEPNG_COMPILE_ZLIB */
7504
7505
7506 #ifdef LODEPNG_COMPILE_PNG
7507
State()7508 State::State()
7509 {
7510 lodepng_state_init(this);
7511 }
7512
State(const State & other)7513 State::State(const State & other)
7514 {
7515 lodepng_state_init(this);
7516 lodepng_state_copy(this, &other);
7517 }
7518
~State()7519 State::~State()
7520 {
7521 lodepng_state_cleanup(this);
7522 }
7523
7524 State & State::operator=(const State & other)
7525 {
7526 lodepng_state_copy(this, &other);
7527 return *this;
7528 }
7529
7530 #ifdef LODEPNG_COMPILE_DECODER
7531
decode(std::vector<unsigned char> & out,unsigned & w,unsigned & h,const unsigned char * in,size_t insize,LodePNGColorType colortype,unsigned bitdepth)7532 unsigned decode(std::vector<unsigned char> & out, unsigned & w, unsigned & h, const unsigned char * in,
7533 size_t insize, LodePNGColorType colortype, unsigned bitdepth)
7534 {
7535 unsigned char * buffer = 0;
7536 unsigned error = lodepng_decode_memory(&buffer, &w, &h, in, insize, colortype, bitdepth);
7537 if(buffer && !error) {
7538 State state;
7539 state.info_raw.colortype = colortype;
7540 state.info_raw.bitdepth = bitdepth;
7541 size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw);
7542 out.insert(out.end(), buffer, &buffer[buffersize]);
7543 }
7544 lodepng_free(buffer);
7545 return error;
7546 }
7547
decode(std::vector<unsigned char> & out,unsigned & w,unsigned & h,const std::vector<unsigned char> & in,LodePNGColorType colortype,unsigned bitdepth)7548 unsigned decode(std::vector<unsigned char> & out, unsigned & w, unsigned & h,
7549 const std::vector<unsigned char> & in, LodePNGColorType colortype, unsigned bitdepth)
7550 {
7551 return decode(out, w, h, in.empty() ? 0 : &in[0], (unsigned)in.size(), colortype, bitdepth);
7552 }
7553
decode(std::vector<unsigned char> & out,unsigned & w,unsigned & h,State & state,const unsigned char * in,size_t insize)7554 unsigned decode(std::vector<unsigned char> & out, unsigned & w, unsigned & h,
7555 State & state,
7556 const unsigned char * in, size_t insize)
7557 {
7558 unsigned char * buffer = NULL;
7559 unsigned error = lodepng_decode(&buffer, &w, &h, &state, in, insize);
7560 if(buffer && !error) {
7561 size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw);
7562 out.insert(out.end(), buffer, &buffer[buffersize]);
7563 }
7564 lodepng_free(buffer);
7565 return error;
7566 }
7567
decode(std::vector<unsigned char> & out,unsigned & w,unsigned & h,State & state,const std::vector<unsigned char> & in)7568 unsigned decode(std::vector<unsigned char> & out, unsigned & w, unsigned & h,
7569 State & state,
7570 const std::vector<unsigned char> & in)
7571 {
7572 return decode(out, w, h, state, in.empty() ? 0 : &in[0], in.size());
7573 }
7574
7575 #ifdef LODEPNG_COMPILE_DISK
decode(std::vector<unsigned char> & out,unsigned & w,unsigned & h,const std::string & filename,LodePNGColorType colortype,unsigned bitdepth)7576 unsigned decode(std::vector<unsigned char> & out, unsigned & w, unsigned & h, const std::string & filename,
7577 LodePNGColorType colortype, unsigned bitdepth)
7578 {
7579 std::vector<unsigned char> buffer;
7580 /* safe output values in case error happens */
7581 w = h = 0;
7582 unsigned error = load_file(buffer, filename);
7583 if(error) return error;
7584 return decode(out, w, h, buffer, colortype, bitdepth);
7585 }
7586 #endif /* LODEPNG_COMPILE_DECODER */
7587 #endif /* LODEPNG_COMPILE_DISK */
7588
7589 #ifdef LODEPNG_COMPILE_ENCODER
encode(std::vector<unsigned char> & out,const unsigned char * in,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)7590 unsigned encode(std::vector<unsigned char> & out, const unsigned char * in, unsigned w, unsigned h,
7591 LodePNGColorType colortype, unsigned bitdepth)
7592 {
7593 unsigned char * buffer;
7594 size_t buffersize;
7595 unsigned error = lodepng_encode_memory(&buffer, &buffersize, in, w, h, colortype, bitdepth);
7596 if(buffer) {
7597 out.insert(out.end(), buffer, &buffer[buffersize]);
7598 lodepng_free(buffer);
7599 }
7600 return error;
7601 }
7602
encode(std::vector<unsigned char> & out,const std::vector<unsigned char> & in,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)7603 unsigned encode(std::vector<unsigned char> & out,
7604 const std::vector<unsigned char> & in, unsigned w, unsigned h,
7605 LodePNGColorType colortype, unsigned bitdepth)
7606 {
7607 if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84;
7608 return encode(out, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth);
7609 }
7610
encode(std::vector<unsigned char> & out,const unsigned char * in,unsigned w,unsigned h,State & state)7611 unsigned encode(std::vector<unsigned char> & out,
7612 const unsigned char * in, unsigned w, unsigned h,
7613 State & state)
7614 {
7615 unsigned char * buffer;
7616 size_t buffersize;
7617 unsigned error = lodepng_encode(&buffer, &buffersize, in, w, h, &state);
7618 if(buffer) {
7619 out.insert(out.end(), buffer, &buffer[buffersize]);
7620 lodepng_free(buffer);
7621 }
7622 return error;
7623 }
7624
encode(std::vector<unsigned char> & out,const std::vector<unsigned char> & in,unsigned w,unsigned h,State & state)7625 unsigned encode(std::vector<unsigned char> & out,
7626 const std::vector<unsigned char> & in, unsigned w, unsigned h,
7627 State & state)
7628 {
7629 if(lodepng_get_raw_size(w, h, &state.info_raw) > in.size()) return 84;
7630 return encode(out, in.empty() ? 0 : &in[0], w, h, state);
7631 }
7632
7633 #ifdef LODEPNG_COMPILE_DISK
encode(const std::string & filename,const unsigned char * in,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)7634 unsigned encode(const std::string & filename,
7635 const unsigned char * in, unsigned w, unsigned h,
7636 LodePNGColorType colortype, unsigned bitdepth)
7637 {
7638 std::vector<unsigned char> buffer;
7639 unsigned error = encode(buffer, in, w, h, colortype, bitdepth);
7640 if(!error) error = save_file(buffer, filename);
7641 return error;
7642 }
7643
encode(const std::string & filename,const std::vector<unsigned char> & in,unsigned w,unsigned h,LodePNGColorType colortype,unsigned bitdepth)7644 unsigned encode(const std::string & filename,
7645 const std::vector<unsigned char> & in, unsigned w, unsigned h,
7646 LodePNGColorType colortype, unsigned bitdepth)
7647 {
7648 if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84;
7649 return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth);
7650 }
7651 #endif /* LODEPNG_COMPILE_DISK */
7652 #endif /* LODEPNG_COMPILE_ENCODER */
7653 #endif /* LODEPNG_COMPILE_PNG */
7654 } /* namespace lodepng */
7655 #endif /*LODEPNG_COMPILE_CPP*/
7656
7657 #endif /*LV_USE_LODEPNG*/
7658