00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "lodepng.h"
00032
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035
00036 #ifdef LODEPNG_COMPILE_CPP
00037 #include <fstream>
00038 #endif
00039
00040 #define VERSION_STRING "20130805"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #ifdef LODEPNG_COMPILE_ALLOCATORS
00061 static void* lodepng_malloc(size_t size)
00062 {
00063 return malloc(size);
00064 }
00065
00066 static void* lodepng_realloc(void* ptr, size_t new_size)
00067 {
00068 return realloc(ptr, new_size);
00069 }
00070
00071 static void lodepng_free(void* ptr)
00072 {
00073 free(ptr);
00074 }
00075 #else
00076 void* lodepng_malloc(size_t size);
00077 void* lodepng_realloc(void* ptr, size_t new_size);
00078 void lodepng_free(void* ptr);
00079 #endif
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 #define CERROR_BREAK(errorvar, code)\
00095 {\
00096 errorvar = code;\
00097 break;\
00098 }
00099
00100
00101 #define ERROR_BREAK(code) CERROR_BREAK(error, code)
00102
00103
00104 #define CERROR_RETURN_ERROR(errorvar, code)\
00105 {\
00106 errorvar = code;\
00107 return code;\
00108 }
00109
00110
00111 #define CERROR_TRY_RETURN(call)\
00112 {\
00113 unsigned error = call;\
00114 if(error) return error;\
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 #ifdef LODEPNG_COMPILE_ZLIB
00127
00128 typedef struct uivector
00129 {
00130 unsigned* data;
00131 size_t size;
00132 size_t allocsize;
00133 } uivector;
00134
00135 static void uivector_cleanup(void* p)
00136 {
00137 ((uivector*)p)->size = ((uivector*)p)->allocsize = 0;
00138 lodepng_free(((uivector*)p)->data);
00139 ((uivector*)p)->data = NULL;
00140 }
00141
00142
00143 static unsigned uivector_resize(uivector* p, size_t size)
00144 {
00145 if(size * sizeof(unsigned) > p->allocsize)
00146 {
00147 size_t newsize = size * sizeof(unsigned) * 2;
00148 void* data = lodepng_realloc(p->data, newsize);
00149 if(data)
00150 {
00151 p->allocsize = newsize;
00152 p->data = (unsigned*)data;
00153 p->size = size;
00154 }
00155 else return 0;
00156 }
00157 else p->size = size;
00158 return 1;
00159 }
00160
00161
00162 static unsigned uivector_resizev(uivector* p, size_t size, unsigned value)
00163 {
00164 size_t oldsize = p->size, i;
00165 if(!uivector_resize(p, size)) return 0;
00166 for(i = oldsize; i < size; i++) p->data[i] = value;
00167 return 1;
00168 }
00169
00170 static void uivector_init(uivector* p)
00171 {
00172 p->data = NULL;
00173 p->size = p->allocsize = 0;
00174 }
00175
00176 #ifdef LODEPNG_COMPILE_ENCODER
00177
00178 static unsigned uivector_push_back(uivector* p, unsigned c)
00179 {
00180 if(!uivector_resize(p, p->size + 1)) return 0;
00181 p->data[p->size - 1] = c;
00182 return 1;
00183 }
00184
00185
00186 static unsigned uivector_copy(uivector* p, const uivector* q)
00187 {
00188 size_t i;
00189 if(!uivector_resize(p, q->size)) return 0;
00190 for(i = 0; i < q->size; i++) p->data[i] = q->data[i];
00191 return 1;
00192 }
00193
00194 static void uivector_swap(uivector* p, uivector* q)
00195 {
00196 size_t tmp;
00197 unsigned* tmpp;
00198 tmp = p->size; p->size = q->size; q->size = tmp;
00199 tmp = p->allocsize; p->allocsize = q->allocsize; q->allocsize = tmp;
00200 tmpp = p->data; p->data = q->data; q->data = tmpp;
00201 }
00202 #endif
00203 #endif
00204
00205
00206
00207
00208 typedef struct ucvector
00209 {
00210 unsigned char* data;
00211 size_t size;
00212 size_t allocsize;
00213 } ucvector;
00214
00215
00216 static unsigned ucvector_resize(ucvector* p, size_t size)
00217 {
00218 if(size * sizeof(unsigned char) > p->allocsize)
00219 {
00220 size_t newsize = size * sizeof(unsigned char) * 2;
00221 void* data = lodepng_realloc(p->data, newsize);
00222 if(data)
00223 {
00224 p->allocsize = newsize;
00225 p->data = (unsigned char*)data;
00226 p->size = size;
00227 }
00228 else return 0;
00229 }
00230 else p->size = size;
00231 return 1;
00232 }
00233
00234 #ifdef LODEPNG_COMPILE_PNG
00235
00236 static void ucvector_cleanup(void* p)
00237 {
00238 ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0;
00239 lodepng_free(((ucvector*)p)->data);
00240 ((ucvector*)p)->data = NULL;
00241 }
00242
00243 static void ucvector_init(ucvector* p)
00244 {
00245 p->data = NULL;
00246 p->size = p->allocsize = 0;
00247 }
00248
00249 #ifdef LODEPNG_COMPILE_DECODER
00250
00251 static unsigned ucvector_resizev(ucvector* p, size_t size, unsigned char value)
00252 {
00253 size_t oldsize = p->size, i;
00254 if(!ucvector_resize(p, size)) return 0;
00255 for(i = oldsize; i < size; i++) p->data[i] = value;
00256 return 1;
00257 }
00258 #endif
00259 #endif
00260
00261 #ifdef LODEPNG_COMPILE_ZLIB
00262
00263
00264 static void ucvector_init_buffer(ucvector* p, unsigned char* buffer, size_t size)
00265 {
00266 p->data = buffer;
00267 p->allocsize = p->size = size;
00268 }
00269 #endif
00270
00271 #if (defined(LODEPNG_COMPILE_PNG) && defined(LODEPNG_COMPILE_ANCILLARY_CHUNKS)) || defined(LODEPNG_COMPILE_ENCODER)
00272
00273 static unsigned ucvector_push_back(ucvector* p, unsigned char c)
00274 {
00275 if(!ucvector_resize(p, p->size + 1)) return 0;
00276 p->data[p->size - 1] = c;
00277 return 1;
00278 }
00279 #endif
00280
00281
00282
00283
00284 #ifdef LODEPNG_COMPILE_PNG
00285 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
00286
00287 static unsigned string_resize(char** out, size_t size)
00288 {
00289 char* data = (char*)lodepng_realloc(*out, size + 1);
00290 if(data)
00291 {
00292 data[size] = 0;
00293 *out = data;
00294 }
00295 return data != 0;
00296 }
00297
00298
00299 static void string_init(char** out)
00300 {
00301 *out = NULL;
00302 string_resize(out, 0);
00303 }
00304
00305
00306 static void string_cleanup(char** out)
00307 {
00308 lodepng_free(*out);
00309 *out = NULL;
00310 }
00311
00312 static void string_set(char** out, const char* in)
00313 {
00314 size_t insize = strlen(in), i = 0;
00315 if(string_resize(out, insize))
00316 {
00317 for(i = 0; i < insize; i++)
00318 {
00319 (*out)[i] = in[i];
00320 }
00321 }
00322 }
00323 #endif
00324 #endif
00325
00326
00327
00328 unsigned lodepng_read32bitInt(const unsigned char* buffer)
00329 {
00330 return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
00331 }
00332
00333 #if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)
00334
00335 static void lodepng_set32bitInt(unsigned char* buffer, unsigned value)
00336 {
00337 buffer[0] = (unsigned char)((value >> 24) & 0xff);
00338 buffer[1] = (unsigned char)((value >> 16) & 0xff);
00339 buffer[2] = (unsigned char)((value >> 8) & 0xff);
00340 buffer[3] = (unsigned char)((value ) & 0xff);
00341 }
00342 #endif
00343
00344 #ifdef LODEPNG_COMPILE_ENCODER
00345 static void lodepng_add32bitInt(ucvector* buffer, unsigned value)
00346 {
00347 ucvector_resize(buffer, buffer->size + 4);
00348 lodepng_set32bitInt(&buffer->data[buffer->size - 4], value);
00349 }
00350 #endif
00351
00352
00353
00354
00355
00356 #ifdef LODEPNG_COMPILE_DISK
00357
00358 unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename)
00359 {
00360 FILE* file;
00361 long size;
00362
00363
00364 *out = 0;
00365 *outsize = 0;
00366
00367 file = fopen(filename, "rb");
00368 if(!file) return 78;
00369
00370
00371 fseek(file , 0 , SEEK_END);
00372 size = ftell(file);
00373 rewind(file);
00374
00375
00376 *outsize = 0;
00377 *out = (unsigned char*)lodepng_malloc((size_t)size);
00378 if(size && (*out)) (*outsize) = fread(*out, 1, (size_t)size, file);
00379
00380 fclose(file);
00381 if(!(*out) && size) return 83;
00382 return 0;
00383 }
00384
00385
00386 unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename)
00387 {
00388 FILE* file;
00389 file = fopen(filename, "wb" );
00390 if(!file) return 79;
00391 fwrite((char*)buffer , 1 , buffersize, file);
00392 fclose(file);
00393 return 0;
00394 }
00395
00396 #endif
00397
00398
00399
00400
00401
00402
00403
00404 #ifdef LODEPNG_COMPILE_ZLIB
00405 #ifdef LODEPNG_COMPILE_ENCODER
00406
00407 static void addBitToStream(size_t* bitpointer, ucvector* bitstream, unsigned char bit)
00408 {
00409
00410 if((*bitpointer) % 8 == 0) ucvector_push_back(bitstream, (unsigned char)0);
00411
00412 (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7));
00413 (*bitpointer)++;
00414 }
00415
00416 static void addBitsToStream(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits)
00417 {
00418 size_t i;
00419 for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> i) & 1));
00420 }
00421
00422 static void addBitsToStreamReversed(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits)
00423 {
00424 size_t i;
00425 for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> (nbits - 1 - i)) & 1));
00426 }
00427 #endif
00428
00429 #ifdef LODEPNG_COMPILE_DECODER
00430
00431 #define READBIT(bitpointer, bitstream) ((bitstream[bitpointer >> 3] >> (bitpointer & 0x7)) & (unsigned char)1)
00432
00433 static unsigned char readBitFromStream(size_t* bitpointer, const unsigned char* bitstream)
00434 {
00435 unsigned char result = (unsigned char)(READBIT(*bitpointer, bitstream));
00436 (*bitpointer)++;
00437 return result;
00438 }
00439
00440 static unsigned readBitsFromStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits)
00441 {
00442 unsigned result = 0, i;
00443 for(i = 0; i < nbits; i++)
00444 {
00445 result += ((unsigned)READBIT(*bitpointer, bitstream)) << i;
00446 (*bitpointer)++;
00447 }
00448 return result;
00449 }
00450 #endif
00451
00452
00453
00454
00455
00456 #define FIRST_LENGTH_CODE_INDEX 257
00457 #define LAST_LENGTH_CODE_INDEX 285
00458
00459 #define NUM_DEFLATE_CODE_SYMBOLS 288
00460
00461 #define NUM_DISTANCE_SYMBOLS 32
00462
00463 #define NUM_CODE_LENGTH_CODES 19
00464
00465
00466 static const unsigned LENGTHBASE[29]
00467 = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
00468 67, 83, 99, 115, 131, 163, 195, 227, 258};
00469
00470
00471 static const unsigned LENGTHEXTRA[29]
00472 = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
00473 4, 4, 4, 4, 5, 5, 5, 5, 0};
00474
00475
00476 static const unsigned DISTANCEBASE[30]
00477 = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513,
00478 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
00479
00480
00481 static const unsigned DISTANCEEXTRA[30]
00482 = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
00483 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
00484
00485
00486
00487 static const unsigned CLCL_ORDER[NUM_CODE_LENGTH_CODES]
00488 = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
00489
00490
00491
00492
00493
00494
00495 typedef struct HuffmanTree
00496 {
00497 unsigned* tree2d;
00498 unsigned* tree1d;
00499 unsigned* lengths;
00500 unsigned maxbitlen;
00501 unsigned numcodes;
00502 } HuffmanTree;
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 static void HuffmanTree_init(HuffmanTree* tree)
00518 {
00519 tree->tree2d = 0;
00520 tree->tree1d = 0;
00521 tree->lengths = 0;
00522 }
00523
00524 static void HuffmanTree_cleanup(HuffmanTree* tree)
00525 {
00526 lodepng_free(tree->tree2d);
00527 lodepng_free(tree->tree1d);
00528 lodepng_free(tree->lengths);
00529 }
00530
00531
00532 static unsigned HuffmanTree_make2DTree(HuffmanTree* tree)
00533 {
00534 unsigned nodefilled = 0;
00535 unsigned treepos = 0;
00536 unsigned n, i;
00537
00538 tree->tree2d = (unsigned*)lodepng_malloc(tree->numcodes * 2 * sizeof(unsigned));
00539 if(!tree->tree2d) return 83;
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 for(n = 0; n < tree->numcodes * 2; n++)
00552 {
00553 tree->tree2d[n] = 32767;
00554 }
00555
00556 for(n = 0; n < tree->numcodes; n++)
00557 {
00558 for(i = 0; i < tree->lengths[n]; i++)
00559 {
00560 unsigned char bit = (unsigned char)((tree->tree1d[n] >> (tree->lengths[n] - i - 1)) & 1);
00561 if(treepos > tree->numcodes - 2) return 55;
00562 if(tree->tree2d[2 * treepos + bit] == 32767)
00563 {
00564 if(i + 1 == tree->lengths[n])
00565 {
00566 tree->tree2d[2 * treepos + bit] = n;
00567 treepos = 0;
00568 }
00569 else
00570 {
00571
00572
00573 nodefilled++;
00574
00575 tree->tree2d[2 * treepos + bit] = nodefilled + tree->numcodes;
00576 treepos = nodefilled;
00577 }
00578 }
00579 else treepos = tree->tree2d[2 * treepos + bit] - tree->numcodes;
00580 }
00581 }
00582
00583 for(n = 0; n < tree->numcodes * 2; n++)
00584 {
00585 if(tree->tree2d[n] == 32767) tree->tree2d[n] = 0;
00586 }
00587
00588 return 0;
00589 }
00590
00591
00592
00593
00594
00595
00596 static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree)
00597 {
00598 uivector blcount;
00599 uivector nextcode;
00600 unsigned bits, n, error = 0;
00601
00602 uivector_init(&blcount);
00603 uivector_init(&nextcode);
00604
00605 tree->tree1d = (unsigned*)lodepng_malloc(tree->numcodes * sizeof(unsigned));
00606 if(!tree->tree1d) error = 83;
00607
00608 if(!uivector_resizev(&blcount, tree->maxbitlen + 1, 0)
00609 || !uivector_resizev(&nextcode, tree->maxbitlen + 1, 0))
00610 error = 83;
00611
00612 if(!error)
00613 {
00614
00615 for(bits = 0; bits < tree->numcodes; bits++) blcount.data[tree->lengths[bits]]++;
00616
00617 for(bits = 1; bits <= tree->maxbitlen; bits++)
00618 {
00619 nextcode.data[bits] = (nextcode.data[bits - 1] + blcount.data[bits - 1]) << 1;
00620 }
00621
00622 for(n = 0; n < tree->numcodes; n++)
00623 {
00624 if(tree->lengths[n] != 0) tree->tree1d[n] = nextcode.data[tree->lengths[n]]++;
00625 }
00626 }
00627
00628 uivector_cleanup(&blcount);
00629 uivector_cleanup(&nextcode);
00630
00631 if(!error) return HuffmanTree_make2DTree(tree);
00632 else return error;
00633 }
00634
00635
00636
00637
00638
00639
00640 static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* bitlen,
00641 size_t numcodes, unsigned maxbitlen)
00642 {
00643 unsigned i;
00644 tree->lengths = (unsigned*)lodepng_malloc(numcodes * sizeof(unsigned));
00645 if(!tree->lengths) return 83;
00646 for(i = 0; i < numcodes; i++) tree->lengths[i] = bitlen[i];
00647 tree->numcodes = (unsigned)numcodes;
00648 tree->maxbitlen = maxbitlen;
00649 return HuffmanTree_makeFromLengths2(tree);
00650 }
00651
00652 #ifdef LODEPNG_COMPILE_ENCODER
00653
00654
00655
00656
00657
00658
00659 typedef struct Coin
00660 {
00661 uivector symbols;
00662 float weight;
00663 } Coin;
00664
00665 static void coin_init(Coin* c)
00666 {
00667 uivector_init(&c->symbols);
00668 }
00669
00670
00671 static void coin_cleanup(void* c)
00672 {
00673 uivector_cleanup(&((Coin*)c)->symbols);
00674 }
00675
00676 static void coin_copy(Coin* c1, const Coin* c2)
00677 {
00678 c1->weight = c2->weight;
00679 uivector_copy(&c1->symbols, &c2->symbols);
00680 }
00681
00682 static void add_coins(Coin* c1, const Coin* c2)
00683 {
00684 size_t i;
00685 for(i = 0; i < c2->symbols.size; i++) uivector_push_back(&c1->symbols, c2->symbols.data[i]);
00686 c1->weight += c2->weight;
00687 }
00688
00689 static void init_coins(Coin* coins, size_t num)
00690 {
00691 size_t i;
00692 for(i = 0; i < num; i++) coin_init(&coins[i]);
00693 }
00694
00695 static void cleanup_coins(Coin* coins, size_t num)
00696 {
00697 size_t i;
00698 for(i = 0; i < num; i++) coin_cleanup(&coins[i]);
00699 }
00700
00701
00702
00703
00704
00705 static void sort_coins(Coin* data, size_t amount)
00706 {
00707 size_t gap = amount;
00708 unsigned char swapped = 0;
00709 while((gap > 1) || swapped)
00710 {
00711 size_t i;
00712 gap = (gap * 10) / 13;
00713 if(gap == 9 || gap == 10) gap = 11;
00714 if(gap < 1) gap = 1;
00715 swapped = 0;
00716 for(i = 0; i < amount - gap; i++)
00717 {
00718 size_t j = i + gap;
00719 if(data[j].weight < data[i].weight)
00720 {
00721 float temp = data[j].weight; data[j].weight = data[i].weight; data[i].weight = temp;
00722 uivector_swap(&data[i].symbols, &data[j].symbols);
00723 swapped = 1;
00724 }
00725 }
00726 }
00727 }
00728
00729 static unsigned append_symbol_coins(Coin* coins, const unsigned* frequencies, unsigned numcodes, size_t sum)
00730 {
00731 unsigned i;
00732 unsigned j = 0;
00733 for(i = 0; i < numcodes; i++)
00734 {
00735 if(frequencies[i] != 0)
00736 {
00737 coins[j].weight = frequencies[i] / (float)sum;
00738 uivector_push_back(&coins[j].symbols, i);
00739 j++;
00740 }
00741 }
00742 return 0;
00743 }
00744
00745 unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies,
00746 size_t numcodes, unsigned maxbitlen)
00747 {
00748 unsigned i, j;
00749 size_t sum = 0, numpresent = 0;
00750 unsigned error = 0;
00751 Coin* coins;
00752 Coin* prev_row;
00753 unsigned numcoins;
00754 unsigned coinmem;
00755
00756 if(numcodes == 0) return 80;
00757
00758 for(i = 0; i < numcodes; i++)
00759 {
00760 if(frequencies[i] > 0)
00761 {
00762 numpresent++;
00763 sum += frequencies[i];
00764 }
00765 }
00766
00767 for(i = 0; i < numcodes; i++) lengths[i] = 0;
00768
00769
00770
00771
00772
00773
00774 if(numpresent == 0)
00775 {
00776 lengths[0] = lengths[1] = 1;
00777 }
00778 else if(numpresent == 1)
00779 {
00780 for(i = 0; i < numcodes; i++)
00781 {
00782 if(frequencies[i])
00783 {
00784 lengths[i] = 1;
00785 lengths[i == 0 ? 1 : 0] = 1;
00786 break;
00787 }
00788 }
00789 }
00790 else
00791 {
00792
00793
00794
00795 coinmem = numpresent * 2;
00796 coins = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem);
00797 prev_row = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem);
00798 if(!coins || !prev_row) return 83;
00799 init_coins(coins, coinmem);
00800 init_coins(prev_row, coinmem);
00801
00802
00803 error = append_symbol_coins(coins, frequencies, numcodes, sum);
00804 numcoins = numpresent;
00805 sort_coins(coins, numcoins);
00806 if(!error)
00807 {
00808 unsigned numprev = 0;
00809 for(j = 1; j <= maxbitlen && !error; j++)
00810 {
00811 unsigned tempnum;
00812 Coin* tempcoins;
00813
00814 tempcoins = prev_row; prev_row = coins; coins = tempcoins;
00815 tempnum = numprev; numprev = numcoins; numcoins = tempnum;
00816
00817 cleanup_coins(coins, numcoins);
00818 init_coins(coins, numcoins);
00819
00820 numcoins = 0;
00821
00822
00823 for(i = 0; i + 1 < numprev; i += 2)
00824 {
00825
00826 Coin* coin = &coins[numcoins++];
00827 coin_copy(coin, &prev_row[i]);
00828 add_coins(coin, &prev_row[i + 1]);
00829 }
00830
00831 if(j < maxbitlen)
00832 {
00833 error = append_symbol_coins(coins + numcoins, frequencies, numcodes, sum);
00834 numcoins += numpresent;
00835 }
00836 sort_coins(coins, numcoins);
00837 }
00838 }
00839
00840 if(!error)
00841 {
00842
00843 for(i = 0; i < numpresent - 1; i++)
00844 {
00845 Coin* coin = &coins[i];
00846 for(j = 0; j < coin->symbols.size; j++) lengths[coin->symbols.data[j]]++;
00847 }
00848 }
00849
00850 cleanup_coins(coins, coinmem);
00851 lodepng_free(coins);
00852 cleanup_coins(prev_row, coinmem);
00853 lodepng_free(prev_row);
00854 }
00855
00856 return error;
00857 }
00858
00859
00860 static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigned* frequencies,
00861 size_t mincodes, size_t numcodes, unsigned maxbitlen)
00862 {
00863 unsigned error = 0;
00864 while(!frequencies[numcodes - 1] && numcodes > mincodes) numcodes--;
00865 tree->maxbitlen = maxbitlen;
00866 tree->numcodes = (unsigned)numcodes;
00867 tree->lengths = (unsigned*)lodepng_realloc(tree->lengths, numcodes * sizeof(unsigned));
00868 if(!tree->lengths) return 83;
00869
00870 memset(tree->lengths, 0, numcodes * sizeof(unsigned));
00871
00872 error = lodepng_huffman_code_lengths(tree->lengths, frequencies, numcodes, maxbitlen);
00873 if(!error) error = HuffmanTree_makeFromLengths2(tree);
00874 return error;
00875 }
00876
00877 static unsigned HuffmanTree_getCode(const HuffmanTree* tree, unsigned index)
00878 {
00879 return tree->tree1d[index];
00880 }
00881
00882 static unsigned HuffmanTree_getLength(const HuffmanTree* tree, unsigned index)
00883 {
00884 return tree->lengths[index];
00885 }
00886 #endif
00887
00888
00889 static unsigned generateFixedLitLenTree(HuffmanTree* tree)
00890 {
00891 unsigned i, error = 0;
00892 unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned));
00893 if(!bitlen) return 83;
00894
00895
00896 for(i = 0; i <= 143; i++) bitlen[i] = 8;
00897 for(i = 144; i <= 255; i++) bitlen[i] = 9;
00898 for(i = 256; i <= 279; i++) bitlen[i] = 7;
00899 for(i = 280; i <= 287; i++) bitlen[i] = 8;
00900
00901 error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15);
00902
00903 lodepng_free(bitlen);
00904 return error;
00905 }
00906
00907
00908 static unsigned generateFixedDistanceTree(HuffmanTree* tree)
00909 {
00910 unsigned i, error = 0;
00911 unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned));
00912 if(!bitlen) return 83;
00913
00914
00915 for(i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen[i] = 5;
00916 error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15);
00917
00918 lodepng_free(bitlen);
00919 return error;
00920 }
00921
00922 #ifdef LODEPNG_COMPILE_DECODER
00923
00924
00925
00926
00927
00928 static unsigned huffmanDecodeSymbol(const unsigned char* in, size_t* bp,
00929 const HuffmanTree* codetree, size_t inbitlength)
00930 {
00931 unsigned treepos = 0, ct;
00932 for(;;)
00933 {
00934 if(*bp >= inbitlength) return (unsigned)(-1);
00935
00936
00937
00938
00939 ct = codetree->tree2d[(treepos << 1) + READBIT(*bp, in)];
00940 (*bp)++;
00941 if(ct < codetree->numcodes) return ct;
00942 else treepos = ct - codetree->numcodes;
00943
00944 if(treepos >= codetree->numcodes) return (unsigned)(-1);
00945 }
00946 }
00947 #endif
00948
00949 #ifdef LODEPNG_COMPILE_DECODER
00950
00951
00952
00953
00954
00955
00956 static void getTreeInflateFixed(HuffmanTree* tree_ll, HuffmanTree* tree_d)
00957 {
00958
00959 generateFixedLitLenTree(tree_ll);
00960 generateFixedDistanceTree(tree_d);
00961 }
00962
00963
00964 static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d,
00965 const unsigned char* in, size_t* bp, size_t inlength)
00966 {
00967
00968 unsigned error = 0;
00969 unsigned n, HLIT, HDIST, HCLEN, i;
00970 size_t inbitlength = inlength * 8;
00971
00972
00973 unsigned* bitlen_ll = 0;
00974 unsigned* bitlen_d = 0;
00975
00976 unsigned* bitlen_cl = 0;
00977 HuffmanTree tree_cl;
00978
00979 if((*bp) >> 3 >= inlength - 2) return 49;
00980
00981
00982 HLIT = readBitsFromStream(bp, in, 5) + 257;
00983
00984 HDIST = readBitsFromStream(bp, in, 5) + 1;
00985
00986 HCLEN = readBitsFromStream(bp, in, 4) + 4;
00987
00988 HuffmanTree_init(&tree_cl);
00989
00990 while(!error)
00991 {
00992
00993
00994 bitlen_cl = (unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(unsigned));
00995 if(!bitlen_cl) ERROR_BREAK(83 );
00996
00997 for(i = 0; i < NUM_CODE_LENGTH_CODES; i++)
00998 {
00999 if(i < HCLEN) bitlen_cl[CLCL_ORDER[i]] = readBitsFromStream(bp, in, 3);
01000 else bitlen_cl[CLCL_ORDER[i]] = 0;
01001 }
01002
01003 error = HuffmanTree_makeFromLengths(&tree_cl, bitlen_cl, NUM_CODE_LENGTH_CODES, 7);
01004 if(error) break;
01005
01006
01007 bitlen_ll = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned));
01008 bitlen_d = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned));
01009 if(!bitlen_ll || !bitlen_d) ERROR_BREAK(83 );
01010 for(i = 0; i < NUM_DEFLATE_CODE_SYMBOLS; i++) bitlen_ll[i] = 0;
01011 for(i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen_d[i] = 0;
01012
01013
01014 i = 0;
01015 while(i < HLIT + HDIST)
01016 {
01017 unsigned code = huffmanDecodeSymbol(in, bp, &tree_cl, inbitlength);
01018 if(code <= 15)
01019 {
01020 if(i < HLIT) bitlen_ll[i] = code;
01021 else bitlen_d[i - HLIT] = code;
01022 i++;
01023 }
01024 else if(code == 16)
01025 {
01026 unsigned replength = 3;
01027 unsigned value;
01028
01029 if(*bp >= inbitlength) ERROR_BREAK(50);
01030 if (i == 0) ERROR_BREAK(54);
01031
01032 replength += readBitsFromStream(bp, in, 2);
01033
01034 if(i < HLIT + 1) value = bitlen_ll[i - 1];
01035 else value = bitlen_d[i - HLIT - 1];
01036
01037 for(n = 0; n < replength; n++)
01038 {
01039 if(i >= HLIT + HDIST) ERROR_BREAK(13);
01040 if(i < HLIT) bitlen_ll[i] = value;
01041 else bitlen_d[i - HLIT] = value;
01042 i++;
01043 }
01044 }
01045 else if(code == 17)
01046 {
01047 unsigned replength = 3;
01048 if(*bp >= inbitlength) ERROR_BREAK(50);
01049
01050 replength += readBitsFromStream(bp, in, 3);
01051
01052
01053 for(n = 0; n < replength; n++)
01054 {
01055 if(i >= HLIT + HDIST) ERROR_BREAK(14);
01056
01057 if(i < HLIT) bitlen_ll[i] = 0;
01058 else bitlen_d[i - HLIT] = 0;
01059 i++;
01060 }
01061 }
01062 else if(code == 18)
01063 {
01064 unsigned replength = 11;
01065 if(*bp >= inbitlength) ERROR_BREAK(50);
01066
01067 replength += readBitsFromStream(bp, in, 7);
01068
01069
01070 for(n = 0; n < replength; n++)
01071 {
01072 if(i >= HLIT + HDIST) ERROR_BREAK(15);
01073
01074 if(i < HLIT) bitlen_ll[i] = 0;
01075 else bitlen_d[i - HLIT] = 0;
01076 i++;
01077 }
01078 }
01079 else
01080 {
01081 if(code == (unsigned)(-1))
01082 {
01083
01084
01085 error = (*bp) > inbitlength ? 10 : 11;
01086 }
01087 else error = 16;
01088 break;
01089 }
01090 }
01091 if(error) break;
01092
01093 if(bitlen_ll[256] == 0) ERROR_BREAK(64);
01094
01095
01096 error = HuffmanTree_makeFromLengths(tree_ll, bitlen_ll, NUM_DEFLATE_CODE_SYMBOLS, 15);
01097 if(error) break;
01098 error = HuffmanTree_makeFromLengths(tree_d, bitlen_d, NUM_DISTANCE_SYMBOLS, 15);
01099
01100 break;
01101 }
01102
01103 lodepng_free(bitlen_cl);
01104 lodepng_free(bitlen_ll);
01105 lodepng_free(bitlen_d);
01106 HuffmanTree_cleanup(&tree_cl);
01107
01108 return error;
01109 }
01110
01111
01112 static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size_t* bp,
01113 size_t* pos, size_t inlength, unsigned btype)
01114 {
01115 unsigned error = 0;
01116 HuffmanTree tree_ll;
01117 HuffmanTree tree_d;
01118 size_t inbitlength = inlength * 8;
01119
01120 HuffmanTree_init(&tree_ll);
01121 HuffmanTree_init(&tree_d);
01122
01123 if(btype == 1) getTreeInflateFixed(&tree_ll, &tree_d);
01124 else if(btype == 2) error = getTreeInflateDynamic(&tree_ll, &tree_d, in, bp, inlength);
01125
01126 while(!error)
01127 {
01128
01129 unsigned code_ll = huffmanDecodeSymbol(in, bp, &tree_ll, inbitlength);
01130 if(code_ll <= 255)
01131 {
01132 if((*pos) >= out->size)
01133 {
01134
01135 if(!ucvector_resize(out, ((*pos) + 1) * 2)) ERROR_BREAK(83 );
01136 }
01137 out->data[(*pos)] = (unsigned char)(code_ll);
01138 (*pos)++;
01139 }
01140 else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX)
01141 {
01142 unsigned code_d, distance;
01143 unsigned numextrabits_l, numextrabits_d;
01144 size_t start, forward, backward, length;
01145
01146
01147 length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX];
01148
01149
01150 numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX];
01151 if(*bp >= inbitlength) ERROR_BREAK(51);
01152 length += readBitsFromStream(bp, in, numextrabits_l);
01153
01154
01155 code_d = huffmanDecodeSymbol(in, bp, &tree_d, inbitlength);
01156 if(code_d > 29)
01157 {
01158 if(code_ll == (unsigned)(-1))
01159 {
01160
01161
01162 error = (*bp) > inlength * 8 ? 10 : 11;
01163 }
01164 else error = 18;
01165 break;
01166 }
01167 distance = DISTANCEBASE[code_d];
01168
01169
01170 numextrabits_d = DISTANCEEXTRA[code_d];
01171 if(*bp >= inbitlength) ERROR_BREAK(51);
01172
01173 distance += readBitsFromStream(bp, in, numextrabits_d);
01174
01175
01176 start = (*pos);
01177 if(distance > start) ERROR_BREAK(52);
01178 backward = start - distance;
01179 if((*pos) + length >= out->size)
01180 {
01181
01182 if(!ucvector_resize(out, ((*pos) + length) * 2)) ERROR_BREAK(83 );
01183 }
01184
01185 for(forward = 0; forward < length; forward++)
01186 {
01187 out->data[(*pos)] = out->data[backward];
01188 (*pos)++;
01189 backward++;
01190 if(backward >= start) backward = start - distance;
01191 }
01192 }
01193 else if(code_ll == 256)
01194 {
01195 break;
01196 }
01197 else
01198 {
01199
01200
01201 error = (*bp) > inlength * 8 ? 10 : 11;
01202 break;
01203 }
01204 }
01205
01206 HuffmanTree_cleanup(&tree_ll);
01207 HuffmanTree_cleanup(&tree_d);
01208
01209 return error;
01210 }
01211
01212 static unsigned inflateNoCompression(ucvector* out, const unsigned char* in, size_t* bp, size_t* pos, size_t inlength)
01213 {
01214
01215 size_t p;
01216 unsigned LEN, NLEN, n, error = 0;
01217 while(((*bp) & 0x7) != 0) (*bp)++;
01218 p = (*bp) / 8;
01219
01220
01221 if(p >= inlength - 4) return 52;
01222 LEN = in[p] + 256 * in[p + 1]; p += 2;
01223 NLEN = in[p] + 256 * in[p + 1]; p += 2;
01224
01225
01226 if(LEN + NLEN != 65535) return 21;
01227
01228 if((*pos) + LEN >= out->size)
01229 {
01230 if(!ucvector_resize(out, (*pos) + LEN)) return 83;
01231 }
01232
01233
01234 if(p + LEN > inlength) return 23;
01235 for(n = 0; n < LEN; n++) out->data[(*pos)++] = in[p++];
01236
01237 (*bp) = p * 8;
01238
01239 return error;
01240 }
01241
01242 static unsigned lodepng_inflatev(ucvector* out,
01243 const unsigned char* in, size_t insize,
01244 const LodePNGDecompressSettings* settings)
01245 {
01246
01247 size_t bp = 0;
01248 unsigned BFINAL = 0;
01249 size_t pos = 0;
01250
01251 unsigned error = 0;
01252
01253 (void)settings;
01254
01255 while(!BFINAL)
01256 {
01257 unsigned BTYPE;
01258 if(bp + 2 >= insize * 8) return 52;
01259 BFINAL = readBitFromStream(&bp, in);
01260 BTYPE = 1 * readBitFromStream(&bp, in);
01261 BTYPE += 2 * readBitFromStream(&bp, in);
01262
01263 if(BTYPE == 3) return 20;
01264 else if(BTYPE == 0) error = inflateNoCompression(out, in, &bp, &pos, insize);
01265 else error = inflateHuffmanBlock(out, in, &bp, &pos, insize, BTYPE);
01266
01267 if(error) return error;
01268 }
01269
01270
01271 if(!ucvector_resize(out, pos)) error = 83;
01272
01273 return error;
01274 }
01275
01276 unsigned lodepng_inflate(unsigned char** out, size_t* outsize,
01277 const unsigned char* in, size_t insize,
01278 const LodePNGDecompressSettings* settings)
01279 {
01280 unsigned error;
01281 ucvector v;
01282 ucvector_init_buffer(&v, *out, *outsize);
01283 error = lodepng_inflatev(&v, in, insize, settings);
01284 *out = v.data;
01285 *outsize = v.size;
01286 return error;
01287 }
01288
01289 static unsigned inflate(unsigned char** out, size_t* outsize,
01290 const unsigned char* in, size_t insize,
01291 const LodePNGDecompressSettings* settings)
01292 {
01293 if(settings->custom_inflate)
01294 {
01295 return settings->custom_inflate(out, outsize, in, insize, settings);
01296 }
01297 else
01298 {
01299 return lodepng_inflate(out, outsize, in, insize, settings);
01300 }
01301 }
01302
01303 #endif
01304
01305 #ifdef LODEPNG_COMPILE_ENCODER
01306
01307
01308
01309
01310
01311 static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258;
01312
01313
01314 static void addHuffmanSymbol(size_t* bp, ucvector* compressed, unsigned code, unsigned bitlen)
01315 {
01316 addBitsToStreamReversed(bp, compressed, code, bitlen);
01317 }
01318
01319
01320
01321 static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value)
01322 {
01323
01324
01325
01326
01327
01328 size_t left = 1;
01329 size_t right = array_size - 1;
01330 while(left <= right)
01331 {
01332 size_t mid = (left + right) / 2;
01333 if(array[mid] <= value) left = mid + 1;
01334 else if(array[mid - 1] > value) right = mid - 1;
01335 else return mid - 1;
01336 }
01337 return array_size - 1;
01338 }
01339
01340 static void addLengthDistance(uivector* values, size_t length, size_t distance)
01341 {
01342
01343
01344
01345
01346
01347
01348 unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length);
01349 unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]);
01350 unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance);
01351 unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]);
01352
01353 uivector_push_back(values, length_code + FIRST_LENGTH_CODE_INDEX);
01354 uivector_push_back(values, extra_length);
01355 uivector_push_back(values, dist_code);
01356 uivector_push_back(values, extra_distance);
01357 }
01358
01359 static const unsigned HASH_NUM_VALUES = 65536;
01360 static const unsigned HASH_NUM_CHARACTERS = 3;
01361 static const unsigned HASH_SHIFT = 2;
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376 typedef struct Hash
01377 {
01378 int* head;
01379 int* val;
01380
01381 unsigned short* chain;
01382 unsigned short* zeros;
01383 } Hash;
01384
01385 static unsigned hash_init(Hash* hash, unsigned windowsize)
01386 {
01387 unsigned i;
01388 hash->head = (int*)lodepng_malloc(sizeof(int) * HASH_NUM_VALUES);
01389 hash->val = (int*)lodepng_malloc(sizeof(int) * windowsize);
01390 hash->chain = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize);
01391 hash->zeros = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize);
01392
01393 if(!hash->head || !hash->val || !hash->chain || !hash->zeros) return 83;
01394
01395
01396 for(i = 0; i < HASH_NUM_VALUES; i++) hash->head[i] = -1;
01397 for(i = 0; i < windowsize; i++) hash->val[i] = -1;
01398 for(i = 0; i < windowsize; i++) hash->chain[i] = i;
01399
01400 return 0;
01401 }
01402
01403 static void hash_cleanup(Hash* hash)
01404 {
01405 lodepng_free(hash->head);
01406 lodepng_free(hash->val);
01407 lodepng_free(hash->chain);
01408 lodepng_free(hash->zeros);
01409 }
01410
01411 static unsigned getHash(const unsigned char* data, size_t size, size_t pos)
01412 {
01413 unsigned result = 0;
01414 size_t amount, i;
01415 if(pos >= size) return 0;
01416 amount = HASH_NUM_CHARACTERS;
01417 if(pos + amount >= size) amount = size - pos;
01418 for(i = 0; i < amount; i++) result ^= (data[pos + i] << (i * HASH_SHIFT));
01419 return result % HASH_NUM_VALUES;
01420 }
01421
01422 static unsigned countZeros(const unsigned char* data, size_t size, size_t pos)
01423 {
01424 const unsigned char* start = data + pos;
01425 const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH;
01426 if(end > data + size) end = data + size;
01427 data = start;
01428 while (data != end && *data == 0) data++;
01429
01430 return (unsigned)(data - start);
01431 }
01432
01433 static void updateHashChain(Hash* hash, size_t pos, int hashval, unsigned windowsize)
01434 {
01435 unsigned wpos = pos % windowsize;
01436 hash->val[wpos] = hashval;
01437 if(hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval];
01438 hash->head[hashval] = wpos;
01439 }
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450 static unsigned encodeLZ77(uivector* out, Hash* hash,
01451 const unsigned char* in, size_t inpos, size_t insize, unsigned windowsize,
01452 unsigned minmatch, unsigned nicematch, unsigned lazymatching)
01453 {
01454 unsigned short numzeros = 0;
01455 int usezeros = windowsize >= 8192;
01456 unsigned pos, i, error = 0;
01457
01458 unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8;
01459 unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64;
01460
01461 if(!error)
01462 {
01463 unsigned offset;
01464 unsigned length;
01465 unsigned lazy = 0;
01466 unsigned lazylength = 0, lazyoffset = 0;
01467 unsigned hashval;
01468 unsigned current_offset, current_length;
01469 const unsigned char *lastptr, *foreptr, *backptr;
01470 unsigned short hashpos, prevpos;
01471
01472 for(pos = inpos; pos < insize; pos++)
01473 {
01474 size_t wpos = pos % windowsize;
01475
01476 hashval = getHash(in, insize, pos);
01477 updateHashChain(hash, pos, hashval, windowsize);
01478
01479 if(usezeros && hashval == 0)
01480 {
01481 numzeros = countZeros(in, insize, pos);
01482 hash->zeros[wpos] = numzeros;
01483 }
01484
01485
01486 length = 0;
01487 offset = 0;
01488
01489 prevpos = hash->head[hashval];
01490 hashpos = hash->chain[prevpos];
01491
01492 lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH];
01493
01494
01495 if(hash->val[wpos] == (int)hashval)
01496 {
01497 unsigned chainlength = 0;
01498 for(;;)
01499 {
01500
01501 if(prevpos < wpos && hashpos > prevpos && hashpos <= wpos) break;
01502 if(prevpos > wpos && (hashpos <= wpos || hashpos > prevpos)) break;
01503 if(chainlength++ >= maxchainlength) break;
01504
01505 current_offset = hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize;
01506 if(current_offset > 0)
01507 {
01508
01509 foreptr = &in[pos];
01510 backptr = &in[pos - current_offset];
01511
01512
01513 if(usezeros && hashval == 0 && hash->val[hashpos] == 0 )
01514 {
01515 unsigned short skip = hash->zeros[hashpos];
01516 if(skip > numzeros) skip = numzeros;
01517 backptr += skip;
01518 foreptr += skip;
01519 }
01520
01521
01522 while(foreptr != lastptr && *backptr == *foreptr)
01523 {
01524 ++backptr;
01525 ++foreptr;
01526 }
01527 current_length = (unsigned)(foreptr - &in[pos]);
01528
01529 if(current_length > length)
01530 {
01531 length = current_length;
01532 offset = current_offset;
01533
01534 if(current_length >= nicematch || current_length == MAX_SUPPORTED_DEFLATE_LENGTH) break;
01535 }
01536 }
01537
01538 if(hashpos == hash->chain[hashpos]) break;
01539
01540 prevpos = hashpos;
01541 hashpos = hash->chain[hashpos];
01542 }
01543 }
01544
01545 if(lazymatching)
01546 {
01547 if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH)
01548 {
01549 lazy = 1;
01550 lazylength = length;
01551 lazyoffset = offset;
01552 continue;
01553 }
01554 if(lazy)
01555 {
01556 lazy = 0;
01557 if(pos == 0) ERROR_BREAK(81);
01558 if(length > lazylength + 1)
01559 {
01560
01561 if(!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 );
01562 }
01563 else
01564 {
01565 length = lazylength;
01566 offset = lazyoffset;
01567 hash->head[hashval] = -1;
01568 pos--;
01569 }
01570 }
01571 }
01572 if(length >= 3 && offset > windowsize) ERROR_BREAK(86 );
01573
01575 if(length < 3)
01576 {
01577 if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 );
01578 }
01579 else if(length < minmatch || (length == 3 && offset > 4096))
01580 {
01581
01582
01583 if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 );
01584 }
01585 else
01586 {
01587 addLengthDistance(out, length, offset);
01588 for(i = 1; i < length; i++)
01589 {
01590 pos++;
01591 hashval = getHash(in, insize, pos);
01592 updateHashChain(hash, pos, hashval, windowsize);
01593 if(usezeros && hashval == 0)
01594 {
01595 hash->zeros[pos % windowsize] = countZeros(in, insize, pos);
01596 }
01597 }
01598 }
01599
01600 }
01601 }
01602
01603 return error;
01604 }
01605
01606
01607
01608 static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, size_t datasize)
01609 {
01610
01611
01612
01613 size_t i, j, numdeflateblocks = (datasize + 65534) / 65535;
01614 unsigned datapos = 0;
01615 for(i = 0; i < numdeflateblocks; i++)
01616 {
01617 unsigned BFINAL, BTYPE, LEN, NLEN;
01618 unsigned char firstbyte;
01619
01620 BFINAL = (i == numdeflateblocks - 1);
01621 BTYPE = 0;
01622
01623 firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1));
01624 ucvector_push_back(out, firstbyte);
01625
01626 LEN = 65535;
01627 if(datasize - datapos < 65535) LEN = (unsigned)datasize - datapos;
01628 NLEN = 65535 - LEN;
01629
01630 ucvector_push_back(out, (unsigned char)(LEN % 256));
01631 ucvector_push_back(out, (unsigned char)(LEN / 256));
01632 ucvector_push_back(out, (unsigned char)(NLEN % 256));
01633 ucvector_push_back(out, (unsigned char)(NLEN / 256));
01634
01635
01636 for(j = 0; j < 65535 && datapos < datasize; j++)
01637 {
01638 ucvector_push_back(out, data[datapos++]);
01639 }
01640 }
01641
01642 return 0;
01643 }
01644
01645
01646
01647
01648
01649
01650 static void writeLZ77data(size_t* bp, ucvector* out, const uivector* lz77_encoded,
01651 const HuffmanTree* tree_ll, const HuffmanTree* tree_d)
01652 {
01653 size_t i = 0;
01654 for(i = 0; i < lz77_encoded->size; i++)
01655 {
01656 unsigned val = lz77_encoded->data[i];
01657 addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_ll, val), HuffmanTree_getLength(tree_ll, val));
01658 if(val > 256)
01659 {
01660 unsigned length_index = val - FIRST_LENGTH_CODE_INDEX;
01661 unsigned n_length_extra_bits = LENGTHEXTRA[length_index];
01662 unsigned length_extra_bits = lz77_encoded->data[++i];
01663
01664 unsigned distance_code = lz77_encoded->data[++i];
01665
01666 unsigned distance_index = distance_code;
01667 unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index];
01668 unsigned distance_extra_bits = lz77_encoded->data[++i];
01669
01670 addBitsToStream(bp, out, length_extra_bits, n_length_extra_bits);
01671 addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_d, distance_code),
01672 HuffmanTree_getLength(tree_d, distance_code));
01673 addBitsToStream(bp, out, distance_extra_bits, n_distance_extra_bits);
01674 }
01675 }
01676 }
01677
01678
01679 static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash,
01680 const unsigned char* data, size_t datapos, size_t dataend,
01681 const LodePNGCompressSettings* settings, int final)
01682 {
01683 unsigned error = 0;
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697 uivector lz77_encoded;
01698 HuffmanTree tree_ll;
01699 HuffmanTree tree_d;
01700 HuffmanTree tree_cl;
01701 uivector frequencies_ll;
01702 uivector frequencies_d;
01703 uivector frequencies_cl;
01704 uivector bitlen_lld;
01705 uivector bitlen_lld_e;
01706
01707
01708
01709 uivector bitlen_cl;
01710 size_t datasize = dataend - datapos;
01711
01712
01713
01714
01715
01716
01717
01718
01719 unsigned BFINAL = final;
01720 size_t numcodes_ll, numcodes_d, i;
01721 unsigned HLIT, HDIST, HCLEN;
01722
01723 uivector_init(&lz77_encoded);
01724 HuffmanTree_init(&tree_ll);
01725 HuffmanTree_init(&tree_d);
01726 HuffmanTree_init(&tree_cl);
01727 uivector_init(&frequencies_ll);
01728 uivector_init(&frequencies_d);
01729 uivector_init(&frequencies_cl);
01730 uivector_init(&bitlen_lld);
01731 uivector_init(&bitlen_lld_e);
01732 uivector_init(&bitlen_cl);
01733
01734
01735
01736 while(!error)
01737 {
01738 if(settings->use_lz77)
01739 {
01740 error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize,
01741 settings->minmatch, settings->nicematch, settings->lazymatching);
01742 if(error) break;
01743 }
01744 else
01745 {
01746 if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 );
01747 for(i = datapos; i < dataend; i++) lz77_encoded.data[i] = data[i];
01748 }
01749
01750 if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83 );
01751 if(!uivector_resizev(&frequencies_d, 30, 0)) ERROR_BREAK(83 );
01752
01753
01754 for(i = 0; i < lz77_encoded.size; i++)
01755 {
01756 unsigned symbol = lz77_encoded.data[i];
01757 frequencies_ll.data[symbol]++;
01758 if(symbol > 256)
01759 {
01760 unsigned dist = lz77_encoded.data[i + 2];
01761 frequencies_d.data[dist]++;
01762 i += 3;
01763 }
01764 }
01765 frequencies_ll.data[256] = 1;
01766
01767
01768 error = HuffmanTree_makeFromFrequencies(&tree_ll, frequencies_ll.data, 257, frequencies_ll.size, 15);
01769 if(error) break;
01770
01771 error = HuffmanTree_makeFromFrequencies(&tree_d, frequencies_d.data, 2, frequencies_d.size, 15);
01772 if(error) break;
01773
01774 numcodes_ll = tree_ll.numcodes; if(numcodes_ll > 286) numcodes_ll = 286;
01775 numcodes_d = tree_d.numcodes; if(numcodes_d > 30) numcodes_d = 30;
01776
01777 for(i = 0; i < numcodes_ll; i++) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_ll, (unsigned)i));
01778 for(i = 0; i < numcodes_d; i++) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_d, (unsigned)i));
01779
01780
01781
01782 for(i = 0; i < (unsigned)bitlen_lld.size; i++)
01783 {
01784 unsigned j = 0;
01785 while(i + j + 1 < (unsigned)bitlen_lld.size && bitlen_lld.data[i + j + 1] == bitlen_lld.data[i]) j++;
01786
01787 if(bitlen_lld.data[i] == 0 && j >= 2)
01788 {
01789 j++;
01790 if(j <= 10)
01791 {
01792 uivector_push_back(&bitlen_lld_e, 17);
01793 uivector_push_back(&bitlen_lld_e, j - 3);
01794 }
01795 else
01796 {
01797 if(j > 138) j = 138;
01798 uivector_push_back(&bitlen_lld_e, 18);
01799 uivector_push_back(&bitlen_lld_e, j - 11);
01800 }
01801 i += (j - 1);
01802 }
01803 else if(j >= 3)
01804 {
01805 size_t k;
01806 unsigned num = j / 6, rest = j % 6;
01807 uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]);
01808 for(k = 0; k < num; k++)
01809 {
01810 uivector_push_back(&bitlen_lld_e, 16);
01811 uivector_push_back(&bitlen_lld_e, 6 - 3);
01812 }
01813 if(rest >= 3)
01814 {
01815 uivector_push_back(&bitlen_lld_e, 16);
01816 uivector_push_back(&bitlen_lld_e, rest - 3);
01817 }
01818 else j -= rest;
01819 i += j;
01820 }
01821 else
01822 {
01823 uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]);
01824 }
01825 }
01826
01827
01828
01829 if(!uivector_resizev(&frequencies_cl, NUM_CODE_LENGTH_CODES, 0)) ERROR_BREAK(83 );
01830 for(i = 0; i < bitlen_lld_e.size; i++)
01831 {
01832 frequencies_cl.data[bitlen_lld_e.data[i]]++;
01833
01834
01835 if(bitlen_lld_e.data[i] >= 16) i++;
01836 }
01837
01838 error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl.data,
01839 frequencies_cl.size, frequencies_cl.size, 7);
01840 if(error) break;
01841
01842 if(!uivector_resize(&bitlen_cl, tree_cl.numcodes)) ERROR_BREAK(83 );
01843 for(i = 0; i < tree_cl.numcodes; i++)
01844 {
01845
01846 bitlen_cl.data[i] = HuffmanTree_getLength(&tree_cl, CLCL_ORDER[i]);
01847 }
01848 while(bitlen_cl.data[bitlen_cl.size - 1] == 0 && bitlen_cl.size > 4)
01849 {
01850
01851 if(!uivector_resize(&bitlen_cl, bitlen_cl.size - 1)) ERROR_BREAK(83 );
01852 }
01853 if(error) break;
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870 addBitToStream(bp, out, BFINAL);
01871 addBitToStream(bp, out, 0);
01872 addBitToStream(bp, out, 1);
01873
01874
01875 HLIT = (unsigned)(numcodes_ll - 257);
01876 HDIST = (unsigned)(numcodes_d - 1);
01877 HCLEN = (unsigned)bitlen_cl.size - 4;
01878
01879 while(!bitlen_cl.data[HCLEN + 4 - 1] && HCLEN > 0) HCLEN--;
01880 addBitsToStream(bp, out, HLIT, 5);
01881 addBitsToStream(bp, out, HDIST, 5);
01882 addBitsToStream(bp, out, HCLEN, 4);
01883
01884
01885 for(i = 0; i < HCLEN + 4; i++) addBitsToStream(bp, out, bitlen_cl.data[i], 3);
01886
01887
01888 for(i = 0; i < bitlen_lld_e.size; i++)
01889 {
01890 addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_cl, bitlen_lld_e.data[i]),
01891 HuffmanTree_getLength(&tree_cl, bitlen_lld_e.data[i]));
01892
01893 if(bitlen_lld_e.data[i] == 16) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 2);
01894 else if(bitlen_lld_e.data[i] == 17) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 3);
01895 else if(bitlen_lld_e.data[i] == 18) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 7);
01896 }
01897
01898
01899 writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d);
01900
01901 if(HuffmanTree_getLength(&tree_ll, 256) == 0) ERROR_BREAK(64);
01902
01903
01904 addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256));
01905
01906 break;
01907 }
01908
01909
01910 uivector_cleanup(&lz77_encoded);
01911 HuffmanTree_cleanup(&tree_ll);
01912 HuffmanTree_cleanup(&tree_d);
01913 HuffmanTree_cleanup(&tree_cl);
01914 uivector_cleanup(&frequencies_ll);
01915 uivector_cleanup(&frequencies_d);
01916 uivector_cleanup(&frequencies_cl);
01917 uivector_cleanup(&bitlen_lld_e);
01918 uivector_cleanup(&bitlen_lld);
01919 uivector_cleanup(&bitlen_cl);
01920
01921 return error;
01922 }
01923
01924 static unsigned deflateFixed(ucvector* out, size_t* bp, Hash* hash,
01925 const unsigned char* data,
01926 size_t datapos, size_t dataend,
01927 const LodePNGCompressSettings* settings, int final)
01928 {
01929 HuffmanTree tree_ll;
01930 HuffmanTree tree_d;
01931
01932 unsigned BFINAL = final;
01933 unsigned error = 0;
01934 size_t i;
01935
01936 HuffmanTree_init(&tree_ll);
01937 HuffmanTree_init(&tree_d);
01938
01939 generateFixedLitLenTree(&tree_ll);
01940 generateFixedDistanceTree(&tree_d);
01941
01942 addBitToStream(bp, out, BFINAL);
01943 addBitToStream(bp, out, 1);
01944 addBitToStream(bp, out, 0);
01945
01946 if(settings->use_lz77)
01947 {
01948 uivector lz77_encoded;
01949 uivector_init(&lz77_encoded);
01950 error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize,
01951 settings->minmatch, settings->nicematch, settings->lazymatching);
01952 if(!error) writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d);
01953 uivector_cleanup(&lz77_encoded);
01954 }
01955 else
01956 {
01957 for(i = datapos; i < dataend; i++)
01958 {
01959 addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, data[i]), HuffmanTree_getLength(&tree_ll, data[i]));
01960 }
01961 }
01962
01963 if(!error) addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256));
01964
01965
01966 HuffmanTree_cleanup(&tree_ll);
01967 HuffmanTree_cleanup(&tree_d);
01968
01969 return error;
01970 }
01971
01972 static unsigned lodepng_deflatev(ucvector* out, const unsigned char* in, size_t insize,
01973 const LodePNGCompressSettings* settings)
01974 {
01975 unsigned error = 0;
01976 size_t i, blocksize, numdeflateblocks;
01977 size_t bp = 0;
01978 Hash hash;
01979
01980 if(settings->btype > 2) return 61;
01981 else if(settings->btype == 0) return deflateNoCompression(out, in, insize);
01982 else if(settings->btype == 1) blocksize = insize;
01983 else
01984 {
01985 blocksize = insize / 8 + 8;
01986 if(blocksize < 65535) blocksize = 65535;
01987 }
01988
01989 numdeflateblocks = (insize + blocksize - 1) / blocksize;
01990 if(numdeflateblocks == 0) numdeflateblocks = 1;
01991
01992 error = hash_init(&hash, settings->windowsize);
01993 if(error) return error;
01994
01995 for(i = 0; i < numdeflateblocks && !error; i++)
01996 {
01997 int final = i == numdeflateblocks - 1;
01998 size_t start = i * blocksize;
01999 size_t end = start + blocksize;
02000 if(end > insize) end = insize;
02001
02002 if(settings->btype == 1) error = deflateFixed(out, &bp, &hash, in, start, end, settings, final);
02003 else if(settings->btype == 2) error = deflateDynamic(out, &bp, &hash, in, start, end, settings, final);
02004 }
02005
02006 hash_cleanup(&hash);
02007
02008 return error;
02009 }
02010
02011 unsigned lodepng_deflate(unsigned char** out, size_t* outsize,
02012 const unsigned char* in, size_t insize,
02013 const LodePNGCompressSettings* settings)
02014 {
02015 unsigned error;
02016 ucvector v;
02017 ucvector_init_buffer(&v, *out, *outsize);
02018 error = lodepng_deflatev(&v, in, insize, settings);
02019 *out = v.data;
02020 *outsize = v.size;
02021 return error;
02022 }
02023
02024 static unsigned deflate(unsigned char** out, size_t* outsize,
02025 const unsigned char* in, size_t insize,
02026 const LodePNGCompressSettings* settings)
02027 {
02028 if(settings->custom_deflate)
02029 {
02030 return settings->custom_deflate(out, outsize, in, insize, settings);
02031 }
02032 else
02033 {
02034 return lodepng_deflate(out, outsize, in, insize, settings);
02035 }
02036 }
02037
02038 #endif
02039
02040
02041
02042
02043
02044 static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len)
02045 {
02046 unsigned s1 = adler & 0xffff;
02047 unsigned s2 = (adler >> 16) & 0xffff;
02048
02049 while(len > 0)
02050 {
02051
02052 unsigned amount = len > 5550 ? 5550 : len;
02053 len -= amount;
02054 while(amount > 0)
02055 {
02056 s1 += (*data++);
02057 s2 += s1;
02058 amount--;
02059 }
02060 s1 %= 65521;
02061 s2 %= 65521;
02062 }
02063
02064 return (s2 << 16) | s1;
02065 }
02066
02067
02068 static unsigned adler32(const unsigned char* data, unsigned len)
02069 {
02070 return update_adler32(1L, data, len);
02071 }
02072
02073
02074
02075
02076
02077 #ifdef LODEPNG_COMPILE_DECODER
02078
02079 unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in,
02080 size_t insize, const LodePNGDecompressSettings* settings)
02081 {
02082 unsigned error = 0;
02083 unsigned CM, CINFO, FDICT;
02084
02085 if(insize < 2) return 53;
02086
02087 if((in[0] * 256 + in[1]) % 31 != 0)
02088 {
02089
02090 return 24;
02091 }
02092
02093 CM = in[0] & 15;
02094 CINFO = (in[0] >> 4) & 15;
02095
02096 FDICT = (in[1] >> 5) & 1;
02097
02098
02099 if(CM != 8 || CINFO > 7)
02100 {
02101
02102 return 25;
02103 }
02104 if(FDICT != 0)
02105 {
02106
02107
02108 return 26;
02109 }
02110
02111 error = inflate(out, outsize, in + 2, insize - 2, settings);
02112 if(error) return error;
02113
02114 if(!settings->ignore_adler32)
02115 {
02116 unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]);
02117 unsigned checksum = adler32(*out, (unsigned)(*outsize));
02118 if(checksum != ADLER32) return 58;
02119 }
02120
02121 return 0;
02122 }
02123
02124 static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in,
02125 size_t insize, const LodePNGDecompressSettings* settings)
02126 {
02127 if(settings->custom_zlib)
02128 return settings->custom_zlib(out, outsize, in, insize, settings);
02129 else
02130 return lodepng_zlib_decompress(out, outsize, in, insize, settings);
02131 }
02132
02133 #endif
02134
02135 #ifdef LODEPNG_COMPILE_ENCODER
02136
02137 unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in,
02138 size_t insize, const LodePNGCompressSettings* settings)
02139 {
02140
02141
02142 ucvector outv;
02143 size_t i;
02144 unsigned error;
02145 unsigned char* deflatedata = 0;
02146 size_t deflatesize = 0;
02147
02148 unsigned ADLER32;
02149
02150 unsigned CMF = 120;
02151 unsigned FLEVEL = 0;
02152 unsigned FDICT = 0;
02153 unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64;
02154 unsigned FCHECK = 31 - CMFFLG % 31;
02155 CMFFLG += FCHECK;
02156
02157
02158 ucvector_init_buffer(&outv, *out, *outsize);
02159
02160 ucvector_push_back(&outv, (unsigned char)(CMFFLG / 256));
02161 ucvector_push_back(&outv, (unsigned char)(CMFFLG % 256));
02162
02163 error = deflate(&deflatedata, &deflatesize, in, insize, settings);
02164
02165 if(!error)
02166 {
02167 ADLER32 = adler32(in, (unsigned)insize);
02168 for(i = 0; i < deflatesize; i++) ucvector_push_back(&outv, deflatedata[i]);
02169 lodepng_free(deflatedata);
02170 lodepng_add32bitInt(&outv, ADLER32);
02171 }
02172
02173 *out = outv.data;
02174 *outsize = outv.size;
02175
02176 return error;
02177 }
02178
02179
02180 static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in,
02181 size_t insize, const LodePNGCompressSettings* settings)
02182 {
02183 if(settings->custom_zlib)
02184 {
02185 return settings->custom_zlib(out, outsize, in, insize, settings);
02186 }
02187 else
02188 {
02189 return lodepng_zlib_compress(out, outsize, in, insize, settings);
02190 }
02191 }
02192
02193 #endif
02194
02195 #else
02196
02197 #ifdef LODEPNG_COMPILE_DECODER
02198 static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in,
02199 size_t insize, const LodePNGDecompressSettings* settings)
02200 {
02201 if (!settings->custom_zlib) return 87;
02202 return settings->custom_zlib(out, outsize, in, insize, settings);
02203 }
02204 #endif
02205 #ifdef LODEPNG_COMPILE_ENCODER
02206 static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in,
02207 size_t insize, const LodePNGCompressSettings* settings)
02208 {
02209 if (!settings->custom_zlib) return 87;
02210 return settings->custom_zlib(out, outsize, in, insize, settings);
02211 }
02212 #endif
02213
02214 #endif
02215
02216
02217
02218 #ifdef LODEPNG_COMPILE_ENCODER
02219
02220
02221 #define DEFAULT_WINDOWSIZE 2048
02222
02223 void lodepng_compress_settings_init(LodePNGCompressSettings* settings)
02224 {
02225
02226 settings->btype = 2;
02227 settings->use_lz77 = 1;
02228 settings->windowsize = DEFAULT_WINDOWSIZE;
02229 settings->minmatch = 3;
02230 settings->nicematch = 128;
02231 settings->lazymatching = 1;
02232
02233 settings->custom_zlib = 0;
02234 settings->custom_deflate = 0;
02235 settings->custom_context = 0;
02236 }
02237
02238 const LodePNGCompressSettings lodepng_default_compress_settings = {2, 1, DEFAULT_WINDOWSIZE, 3, 128, 1, 0, 0, 0};
02239
02240
02241 #endif
02242
02243 #ifdef LODEPNG_COMPILE_DECODER
02244
02245 void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings)
02246 {
02247 settings->ignore_adler32 = 0;
02248
02249 settings->custom_zlib = 0;
02250 settings->custom_inflate = 0;
02251 settings->custom_context = 0;
02252 }
02253
02254 const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, 0};
02255
02256 #endif
02257
02258
02259
02260
02261
02262
02263
02264 #ifdef LODEPNG_COMPILE_PNG
02265
02266
02267
02268
02269
02270
02271 static unsigned lodepng_crc32_table[256] = {
02272 0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035,
02273 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049,
02274 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639,
02275 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317,
02276 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443,
02277 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665,
02278 651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303,
02279 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565,
02280 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059,
02281 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297,
02282 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223,
02283 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405,
02284 1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995,
02285 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649,
02286 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015,
02287 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989,
02288 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523,
02289 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377,
02290 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879,
02291 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637,
02292 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859,
02293 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161,
02294 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815,
02295 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221,
02296 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371,
02297 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881,
02298 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567,
02299 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701,
02300 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035,
02301 2932959818, 3654703836, 1088359270, 936918000, 2847714899, 3736837829, 1202900863, 817233897,
02302 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431,
02303 3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117
02304 };
02305
02306
02307 unsigned lodepng_crc32(const unsigned char* buf, size_t len)
02308 {
02309 unsigned c = 0xffffffffL;
02310 size_t n;
02311
02312 for(n = 0; n < len; n++)
02313 {
02314 c = lodepng_crc32_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
02315 }
02316 return c ^ 0xffffffffL;
02317 }
02318
02319
02320
02321
02322
02323 static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream)
02324 {
02325 unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1);
02326 (*bitpointer)++;
02327 return result;
02328 }
02329
02330 static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits)
02331 {
02332 unsigned result = 0;
02333 size_t i;
02334 for(i = nbits - 1; i < nbits; i--)
02335 {
02336 result += (unsigned)readBitFromReversedStream(bitpointer, bitstream) << i;
02337 }
02338 return result;
02339 }
02340
02341 #ifdef LODEPNG_COMPILE_DECODER
02342 static void setBitOfReversedStream0(size_t* bitpointer, unsigned char* bitstream, unsigned char bit)
02343 {
02344
02345 if(bit)
02346 {
02347
02348 bitstream[(*bitpointer) >> 3] |= (bit << (7 - ((*bitpointer) & 0x7)));
02349 }
02350 (*bitpointer)++;
02351 }
02352 #endif
02353
02354 static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned char bit)
02355 {
02356
02357 if(bit == 0) bitstream[(*bitpointer) >> 3] &= (unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7))));
02358 else bitstream[(*bitpointer) >> 3] |= (1 << (7 - ((*bitpointer) & 0x7)));
02359 (*bitpointer)++;
02360 }
02361
02362
02363
02364
02365
02366 unsigned lodepng_chunk_length(const unsigned char* chunk)
02367 {
02368 return lodepng_read32bitInt(&chunk[0]);
02369 }
02370
02371 void lodepng_chunk_type(char type[5], const unsigned char* chunk)
02372 {
02373 unsigned i;
02374 for(i = 0; i < 4; i++) type[i] = chunk[4 + i];
02375 type[4] = 0;
02376 }
02377
02378 unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type)
02379 {
02380 if(strlen(type) != 4) return 0;
02381 return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]);
02382 }
02383
02384 unsigned char lodepng_chunk_ancillary(const unsigned char* chunk)
02385 {
02386 return((chunk[4] & 32) != 0);
02387 }
02388
02389 unsigned char lodepng_chunk_private(const unsigned char* chunk)
02390 {
02391 return((chunk[6] & 32) != 0);
02392 }
02393
02394 unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk)
02395 {
02396 return((chunk[7] & 32) != 0);
02397 }
02398
02399 unsigned char* lodepng_chunk_data(unsigned char* chunk)
02400 {
02401 return &chunk[8];
02402 }
02403
02404 const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk)
02405 {
02406 return &chunk[8];
02407 }
02408
02409 unsigned lodepng_chunk_check_crc(const unsigned char* chunk)
02410 {
02411 unsigned length = lodepng_chunk_length(chunk);
02412 unsigned CRC = lodepng_read32bitInt(&chunk[length + 8]);
02413
02414 unsigned checksum = lodepng_crc32(&chunk[4], length + 4);
02415 if(CRC != checksum) return 1;
02416 else return 0;
02417 }
02418
02419 void lodepng_chunk_generate_crc(unsigned char* chunk)
02420 {
02421 unsigned length = lodepng_chunk_length(chunk);
02422 unsigned CRC = lodepng_crc32(&chunk[4], length + 4);
02423 lodepng_set32bitInt(chunk + 8 + length, CRC);
02424 }
02425
02426 unsigned char* lodepng_chunk_next(unsigned char* chunk)
02427 {
02428 unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12;
02429 return &chunk[total_chunk_length];
02430 }
02431
02432 const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk)
02433 {
02434 unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12;
02435 return &chunk[total_chunk_length];
02436 }
02437
02438 unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk)
02439 {
02440 unsigned i;
02441 unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12;
02442 unsigned char *chunk_start, *new_buffer;
02443 size_t new_length = (*outlength) + total_chunk_length;
02444 if(new_length < total_chunk_length || new_length < (*outlength)) return 77;
02445
02446 new_buffer = (unsigned char*)lodepng_realloc(*out, new_length);
02447 if(!new_buffer) return 83;
02448 (*out) = new_buffer;
02449 (*outlength) = new_length;
02450 chunk_start = &(*out)[new_length - total_chunk_length];
02451
02452 for(i = 0; i < total_chunk_length; i++) chunk_start[i] = chunk[i];
02453
02454 return 0;
02455 }
02456
02457 unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length,
02458 const char* type, const unsigned char* data)
02459 {
02460 unsigned i;
02461 unsigned char *chunk, *new_buffer;
02462 size_t new_length = (*outlength) + length + 12;
02463 if(new_length < length + 12 || new_length < (*outlength)) return 77;
02464 new_buffer = (unsigned char*)lodepng_realloc(*out, new_length);
02465 if(!new_buffer) return 83;
02466 (*out) = new_buffer;
02467 (*outlength) = new_length;
02468 chunk = &(*out)[(*outlength) - length - 12];
02469
02470
02471 lodepng_set32bitInt(chunk, (unsigned)length);
02472
02473
02474 chunk[4] = type[0];
02475 chunk[5] = type[1];
02476 chunk[6] = type[2];
02477 chunk[7] = type[3];
02478
02479
02480 for(i = 0; i < length; i++) chunk[8 + i] = data[i];
02481
02482
02483 lodepng_chunk_generate_crc(chunk);
02484
02485 return 0;
02486 }
02487
02488
02489
02490
02491
02492
02493 static unsigned checkColorValidity(LodePNGColorType colortype, unsigned bd)
02494 {
02495 switch(colortype)
02496 {
02497 case 0: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break;
02498 case 2: if(!( bd == 8 || bd == 16)) return 37; break;
02499 case 3: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; break;
02500 case 4: if(!( bd == 8 || bd == 16)) return 37; break;
02501 case 6: if(!( bd == 8 || bd == 16)) return 37; break;
02502 default: return 31;
02503 }
02504 return 0;
02505 }
02506
02507 static unsigned getNumColorChannels(LodePNGColorType colortype)
02508 {
02509 switch(colortype)
02510 {
02511 case 0: return 1;
02512 case 2: return 3;
02513 case 3: return 1;
02514 case 4: return 2;
02515 case 6: return 4;
02516 }
02517 return 0;
02518 }
02519
02520 static unsigned lodepng_get_bpp_lct(LodePNGColorType colortype, unsigned bitdepth)
02521 {
02522
02523 return getNumColorChannels(colortype) * bitdepth;
02524 }
02525
02526
02527
02528 void lodepng_color_mode_init(LodePNGColorMode* info)
02529 {
02530 info->key_defined = 0;
02531 info->key_r = info->key_g = info->key_b = 0;
02532 info->colortype = LCT_RGBA;
02533 info->bitdepth = 8;
02534 info->palette = 0;
02535 info->palettesize = 0;
02536 }
02537
02538 void lodepng_color_mode_cleanup(LodePNGColorMode* info)
02539 {
02540 lodepng_palette_clear(info);
02541 }
02542
02543 unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source)
02544 {
02545 size_t i;
02546 lodepng_color_mode_cleanup(dest);
02547 *dest = *source;
02548 if(source->palette)
02549 {
02550 dest->palette = (unsigned char*)lodepng_malloc(1024);
02551 if(!dest->palette && source->palettesize) return 83;
02552 for(i = 0; i < source->palettesize * 4; i++) dest->palette[i] = source->palette[i];
02553 }
02554 return 0;
02555 }
02556
02557 static int lodepng_color_mode_equal(const LodePNGColorMode* a, const LodePNGColorMode* b)
02558 {
02559 size_t i;
02560 if(a->colortype != b->colortype) return 0;
02561 if(a->bitdepth != b->bitdepth) return 0;
02562 if(a->key_defined != b->key_defined) return 0;
02563 if(a->key_defined)
02564 {
02565 if(a->key_r != b->key_r) return 0;
02566 if(a->key_g != b->key_g) return 0;
02567 if(a->key_b != b->key_b) return 0;
02568 }
02569 if(a->palettesize != b->palettesize) return 0;
02570 for(i = 0; i < a->palettesize * 4; i++)
02571 {
02572 if(a->palette[i] != b->palette[i]) return 0;
02573 }
02574 return 1;
02575 }
02576
02577 void lodepng_palette_clear(LodePNGColorMode* info)
02578 {
02579 if(info->palette) lodepng_free(info->palette);
02580 info->palette = 0;
02581 info->palettesize = 0;
02582 }
02583
02584 unsigned lodepng_palette_add(LodePNGColorMode* info,
02585 unsigned char r, unsigned char g, unsigned char b, unsigned char a)
02586 {
02587 unsigned char* data;
02588
02589
02590 if(!info->palette)
02591 {
02592
02593 data = (unsigned char*)lodepng_realloc(info->palette, 1024);
02594 if(!data) return 83;
02595 else info->palette = data;
02596 }
02597 info->palette[4 * info->palettesize + 0] = r;
02598 info->palette[4 * info->palettesize + 1] = g;
02599 info->palette[4 * info->palettesize + 2] = b;
02600 info->palette[4 * info->palettesize + 3] = a;
02601 info->palettesize++;
02602 return 0;
02603 }
02604
02605 unsigned lodepng_get_bpp(const LodePNGColorMode* info)
02606 {
02607
02608 return lodepng_get_bpp_lct(info->colortype, info->bitdepth);
02609 }
02610
02611 unsigned lodepng_get_channels(const LodePNGColorMode* info)
02612 {
02613 return getNumColorChannels(info->colortype);
02614 }
02615
02616 unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info)
02617 {
02618 return info->colortype == LCT_GREY || info->colortype == LCT_GREY_ALPHA;
02619 }
02620
02621 unsigned lodepng_is_alpha_type(const LodePNGColorMode* info)
02622 {
02623 return (info->colortype & 4) != 0;
02624 }
02625
02626 unsigned lodepng_is_palette_type(const LodePNGColorMode* info)
02627 {
02628 return info->colortype == LCT_PALETTE;
02629 }
02630
02631 unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info)
02632 {
02633 size_t i;
02634 for(i = 0; i < info->palettesize; i++)
02635 {
02636 if(info->palette[i * 4 + 3] < 255) return 1;
02637 }
02638 return 0;
02639 }
02640
02641 unsigned lodepng_can_have_alpha(const LodePNGColorMode* info)
02642 {
02643 return info->key_defined
02644 || lodepng_is_alpha_type(info)
02645 || lodepng_has_palette_alpha(info);
02646 }
02647
02648 size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color)
02649 {
02650 return (w * h * lodepng_get_bpp(color) + 7) / 8;
02651 }
02652
02653 size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth)
02654 {
02655 return (w * h * lodepng_get_bpp_lct(colortype, bitdepth) + 7) / 8;
02656 }
02657
02658 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
02659
02660 static void LodePNGUnknownChunks_init(LodePNGInfo* info)
02661 {
02662 unsigned i;
02663 for(i = 0; i < 3; i++) info->unknown_chunks_data[i] = 0;
02664 for(i = 0; i < 3; i++) info->unknown_chunks_size[i] = 0;
02665 }
02666
02667 static void LodePNGUnknownChunks_cleanup(LodePNGInfo* info)
02668 {
02669 unsigned i;
02670 for(i = 0; i < 3; i++) lodepng_free(info->unknown_chunks_data[i]);
02671 }
02672
02673 static unsigned LodePNGUnknownChunks_copy(LodePNGInfo* dest, const LodePNGInfo* src)
02674 {
02675 unsigned i;
02676
02677 LodePNGUnknownChunks_cleanup(dest);
02678
02679 for(i = 0; i < 3; i++)
02680 {
02681 size_t j;
02682 dest->unknown_chunks_size[i] = src->unknown_chunks_size[i];
02683 dest->unknown_chunks_data[i] = (unsigned char*)lodepng_malloc(src->unknown_chunks_size[i]);
02684 if(!dest->unknown_chunks_data[i] && dest->unknown_chunks_size[i]) return 83;
02685 for(j = 0; j < src->unknown_chunks_size[i]; j++)
02686 {
02687 dest->unknown_chunks_data[i][j] = src->unknown_chunks_data[i][j];
02688 }
02689 }
02690
02691 return 0;
02692 }
02693
02694
02695
02696 static void LodePNGText_init(LodePNGInfo* info)
02697 {
02698 info->text_num = 0;
02699 info->text_keys = NULL;
02700 info->text_strings = NULL;
02701 }
02702
02703 static void LodePNGText_cleanup(LodePNGInfo* info)
02704 {
02705 size_t i;
02706 for(i = 0; i < info->text_num; i++)
02707 {
02708 string_cleanup(&info->text_keys[i]);
02709 string_cleanup(&info->text_strings[i]);
02710 }
02711 lodepng_free(info->text_keys);
02712 lodepng_free(info->text_strings);
02713 }
02714
02715 static unsigned LodePNGText_copy(LodePNGInfo* dest, const LodePNGInfo* source)
02716 {
02717 size_t i = 0;
02718 dest->text_keys = 0;
02719 dest->text_strings = 0;
02720 dest->text_num = 0;
02721 for(i = 0; i < source->text_num; i++)
02722 {
02723 CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i]));
02724 }
02725 return 0;
02726 }
02727
02728 void lodepng_clear_text(LodePNGInfo* info)
02729 {
02730 LodePNGText_cleanup(info);
02731 }
02732
02733 unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str)
02734 {
02735 char** new_keys = (char**)(lodepng_realloc(info->text_keys, sizeof(char*) * (info->text_num + 1)));
02736 char** new_strings = (char**)(lodepng_realloc(info->text_strings, sizeof(char*) * (info->text_num + 1)));
02737 if(!new_keys || !new_strings)
02738 {
02739 lodepng_free(new_keys);
02740 lodepng_free(new_strings);
02741 return 83;
02742 }
02743
02744 info->text_num++;
02745 info->text_keys = new_keys;
02746 info->text_strings = new_strings;
02747
02748 string_init(&info->text_keys[info->text_num - 1]);
02749 string_set(&info->text_keys[info->text_num - 1], key);
02750
02751 string_init(&info->text_strings[info->text_num - 1]);
02752 string_set(&info->text_strings[info->text_num - 1], str);
02753
02754 return 0;
02755 }
02756
02757
02758
02759 static void LodePNGIText_init(LodePNGInfo* info)
02760 {
02761 info->itext_num = 0;
02762 info->itext_keys = NULL;
02763 info->itext_langtags = NULL;
02764 info->itext_transkeys = NULL;
02765 info->itext_strings = NULL;
02766 }
02767
02768 static void LodePNGIText_cleanup(LodePNGInfo* info)
02769 {
02770 size_t i;
02771 for(i = 0; i < info->itext_num; i++)
02772 {
02773 string_cleanup(&info->itext_keys[i]);
02774 string_cleanup(&info->itext_langtags[i]);
02775 string_cleanup(&info->itext_transkeys[i]);
02776 string_cleanup(&info->itext_strings[i]);
02777 }
02778 lodepng_free(info->itext_keys);
02779 lodepng_free(info->itext_langtags);
02780 lodepng_free(info->itext_transkeys);
02781 lodepng_free(info->itext_strings);
02782 }
02783
02784 static unsigned LodePNGIText_copy(LodePNGInfo* dest, const LodePNGInfo* source)
02785 {
02786 size_t i = 0;
02787 dest->itext_keys = 0;
02788 dest->itext_langtags = 0;
02789 dest->itext_transkeys = 0;
02790 dest->itext_strings = 0;
02791 dest->itext_num = 0;
02792 for(i = 0; i < source->itext_num; i++)
02793 {
02794 CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i],
02795 source->itext_transkeys[i], source->itext_strings[i]));
02796 }
02797 return 0;
02798 }
02799
02800 void lodepng_clear_itext(LodePNGInfo* info)
02801 {
02802 LodePNGIText_cleanup(info);
02803 }
02804
02805 unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag,
02806 const char* transkey, const char* str)
02807 {
02808 char** new_keys = (char**)(lodepng_realloc(info->itext_keys, sizeof(char*) * (info->itext_num + 1)));
02809 char** new_langtags = (char**)(lodepng_realloc(info->itext_langtags, sizeof(char*) * (info->itext_num + 1)));
02810 char** new_transkeys = (char**)(lodepng_realloc(info->itext_transkeys, sizeof(char*) * (info->itext_num + 1)));
02811 char** new_strings = (char**)(lodepng_realloc(info->itext_strings, sizeof(char*) * (info->itext_num + 1)));
02812 if(!new_keys || !new_langtags || !new_transkeys || !new_strings)
02813 {
02814 lodepng_free(new_keys);
02815 lodepng_free(new_langtags);
02816 lodepng_free(new_transkeys);
02817 lodepng_free(new_strings);
02818 return 83;
02819 }
02820
02821 info->itext_num++;
02822 info->itext_keys = new_keys;
02823 info->itext_langtags = new_langtags;
02824 info->itext_transkeys = new_transkeys;
02825 info->itext_strings = new_strings;
02826
02827 string_init(&info->itext_keys[info->itext_num - 1]);
02828 string_set(&info->itext_keys[info->itext_num - 1], key);
02829
02830 string_init(&info->itext_langtags[info->itext_num - 1]);
02831 string_set(&info->itext_langtags[info->itext_num - 1], langtag);
02832
02833 string_init(&info->itext_transkeys[info->itext_num - 1]);
02834 string_set(&info->itext_transkeys[info->itext_num - 1], transkey);
02835
02836 string_init(&info->itext_strings[info->itext_num - 1]);
02837 string_set(&info->itext_strings[info->itext_num - 1], str);
02838
02839 return 0;
02840 }
02841 #endif
02842
02843 void lodepng_info_init(LodePNGInfo* info)
02844 {
02845 lodepng_color_mode_init(&info->color);
02846 info->interlace_method = 0;
02847 info->compression_method = 0;
02848 info->filter_method = 0;
02849 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
02850 info->background_defined = 0;
02851 info->background_r = info->background_g = info->background_b = 0;
02852
02853 LodePNGText_init(info);
02854 LodePNGIText_init(info);
02855
02856 info->time_defined = 0;
02857 info->phys_defined = 0;
02858
02859 LodePNGUnknownChunks_init(info);
02860 #endif
02861 }
02862
02863 void lodepng_info_cleanup(LodePNGInfo* info)
02864 {
02865 lodepng_color_mode_cleanup(&info->color);
02866 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
02867 LodePNGText_cleanup(info);
02868 LodePNGIText_cleanup(info);
02869
02870 LodePNGUnknownChunks_cleanup(info);
02871 #endif
02872 }
02873
02874 unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source)
02875 {
02876 lodepng_info_cleanup(dest);
02877 *dest = *source;
02878 lodepng_color_mode_init(&dest->color);
02879 CERROR_TRY_RETURN(lodepng_color_mode_copy(&dest->color, &source->color));
02880
02881 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
02882 CERROR_TRY_RETURN(LodePNGText_copy(dest, source));
02883 CERROR_TRY_RETURN(LodePNGIText_copy(dest, source));
02884
02885 LodePNGUnknownChunks_init(dest);
02886 CERROR_TRY_RETURN(LodePNGUnknownChunks_copy(dest, source));
02887 #endif
02888 return 0;
02889 }
02890
02891 void lodepng_info_swap(LodePNGInfo* a, LodePNGInfo* b)
02892 {
02893 LodePNGInfo temp = *a;
02894 *a = *b;
02895 *b = temp;
02896 }
02897
02898
02899
02900
02901 static void addColorBits(unsigned char* out, size_t index, unsigned bits, unsigned in)
02902 {
02903
02904 unsigned p = index % (8 / bits);
02905 in &= (1 << bits) - 1;
02906 in = in << (bits * (8 / bits - p - 1));
02907 if(p == 0) out[index * bits / 8] = in;
02908 else out[index * bits / 8] |= in;
02909 }
02910
02911 typedef struct ColorTree ColorTree;
02912
02913
02914
02915
02916
02917
02918
02919 struct ColorTree
02920 {
02921 ColorTree* children[16];
02922 int index;
02923 };
02924
02925 static void color_tree_init(ColorTree* tree)
02926 {
02927 int i;
02928 for(i = 0; i < 16; i++) tree->children[i] = 0;
02929 tree->index = -1;
02930 }
02931
02932 static void color_tree_cleanup(ColorTree* tree)
02933 {
02934 int i;
02935 for(i = 0; i < 16; i++)
02936 {
02937 if(tree->children[i])
02938 {
02939 color_tree_cleanup(tree->children[i]);
02940 lodepng_free(tree->children[i]);
02941 }
02942 }
02943 }
02944
02945
02946 static int color_tree_get(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
02947 {
02948 int bit = 0;
02949 for(bit = 0; bit < 8; bit++)
02950 {
02951 int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1);
02952 if(!tree->children[i]) return -1;
02953 else tree = tree->children[i];
02954 }
02955 return tree ? tree->index : -1;
02956 }
02957
02958 #ifdef LODEPNG_COMPILE_ENCODER
02959 static int color_tree_has(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
02960 {
02961 return color_tree_get(tree, r, g, b, a) >= 0;
02962 }
02963 #endif
02964
02965
02966
02967 static void color_tree_add(ColorTree* tree,
02968 unsigned char r, unsigned char g, unsigned char b, unsigned char a, int index)
02969 {
02970 int bit;
02971 for(bit = 0; bit < 8; bit++)
02972 {
02973 int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1);
02974 if(!tree->children[i])
02975 {
02976 tree->children[i] = (ColorTree*)lodepng_malloc(sizeof(ColorTree));
02977 color_tree_init(tree->children[i]);
02978 }
02979 tree = tree->children[i];
02980 }
02981 tree->index = index;
02982 }
02983
02984
02985 static unsigned rgba8ToPixel(unsigned char* out, size_t i,
02986 const LodePNGColorMode* mode, ColorTree* tree ,
02987 unsigned char r, unsigned char g, unsigned char b, unsigned char a)
02988 {
02989 if(mode->colortype == LCT_GREY)
02990 {
02991 unsigned char grey = r; ;
02992 if(mode->bitdepth == 8) out[i] = grey;
02993 else if(mode->bitdepth == 16) out[i * 2 + 0] = out[i * 2 + 1] = grey;
02994 else
02995 {
02996
02997 grey = (grey >> (8 - mode->bitdepth)) & ((1 << mode->bitdepth) - 1);
02998 addColorBits(out, i, mode->bitdepth, grey);
02999 }
03000 }
03001 else if(mode->colortype == LCT_RGB)
03002 {
03003 if(mode->bitdepth == 8)
03004 {
03005 out[i * 3 + 0] = r;
03006 out[i * 3 + 1] = g;
03007 out[i * 3 + 2] = b;
03008 }
03009 else
03010 {
03011 out[i * 6 + 0] = out[i * 6 + 1] = r;
03012 out[i * 6 + 2] = out[i * 6 + 3] = g;
03013 out[i * 6 + 4] = out[i * 6 + 5] = b;
03014 }
03015 }
03016 else if(mode->colortype == LCT_PALETTE)
03017 {
03018 int index = color_tree_get(tree, r, g, b, a);
03019 if(index < 0) return 82;
03020 if(mode->bitdepth == 8) out[i] = index;
03021 else addColorBits(out, i, mode->bitdepth, index);
03022 }
03023 else if(mode->colortype == LCT_GREY_ALPHA)
03024 {
03025 unsigned char grey = r; ;
03026 if(mode->bitdepth == 8)
03027 {
03028 out[i * 2 + 0] = grey;
03029 out[i * 2 + 1] = a;
03030 }
03031 else if(mode->bitdepth == 16)
03032 {
03033 out[i * 4 + 0] = out[i * 4 + 1] = grey;
03034 out[i * 4 + 2] = out[i * 4 + 3] = a;
03035 }
03036 }
03037 else if(mode->colortype == LCT_RGBA)
03038 {
03039 if(mode->bitdepth == 8)
03040 {
03041 out[i * 4 + 0] = r;
03042 out[i * 4 + 1] = g;
03043 out[i * 4 + 2] = b;
03044 out[i * 4 + 3] = a;
03045 }
03046 else
03047 {
03048 out[i * 8 + 0] = out[i * 8 + 1] = r;
03049 out[i * 8 + 2] = out[i * 8 + 3] = g;
03050 out[i * 8 + 4] = out[i * 8 + 5] = b;
03051 out[i * 8 + 6] = out[i * 8 + 7] = a;
03052 }
03053 }
03054
03055 return 0;
03056 }
03057
03058
03059 static unsigned rgba16ToPixel(unsigned char* out, size_t i,
03060 const LodePNGColorMode* mode,
03061 unsigned short r, unsigned short g, unsigned short b, unsigned short a)
03062 {
03063 if(mode->bitdepth != 16) return 85;
03064 if(mode->colortype == LCT_GREY)
03065 {
03066 unsigned short grey = r; ;
03067 out[i * 2 + 0] = (grey >> 8) & 255;
03068 out[i * 2 + 1] = grey & 255;
03069 }
03070 else if(mode->colortype == LCT_RGB)
03071 {
03072 out[i * 6 + 0] = (r >> 8) & 255;
03073 out[i * 6 + 1] = r & 255;
03074 out[i * 6 + 2] = (g >> 8) & 255;
03075 out[i * 6 + 3] = g & 255;
03076 out[i * 6 + 4] = (b >> 8) & 255;
03077 out[i * 6 + 5] = b & 255;
03078 }
03079 else if(mode->colortype == LCT_GREY_ALPHA)
03080 {
03081 unsigned short grey = r; ;
03082 out[i * 4 + 0] = (grey >> 8) & 255;
03083 out[i * 4 + 1] = grey & 255;
03084 out[i * 4 + 2] = (a >> 8) & 255;
03085 out[i * 4 + 3] = a & 255;
03086 }
03087 else if(mode->colortype == LCT_RGBA)
03088 {
03089 out[i * 8 + 0] = (r >> 8) & 255;
03090 out[i * 8 + 1] = r & 255;
03091 out[i * 8 + 2] = (g >> 8) & 255;
03092 out[i * 8 + 3] = g & 255;
03093 out[i * 8 + 4] = (b >> 8) & 255;
03094 out[i * 8 + 5] = b & 255;
03095 out[i * 8 + 6] = (a >> 8) & 255;
03096 out[i * 8 + 7] = a & 255;
03097 }
03098
03099 return 0;
03100 }
03101
03102
03103 static unsigned getPixelColorRGBA8(unsigned char* r, unsigned char* g,
03104 unsigned char* b, unsigned char* a,
03105 const unsigned char* in, size_t i,
03106 const LodePNGColorMode* mode,
03107 unsigned fix_png)
03108 {
03109 if(mode->colortype == LCT_GREY)
03110 {
03111 if(mode->bitdepth == 8)
03112 {
03113 *r = *g = *b = in[i];
03114 if(mode->key_defined && *r == mode->key_r) *a = 0;
03115 else *a = 255;
03116 }
03117 else if(mode->bitdepth == 16)
03118 {
03119 *r = *g = *b = in[i * 2 + 0];
03120 if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0;
03121 else *a = 255;
03122 }
03123 else
03124 {
03125 unsigned highest = ((1U << mode->bitdepth) - 1U);
03126 size_t j = i * mode->bitdepth;
03127 unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth);
03128 *r = *g = *b = (value * 255) / highest;
03129 if(mode->key_defined && value == mode->key_r) *a = 0;
03130 else *a = 255;
03131 }
03132 }
03133 else if(mode->colortype == LCT_RGB)
03134 {
03135 if(mode->bitdepth == 8)
03136 {
03137 *r = in[i * 3 + 0]; *g = in[i * 3 + 1]; *b = in[i * 3 + 2];
03138 if(mode->key_defined && *r == mode->key_r && *g == mode->key_g && *b == mode->key_b) *a = 0;
03139 else *a = 255;
03140 }
03141 else
03142 {
03143 *r = in[i * 6 + 0];
03144 *g = in[i * 6 + 2];
03145 *b = in[i * 6 + 4];
03146 if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r
03147 && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g
03148 && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0;
03149 else *a = 255;
03150 }
03151 }
03152 else if(mode->colortype == LCT_PALETTE)
03153 {
03154 unsigned index;
03155 if(mode->bitdepth == 8) index = in[i];
03156 else
03157 {
03158 size_t j = i * mode->bitdepth;
03159 index = readBitsFromReversedStream(&j, in, mode->bitdepth);
03160 }
03161
03162 if(index >= mode->palettesize)
03163 {
03164
03165 if(!fix_png) return (mode->bitdepth == 8 ? 46 : 47);
03166 *r = *g = *b = 0;
03167 *a = 255;
03168 }
03169 else
03170 {
03171 *r = mode->palette[index * 4 + 0];
03172 *g = mode->palette[index * 4 + 1];
03173 *b = mode->palette[index * 4 + 2];
03174 *a = mode->palette[index * 4 + 3];
03175 }
03176 }
03177 else if(mode->colortype == LCT_GREY_ALPHA)
03178 {
03179 if(mode->bitdepth == 8)
03180 {
03181 *r = *g = *b = in[i * 2 + 0];
03182 *a = in[i * 2 + 1];
03183 }
03184 else
03185 {
03186 *r = *g = *b = in[i * 4 + 0];
03187 *a = in[i * 4 + 2];
03188 }
03189 }
03190 else if(mode->colortype == LCT_RGBA)
03191 {
03192 if(mode->bitdepth == 8)
03193 {
03194 *r = in[i * 4 + 0];
03195 *g = in[i * 4 + 1];
03196 *b = in[i * 4 + 2];
03197 *a = in[i * 4 + 3];
03198 }
03199 else
03200 {
03201 *r = in[i * 8 + 0];
03202 *g = in[i * 8 + 2];
03203 *b = in[i * 8 + 4];
03204 *a = in[i * 8 + 6];
03205 }
03206 }
03207
03208 return 0;
03209 }
03210
03211
03212
03213
03214
03215
03216 static unsigned getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels,
03217 unsigned has_alpha, const unsigned char* in,
03218 const LodePNGColorMode* mode,
03219 unsigned fix_png)
03220 {
03221 unsigned num_channels = has_alpha ? 4 : 3;
03222 size_t i;
03223 if(mode->colortype == LCT_GREY)
03224 {
03225 if(mode->bitdepth == 8)
03226 {
03227 for(i = 0; i < numpixels; i++, buffer += num_channels)
03228 {
03229 buffer[0] = buffer[1] = buffer[2] = in[i];
03230 if(has_alpha) buffer[3] = mode->key_defined && in[i] == mode->key_r ? 0 : 255;
03231 }
03232 }
03233 else if(mode->bitdepth == 16)
03234 {
03235 for(i = 0; i < numpixels; i++, buffer += num_channels)
03236 {
03237 buffer[0] = buffer[1] = buffer[2] = in[i * 2];
03238 if(has_alpha) buffer[3] = mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r ? 0 : 255;
03239 }
03240 }
03241 else
03242 {
03243 unsigned highest = ((1U << mode->bitdepth) - 1U);
03244 size_t j = 0;
03245 for(i = 0; i < numpixels; i++, buffer += num_channels)
03246 {
03247 unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth);
03248 buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest;
03249 if(has_alpha) buffer[3] = mode->key_defined && value == mode->key_r ? 0 : 255;
03250 }
03251 }
03252 }
03253 else if(mode->colortype == LCT_RGB)
03254 {
03255 if(mode->bitdepth == 8)
03256 {
03257 for(i = 0; i < numpixels; i++, buffer += num_channels)
03258 {
03259 buffer[0] = in[i * 3 + 0];
03260 buffer[1] = in[i * 3 + 1];
03261 buffer[2] = in[i * 3 + 2];
03262 if(has_alpha) buffer[3] = mode->key_defined && buffer[0] == mode->key_r
03263 && buffer[1]== mode->key_g && buffer[2] == mode->key_b ? 0 : 255;
03264 }
03265 }
03266 else
03267 {
03268 for(i = 0; i < numpixels; i++, buffer += num_channels)
03269 {
03270 buffer[0] = in[i * 6 + 0];
03271 buffer[1] = in[i * 6 + 2];
03272 buffer[2] = in[i * 6 + 4];
03273 if(has_alpha) buffer[3] = mode->key_defined
03274 && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r
03275 && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g
03276 && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b ? 0 : 255;
03277 }
03278 }
03279 }
03280 else if(mode->colortype == LCT_PALETTE)
03281 {
03282 unsigned index;
03283 size_t j = 0;
03284 for(i = 0; i < numpixels; i++, buffer += num_channels)
03285 {
03286 if(mode->bitdepth == 8) index = in[i];
03287 else index = readBitsFromReversedStream(&j, in, mode->bitdepth);
03288
03289 if(index >= mode->palettesize)
03290 {
03291
03292 if(!fix_png) return (mode->bitdepth == 8 ? 46 : 47);
03293 buffer[0] = buffer[1] = buffer[2] = 0;
03294 if(has_alpha) buffer[3] = 255;
03295 }
03296 else
03297 {
03298 buffer[0] = mode->palette[index * 4 + 0];
03299 buffer[1] = mode->palette[index * 4 + 1];
03300 buffer[2] = mode->palette[index * 4 + 2];
03301 if(has_alpha) buffer[3] = mode->palette[index * 4 + 3];
03302 }
03303 }
03304 }
03305 else if(mode->colortype == LCT_GREY_ALPHA)
03306 {
03307 if(mode->bitdepth == 8)
03308 {
03309 for(i = 0; i < numpixels; i++, buffer += num_channels)
03310 {
03311 buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0];
03312 if(has_alpha) buffer[3] = in[i * 2 + 1];
03313 }
03314 }
03315 else
03316 {
03317 for(i = 0; i < numpixels; i++, buffer += num_channels)
03318 {
03319 buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0];
03320 if(has_alpha) buffer[3] = in[i * 4 + 2];
03321 }
03322 }
03323 }
03324 else if(mode->colortype == LCT_RGBA)
03325 {
03326 if(mode->bitdepth == 8)
03327 {
03328 for(i = 0; i < numpixels; i++, buffer += num_channels)
03329 {
03330 buffer[0] = in[i * 4 + 0];
03331 buffer[1] = in[i * 4 + 1];
03332 buffer[2] = in[i * 4 + 2];
03333 if(has_alpha) buffer[3] = in[i * 4 + 3];
03334 }
03335 }
03336 else
03337 {
03338 for(i = 0; i < numpixels; i++, buffer += num_channels)
03339 {
03340 buffer[0] = in[i * 8 + 0];
03341 buffer[1] = in[i * 8 + 2];
03342 buffer[2] = in[i * 8 + 4];
03343 if(has_alpha) buffer[3] = in[i * 8 + 6];
03344 }
03345 }
03346 }
03347
03348 return 0;
03349 }
03350
03351
03352
03353 static unsigned getPixelColorRGBA16(unsigned short* r, unsigned short* g, unsigned short* b, unsigned short* a,
03354 const unsigned char* in, size_t i, const LodePNGColorMode* mode)
03355 {
03356 if(mode->bitdepth != 16) return 85;
03357
03358 if(mode->colortype == LCT_GREY)
03359 {
03360 *r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1];
03361 if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0;
03362 else *a = 65535;
03363 }
03364 else if(mode->colortype == LCT_RGB)
03365 {
03366 *r = 256 * in[i * 6 + 0] + in[i * 6 + 1];
03367 *g = 256 * in[i * 6 + 2] + in[i * 6 + 3];
03368 *b = 256 * in[i * 6 + 4] + in[i * 6 + 5];
03369 if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r
03370 && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g
03371 && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0;
03372 else *a = 65535;
03373 }
03374 else if(mode->colortype == LCT_GREY_ALPHA)
03375 {
03376 *r = *g = *b = 256 * in[i * 4 + 0] + in[i * 4 + 1];
03377 *a = 256 * in[i * 4 + 2] + in[i * 4 + 3];
03378 }
03379 else if(mode->colortype == LCT_RGBA)
03380 {
03381 *r = 256 * in[i * 8 + 0] + in[i * 8 + 1];
03382 *g = 256 * in[i * 8 + 2] + in[i * 8 + 3];
03383 *b = 256 * in[i * 8 + 4] + in[i * 8 + 5];
03384 *a = 256 * in[i * 8 + 6] + in[i * 8 + 7];
03385 }
03386 else return 85;
03387
03388 return 0;
03389 }
03390
03391
03392
03393
03394
03395
03396 unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
03397 LodePNGColorMode* mode_out, LodePNGColorMode* mode_in,
03398 unsigned w, unsigned h, unsigned fix_png)
03399 {
03400 unsigned error = 0;
03401 size_t i;
03402 ColorTree tree;
03403 size_t numpixels = w * h;
03404
03405 if(lodepng_color_mode_equal(mode_out, mode_in))
03406 {
03407 size_t numbytes = lodepng_get_raw_size(w, h, mode_in);
03408 for(i = 0; i < numbytes; i++) out[i] = in[i];
03409 return error;
03410 }
03411
03412 if(mode_out->colortype == LCT_PALETTE)
03413 {
03414 size_t palsize = 1 << mode_out->bitdepth;
03415 if(mode_out->palettesize < palsize) palsize = mode_out->palettesize;
03416 color_tree_init(&tree);
03417 for(i = 0; i < palsize; i++)
03418 {
03419 unsigned char* p = &mode_out->palette[i * 4];
03420 color_tree_add(&tree, p[0], p[1], p[2], p[3], i);
03421 }
03422 }
03423
03424 if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16)
03425 {
03426 for(i = 0; i < numpixels; i++)
03427 {
03428 unsigned short r = 0, g = 0, b = 0, a = 0;
03429 error = getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in);
03430 if(error) break;
03431 error = rgba16ToPixel(out, i, mode_out, r, g, b, a);
03432 if(error) break;
03433 }
03434 }
03435 else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA)
03436 {
03437 error = getPixelColorsRGBA8(out, numpixels, 1, in, mode_in, fix_png);
03438 }
03439 else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB)
03440 {
03441 error = getPixelColorsRGBA8(out, numpixels, 0, in, mode_in, fix_png);
03442 }
03443 else
03444 {
03445 unsigned char r = 0, g = 0, b = 0, a = 0;
03446 for(i = 0; i < numpixels; i++)
03447 {
03448 error = getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in, fix_png);
03449 if(error) break;
03450 error = rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a);
03451 if(error) break;
03452 }
03453 }
03454
03455 if(mode_out->colortype == LCT_PALETTE)
03456 {
03457 color_tree_cleanup(&tree);
03458 }
03459
03460 return error;
03461 }
03462
03463 #ifdef LODEPNG_COMPILE_ENCODER
03464
03465 typedef struct ColorProfile
03466 {
03467 unsigned char sixteenbit;
03468 unsigned char sixteenbit_done;
03469
03470
03471 unsigned char colored;
03472 unsigned char colored_done;
03473
03474 unsigned char key;
03475 unsigned short key_r;
03476 unsigned short key_g;
03477 unsigned short key_b;
03478 unsigned char alpha;
03479 unsigned char alpha_done;
03480
03481 unsigned numcolors;
03482 ColorTree tree;
03483 unsigned char* palette;
03484 unsigned maxnumcolors;
03485 unsigned char numcolors_done;
03486
03487 unsigned greybits;
03488 unsigned char greybits_done;
03489
03490 } ColorProfile;
03491
03492 static void color_profile_init(ColorProfile* profile, LodePNGColorMode* mode)
03493 {
03494 profile->sixteenbit = 0;
03495 profile->sixteenbit_done = mode->bitdepth == 16 ? 0 : 1;
03496
03497 profile->colored = 0;
03498 profile->colored_done = lodepng_is_greyscale_type(mode) ? 1 : 0;
03499
03500 profile->key = 0;
03501 profile->alpha = 0;
03502 profile->alpha_done = lodepng_can_have_alpha(mode) ? 0 : 1;
03503
03504 profile->numcolors = 0;
03505 color_tree_init(&profile->tree);
03506 profile->palette = (unsigned char*)lodepng_malloc(1024);
03507 profile->maxnumcolors = 257;
03508 if(lodepng_get_bpp(mode) <= 8)
03509 {
03510 int bpp = lodepng_get_bpp(mode);
03511 profile->maxnumcolors = bpp == 1 ? 2 : (bpp == 2 ? 4 : (bpp == 4 ? 16 : 256));
03512 }
03513 profile->numcolors_done = 0;
03514
03515 profile->greybits = 1;
03516 profile->greybits_done = lodepng_get_bpp(mode) == 1 ? 1 : 0;
03517 }
03518
03519 static void color_profile_cleanup(ColorProfile* profile)
03520 {
03521 color_tree_cleanup(&profile->tree);
03522 lodepng_free(profile->palette);
03523 }
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546 unsigned getValueRequiredBits(unsigned short value)
03547 {
03548 if(value == 0 || value == 255) return 1;
03549
03550 if(value % 17 == 0) return value % 85 == 0 ? 2 : 4;
03551 return 8;
03552 }
03553
03554
03555
03556 static unsigned get_color_profile(ColorProfile* profile,
03557 const unsigned char* in,
03558 size_t numpixels ,
03559 LodePNGColorMode* mode,
03560 unsigned fix_png)
03561 {
03562 unsigned error = 0;
03563 size_t i;
03564
03565 if(mode->bitdepth == 16)
03566 {
03567 for(i = 0; i < numpixels; i++)
03568 {
03569 unsigned short r, g, b, a;
03570 error = getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode);
03571 if(error) break;
03572
03573
03574
03575 if(!profile->sixteenbit_done
03576 && (((r & 255) != ((r >> 8) & 255))
03577 || ((g & 255) != ((g >> 8) & 255))
03578 || ((b & 255) != ((b >> 8) & 255))))
03579 {
03580 profile->sixteenbit = 1;
03581 profile->sixteenbit_done = 1;
03582 profile->greybits_done = 1;
03583 profile->numcolors_done = 1;
03584 }
03585
03586 if(!profile->colored_done && (r != g || r != b))
03587 {
03588 profile->colored = 1;
03589 profile->colored_done = 1;
03590 profile->greybits_done = 1;
03591 }
03592
03593 if(!profile->alpha_done && a != 65535)
03594 {
03595
03596 if(a == 0 && numpixels > 16 && !(profile->key && (r != profile->key_r || g != profile->key_g || b != profile->key_b)))
03597 {
03598 if(!profile->alpha && !profile->key)
03599 {
03600 profile->key = 1;
03601 profile->key_r = r;
03602 profile->key_g = g;
03603 profile->key_b = b;
03604 }
03605 }
03606 else
03607 {
03608 profile->alpha = 1;
03609 profile->alpha_done = 1;
03610 profile->greybits_done = 1;
03611 }
03612 }
03613
03614
03615 if(!profile->alpha_done && a == 65535 && profile->key
03616 && r == profile->key_r && g == profile->key_g && b == profile->key_b)
03617 {
03618 profile->alpha = 1;
03619 profile->alpha_done = 1;
03620 profile->greybits_done = 1;
03621 }
03622
03623 if(!profile->greybits_done)
03624 {
03625
03626 unsigned bits = getValueRequiredBits(r);
03627 if(bits > profile->greybits) profile->greybits = bits;
03628 if(profile->greybits >= 8) profile->greybits_done = 1;
03629 }
03630
03631 if(!profile->numcolors_done)
03632 {
03633
03634 if(!color_tree_has(&profile->tree, (unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a))
03635 {
03636 color_tree_add(&profile->tree, (unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a,
03637 profile->numcolors);
03638 if(profile->numcolors < 256)
03639 {
03640 unsigned char* p = profile->palette;
03641 unsigned i = profile->numcolors;
03642 p[i * 4 + 0] = (unsigned char)r;
03643 p[i * 4 + 1] = (unsigned char)g;
03644 p[i * 4 + 2] = (unsigned char)b;
03645 p[i * 4 + 3] = (unsigned char)a;
03646 }
03647 profile->numcolors++;
03648 if(profile->numcolors >= profile->maxnumcolors) profile->numcolors_done = 1;
03649 }
03650 }
03651
03652 if(profile->alpha_done && profile->numcolors_done
03653 && profile->colored_done && profile->sixteenbit_done && profile->greybits_done)
03654 {
03655 break;
03656 }
03657 };
03658 }
03659 else
03660 {
03661 for(i = 0; i < numpixels; i++)
03662 {
03663 unsigned char r = 0, g = 0, b = 0, a = 0;
03664 error = getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode, fix_png);
03665 if(error) break;
03666
03667 if(!profile->colored_done && (r != g || r != b))
03668 {
03669 profile->colored = 1;
03670 profile->colored_done = 1;
03671 profile->greybits_done = 1;
03672 }
03673
03674 if(!profile->alpha_done && a != 255)
03675 {
03676 if(a == 0 && !(profile->key && (r != profile->key_r || g != profile->key_g || b != profile->key_b)))
03677 {
03678 if(!profile->key)
03679 {
03680 profile->key = 1;
03681 profile->key_r = r;
03682 profile->key_g = g;
03683 profile->key_b = b;
03684 }
03685 }
03686 else
03687 {
03688 profile->alpha = 1;
03689 profile->alpha_done = 1;
03690 profile->greybits_done = 1;
03691 }
03692 }
03693
03694
03695 if(!profile->alpha_done && a == 255 && profile->key
03696 && r == profile->key_r && g == profile->key_g && b == profile->key_b)
03697 {
03698 profile->alpha = 1;
03699 profile->alpha_done = 1;
03700 profile->greybits_done = 1;
03701 }
03702
03703 if(!profile->greybits_done)
03704 {
03705 unsigned bits = getValueRequiredBits(r);
03706 if(bits > profile->greybits) profile->greybits = bits;
03707 if(profile->greybits >= 8) profile->greybits_done = 1;
03708 }
03709
03710 if(!profile->numcolors_done)
03711 {
03712 if(!color_tree_has(&profile->tree, r, g, b, a))
03713 {
03714
03715 color_tree_add(&profile->tree, r, g, b, a, profile->numcolors);
03716 if(profile->numcolors < 256)
03717 {
03718 unsigned char* p = profile->palette;
03719 unsigned i = profile->numcolors;
03720 p[i * 4 + 0] = r;
03721 p[i * 4 + 1] = g;
03722 p[i * 4 + 2] = b;
03723 p[i * 4 + 3] = a;
03724 }
03725 profile->numcolors++;
03726 if(profile->numcolors >= profile->maxnumcolors) profile->numcolors_done = 1;
03727 }
03728 }
03729
03730 if(profile->alpha_done && profile->numcolors_done && profile->colored_done && profile->greybits_done)
03731 {
03732 break;
03733 }
03734 };
03735 }
03736
03737
03738 if(mode->bitdepth < 16)
03739 {
03740
03741 profile->key_r *= 257;
03742 profile->key_g *= 257;
03743 profile->key_b *= 257;
03744 }
03745
03746 return error;
03747 }
03748
03749 static void setColorKeyFrom16bit(LodePNGColorMode* mode_out, unsigned r, unsigned g, unsigned b, unsigned bitdepth)
03750 {
03751 unsigned mask = (1 << bitdepth) - 1;
03752 mode_out->key_defined = 1;
03753 mode_out->key_r = r & mask;
03754 mode_out->key_g = g & mask;
03755 mode_out->key_b = b & mask;
03756 }
03757
03758
03759
03760 static unsigned doAutoChooseColor(LodePNGColorMode* mode_out,
03761 const unsigned char* image, unsigned w, unsigned h, LodePNGColorMode* mode_in,
03762 LodePNGAutoConvert auto_convert)
03763 {
03764 ColorProfile profile;
03765 unsigned error = 0;
03766 int no_nibbles = auto_convert == LAC_AUTO_NO_NIBBLES || auto_convert == LAC_AUTO_NO_NIBBLES_NO_PALETTE;
03767 int no_palette = auto_convert == LAC_AUTO_NO_PALETTE || auto_convert == LAC_AUTO_NO_NIBBLES_NO_PALETTE;
03768
03769 if(auto_convert == LAC_ALPHA)
03770 {
03771 if(mode_out->colortype != LCT_RGBA && mode_out->colortype != LCT_GREY_ALPHA) return 0;
03772 }
03773
03774 color_profile_init(&profile, mode_in);
03775 if(auto_convert == LAC_ALPHA)
03776 {
03777 profile.colored_done = 1;
03778 profile.greybits_done = 1;
03779 profile.numcolors_done = 1;
03780 profile.sixteenbit_done = 1;
03781 }
03782 error = get_color_profile(&profile, image, w * h, mode_in, 0 );
03783 if(!error && auto_convert == LAC_ALPHA)
03784 {
03785 if(!profile.alpha)
03786 {
03787 mode_out->colortype = (mode_out->colortype == LCT_RGBA ? LCT_RGB : LCT_GREY);
03788 if(profile.key) setColorKeyFrom16bit(mode_out, profile.key_r, profile.key_g, profile.key_b, mode_out->bitdepth);
03789 }
03790 }
03791 else if(!error && auto_convert != LAC_ALPHA)
03792 {
03793 mode_out->key_defined = 0;
03794
03795 if(profile.sixteenbit)
03796 {
03797 mode_out->bitdepth = 16;
03798 if(profile.alpha)
03799 {
03800 mode_out->colortype = profile.colored ? LCT_RGBA : LCT_GREY_ALPHA;
03801 }
03802 else
03803 {
03804 mode_out->colortype = profile.colored ? LCT_RGB : LCT_GREY;
03805 if(profile.key) setColorKeyFrom16bit(mode_out, profile.key_r, profile.key_g, profile.key_b, mode_out->bitdepth);
03806 }
03807 }
03808 else
03809 {
03810
03811 unsigned n = profile.numcolors;
03812 int palette_ok = !no_palette && n <= 256 && (n * 2 < w * h);
03813 unsigned palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8));
03814 int grey_ok = !profile.colored && !profile.alpha;
03815 if(palette_ok || grey_ok)
03816 {
03817 if(!palette_ok || (grey_ok && profile.greybits <= palettebits))
03818 {
03819 unsigned grey = profile.key_r;
03820 mode_out->colortype = LCT_GREY;
03821 mode_out->bitdepth = profile.greybits;
03822 if(profile.key) setColorKeyFrom16bit(mode_out, grey, grey, grey, mode_out->bitdepth);
03823 }
03824 else
03825 {
03826
03827 unsigned i;
03828 unsigned char* p = profile.palette;
03829
03830 lodepng_palette_clear(mode_out);
03831 for(i = 0; i < profile.numcolors; i++)
03832 {
03833 error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]);
03834 if(error) break;
03835 }
03836
03837 mode_out->colortype = LCT_PALETTE;
03838 mode_out->bitdepth = palettebits;
03839 }
03840 }
03841 else
03842 {
03843 mode_out->bitdepth = 8;
03844 if(profile.alpha)
03845 {
03846 mode_out->colortype = profile.colored ? LCT_RGBA : LCT_GREY_ALPHA;
03847 }
03848 else
03849 {
03850 mode_out->colortype = profile.colored ? LCT_RGB : LCT_GREY ;
03851 if(profile.key) setColorKeyFrom16bit(mode_out, profile.key_r, profile.key_g, profile.key_b, mode_out->bitdepth);
03852 }
03853 }
03854 }
03855 }
03856
03857 color_profile_cleanup(&profile);
03858
03859 if(mode_out->colortype == LCT_PALETTE && mode_in->palettesize == mode_out->palettesize)
03860 {
03861
03862 size_t i;
03863 for(i = 0; i < mode_in->palettesize * 4; i++)
03864 {
03865 mode_out->palette[i] = mode_in->palette[i];
03866 }
03867 }
03868
03869 if(no_nibbles && mode_out->bitdepth < 8)
03870 {
03871
03872 mode_out->bitdepth = 8;
03873 }
03874
03875 return error;
03876 }
03877
03878 #endif
03879
03880
03881
03882
03883
03884
03885 static unsigned char paethPredictor(short a, short b, short c)
03886 {
03887 short pa = abs(b - c);
03888 short pb = abs(a - c);
03889 short pc = abs(a + b - c - c);
03890
03891 if(pc < pa && pc < pb) return (unsigned char)c;
03892 else if(pb < pa) return (unsigned char)b;
03893 else return (unsigned char)a;
03894 }
03895
03896
03897
03898 static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 };
03899 static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 };
03900 static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 };
03901 static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 };
03902
03903
03904
03905
03906
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918 static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8],
03919 size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp)
03920 {
03921
03922 unsigned i;
03923
03924
03925 for(i = 0; i < 7; i++)
03926 {
03927 passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i];
03928 passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i];
03929 if(passw[i] == 0) passh[i] = 0;
03930 if(passh[i] == 0) passw[i] = 0;
03931 }
03932
03933 filter_passstart[0] = padded_passstart[0] = passstart[0] = 0;
03934 for(i = 0; i < 7; i++)
03935 {
03936
03937 filter_passstart[i + 1] = filter_passstart[i]
03938 + ((passw[i] && passh[i]) ? passh[i] * (1 + (passw[i] * bpp + 7) / 8) : 0);
03939
03940 padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7) / 8);
03941
03942 passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7) / 8;
03943 }
03944 }
03945
03946 #ifdef LODEPNG_COMPILE_DECODER
03947
03948
03949
03950
03951
03952
03953 unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state,
03954 const unsigned char* in, size_t insize)
03955 {
03956 LodePNGInfo* info = &state->info_png;
03957 if(insize == 0 || in == 0)
03958 {
03959 CERROR_RETURN_ERROR(state->error, 48);
03960 }
03961 if(insize < 29)
03962 {
03963 CERROR_RETURN_ERROR(state->error, 27);
03964 }
03965
03966
03967 lodepng_info_cleanup(info);
03968 lodepng_info_init(info);
03969
03970 if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71
03971 || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10)
03972 {
03973 CERROR_RETURN_ERROR(state->error, 28);
03974 }
03975 if(in[12] != 'I' || in[13] != 'H' || in[14] != 'D' || in[15] != 'R')
03976 {
03977 CERROR_RETURN_ERROR(state->error, 29);
03978 }
03979
03980
03981 *w = lodepng_read32bitInt(&in[16]);
03982 *h = lodepng_read32bitInt(&in[20]);
03983 info->color.bitdepth = in[24];
03984 info->color.colortype = (LodePNGColorType)in[25];
03985 info->compression_method = in[26];
03986 info->filter_method = in[27];
03987 info->interlace_method = in[28];
03988
03989 if(!state->decoder.ignore_crc)
03990 {
03991 unsigned CRC = lodepng_read32bitInt(&in[29]);
03992 unsigned checksum = lodepng_crc32(&in[12], 17);
03993 if(CRC != checksum)
03994 {
03995 CERROR_RETURN_ERROR(state->error, 57);
03996 }
03997 }
03998
03999
04000 if(info->compression_method != 0) CERROR_RETURN_ERROR(state->error, 32);
04001
04002 if(info->filter_method != 0) CERROR_RETURN_ERROR(state->error, 33);
04003
04004 if(info->interlace_method > 1) CERROR_RETURN_ERROR(state->error, 34);
04005
04006 state->error = checkColorValidity(info->color.colortype, info->color.bitdepth);
04007 return state->error;
04008 }
04009
04010 static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon,
04011 size_t bytewidth, unsigned char filterType, size_t length)
04012 {
04013
04014
04015
04016
04017
04018
04019
04020
04021
04022 size_t i;
04023 switch(filterType)
04024 {
04025 case 0:
04026 for(i = 0; i < length; i++) recon[i] = scanline[i];
04027 break;
04028 case 1:
04029 for(i = 0; i < bytewidth; i++) recon[i] = scanline[i];
04030 for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth];
04031 break;
04032 case 2:
04033 if(precon)
04034 {
04035 for(i = 0; i < length; i++) recon[i] = scanline[i] + precon[i];
04036 }
04037 else
04038 {
04039 for(i = 0; i < length; i++) recon[i] = scanline[i];
04040 }
04041 break;
04042 case 3:
04043 if(precon)
04044 {
04045 for(i = 0; i < bytewidth; i++) recon[i] = scanline[i] + precon[i] / 2;
04046 for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2);
04047 }
04048 else
04049 {
04050 for(i = 0; i < bytewidth; i++) recon[i] = scanline[i];
04051 for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth] / 2;
04052 }
04053 break;
04054 case 4:
04055 if(precon)
04056 {
04057 for(i = 0; i < bytewidth; i++)
04058 {
04059 recon[i] = (scanline[i] + precon[i]);
04060 }
04061 for(i = bytewidth; i < length; i++)
04062 {
04063 recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth]));
04064 }
04065 }
04066 else
04067 {
04068 for(i = 0; i < bytewidth; i++)
04069 {
04070 recon[i] = scanline[i];
04071 }
04072 for(i = bytewidth; i < length; i++)
04073 {
04074
04075 recon[i] = (scanline[i] + recon[i - bytewidth]);
04076 }
04077 }
04078 break;
04079 default: return 36;
04080 }
04081 return 0;
04082 }
04083
04084 static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp)
04085 {
04086
04087
04088
04089
04090
04091
04092
04093
04094 unsigned y;
04095 unsigned char* prevline = 0;
04096
04097
04098 size_t bytewidth = (bpp + 7) / 8;
04099 size_t linebytes = (w * bpp + 7) / 8;
04100
04101 for(y = 0; y < h; y++)
04102 {
04103 size_t outindex = linebytes * y;
04104 size_t inindex = (1 + linebytes) * y;
04105 unsigned char filterType = in[inindex];
04106
04107 CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes));
04108
04109 prevline = &out[outindex];
04110 }
04111
04112 return 0;
04113 }
04114
04115
04116
04117
04118
04119
04120
04121
04122
04123
04124
04125
04126 static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp)
04127 {
04128 unsigned passw[7], passh[7];
04129 size_t filter_passstart[8], padded_passstart[8], passstart[8];
04130 unsigned i;
04131
04132 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
04133
04134 if(bpp >= 8)
04135 {
04136 for(i = 0; i < 7; i++)
04137 {
04138 unsigned x, y, b;
04139 size_t bytewidth = bpp / 8;
04140 for(y = 0; y < passh[i]; y++)
04141 for(x = 0; x < passw[i]; x++)
04142 {
04143 size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth;
04144 size_t pixeloutstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth;
04145 for(b = 0; b < bytewidth; b++)
04146 {
04147 out[pixeloutstart + b] = in[pixelinstart + b];
04148 }
04149 }
04150 }
04151 }
04152 else
04153 {
04154 for(i = 0; i < 7; i++)
04155 {
04156 unsigned x, y, b;
04157 unsigned ilinebits = bpp * passw[i];
04158 unsigned olinebits = bpp * w;
04159 size_t obp, ibp;
04160 for(y = 0; y < passh[i]; y++)
04161 for(x = 0; x < passw[i]; x++)
04162 {
04163 ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp);
04164 obp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp;
04165 for(b = 0; b < bpp; b++)
04166 {
04167 unsigned char bit = readBitFromReversedStream(&ibp, in);
04168
04169 setBitOfReversedStream0(&obp, out, bit);
04170 }
04171 }
04172 }
04173 }
04174 }
04175
04176 static void removePaddingBits(unsigned char* out, const unsigned char* in,
04177 size_t olinebits, size_t ilinebits, unsigned h)
04178 {
04179
04180
04181
04182
04183
04184
04185
04186
04187
04188 unsigned y;
04189 size_t diff = ilinebits - olinebits;
04190 size_t ibp = 0, obp = 0;
04191 for(y = 0; y < h; y++)
04192 {
04193 size_t x;
04194 for(x = 0; x < olinebits; x++)
04195 {
04196 unsigned char bit = readBitFromReversedStream(&ibp, in);
04197 setBitOfReversedStream(&obp, out, bit);
04198 }
04199 ibp += diff;
04200 }
04201 }
04202
04203
04204
04205
04206 static unsigned postProcessScanlines(unsigned char* out, unsigned char* in,
04207 unsigned w, unsigned h, const LodePNGInfo* info_png)
04208 {
04209
04210
04211
04212
04213
04214
04215
04216 unsigned bpp = lodepng_get_bpp(&info_png->color);
04217 if(bpp == 0) return 31;
04218
04219 if(info_png->interlace_method == 0)
04220 {
04221 if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8)
04222 {
04223 CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp));
04224 removePaddingBits(out, in, w * bpp, ((w * bpp + 7) / 8) * 8, h);
04225 }
04226
04227 else CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp));
04228 }
04229 else
04230 {
04231 unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8];
04232 unsigned i;
04233
04234 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
04235
04236 for(i = 0; i < 7; i++)
04237 {
04238 CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp));
04239
04240
04241 if(bpp < 8)
04242 {
04243
04244
04245 removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp,
04246 ((passw[i] * bpp + 7) / 8) * 8, passh[i]);
04247 }
04248 }
04249
04250 Adam7_deinterlace(out, in, w, h, bpp);
04251 }
04252
04253 return 0;
04254 }
04255
04256 static unsigned readChunk_PLTE(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength)
04257 {
04258 unsigned pos = 0, i;
04259 if(color->palette) lodepng_free(color->palette);
04260 color->palettesize = chunkLength / 3;
04261 color->palette = (unsigned char*)lodepng_malloc(4 * color->palettesize);
04262 if(!color->palette && color->palettesize)
04263 {
04264 color->palettesize = 0;
04265 return 83;
04266 }
04267 if(color->palettesize > 256) return 38;
04268
04269 for(i = 0; i < color->palettesize; i++)
04270 {
04271 color->palette[4 * i + 0] = data[pos++];
04272 color->palette[4 * i + 1] = data[pos++];
04273 color->palette[4 * i + 2] = data[pos++];
04274 color->palette[4 * i + 3] = 255;
04275 }
04276
04277 return 0;
04278 }
04279
04280 static unsigned readChunk_tRNS(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength)
04281 {
04282 unsigned i;
04283 if(color->colortype == LCT_PALETTE)
04284 {
04285
04286 if(chunkLength > color->palettesize) return 38;
04287
04288 for(i = 0; i < chunkLength; i++) color->palette[4 * i + 3] = data[i];
04289 }
04290 else if(color->colortype == LCT_GREY)
04291 {
04292
04293 if(chunkLength != 2) return 30;
04294
04295 color->key_defined = 1;
04296 color->key_r = color->key_g = color->key_b = 256 * data[0] + data[1];
04297 }
04298 else if(color->colortype == LCT_RGB)
04299 {
04300
04301 if(chunkLength != 6) return 41;
04302
04303 color->key_defined = 1;
04304 color->key_r = 256 * data[0] + data[1];
04305 color->key_g = 256 * data[2] + data[3];
04306 color->key_b = 256 * data[4] + data[5];
04307 }
04308 else return 42;
04309
04310 return 0;
04311 }
04312
04313
04314 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
04315
04316 static unsigned readChunk_bKGD(LodePNGInfo* info, const unsigned char* data, size_t chunkLength)
04317 {
04318 if(info->color.colortype == LCT_PALETTE)
04319 {
04320
04321 if(chunkLength != 1) return 43;
04322
04323 info->background_defined = 1;
04324 info->background_r = info->background_g = info->background_b = data[0];
04325 }
04326 else if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA)
04327 {
04328
04329 if(chunkLength != 2) return 44;
04330
04331 info->background_defined = 1;
04332 info->background_r = info->background_g = info->background_b
04333 = 256 * data[0] + data[1];
04334 }
04335 else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA)
04336 {
04337
04338 if(chunkLength != 6) return 45;
04339
04340 info->background_defined = 1;
04341 info->background_r = 256 * data[0] + data[1];
04342 info->background_g = 256 * data[2] + data[3];
04343 info->background_b = 256 * data[4] + data[5];
04344 }
04345
04346 return 0;
04347 }
04348
04349
04350 static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, size_t chunkLength)
04351 {
04352 unsigned error = 0;
04353 char *key = 0, *str = 0;
04354 unsigned i;
04355
04356 while(!error)
04357 {
04358 unsigned length, string2_begin;
04359
04360 length = 0;
04361 while(length < chunkLength && data[length] != 0) length++;
04362
04363
04364 if(length < 1 || length > 79) CERROR_BREAK(error, 89);
04365
04366 key = (char*)lodepng_malloc(length + 1);
04367 if(!key) CERROR_BREAK(error, 83);
04368
04369 key[length] = 0;
04370 for(i = 0; i < length; i++) key[i] = data[i];
04371
04372 string2_begin = length + 1;
04373
04374 length = chunkLength < string2_begin ? 0 : chunkLength - string2_begin;
04375 str = (char*)lodepng_malloc(length + 1);
04376 if(!str) CERROR_BREAK(error, 83);
04377
04378 str[length] = 0;
04379 for(i = 0; i < length; i++) str[i] = data[string2_begin + i];
04380
04381 error = lodepng_add_text(info, key, str);
04382
04383 break;
04384 }
04385
04386 lodepng_free(key);
04387 lodepng_free(str);
04388
04389 return error;
04390 }
04391
04392
04393 static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings,
04394 const unsigned char* data, size_t chunkLength)
04395 {
04396 unsigned error = 0;
04397 unsigned i;
04398
04399 unsigned length, string2_begin;
04400 char *key = 0;
04401 ucvector decoded;
04402
04403 ucvector_init(&decoded);
04404
04405 while(!error)
04406 {
04407 for(length = 0; length < chunkLength && data[length] != 0; length++) ;
04408 if(length + 2 >= chunkLength) CERROR_BREAK(error, 75);
04409 if(length < 1 || length > 79) CERROR_BREAK(error, 89);
04410
04411 key = (char*)lodepng_malloc(length + 1);
04412 if(!key) CERROR_BREAK(error, 83);
04413
04414 key[length] = 0;
04415 for(i = 0; i < length; i++) key[i] = data[i];
04416
04417 if(data[length + 1] != 0) CERROR_BREAK(error, 72);
04418
04419 string2_begin = length + 2;
04420 if(string2_begin > chunkLength) CERROR_BREAK(error, 75);
04421
04422 length = chunkLength - string2_begin;
04423
04424 error = zlib_decompress(&decoded.data, &decoded.size,
04425 (unsigned char*)(&data[string2_begin]),
04426 length, zlibsettings);
04427 if(error) break;
04428 ucvector_push_back(&decoded, 0);
04429
04430 error = lodepng_add_text(info, key, (char*)decoded.data);
04431
04432 break;
04433 }
04434
04435 lodepng_free(key);
04436 ucvector_cleanup(&decoded);
04437
04438 return error;
04439 }
04440
04441
04442 static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings,
04443 const unsigned char* data, size_t chunkLength)
04444 {
04445 unsigned error = 0;
04446 unsigned i;
04447
04448 unsigned length, begin, compressed;
04449 char *key = 0, *langtag = 0, *transkey = 0;
04450 ucvector decoded;
04451 ucvector_init(&decoded);
04452
04453 while(!error)
04454 {
04455
04456
04457 if(chunkLength < 5) CERROR_BREAK(error, 30);
04458
04459
04460 for(length = 0; length < chunkLength && data[length] != 0; length++) ;
04461 if(length + 3 >= chunkLength) CERROR_BREAK(error, 75);
04462 if(length < 1 || length > 79) CERROR_BREAK(error, 89);
04463
04464 key = (char*)lodepng_malloc(length + 1);
04465 if(!key) CERROR_BREAK(error, 83);
04466
04467 key[length] = 0;
04468 for(i = 0; i < length; i++) key[i] = data[i];
04469
04470
04471 compressed = data[length + 1];
04472 if(data[length + 2] != 0) CERROR_BREAK(error, 72);
04473
04474
04475
04476
04477
04478 begin = length + 3;
04479 length = 0;
04480 for(i = begin; i < chunkLength && data[i] != 0; i++) length++;
04481
04482 langtag = (char*)lodepng_malloc(length + 1);
04483 if(!langtag) CERROR_BREAK(error, 83);
04484
04485 langtag[length] = 0;
04486 for(i = 0; i < length; i++) langtag[i] = data[begin + i];
04487
04488
04489 begin += length + 1;
04490 length = 0;
04491 for(i = begin; i < chunkLength && data[i] != 0; i++) length++;
04492
04493 transkey = (char*)lodepng_malloc(length + 1);
04494 if(!transkey) CERROR_BREAK(error, 83);
04495
04496 transkey[length] = 0;
04497 for(i = 0; i < length; i++) transkey[i] = data[begin + i];
04498
04499
04500 begin += length + 1;
04501
04502 length = chunkLength < begin ? 0 : chunkLength - begin;
04503
04504 if(compressed)
04505 {
04506
04507 error = zlib_decompress(&decoded.data, &decoded.size,
04508 (unsigned char*)(&data[begin]),
04509 length, zlibsettings);
04510 if(error) break;
04511 if(decoded.allocsize < decoded.size) decoded.allocsize = decoded.size;
04512 ucvector_push_back(&decoded, 0);
04513 }
04514 else
04515 {
04516 if(!ucvector_resize(&decoded, length + 1)) CERROR_BREAK(error, 83 );
04517
04518 decoded.data[length] = 0;
04519 for(i = 0; i < length; i++) decoded.data[i] = data[begin + i];
04520 }
04521
04522 error = lodepng_add_itext(info, key, langtag, transkey, (char*)decoded.data);
04523
04524 break;
04525 }
04526
04527 lodepng_free(key);
04528 lodepng_free(langtag);
04529 lodepng_free(transkey);
04530 ucvector_cleanup(&decoded);
04531
04532 return error;
04533 }
04534
04535 static unsigned readChunk_tIME(LodePNGInfo* info, const unsigned char* data, size_t chunkLength)
04536 {
04537 if(chunkLength != 7) return 73;
04538
04539 info->time_defined = 1;
04540 info->time.year = 256 * data[0] + data[+ 1];
04541 info->time.month = data[2];
04542 info->time.day = data[3];
04543 info->time.hour = data[4];
04544 info->time.minute = data[5];
04545 info->time.second = data[6];
04546
04547 return 0;
04548 }
04549
04550 static unsigned readChunk_pHYs(LodePNGInfo* info, const unsigned char* data, size_t chunkLength)
04551 {
04552 if(chunkLength != 9) return 74;
04553
04554 info->phys_defined = 1;
04555 info->phys_x = 16777216 * data[0] + 65536 * data[1] + 256 * data[2] + data[3];
04556 info->phys_y = 16777216 * data[4] + 65536 * data[5] + 256 * data[6] + data[7];
04557 info->phys_unit = data[8];
04558
04559 return 0;
04560 }
04561 #endif
04562
04563
04564 static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
04565 LodePNGState* state,
04566 const unsigned char* in, size_t insize)
04567 {
04568 unsigned char IEND = 0;
04569 const unsigned char* chunk;
04570 size_t i;
04571 ucvector idat;
04572
04573
04574 unsigned unknown = 0;
04575 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
04576 unsigned critical_pos = 1;
04577 #endif
04578
04579
04580 *out = 0;
04581
04582 state->error = lodepng_inspect(w, h, state, in, insize);
04583 if(state->error) return;
04584
04585 ucvector_init(&idat);
04586 chunk = &in[33];
04587
04588
04589
04590 while(!IEND && !state->error)
04591 {
04592 unsigned chunkLength;
04593 const unsigned char* data;
04594
04595
04596 if((size_t)((chunk - in) + 12) > insize || chunk < in) CERROR_BREAK(state->error, 30);
04597
04598
04599 chunkLength = lodepng_chunk_length(chunk);
04600
04601 if(chunkLength > 2147483647) CERROR_BREAK(state->error, 63);
04602
04603 if((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in)
04604 {
04605 CERROR_BREAK(state->error, 64);
04606 }
04607
04608 data = lodepng_chunk_data_const(chunk);
04609
04610
04611 if(lodepng_chunk_type_equals(chunk, "IDAT"))
04612 {
04613 size_t oldsize = idat.size;
04614 if(!ucvector_resize(&idat, oldsize + chunkLength)) CERROR_BREAK(state->error, 83 );
04615 for(i = 0; i < chunkLength; i++) idat.data[oldsize + i] = data[i];
04616 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
04617 critical_pos = 3;
04618 #endif
04619 }
04620
04621 else if(lodepng_chunk_type_equals(chunk, "IEND"))
04622 {
04623 IEND = 1;
04624 }
04625
04626 else if(lodepng_chunk_type_equals(chunk, "PLTE"))
04627 {
04628 state->error = readChunk_PLTE(&state->info_png.color, data, chunkLength);
04629 if(state->error) break;
04630 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
04631 critical_pos = 2;
04632 #endif
04633 }
04634
04635 else if(lodepng_chunk_type_equals(chunk, "tRNS"))
04636 {
04637 state->error = readChunk_tRNS(&state->info_png.color, data, chunkLength);
04638 if(state->error) break;
04639 }
04640 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
04641
04642 else if(lodepng_chunk_type_equals(chunk, "bKGD"))
04643 {
04644 state->error = readChunk_bKGD(&state->info_png, data, chunkLength);
04645 if(state->error) break;
04646 }
04647
04648 else if(lodepng_chunk_type_equals(chunk, "tEXt"))
04649 {
04650 if(state->decoder.read_text_chunks)
04651 {
04652 state->error = readChunk_tEXt(&state->info_png, data, chunkLength);
04653 if(state->error) break;
04654 }
04655 }
04656
04657 else if(lodepng_chunk_type_equals(chunk, "zTXt"))
04658 {
04659 if(state->decoder.read_text_chunks)
04660 {
04661 state->error = readChunk_zTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
04662 if(state->error) break;
04663 }
04664 }
04665
04666 else if(lodepng_chunk_type_equals(chunk, "iTXt"))
04667 {
04668 if(state->decoder.read_text_chunks)
04669 {
04670 state->error = readChunk_iTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength);
04671 if(state->error) break;
04672 }
04673 }
04674 else if(lodepng_chunk_type_equals(chunk, "tIME"))
04675 {
04676 state->error = readChunk_tIME(&state->info_png, data, chunkLength);
04677 if(state->error) break;
04678 }
04679 else if(lodepng_chunk_type_equals(chunk, "pHYs"))
04680 {
04681 state->error = readChunk_pHYs(&state->info_png, data, chunkLength);
04682 if(state->error) break;
04683 }
04684 #endif
04685 else
04686 {
04687
04688 if(!lodepng_chunk_ancillary(chunk)) CERROR_BREAK(state->error, 69);
04689
04690 unknown = 1;
04691 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
04692 if(state->decoder.remember_unknown_chunks)
04693 {
04694 state->error = lodepng_chunk_append(&state->info_png.unknown_chunks_data[critical_pos - 1],
04695 &state->info_png.unknown_chunks_size[critical_pos - 1], chunk);
04696 if(state->error) break;
04697 }
04698 #endif
04699 }
04700
04701 if(!state->decoder.ignore_crc && !unknown)
04702 {
04703 if(lodepng_chunk_check_crc(chunk)) CERROR_BREAK(state->error, 57);
04704 }
04705
04706 if(!IEND) chunk = lodepng_chunk_next_const(chunk);
04707 }
04708
04709 if(!state->error)
04710 {
04711 ucvector scanlines;
04712 ucvector_init(&scanlines);
04713
04714
04715 if(!ucvector_resize(&scanlines, lodepng_get_raw_size(*w, *h, &state->info_png.color) + *h))
04716 {
04717 state->error = 83;
04718 }
04719 if(!state->error)
04720 {
04721
04722 state->error = zlib_decompress(&scanlines.data, &scanlines.size, idat.data,
04723 idat.size, &state->decoder.zlibsettings);
04724 }
04725
04726 if(!state->error)
04727 {
04728 ucvector outv;
04729 ucvector_init(&outv);
04730 if(!ucvector_resizev(&outv,
04731 lodepng_get_raw_size(*w, *h, &state->info_png.color), 0)) state->error = 83;
04732 if(!state->error) state->error = postProcessScanlines(outv.data, scanlines.data, *w, *h, &state->info_png);
04733 *out = outv.data;
04734 }
04735 ucvector_cleanup(&scanlines);
04736 }
04737
04738 ucvector_cleanup(&idat);
04739 }
04740
04741 unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h,
04742 LodePNGState* state,
04743 const unsigned char* in, size_t insize)
04744 {
04745 *out = 0;
04746 decodeGeneric(out, w, h, state, in, insize);
04747 if(state->error) return state->error;
04748 if(!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color))
04749 {
04750
04751
04752
04753 if(!state->decoder.color_convert)
04754 {
04755 state->error = lodepng_color_mode_copy(&state->info_raw, &state->info_png.color);
04756 if(state->error) return state->error;
04757 }
04758 }
04759 else
04760 {
04761
04762 unsigned char* data = *out;
04763 size_t outsize;
04764
04765
04766
04767 if(!(state->info_raw.colortype == LCT_RGB || state->info_raw.colortype == LCT_RGBA)
04768 && !(state->info_raw.bitdepth == 8))
04769 {
04770 return 56;
04771 }
04772
04773 outsize = lodepng_get_raw_size(*w, *h, &state->info_raw);
04774 *out = (unsigned char*)lodepng_malloc(outsize);
04775 if(!(*out))
04776 {
04777 state->error = 83;
04778 }
04779 else state->error = lodepng_convert(*out, data, &state->info_raw, &state->info_png.color, *w, *h, state->decoder.fix_png);
04780 lodepng_free(data);
04781 }
04782 return state->error;
04783 }
04784
04785 unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in,
04786 size_t insize, LodePNGColorType colortype, unsigned bitdepth)
04787 {
04788 unsigned error;
04789 LodePNGState state;
04790 lodepng_state_init(&state);
04791 state.info_raw.colortype = colortype;
04792 state.info_raw.bitdepth = bitdepth;
04793 error = lodepng_decode(out, w, h, &state, in, insize);
04794 lodepng_state_cleanup(&state);
04795 return error;
04796 }
04797
04798 unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize)
04799 {
04800 return lodepng_decode_memory(out, w, h, in, insize, LCT_RGBA, 8);
04801 }
04802
04803 unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize)
04804 {
04805 return lodepng_decode_memory(out, w, h, in, insize, LCT_RGB, 8);
04806 }
04807
04808 #ifdef LODEPNG_COMPILE_DISK
04809 unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename,
04810 LodePNGColorType colortype, unsigned bitdepth)
04811 {
04812 unsigned char* buffer;
04813 size_t buffersize;
04814 unsigned error;
04815 error = lodepng_load_file(&buffer, &buffersize, filename);
04816 if(!error) error = lodepng_decode_memory(out, w, h, buffer, buffersize, colortype, bitdepth);
04817 lodepng_free(buffer);
04818 return error;
04819 }
04820
04821 unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename)
04822 {
04823 return lodepng_decode_file(out, w, h, filename, LCT_RGBA, 8);
04824 }
04825
04826 unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename)
04827 {
04828 return lodepng_decode_file(out, w, h, filename, LCT_RGB, 8);
04829 }
04830 #endif
04831
04832 void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings)
04833 {
04834 settings->color_convert = 1;
04835 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
04836 settings->read_text_chunks = 1;
04837 settings->remember_unknown_chunks = 0;
04838 #endif
04839 settings->ignore_crc = 0;
04840 settings->fix_png = 0;
04841 lodepng_decompress_settings_init(&settings->zlibsettings);
04842 }
04843
04844 #endif
04845
04846 #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER)
04847
04848 void lodepng_state_init(LodePNGState* state)
04849 {
04850 #ifdef LODEPNG_COMPILE_DECODER
04851 lodepng_decoder_settings_init(&state->decoder);
04852 #endif
04853 #ifdef LODEPNG_COMPILE_ENCODER
04854 lodepng_encoder_settings_init(&state->encoder);
04855 #endif
04856 lodepng_color_mode_init(&state->info_raw);
04857 lodepng_info_init(&state->info_png);
04858 state->error = 1;
04859 }
04860
04861 void lodepng_state_cleanup(LodePNGState* state)
04862 {
04863 lodepng_color_mode_cleanup(&state->info_raw);
04864 lodepng_info_cleanup(&state->info_png);
04865 }
04866
04867 void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source)
04868 {
04869 lodepng_state_cleanup(dest);
04870 *dest = *source;
04871 lodepng_color_mode_init(&dest->info_raw);
04872 lodepng_info_init(&dest->info_png);
04873 dest->error = lodepng_color_mode_copy(&dest->info_raw, &source->info_raw); if(dest->error) return;
04874 dest->error = lodepng_info_copy(&dest->info_png, &source->info_png); if(dest->error) return;
04875 }
04876
04877 #endif
04878
04879 #ifdef LODEPNG_COMPILE_ENCODER
04880
04881
04882
04883
04884
04885
04886 static unsigned addChunk(ucvector* out, const char* chunkName, const unsigned char* data, size_t length)
04887 {
04888 CERROR_TRY_RETURN(lodepng_chunk_create(&out->data, &out->size, (unsigned)length, chunkName, data));
04889 out->allocsize = out->size;
04890 return 0;
04891 }
04892
04893 static void writeSignature(ucvector* out)
04894 {
04895
04896 ucvector_push_back(out, 137);
04897 ucvector_push_back(out, 80);
04898 ucvector_push_back(out, 78);
04899 ucvector_push_back(out, 71);
04900 ucvector_push_back(out, 13);
04901 ucvector_push_back(out, 10);
04902 ucvector_push_back(out, 26);
04903 ucvector_push_back(out, 10);
04904 }
04905
04906 static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h,
04907 LodePNGColorType colortype, unsigned bitdepth, unsigned interlace_method)
04908 {
04909 unsigned error = 0;
04910 ucvector header;
04911 ucvector_init(&header);
04912
04913 lodepng_add32bitInt(&header, w);
04914 lodepng_add32bitInt(&header, h);
04915 ucvector_push_back(&header, (unsigned char)bitdepth);
04916 ucvector_push_back(&header, (unsigned char)colortype);
04917 ucvector_push_back(&header, 0);
04918 ucvector_push_back(&header, 0);
04919 ucvector_push_back(&header, interlace_method);
04920
04921 error = addChunk(out, "IHDR", header.data, header.size);
04922 ucvector_cleanup(&header);
04923
04924 return error;
04925 }
04926
04927 static unsigned addChunk_PLTE(ucvector* out, const LodePNGColorMode* info)
04928 {
04929 unsigned error = 0;
04930 size_t i;
04931 ucvector PLTE;
04932 ucvector_init(&PLTE);
04933 for(i = 0; i < info->palettesize * 4; i++)
04934 {
04935
04936 if(i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]);
04937 }
04938 error = addChunk(out, "PLTE", PLTE.data, PLTE.size);
04939 ucvector_cleanup(&PLTE);
04940
04941 return error;
04942 }
04943
04944 static unsigned addChunk_tRNS(ucvector* out, const LodePNGColorMode* info)
04945 {
04946 unsigned error = 0;
04947 size_t i;
04948 ucvector tRNS;
04949 ucvector_init(&tRNS);
04950 if(info->colortype == LCT_PALETTE)
04951 {
04952 size_t amount = info->palettesize;
04953
04954 for(i = info->palettesize; i > 0; i--)
04955 {
04956 if(info->palette[4 * (i - 1) + 3] == 255) amount--;
04957 else break;
04958 }
04959
04960 for(i = 0; i < amount; i++) ucvector_push_back(&tRNS, info->palette[4 * i + 3]);
04961 }
04962 else if(info->colortype == LCT_GREY)
04963 {
04964 if(info->key_defined)
04965 {
04966 ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256));
04967 ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256));
04968 }
04969 }
04970 else if(info->colortype == LCT_RGB)
04971 {
04972 if(info->key_defined)
04973 {
04974 ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256));
04975 ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256));
04976 ucvector_push_back(&tRNS, (unsigned char)(info->key_g / 256));
04977 ucvector_push_back(&tRNS, (unsigned char)(info->key_g % 256));
04978 ucvector_push_back(&tRNS, (unsigned char)(info->key_b / 256));
04979 ucvector_push_back(&tRNS, (unsigned char)(info->key_b % 256));
04980 }
04981 }
04982
04983 error = addChunk(out, "tRNS", tRNS.data, tRNS.size);
04984 ucvector_cleanup(&tRNS);
04985
04986 return error;
04987 }
04988
04989 static unsigned addChunk_IDAT(ucvector* out, const unsigned char* data, size_t datasize,
04990 LodePNGCompressSettings* zlibsettings)
04991 {
04992 ucvector zlibdata;
04993 unsigned error = 0;
04994
04995
04996 ucvector_init(&zlibdata);
04997 error = zlib_compress(&zlibdata.data, &zlibdata.size, data, datasize, zlibsettings);
04998 if(!error) error = addChunk(out, "IDAT", zlibdata.data, zlibdata.size);
04999 ucvector_cleanup(&zlibdata);
05000
05001 return error;
05002 }
05003
05004 static unsigned addChunk_IEND(ucvector* out)
05005 {
05006 unsigned error = 0;
05007 error = addChunk(out, "IEND", 0, 0);
05008 return error;
05009 }
05010
05011 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
05012
05013 static unsigned addChunk_tEXt(ucvector* out, const char* keyword, const char* textstring)
05014 {
05015 unsigned error = 0;
05016 size_t i;
05017 ucvector text;
05018 ucvector_init(&text);
05019 for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&text, (unsigned char)keyword[i]);
05020 if(i < 1 || i > 79) return 89;
05021 ucvector_push_back(&text, 0);
05022 for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&text, (unsigned char)textstring[i]);
05023 error = addChunk(out, "tEXt", text.data, text.size);
05024 ucvector_cleanup(&text);
05025
05026 return error;
05027 }
05028
05029 static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* textstring,
05030 LodePNGCompressSettings* zlibsettings)
05031 {
05032 unsigned error = 0;
05033 ucvector data, compressed;
05034 size_t i, textsize = strlen(textstring);
05035
05036 ucvector_init(&data);
05037 ucvector_init(&compressed);
05038 for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]);
05039 if(i < 1 || i > 79) return 89;
05040 ucvector_push_back(&data, 0);
05041 ucvector_push_back(&data, 0);
05042
05043 error = zlib_compress(&compressed.data, &compressed.size,
05044 (unsigned char*)textstring, textsize, zlibsettings);
05045 if(!error)
05046 {
05047 for(i = 0; i < compressed.size; i++) ucvector_push_back(&data, compressed.data[i]);
05048 error = addChunk(out, "zTXt", data.data, data.size);
05049 }
05050
05051 ucvector_cleanup(&compressed);
05052 ucvector_cleanup(&data);
05053 return error;
05054 }
05055
05056 static unsigned addChunk_iTXt(ucvector* out, unsigned compressed, const char* keyword, const char* langtag,
05057 const char* transkey, const char* textstring, LodePNGCompressSettings* zlibsettings)
05058 {
05059 unsigned error = 0;
05060 ucvector data;
05061 size_t i, textsize = strlen(textstring);
05062
05063 ucvector_init(&data);
05064
05065 for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]);
05066 if(i < 1 || i > 79) return 89;
05067 ucvector_push_back(&data, 0);
05068 ucvector_push_back(&data, compressed ? 1 : 0);
05069 ucvector_push_back(&data, 0);
05070 for(i = 0; langtag[i] != 0; i++) ucvector_push_back(&data, (unsigned char)langtag[i]);
05071 ucvector_push_back(&data, 0);
05072 for(i = 0; transkey[i] != 0; i++) ucvector_push_back(&data, (unsigned char)transkey[i]);
05073 ucvector_push_back(&data, 0);
05074
05075 if(compressed)
05076 {
05077 ucvector compressed_data;
05078 ucvector_init(&compressed_data);
05079 error = zlib_compress(&compressed_data.data, &compressed_data.size,
05080 (unsigned char*)textstring, textsize, zlibsettings);
05081 if(!error)
05082 {
05083 for(i = 0; i < compressed_data.size; i++) ucvector_push_back(&data, compressed_data.data[i]);
05084 }
05085 ucvector_cleanup(&compressed_data);
05086 }
05087 else
05088 {
05089 for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&data, (unsigned char)textstring[i]);
05090 }
05091
05092 if(!error) error = addChunk(out, "iTXt", data.data, data.size);
05093 ucvector_cleanup(&data);
05094 return error;
05095 }
05096
05097 static unsigned addChunk_bKGD(ucvector* out, const LodePNGInfo* info)
05098 {
05099 unsigned error = 0;
05100 ucvector bKGD;
05101 ucvector_init(&bKGD);
05102 if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA)
05103 {
05104 ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256));
05105 ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256));
05106 }
05107 else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA)
05108 {
05109 ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256));
05110 ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256));
05111 ucvector_push_back(&bKGD, (unsigned char)(info->background_g / 256));
05112 ucvector_push_back(&bKGD, (unsigned char)(info->background_g % 256));
05113 ucvector_push_back(&bKGD, (unsigned char)(info->background_b / 256));
05114 ucvector_push_back(&bKGD, (unsigned char)(info->background_b % 256));
05115 }
05116 else if(info->color.colortype == LCT_PALETTE)
05117 {
05118 ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256));
05119 }
05120
05121 error = addChunk(out, "bKGD", bKGD.data, bKGD.size);
05122 ucvector_cleanup(&bKGD);
05123
05124 return error;
05125 }
05126
05127 static unsigned addChunk_tIME(ucvector* out, const LodePNGTime* time)
05128 {
05129 unsigned error = 0;
05130 unsigned char* data = (unsigned char*)lodepng_malloc(7);
05131 if(!data) return 83;
05132 data[0] = (unsigned char)(time->year / 256);
05133 data[1] = (unsigned char)(time->year % 256);
05134 data[2] = time->month;
05135 data[3] = time->day;
05136 data[4] = time->hour;
05137 data[5] = time->minute;
05138 data[6] = time->second;
05139 error = addChunk(out, "tIME", data, 7);
05140 lodepng_free(data);
05141 return error;
05142 }
05143
05144 static unsigned addChunk_pHYs(ucvector* out, const LodePNGInfo* info)
05145 {
05146 unsigned error = 0;
05147 ucvector data;
05148 ucvector_init(&data);
05149
05150 lodepng_add32bitInt(&data, info->phys_x);
05151 lodepng_add32bitInt(&data, info->phys_y);
05152 ucvector_push_back(&data, info->phys_unit);
05153
05154 error = addChunk(out, "pHYs", data.data, data.size);
05155 ucvector_cleanup(&data);
05156
05157 return error;
05158 }
05159
05160 #endif
05161
05162 static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline,
05163 size_t length, size_t bytewidth, unsigned char filterType)
05164 {
05165 size_t i;
05166 switch(filterType)
05167 {
05168 case 0:
05169 for(i = 0; i < length; i++) out[i] = scanline[i];
05170 break;
05171 case 1:
05172 if(prevline)
05173 {
05174 for(i = 0; i < bytewidth; i++) out[i] = scanline[i];
05175 for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth];
05176 }
05177 else
05178 {
05179 for(i = 0; i < bytewidth; i++) out[i] = scanline[i];
05180 for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth];
05181 }
05182 break;
05183 case 2:
05184 if(prevline)
05185 {
05186 for(i = 0; i < length; i++) out[i] = scanline[i] - prevline[i];
05187 }
05188 else
05189 {
05190 for(i = 0; i < length; i++) out[i] = scanline[i];
05191 }
05192 break;
05193 case 3:
05194 if(prevline)
05195 {
05196 for(i = 0; i < bytewidth; i++) out[i] = scanline[i] - prevline[i] / 2;
05197 for(i = bytewidth; i < length; i++) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) / 2);
05198 }
05199 else
05200 {
05201 for(i = 0; i < bytewidth; i++) out[i] = scanline[i];
05202 for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth] / 2;
05203 }
05204 break;
05205 case 4:
05206 if(prevline)
05207 {
05208
05209 for(i = 0; i < bytewidth; i++) out[i] = (scanline[i] - prevline[i]);
05210 for(i = bytewidth; i < length; i++)
05211 {
05212 out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth]));
05213 }
05214 }
05215 else
05216 {
05217 for(i = 0; i < bytewidth; i++) out[i] = scanline[i];
05218
05219 for(i = bytewidth; i < length; i++) out[i] = (scanline[i] - scanline[i - bytewidth]);
05220 }
05221 break;
05222 default: return;
05223 }
05224 }
05225
05226
05227 static float flog2(float f)
05228 {
05229 float result = 0;
05230 while(f > 32) { result += 4; f /= 16; }
05231 while(f > 2) { result++; f /= 2; }
05232 return result + 1.442695f * (f * f * f / 3 - 3 * f * f / 2 + 3 * f - 1.83333f);
05233 }
05234
05235 static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h,
05236 const LodePNGColorMode* info, const LodePNGEncoderSettings* settings)
05237 {
05238
05239
05240
05241
05242
05243
05244 unsigned bpp = lodepng_get_bpp(info);
05245
05246 size_t linebytes = (w * bpp + 7) / 8;
05247
05248 size_t bytewidth = (bpp + 7) / 8;
05249 const unsigned char* prevline = 0;
05250 unsigned x, y;
05251 unsigned error = 0;
05252 LodePNGFilterStrategy strategy = settings->filter_strategy;
05253
05254
05255
05256
05257
05258
05259
05260
05261
05262
05263
05264
05265
05266
05267 if(settings->filter_palette_zero &&
05268 (info->colortype == LCT_PALETTE || info->bitdepth < 8)) strategy = LFS_ZERO;
05269
05270 if(bpp == 0) return 31;
05271
05272 if(strategy == LFS_ZERO)
05273 {
05274 for(y = 0; y < h; y++)
05275 {
05276 size_t outindex = (1 + linebytes) * y;
05277 size_t inindex = linebytes * y;
05278 out[outindex] = 0;
05279 filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, 0);
05280 prevline = &in[inindex];
05281 }
05282 }
05283 else if(strategy == LFS_MINSUM)
05284 {
05285
05286 size_t sum[5];
05287 ucvector attempt[5];
05288 size_t smallest = 0;
05289 unsigned type, bestType = 0;
05290
05291 for(type = 0; type < 5; type++)
05292 {
05293 ucvector_init(&attempt[type]);
05294 if(!ucvector_resize(&attempt[type], linebytes)) return 83;
05295 }
05296
05297 if(!error)
05298 {
05299 for(y = 0; y < h; y++)
05300 {
05301
05302 for(type = 0; type < 5; type++)
05303 {
05304 filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type);
05305
05306
05307 sum[type] = 0;
05308 if(type == 0)
05309 {
05310 for(x = 0; x < linebytes; x++) sum[type] += (unsigned char)(attempt[type].data[x]);
05311 }
05312 else
05313 {
05314 for(x = 0; x < linebytes; x++)
05315 {
05316
05317
05318
05319 signed char s = (signed char)(attempt[type].data[x]);
05320 sum[type] += s < 0 ? -s : s;
05321 }
05322 }
05323
05324
05325 if(type == 0 || sum[type] < smallest)
05326 {
05327 bestType = type;
05328 smallest = sum[type];
05329 }
05330 }
05331
05332 prevline = &in[y * linebytes];
05333
05334
05335 out[y * (linebytes + 1)] = bestType;
05336 for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x];
05337 }
05338 }
05339
05340 for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]);
05341 }
05342 else if(strategy == LFS_ENTROPY)
05343 {
05344 float sum[5];
05345 ucvector attempt[5];
05346 float smallest = 0;
05347 unsigned type, bestType = 0;
05348 unsigned count[256];
05349
05350 for(type = 0; type < 5; type++)
05351 {
05352 ucvector_init(&attempt[type]);
05353 if(!ucvector_resize(&attempt[type], linebytes)) return 83;
05354 }
05355
05356 for(y = 0; y < h; y++)
05357 {
05358
05359 for(type = 0; type < 5; type++)
05360 {
05361 filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type);
05362 for(x = 0; x < 256; x++) count[x] = 0;
05363 for(x = 0; x < linebytes; x++) count[attempt[type].data[x]]++;
05364 count[type]++;
05365 sum[type] = 0;
05366 for(x = 0; x < 256; x++)
05367 {
05368 float p = count[x] / (float)(linebytes + 1);
05369 sum[type] += count[x] == 0 ? 0 : flog2(1 / p) * p;
05370 }
05371
05372 if(type == 0 || sum[type] < smallest)
05373 {
05374 bestType = type;
05375 smallest = sum[type];
05376 }
05377 }
05378
05379 prevline = &in[y * linebytes];
05380
05381
05382 out[y * (linebytes + 1)] = bestType;
05383 for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x];
05384 }
05385
05386 for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]);
05387 }
05388 else if(strategy == LFS_PREDEFINED)
05389 {
05390 for(y = 0; y < h; y++)
05391 {
05392 size_t outindex = (1 + linebytes) * y;
05393 size_t inindex = linebytes * y;
05394 unsigned type = settings->predefined_filters[y];
05395 out[outindex] = type;
05396 filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type);
05397 prevline = &in[inindex];
05398 }
05399 }
05400 else if(strategy == LFS_BRUTE_FORCE)
05401 {
05402
05403
05404
05405 size_t size[5];
05406 ucvector attempt[5];
05407 size_t smallest = 0;
05408 unsigned type = 0, bestType = 0;
05409 unsigned char* dummy;
05410 LodePNGCompressSettings zlibsettings = settings->zlibsettings;
05411
05412
05413
05414
05415 zlibsettings.btype = 1;
05416
05417
05418 zlibsettings.custom_zlib = 0;
05419 zlibsettings.custom_deflate = 0;
05420 for(type = 0; type < 5; type++)
05421 {
05422 ucvector_init(&attempt[type]);
05423 ucvector_resize(&attempt[type], linebytes);
05424 }
05425 for(y = 0; y < h; y++)
05426 {
05427 for(type = 0; type < 5; type++)
05428 {
05429 unsigned testsize = attempt[type].size;
05430
05431
05432 filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type);
05433 size[type] = 0;
05434 dummy = 0;
05435 zlib_compress(&dummy, &size[type], attempt[type].data, testsize, &zlibsettings);
05436 lodepng_free(dummy);
05437
05438 if(type == 0 || size[type] < smallest)
05439 {
05440 bestType = type;
05441 smallest = size[type];
05442 }
05443 }
05444 prevline = &in[y * linebytes];
05445 out[y * (linebytes + 1)] = bestType;
05446 for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x];
05447 }
05448 for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]);
05449 }
05450 else return 88;
05451
05452 return error;
05453 }
05454
05455 static void addPaddingBits(unsigned char* out, const unsigned char* in,
05456 size_t olinebits, size_t ilinebits, unsigned h)
05457 {
05458
05459
05460 unsigned y;
05461 size_t diff = olinebits - ilinebits;
05462 size_t obp = 0, ibp = 0;
05463 for(y = 0; y < h; y++)
05464 {
05465 size_t x;
05466 for(x = 0; x < ilinebits; x++)
05467 {
05468 unsigned char bit = readBitFromReversedStream(&ibp, in);
05469 setBitOfReversedStream(&obp, out, bit);
05470 }
05471
05472
05473 for(x = 0; x < diff; x++) setBitOfReversedStream(&obp, out, 0);
05474 }
05475 }
05476
05477
05478
05479
05480
05481
05482
05483
05484
05485
05486
05487
05488 static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp)
05489 {
05490 unsigned passw[7], passh[7];
05491 size_t filter_passstart[8], padded_passstart[8], passstart[8];
05492 unsigned i;
05493
05494 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
05495
05496 if(bpp >= 8)
05497 {
05498 for(i = 0; i < 7; i++)
05499 {
05500 unsigned x, y, b;
05501 size_t bytewidth = bpp / 8;
05502 for(y = 0; y < passh[i]; y++)
05503 for(x = 0; x < passw[i]; x++)
05504 {
05505 size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth;
05506 size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth;
05507 for(b = 0; b < bytewidth; b++)
05508 {
05509 out[pixeloutstart + b] = in[pixelinstart + b];
05510 }
05511 }
05512 }
05513 }
05514 else
05515 {
05516 for(i = 0; i < 7; i++)
05517 {
05518 unsigned x, y, b;
05519 unsigned ilinebits = bpp * passw[i];
05520 unsigned olinebits = bpp * w;
05521 size_t obp, ibp;
05522 for(y = 0; y < passh[i]; y++)
05523 for(x = 0; x < passw[i]; x++)
05524 {
05525 ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp;
05526 obp = (8 * passstart[i]) + (y * ilinebits + x * bpp);
05527 for(b = 0; b < bpp; b++)
05528 {
05529 unsigned char bit = readBitFromReversedStream(&ibp, in);
05530 setBitOfReversedStream(&obp, out, bit);
05531 }
05532 }
05533 }
05534 }
05535 }
05536
05537
05538
05539 static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const unsigned char* in,
05540 unsigned w, unsigned h,
05541 const LodePNGInfo* info_png, const LodePNGEncoderSettings* settings)
05542 {
05543
05544
05545
05546
05547
05548 unsigned bpp = lodepng_get_bpp(&info_png->color);
05549 unsigned error = 0;
05550
05551 if(info_png->interlace_method == 0)
05552 {
05553 *outsize = h + (h * ((w * bpp + 7) / 8));
05554 *out = (unsigned char*)lodepng_malloc(*outsize);
05555 if(!(*out) && (*outsize)) error = 83;
05556
05557 if(!error)
05558 {
05559
05560 if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8)
05561 {
05562 unsigned char* padded = (unsigned char*)lodepng_malloc(h * ((w * bpp + 7) / 8));
05563 if(!padded) error = 83;
05564 if(!error)
05565 {
05566 addPaddingBits(padded, in, ((w * bpp + 7) / 8) * 8, w * bpp, h);
05567 error = filter(*out, padded, w, h, &info_png->color, settings);
05568 }
05569 lodepng_free(padded);
05570 }
05571 else
05572 {
05573
05574 error = filter(*out, in, w, h, &info_png->color, settings);
05575 }
05576 }
05577 }
05578 else
05579 {
05580 unsigned passw[7], passh[7];
05581 size_t filter_passstart[8], padded_passstart[8], passstart[8];
05582 unsigned char* adam7;
05583
05584 Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp);
05585
05586 *outsize = filter_passstart[7];
05587 *out = (unsigned char*)lodepng_malloc(*outsize);
05588 if(!(*out)) error = 83;
05589
05590 adam7 = (unsigned char*)lodepng_malloc(passstart[7]);
05591 if(!adam7 && passstart[7]) error = 83;
05592
05593 if(!error)
05594 {
05595 unsigned i;
05596
05597 Adam7_interlace(adam7, in, w, h, bpp);
05598 for(i = 0; i < 7; i++)
05599 {
05600 if(bpp < 8)
05601 {
05602 unsigned char* padded = (unsigned char*)lodepng_malloc(padded_passstart[i + 1] - padded_passstart[i]);
05603 if(!padded) ERROR_BREAK(83);
05604 addPaddingBits(padded, &adam7[passstart[i]],
05605 ((passw[i] * bpp + 7) / 8) * 8, passw[i] * bpp, passh[i]);
05606 error = filter(&(*out)[filter_passstart[i]], padded,
05607 passw[i], passh[i], &info_png->color, settings);
05608 lodepng_free(padded);
05609 }
05610 else
05611 {
05612 error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]],
05613 passw[i], passh[i], &info_png->color, settings);
05614 }
05615
05616 if(error) break;
05617 }
05618 }
05619
05620 lodepng_free(adam7);
05621 }
05622
05623 return error;
05624 }
05625
05626
05627
05628
05629
05630
05631
05632 static unsigned getPaletteTranslucency(const unsigned char* palette, size_t palettesize)
05633 {
05634 size_t i, key = 0;
05635 unsigned r = 0, g = 0, b = 0;
05636 for(i = 0; i < palettesize; i++)
05637 {
05638 if(!key && palette[4 * i + 3] == 0)
05639 {
05640 r = palette[4 * i + 0]; g = palette[4 * i + 1]; b = palette[4 * i + 2];
05641 key = 1;
05642 i = (size_t)(-1);
05643 }
05644 else if(palette[4 * i + 3] != 255) return 2;
05645
05646 else if(key && r == palette[i * 4 + 0] && g == palette[i * 4 + 1] && b == palette[i * 4 + 2]) return 2;
05647 }
05648 return key;
05649 }
05650
05651 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
05652 static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t datasize)
05653 {
05654 unsigned char* inchunk = data;
05655 while((size_t)(inchunk - data) < datasize)
05656 {
05657 CERROR_TRY_RETURN(lodepng_chunk_append(&out->data, &out->size, inchunk));
05658 out->allocsize = out->size;
05659 inchunk = lodepng_chunk_next(inchunk);
05660 }
05661 return 0;
05662 }
05663 #endif
05664
05665 unsigned lodepng_encode(unsigned char** out, size_t* outsize,
05666 const unsigned char* image, unsigned w, unsigned h,
05667 LodePNGState* state)
05668 {
05669 LodePNGInfo info;
05670 ucvector outv;
05671 unsigned char* data = 0;
05672 size_t datasize = 0;
05673
05674
05675 *out = 0;
05676 *outsize = 0;
05677 state->error = 0;
05678
05679 lodepng_info_init(&info);
05680 lodepng_info_copy(&info, &state->info_png);
05681
05682 if((info.color.colortype == LCT_PALETTE || state->encoder.force_palette)
05683 && (info.color.palettesize == 0 || info.color.palettesize > 256))
05684 {
05685 state->error = 68;
05686 return state->error;
05687 }
05688
05689 if(state->encoder.auto_convert != LAC_NO)
05690 {
05691 state->error = doAutoChooseColor(&info.color, image, w, h, &state->info_raw,
05692 state->encoder.auto_convert);
05693 }
05694 if(state->error) return state->error;
05695
05696 if(state->encoder.zlibsettings.windowsize > 32768)
05697 {
05698 CERROR_RETURN_ERROR(state->error, 60);
05699 }
05700 if(state->encoder.zlibsettings.btype > 2)
05701 {
05702 CERROR_RETURN_ERROR(state->error, 61);
05703 }
05704 if(state->info_png.interlace_method > 1)
05705 {
05706 CERROR_RETURN_ERROR(state->error, 71);
05707 }
05708
05709 state->error = checkColorValidity(info.color.colortype, info.color.bitdepth);
05710 if(state->error) return state->error;
05711 state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth);
05712 if(state->error) return state->error;
05713
05714 if(!lodepng_color_mode_equal(&state->info_raw, &info.color))
05715 {
05716 unsigned char* converted;
05717 size_t size = (w * h * lodepng_get_bpp(&info.color) + 7) / 8;
05718
05719 converted = (unsigned char*)lodepng_malloc(size);
05720 if(!converted && size) state->error = 83;
05721 if(!state->error)
05722 {
05723 state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h, 0 );
05724 }
05725 if(!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder);
05726 lodepng_free(converted);
05727 }
05728 else preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder);
05729
05730 ucvector_init(&outv);
05731 while(!state->error)
05732 {
05733 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
05734 size_t i;
05735 #endif
05736
05737 writeSignature(&outv);
05738
05739 addChunk_IHDR(&outv, w, h, info.color.colortype, info.color.bitdepth, info.interlace_method);
05740 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
05741
05742 if(info.unknown_chunks_data[0])
05743 {
05744 state->error = addUnknownChunks(&outv, info.unknown_chunks_data[0], info.unknown_chunks_size[0]);
05745 if(state->error) break;
05746 }
05747 #endif
05748
05749 if(info.color.colortype == LCT_PALETTE)
05750 {
05751 addChunk_PLTE(&outv, &info.color);
05752 }
05753 if(state->encoder.force_palette && (info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA))
05754 {
05755 addChunk_PLTE(&outv, &info.color);
05756 }
05757
05758 if(info.color.colortype == LCT_PALETTE && getPaletteTranslucency(info.color.palette, info.color.palettesize) != 0)
05759 {
05760 addChunk_tRNS(&outv, &info.color);
05761 }
05762 if((info.color.colortype == LCT_GREY || info.color.colortype == LCT_RGB) && info.color.key_defined)
05763 {
05764 addChunk_tRNS(&outv, &info.color);
05765 }
05766 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
05767
05768 if(info.background_defined) addChunk_bKGD(&outv, &info);
05769
05770 if(info.phys_defined) addChunk_pHYs(&outv, &info);
05771
05772
05773 if(info.unknown_chunks_data[1])
05774 {
05775 state->error = addUnknownChunks(&outv, info.unknown_chunks_data[1], info.unknown_chunks_size[1]);
05776 if(state->error) break;
05777 }
05778 #endif
05779
05780 state->error = addChunk_IDAT(&outv, data, datasize, &state->encoder.zlibsettings);
05781 if(state->error) break;
05782 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
05783
05784 if(info.time_defined) addChunk_tIME(&outv, &info.time);
05785
05786 for(i = 0; i < info.text_num; i++)
05787 {
05788 if(strlen(info.text_keys[i]) > 79)
05789 {
05790 state->error = 66;
05791 break;
05792 }
05793 if(strlen(info.text_keys[i]) < 1)
05794 {
05795 state->error = 67;
05796 break;
05797 }
05798 if(state->encoder.text_compression)
05799 addChunk_zTXt(&outv, info.text_keys[i], info.text_strings[i], &state->encoder.zlibsettings);
05800 else
05801 addChunk_tEXt(&outv, info.text_keys[i], info.text_strings[i]);
05802 }
05803
05804 if(state->encoder.add_id)
05805 {
05806 unsigned alread_added_id_text = 0;
05807 for(i = 0; i < info.text_num; i++)
05808 {
05809 if(!strcmp(info.text_keys[i], "LodePNG"))
05810 {
05811 alread_added_id_text = 1;
05812 break;
05813 }
05814 }
05815 if(alread_added_id_text == 0)
05816 addChunk_tEXt(&outv, "LodePNG", VERSION_STRING);
05817 }
05818
05819 for(i = 0; i < info.itext_num; i++)
05820 {
05821 if(strlen(info.itext_keys[i]) > 79)
05822 {
05823 state->error = 66;
05824 break;
05825 }
05826 if(strlen(info.itext_keys[i]) < 1)
05827 {
05828 state->error = 67;
05829 break;
05830 }
05831 addChunk_iTXt(&outv, state->encoder.text_compression,
05832 info.itext_keys[i], info.itext_langtags[i], info.itext_transkeys[i], info.itext_strings[i],
05833 &state->encoder.zlibsettings);
05834 }
05835
05836
05837 if(info.unknown_chunks_data[2])
05838 {
05839 state->error = addUnknownChunks(&outv, info.unknown_chunks_data[2], info.unknown_chunks_size[2]);
05840 if(state->error) break;
05841 }
05842 #endif
05843
05844 addChunk_IEND(&outv);
05845
05846 break;
05847 }
05848
05849 lodepng_info_cleanup(&info);
05850 lodepng_free(data);
05851
05852 *out = outv.data;
05853 *outsize = outv.size;
05854
05855 return state->error;
05856 }
05857
05858 unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, const unsigned char* image,
05859 unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth)
05860 {
05861 unsigned error;
05862 LodePNGState state;
05863 lodepng_state_init(&state);
05864 state.info_raw.colortype = colortype;
05865 state.info_raw.bitdepth = bitdepth;
05866 state.info_png.color.colortype = colortype;
05867 state.info_png.color.bitdepth = bitdepth;
05868 lodepng_encode(out, outsize, image, w, h, &state);
05869 error = state.error;
05870 lodepng_state_cleanup(&state);
05871 return error;
05872 }
05873
05874 unsigned lodepng_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h)
05875 {
05876 return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGBA, 8);
05877 }
05878
05879 unsigned lodepng_encode24(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h)
05880 {
05881 return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGB, 8);
05882 }
05883
05884 #ifdef LODEPNG_COMPILE_DISK
05885 unsigned lodepng_encode_file(const char* filename, const unsigned char* image, unsigned w, unsigned h,
05886 LodePNGColorType colortype, unsigned bitdepth)
05887 {
05888 unsigned char* buffer;
05889 size_t buffersize;
05890 unsigned error = lodepng_encode_memory(&buffer, &buffersize, image, w, h, colortype, bitdepth);
05891 if(!error) error = lodepng_save_file(buffer, buffersize, filename);
05892 lodepng_free(buffer);
05893 return error;
05894 }
05895
05896 unsigned lodepng_encode32_file(const char* filename, const unsigned char* image, unsigned w, unsigned h)
05897 {
05898 return lodepng_encode_file(filename, image, w, h, LCT_RGBA, 8);
05899 }
05900
05901 unsigned lodepng_encode24_file(const char* filename, const unsigned char* image, unsigned w, unsigned h)
05902 {
05903 return lodepng_encode_file(filename, image, w, h, LCT_RGB, 8);
05904 }
05905 #endif
05906
05907 void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings)
05908 {
05909 lodepng_compress_settings_init(&settings->zlibsettings);
05910 settings->filter_palette_zero = 1;
05911 settings->filter_strategy = LFS_MINSUM;
05912 settings->auto_convert = LAC_AUTO;
05913 settings->force_palette = 0;
05914 settings->predefined_filters = 0;
05915 #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
05916 settings->add_id = 0;
05917 settings->text_compression = 1;
05918 #endif
05919 }
05920
05921 #endif
05922 #endif
05923
05924 #ifdef LODEPNG_COMPILE_ERROR_TEXT
05925
05926
05927
05928
05929 const char* lodepng_error_text(unsigned code)
05930 {
05931 switch(code)
05932 {
05933 case 0: return "no error, everything went ok";
05934 case 1: return "nothing done yet";
05935 case 10: return "end of input memory reached without huffman end code";
05936 case 11: return "error in code tree made it jump outside of huffman tree";
05937 case 13: return "problem while processing dynamic deflate block";
05938 case 14: return "problem while processing dynamic deflate block";
05939 case 15: return "problem while processing dynamic deflate block";
05940 case 16: return "unexisting code while processing dynamic deflate block";
05941 case 17: return "end of out buffer memory reached while inflating";
05942 case 18: return "invalid distance code while inflating";
05943 case 19: return "end of out buffer memory reached while inflating";
05944 case 20: return "invalid deflate block BTYPE encountered while decoding";
05945 case 21: return "NLEN is not ones complement of LEN in a deflate block";
05946
05947
05948
05949
05950 case 22: return "end of out buffer memory reached while inflating";
05951 case 23: return "end of in buffer memory reached while inflating";
05952 case 24: return "invalid FCHECK in zlib header";
05953 case 25: return "invalid compression method in zlib header";
05954 case 26: return "FDICT encountered in zlib header while it's not used for PNG";
05955 case 27: return "PNG file is smaller than a PNG header";
05956
05957 case 28: return "incorrect PNG signature, it's no PNG or corrupted";
05958 case 29: return "first chunk is not the header chunk";
05959 case 30: return "chunk length too large, chunk broken off at end of file";
05960 case 31: return "illegal PNG color type or bpp";
05961 case 32: return "illegal PNG compression method";
05962 case 33: return "illegal PNG filter method";
05963 case 34: return "illegal PNG interlace method";
05964 case 35: return "chunk length of a chunk is too large or the chunk too small";
05965 case 36: return "illegal PNG filter type encountered";
05966 case 37: return "illegal bit depth for this color type given";
05967 case 38: return "the palette is too big";
05968 case 39: return "more palette alpha values given in tRNS chunk than there are colors in the palette";
05969 case 40: return "tRNS chunk has wrong size for greyscale image";
05970 case 41: return "tRNS chunk has wrong size for RGB image";
05971 case 42: return "tRNS chunk appeared while it was not allowed for this color type";
05972 case 43: return "bKGD chunk has wrong size for palette image";
05973 case 44: return "bKGD chunk has wrong size for greyscale image";
05974 case 45: return "bKGD chunk has wrong size for RGB image";
05975
05976 case 46: return "a value in indexed image is larger than the palette size (bitdepth = 8)";
05977
05978 case 47: return "a value in indexed image is larger than the palette size (bitdepth < 8)";
05979
05980 case 48: return "empty input or file doesn't exist";
05981 case 49: return "jumped past memory while generating dynamic huffman tree";
05982 case 50: return "jumped past memory while generating dynamic huffman tree";
05983 case 51: return "jumped past memory while inflating huffman block";
05984 case 52: return "jumped past memory while inflating";
05985 case 53: return "size of zlib data too small";
05986 case 54: return "repeat symbol in tree while there was no value symbol yet";
05987
05988
05989
05990 case 55: return "jumped past tree while generating huffman tree";
05991 case 56: return "given output image colortype or bitdepth not supported for color conversion";
05992 case 57: return "invalid CRC encountered (checking CRC can be disabled)";
05993 case 58: return "invalid ADLER32 encountered (checking ADLER32 can be disabled)";
05994 case 59: return "requested color conversion not supported";
05995 case 60: return "invalid window size given in the settings of the encoder (must be 0-32768)";
05996 case 61: return "invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)";
05997
05998 case 62: return "conversion from color to greyscale not supported";
05999 case 63: return "length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk";
06000
06001 case 64: return "the length of the END symbol 256 in the Huffman tree is 0";
06002 case 66: return "the length of a text chunk keyword given to the encoder is longer than the maximum of 79 bytes";
06003 case 67: return "the length of a text chunk keyword given to the encoder is smaller than the minimum of 1 byte";
06004 case 68: return "tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors";
06005 case 69: return "unknown chunk type with 'critical' flag encountered by the decoder";
06006 case 71: return "unexisting interlace mode given to encoder (must be 0 or 1)";
06007 case 72: return "while decoding, unexisting compression method encountering in zTXt or iTXt chunk (it must be 0)";
06008 case 73: return "invalid tIME chunk size";
06009 case 74: return "invalid pHYs chunk size";
06010
06011 case 75: return "no null termination char found while decoding text chunk";
06012 case 76: return "iTXt chunk too short to contain required bytes";
06013 case 77: return "integer overflow in buffer size";
06014 case 78: return "failed to open file for reading";
06015 case 79: return "failed to open file for writing";
06016 case 80: return "tried creating a tree of 0 symbols";
06017 case 81: return "lazy matching at pos 0 is impossible";
06018 case 82: return "color conversion to palette requested while a color isn't in palette";
06019 case 83: return "memory allocation failed";
06020 case 84: return "given image too small to contain all pixels to be encoded";
06021 case 85: return "internal color conversion bug";
06022 case 86: return "impossible offset in lz77 encoding (internal bug)";
06023 case 87: return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined";
06024 case 88: return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy";
06025 case 89: return "text chunk keyword too short or long: must have size 1-79";
06026 }
06027 return "unknown error code";
06028 }
06029 #endif
06030
06031
06032
06033
06034
06035
06036
06037
06038 #ifdef LODEPNG_COMPILE_CPP
06039 namespace lodepng
06040 {
06041
06042 #ifdef LODEPNG_COMPILE_DISK
06043 void load_file(std::vector<unsigned char>& buffer, const std::string& filename)
06044 {
06045 std::ifstream file(filename.c_str(), std::ios::in|std::ios::binary|std::ios::ate);
06046
06047
06048 std::streamsize size = 0;
06049 if(file.seekg(0, std::ios::end).good()) size = file.tellg();
06050 if(file.seekg(0, std::ios::beg).good()) size -= file.tellg();
06051
06052
06053 buffer.resize(size_t(size));
06054 if(size > 0) file.read((char*)(&buffer[0]), size);
06055 }
06056
06057
06058 void save_file(const std::vector<unsigned char>& buffer, const std::string& filename)
06059 {
06060 std::ofstream file(filename.c_str(), std::ios::out|std::ios::binary);
06061 file.write(buffer.empty() ? 0 : (char*)&buffer[0], std::streamsize(buffer.size()));
06062 }
06063 #endif //LODEPNG_COMPILE_DISK
06064
06065 #ifdef LODEPNG_COMPILE_ZLIB
06066 #ifdef LODEPNG_COMPILE_DECODER
06067 unsigned decompress(std::vector<unsigned char>& out, const unsigned char* in, size_t insize,
06068 const LodePNGDecompressSettings& settings)
06069 {
06070 unsigned char* buffer = 0;
06071 size_t buffersize = 0;
06072 unsigned error = zlib_decompress(&buffer, &buffersize, in, insize, &settings);
06073 if(buffer)
06074 {
06075 out.insert(out.end(), &buffer[0], &buffer[buffersize]);
06076 lodepng_free(buffer);
06077 }
06078 return error;
06079 }
06080
06081 unsigned decompress(std::vector<unsigned char>& out, const std::vector<unsigned char>& in,
06082 const LodePNGDecompressSettings& settings)
06083 {
06084 return decompress(out, in.empty() ? 0 : &in[0], in.size(), settings);
06085 }
06086 #endif //LODEPNG_COMPILE_DECODER
06087
06088 #ifdef LODEPNG_COMPILE_ENCODER
06089 unsigned compress(std::vector<unsigned char>& out, const unsigned char* in, size_t insize,
06090 const LodePNGCompressSettings& settings)
06091 {
06092 unsigned char* buffer = 0;
06093 size_t buffersize = 0;
06094 unsigned error = zlib_compress(&buffer, &buffersize, in, insize, &settings);
06095 if(buffer)
06096 {
06097 out.insert(out.end(), &buffer[0], &buffer[buffersize]);
06098 lodepng_free(buffer);
06099 }
06100 return error;
06101 }
06102
06103 unsigned compress(std::vector<unsigned char>& out, const std::vector<unsigned char>& in,
06104 const LodePNGCompressSettings& settings)
06105 {
06106 return compress(out, in.empty() ? 0 : &in[0], in.size(), settings);
06107 }
06108 #endif //LODEPNG_COMPILE_ENCODER
06109 #endif //LODEPNG_COMPILE_ZLIB
06110
06111
06112 #ifdef LODEPNG_COMPILE_PNG
06113
06114 State::State()
06115 {
06116 lodepng_state_init(this);
06117 }
06118
06119 State::State(const State& other)
06120 {
06121 lodepng_state_init(this);
06122 lodepng_state_copy(this, &other);
06123 }
06124
06125 State::~State()
06126 {
06127 lodepng_state_cleanup(this);
06128 }
06129
06130 State& State::operator=(const State& other)
06131 {
06132 lodepng_state_copy(this, &other);
06133 return *this;
06134 }
06135
06136 #ifdef LODEPNG_COMPILE_DECODER
06137
06138 unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h, const unsigned char* in,
06139 size_t insize, LodePNGColorType colortype, unsigned bitdepth)
06140 {
06141 unsigned char* buffer;
06142 unsigned error = lodepng_decode_memory(&buffer, &w, &h, in, insize, colortype, bitdepth);
06143 if(buffer && !error)
06144 {
06145 State state;
06146 state.info_raw.colortype = colortype;
06147 state.info_raw.bitdepth = bitdepth;
06148 size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw);
06149 out.insert(out.end(), &buffer[0], &buffer[buffersize]);
06150 lodepng_free(buffer);
06151 }
06152 return error;
06153 }
06154
06155 unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
06156 const std::vector<unsigned char>& in, LodePNGColorType colortype, unsigned bitdepth)
06157 {
06158 return decode(out, w, h, in.empty() ? 0 : &in[0], (unsigned)in.size(), colortype, bitdepth);
06159 }
06160
06161 unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
06162 State& state,
06163 const unsigned char* in, size_t insize)
06164 {
06165 unsigned char* buffer;
06166 unsigned error = lodepng_decode(&buffer, &w, &h, &state, in, insize);
06167 if(buffer && !error)
06168 {
06169 size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw);
06170 out.insert(out.end(), &buffer[0], &buffer[buffersize]);
06171 lodepng_free(buffer);
06172 }
06173 return error;
06174 }
06175
06176 unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h,
06177 State& state,
06178 const std::vector<unsigned char>& in)
06179 {
06180 return decode(out, w, h, state, in.empty() ? 0 : &in[0], in.size());
06181 }
06182
06183 #ifdef LODEPNG_COMPILE_DISK
06184 unsigned decode(std::vector<unsigned char>& out, unsigned& w, unsigned& h, const std::string& filename,
06185 LodePNGColorType colortype, unsigned bitdepth)
06186 {
06187 std::vector<unsigned char> buffer;
06188 load_file(buffer, filename);
06189 return decode(out, w, h, buffer, colortype, bitdepth);
06190 }
06191 #endif //LODEPNG_COMPILE_DECODER
06192 #endif //LODEPNG_COMPILE_DISK
06193
06194 #ifdef LODEPNG_COMPILE_ENCODER
06195 unsigned encode(std::vector<unsigned char>& out, const unsigned char* in, unsigned w, unsigned h,
06196 LodePNGColorType colortype, unsigned bitdepth)
06197 {
06198 unsigned char* buffer;
06199 size_t buffersize;
06200 unsigned error = lodepng_encode_memory(&buffer, &buffersize, in, w, h, colortype, bitdepth);
06201 if(buffer)
06202 {
06203 out.insert(out.end(), &buffer[0], &buffer[buffersize]);
06204 lodepng_free(buffer);
06205 }
06206 return error;
06207 }
06208
06209 unsigned encode(std::vector<unsigned char>& out,
06210 const std::vector<unsigned char>& in, unsigned w, unsigned h,
06211 LodePNGColorType colortype, unsigned bitdepth)
06212 {
06213 if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84;
06214 return encode(out, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth);
06215 }
06216
06217 unsigned encode(std::vector<unsigned char>& out,
06218 const unsigned char* in, unsigned w, unsigned h,
06219 State& state)
06220 {
06221 unsigned char* buffer;
06222 size_t buffersize;
06223 unsigned error = lodepng_encode(&buffer, &buffersize, in, w, h, &state);
06224 if(buffer)
06225 {
06226 out.insert(out.end(), &buffer[0], &buffer[buffersize]);
06227 lodepng_free(buffer);
06228 }
06229 return error;
06230 }
06231
06232 unsigned encode(std::vector<unsigned char>& out,
06233 const std::vector<unsigned char>& in, unsigned w, unsigned h,
06234 State& state)
06235 {
06236 if(lodepng_get_raw_size(w, h, &state.info_raw) > in.size()) return 84;
06237 return encode(out, in.empty() ? 0 : &in[0], w, h, state);
06238 }
06239
06240 #ifdef LODEPNG_COMPILE_DISK
06241 unsigned encode(const std::string& filename,
06242 const unsigned char* in, unsigned w, unsigned h,
06243 LodePNGColorType colortype, unsigned bitdepth)
06244 {
06245 std::vector<unsigned char> buffer;
06246 unsigned error = encode(buffer, in, w, h, colortype, bitdepth);
06247 if(!error) save_file(buffer, filename);
06248 return error;
06249 }
06250
06251 unsigned encode(const std::string& filename,
06252 const std::vector<unsigned char>& in, unsigned w, unsigned h,
06253 LodePNGColorType colortype, unsigned bitdepth)
06254 {
06255 if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84;
06256 return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth);
06257 }
06258 #endif //LODEPNG_COMPILE_DISK
06259 #endif //LODEPNG_COMPILE_ENCODER
06260 #endif //LODEPNG_COMPILE_PNG
06261 }
06262 #endif