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