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