| 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 | |