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