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