Updated LodePNG to 2018.06.11 version

This commit is contained in:
vsonnier 2018-08-09 20:49:59 +02:00
parent a7e4d911e9
commit 5e8e608a9c
2 changed files with 181 additions and 102 deletions

View File

@ -1,7 +1,7 @@
/*
LodePNG version 20161127
LodePNG version 20180611
Copyright (c) 2005-2016 Lode Vandevenne
Copyright (c) 2005-2018 Lode Vandevenne
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -39,7 +39,7 @@ Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for
#pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/
#endif /*_MSC_VER */
const char* LODEPNG_VERSION_STRING = "20161127";
const char* LODEPNG_VERSION_STRING = "20180611";
/*
This source file is built up in the following large parts. The code sections
@ -62,11 +62,17 @@ from here.*/
#ifdef LODEPNG_COMPILE_ALLOCATORS
static void* lodepng_malloc(size_t size)
{
#ifdef LODEPNG_MAX_ALLOC
if(size > LODEPNG_MAX_ALLOC) return 0;
#endif
return malloc(size);
}
static void* lodepng_realloc(void* ptr, size_t new_size)
{
#ifdef LODEPNG_MAX_ALLOC
if(new_size > LODEPNG_MAX_ALLOC) return 0;
#endif
return realloc(ptr, new_size);
}
@ -86,6 +92,8 @@ void lodepng_free(void* ptr);
/* ////////////////////////////////////////////////////////////////////////// */
/* ////////////////////////////////////////////////////////////////////////// */
#define LODEPNG_MAX(a, b) (((a) > (b)) ? (a) : (b))
/*
Often in case of an error a value is assigned to a variable and then it breaks
out of a loop (to go to the cleanup phase of a function). This macro does that.
@ -795,7 +803,7 @@ unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequen
BPMNode* leaves; /*the symbols, only those with > 0 frequency*/
if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/
if((1u << maxbitlen) < numcodes) return 80; /*error: represent all symbols*/
if((1u << maxbitlen) < (unsigned)numcodes) return 80; /*error: represent all symbols*/
leaves = (BPMNode*)lodepng_malloc(numcodes * sizeof(*leaves));
if(!leaves) return 83; /*alloc fail*/
@ -1171,7 +1179,7 @@ static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size
code_d = huffmanDecodeSymbol(in, bp, &tree_d, inbitlength);
if(code_d > 29)
{
if(code_ll == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/
if(code_d == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/
{
/*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol
(10=no endcode, 11=wrong jump outside of tree)*/
@ -1455,11 +1463,11 @@ static void updateHashChain(Hash* hash, size_t wpos, unsigned hashval, unsigned
{
hash->val[wpos] = (int)hashval;
if(hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval];
hash->head[hashval] = wpos;
hash->head[hashval] = (int)wpos;
hash->zeros[wpos] = numzeros;
if(hash->headz[numzeros] != -1) hash->chainz[wpos] = hash->headz[numzeros];
hash->headz[numzeros] = wpos;
hash->headz[numzeros] = (int)wpos;
}
/*
@ -1531,7 +1539,7 @@ static unsigned encodeLZ77(uivector* out, Hash* hash,
for(;;)
{
if(chainlength++ >= maxchainlength) break;
current_offset = hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize;
current_offset = (unsigned)(hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize);
if(current_offset < prev_offset) break; /*stop when went completely around the circular buffer*/
prev_offset = current_offset;
@ -2090,13 +2098,13 @@ static unsigned deflate(unsigned char** out, size_t* outsize,
static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len)
{
unsigned s1 = adler & 0xffff;
unsigned s2 = (adler >> 16) & 0xffff;
unsigned s1 = adler & 0xffff;
unsigned s2 = (adler >> 16) & 0xffff;
while(len > 0)
{
/*at least 5550 sums can be done before the sums overflow, saving a lot of module divisions*/
unsigned amount = len > 5550 ? 5550 : len;
/*at least 5552 sums can be done before the sums overflow, saving a lot of module divisions*/
unsigned amount = len > 5552 ? 5552 : len;
len -= amount;
while(amount > 0)
{
@ -2621,15 +2629,10 @@ static int lodepng_color_mode_equal(const LodePNGColorMode* a, const LodePNGColo
if(a->key_g != b->key_g) return 0;
if(a->key_b != b->key_b) return 0;
}
/*if one of the palette sizes is 0, then we consider it to be the same as the
other: it means that e.g. the palette was not given by the user and should be
considered the same as the palette inside the PNG.*/
if(1/*a->palettesize != 0 && b->palettesize != 0*/) {
if(a->palettesize != b->palettesize) return 0;
for(i = 0; i != a->palettesize * 4; ++i)
{
if(a->palette[i] != b->palette[i]) return 0;
}
if(a->palettesize != b->palettesize) return 0;
for(i = 0; i != a->palettesize * 4; ++i)
{
if(a->palette[i] != b->palette[i]) return 0;
}
return 1;
}
@ -2705,32 +2708,75 @@ unsigned lodepng_can_have_alpha(const LodePNGColorMode* info)
|| lodepng_has_palette_alpha(info);
}
size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color)
size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth)
{
/*will not overflow for any color type if roughly w * h < 268435455*/
size_t bpp = lodepng_get_bpp(color);
size_t n = w * h;
size_t bpp = lodepng_get_bpp_lct(colortype, bitdepth);
size_t n = (size_t)w * (size_t)h;
return ((n / 8) * bpp) + ((n & 7) * bpp + 7) / 8;
}
size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth)
size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color)
{
/*will not overflow for any color type if roughly w * h < 268435455*/
size_t bpp = lodepng_get_bpp_lct(colortype, bitdepth);
size_t n = w * h;
return ((n / 8) * bpp) + ((n & 7) * bpp + 7) / 8;
return lodepng_get_raw_size_lct(w, h, color->colortype, color->bitdepth);
}
#ifdef LODEPNG_COMPILE_PNG
#ifdef LODEPNG_COMPILE_DECODER
/*in an idat chunk, each scanline is a multiple of 8 bits, unlike the lodepng output buffer*/
/*in an idat chunk, each scanline is a multiple of 8 bits, unlike the lodepng output buffer,
and in addition has one extra byte per line: the filter byte. So this gives a larger
result than lodepng_get_raw_size. */
static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, const LodePNGColorMode* color)
{
/*will not overflow for any color type if roughly w * h < 268435455*/
size_t bpp = lodepng_get_bpp(color);
size_t line = ((w / 8) * bpp) + ((w & 7) * bpp + 7) / 8;
return h * line;
/* + 1 for the filter byte, and possibly plus padding bits per line */
size_t line = ((size_t)(w / 8) * bpp) + 1 + ((w & 7) * bpp + 7) / 8;
return (size_t)h * line;
}
/* Safely check if multiplying two integers will overflow (no undefined
behavior, compiler removing the code, etc...) and output result. */
static int lodepng_mulofl(size_t a, size_t b, size_t* result)
{
*result = a * b; /* Unsigned multiplication is well defined and safe in C90 */
return (a != 0 && *result / a != b);
}
/* Safely check if adding two integers will overflow (no undefined
behavior, compiler removing the code, etc...) and output result. */
static int lodepng_addofl(size_t a, size_t b, size_t* result)
{
*result = a + b; /* Unsigned addition is well defined and safe in C90 */
return *result < a;
}
/*Safely checks whether size_t overflow can be caused due to amount of pixels.
This check is overcautious rather than precise. If this check indicates no overflow,
you can safely compute in a size_t (but not an unsigned):
-(size_t)w * (size_t)h * 8
-amount of bytes in IDAT (including filter, padding and Adam7 bytes)
-amount of bytes in raw color model
Returns 1 if overflow possible, 0 if not.
*/
static int lodepng_pixel_overflow(unsigned w, unsigned h,
const LodePNGColorMode* pngcolor, const LodePNGColorMode* rawcolor)
{
size_t bpp = LODEPNG_MAX(lodepng_get_bpp(pngcolor), lodepng_get_bpp(rawcolor));
size_t numpixels, total;
size_t line; /* bytes per line in worst case */
if(lodepng_mulofl((size_t)w, (size_t)h, &numpixels)) return 1;
if(lodepng_mulofl(numpixels, 8, &total)) return 1; /* bit pointer with 8-bit color, or 8 bytes per channel color */
/* Bytes per scanline with the expression "(w / 8) * bpp) + ((w & 7) * bpp + 7) / 8" */
if(lodepng_mulofl((size_t)(w / 8), bpp, &line)) return 1;
if(lodepng_addofl(line, ((w & 7) * bpp + 7) / 8, &line)) return 1;
if(lodepng_addofl(line, 5, &line)) return 1; /* 5 bytes overhead per line: 1 filterbyte, 4 for Adam7 worst case */
if(lodepng_mulofl(line, h, &total)) return 1; /* Total bytes in worst case */
return 0; /* no overflow */
}
#endif /*LODEPNG_COMPILE_DECODER*/
#endif /*LODEPNG_COMPILE_PNG*/
@ -3462,7 +3508,8 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
{
size_t i;
ColorTree tree;
size_t numpixels = w * h;
size_t numpixels = (size_t)w * (size_t)h;
unsigned error = 0;
if(lodepng_color_mode_equal(mode_out, mode_in))
{
@ -3475,7 +3522,7 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
{
size_t palettesize = mode_out->palettesize;
const unsigned char* palette = mode_out->palette;
size_t palsize = 1u << mode_out->bitdepth;
size_t palsize = (size_t)1u << mode_out->bitdepth;
/*if the user specified output palette but did not give the values, assume
they want the values of the input color type (assuming that one is palette).
Note that we never create a new palette ourselves.*/
@ -3483,13 +3530,22 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
{
palettesize = mode_in->palettesize;
palette = mode_in->palette;
/*if the input was also palette with same bitdepth, then the color types are also
equal, so copy literally. This to preserve the exact indices that were in the PNG
even in case there are duplicate colors in the palette.*/
if (mode_in->colortype == LCT_PALETTE && mode_in->bitdepth == mode_out->bitdepth)
{
size_t numbytes = lodepng_get_raw_size(w, h, mode_in);
for(i = 0; i != numbytes; ++i) out[i] = in[i];
return 0;
}
}
if(palettesize < palsize) palsize = palettesize;
color_tree_init(&tree);
for(i = 0; i != palsize; ++i)
{
const unsigned char* p = &palette[i * 4];
color_tree_add(&tree, p[0], p[1], p[2], p[3], i);
color_tree_add(&tree, p[0], p[1], p[2], p[3], (unsigned)i);
}
}
@ -3516,7 +3572,8 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
for(i = 0; i != numpixels; ++i)
{
getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in);
CERROR_TRY_RETURN(rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a));
error = rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a);
if (error) break;
}
}
@ -3525,7 +3582,7 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
color_tree_cleanup(&tree);
}
return 0; /*no error*/
return error;
}
#ifdef LODEPNG_COMPILE_ENCODER
@ -3571,7 +3628,7 @@ unsigned lodepng_get_color_profile(LodePNGColorProfile* profile,
unsigned error = 0;
size_t i;
ColorTree tree;
size_t numpixels = w * h;
size_t numpixels = (size_t)w * (size_t)h;
unsigned colored_done = lodepng_is_greyscale_type(mode) ? 1 : 0;
unsigned alpha_done = lodepng_can_have_alpha(mode) ? 0 : 1;
@ -3766,14 +3823,16 @@ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out,
{
LodePNGColorProfile prof;
unsigned error = 0;
unsigned i, n, palettebits, palette_ok;
unsigned palettebits, palette_ok;
size_t i, n;
size_t numpixels = (size_t)w * (size_t)h;
lodepng_color_profile_init(&prof);
error = lodepng_get_color_profile(&prof, image, w, h, mode_in);
if(error) return error;
mode_out->key_defined = 0;
if(prof.key && w * h <= 16)
if(prof.key && numpixels <= 16)
{
prof.alpha = 1; /*too few pixels to justify tRNS chunk overhead*/
prof.key = 0;
@ -3782,7 +3841,7 @@ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out,
n = prof.numcolors;
palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8));
palette_ok = n <= 256 && prof.bits <= 8;
if(w * h < n * 2) palette_ok = 0; /*don't add palette overhead if image has only a few pixels*/
if(numpixels < n * 2) palette_ok = 0; /*don't add palette overhead if image has only a few pixels*/
if(!prof.colored && prof.bits <= palettebits) palette_ok = 0; /*grey is less overhead*/
if(palette_ok)
@ -4329,7 +4388,7 @@ static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, siz
string2_begin = length + 1; /*skip keyword null terminator*/
length = chunkLength < string2_begin ? 0 : chunkLength - string2_begin;
length = (unsigned)(chunkLength < string2_begin ? 0 : chunkLength - string2_begin);
str = (char*)lodepng_malloc(length + 1);
if(!str) CERROR_BREAK(error, 83); /*alloc fail*/
@ -4377,7 +4436,7 @@ static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSetting
string2_begin = length + 2;
if(string2_begin > chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/
length = chunkLength - string2_begin;
length = (unsigned)chunkLength - string2_begin;
/*will fail if zlib error, e.g. if length is too small*/
error = zlib_decompress(&decoded.data, &decoded.size,
(unsigned char*)(&data[string2_begin]),
@ -4457,7 +4516,7 @@ static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSetting
/*read the actual text*/
begin += length + 1;
length = chunkLength < begin ? 0 : chunkLength - begin;
length = (unsigned)chunkLength < begin ? 0 : (unsigned)chunkLength - begin;
if(compressed)
{
@ -4529,7 +4588,6 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
ucvector idat; /*the data from idat chunks*/
ucvector scanlines;
size_t predict;
size_t numpixels;
size_t outsize = 0;
/*for unknown chunk order*/
@ -4544,13 +4602,10 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/
if(state->error) return;
numpixels = *w * *h;
/*multiplication overflow*/
if(*h != 0 && numpixels / *h != *w) CERROR_RETURN(state->error, 92);
/*multiplication overflow possible further below. Allows up to 2^31-1 pixel
bytes with 16-bit RGBA, the rest is room for filter bytes.*/
if(numpixels > 268435455) CERROR_RETURN(state->error, 92);
if(lodepng_pixel_overflow(*w, *h, &state->info_png.color, &state->info_raw))
{
CERROR_RETURN(state->error, 92); /*overflow possible due to amount of pixels*/
}
ucvector_init(&idat);
chunk = &in[33]; /*first byte of the first chunk after the header*/
@ -4563,12 +4618,20 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
const unsigned char* data; /*the data in the chunk*/
/*error: size of the in buffer too small to contain next chunk*/
if((size_t)((chunk - in) + 12) > insize || chunk < in) CERROR_BREAK(state->error, 30);
if((size_t)((chunk - in) + 12) > insize || chunk < in)
{
if(state->decoder.ignore_end) break; /*other errors may still happen though*/
CERROR_BREAK(state->error, 30);
}
/*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/
chunkLength = lodepng_chunk_length(chunk);
/*error: chunk length larger than the max PNG chunk size*/
if(chunkLength > 2147483647) CERROR_BREAK(state->error, 63);
if(chunkLength > 2147483647)
{
if(state->decoder.ignore_end) break; /*other errors may still happen though*/
CERROR_BREAK(state->error, 63);
}
if((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in)
{
@ -4581,7 +4644,9 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
if(lodepng_chunk_type_equals(chunk, "IDAT"))
{
size_t oldsize = idat.size;
if(!ucvector_resize(&idat, oldsize + chunkLength)) CERROR_BREAK(state->error, 83 /*alloc fail*/);
size_t newsize;
if(lodepng_addofl(oldsize, chunkLength, &newsize)) CERROR_BREAK(state->error, 95);
if(!ucvector_resize(&idat, newsize)) CERROR_BREAK(state->error, 83 /*alloc fail*/);
for(i = 0; i != chunkLength; ++i) idat.data[oldsize + i] = data[i];
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
critical_pos = 3;
@ -4655,7 +4720,10 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
else /*it's not an implemented chunk type, so ignore it: skip over the data*/
{
/*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/
if(!lodepng_chunk_ancillary(chunk)) CERROR_BREAK(state->error, 69);
if(!state->decoder.ignore_critical && !lodepng_chunk_ancillary(chunk))
{
CERROR_BREAK(state->error, 69);
}
unknown = 1;
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
@ -4681,21 +4749,20 @@ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h,
If the decompressed size does not match the prediction, the image must be corrupt.*/
if(state->info_png.interlace_method == 0)
{
/*The extra *h is added because this are the filter bytes every scanline starts with*/
predict = lodepng_get_raw_size_idat(*w, *h, &state->info_png.color) + *h;
predict = lodepng_get_raw_size_idat(*w, *h, &state->info_png.color);
}
else
{
/*Adam-7 interlaced: predicted size is the sum of the 7 sub-images sizes*/
const LodePNGColorMode* color = &state->info_png.color;
predict = 0;
predict += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, color) + ((*h + 7) >> 3);
if(*w > 4) predict += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, color) + ((*h + 7) >> 3);
predict += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, color) + ((*h + 3) >> 3);
if(*w > 2) predict += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, color) + ((*h + 3) >> 2);
predict += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, color) + ((*h + 1) >> 2);
if(*w > 1) predict += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, color) + ((*h + 1) >> 1);
predict += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, color) + ((*h + 0) >> 1);
predict += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, color);
if(*w > 4) predict += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, color);
predict += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, color);
if(*w > 2) predict += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, color);
predict += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, color);
if(*w > 1) predict += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, color);
predict += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, color);
}
if(!state->error && !ucvector_reserve(&scanlines, predict)) state->error = 83; /*alloc fail*/
if(!state->error)
@ -4820,6 +4887,8 @@ void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings)
settings->remember_unknown_chunks = 0;
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
settings->ignore_crc = 0;
settings->ignore_critical = 0;
settings->ignore_end = 0;
lodepng_decompress_settings_init(&settings->zlibsettings);
}
@ -5400,7 +5469,7 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w,
{
for(type = 0; type != 5; ++type)
{
unsigned testsize = linebytes;
unsigned testsize = (unsigned)linebytes;
/*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/
filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type);
@ -5651,22 +5720,12 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize,
*outsize = 0;
state->error = 0;
lodepng_info_init(&info);
lodepng_info_copy(&info, &state->info_png);
if((info.color.colortype == LCT_PALETTE || state->encoder.force_palette)
&& (info.color.palettesize == 0 || info.color.palettesize > 256))
/*check input values validity*/
if((state->info_png.color.colortype == LCT_PALETTE || state->encoder.force_palette)
&& (state->info_png.color.palettesize == 0 || state->info_png.color.palettesize > 256))
{
state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/
return state->error;
CERROR_RETURN_ERROR(state->error, 68); /*invalid palette size, it is only allowed to be 1-256*/
}
if(state->encoder.auto_convert)
{
state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw);
}
if(state->error) return state->error;
if(state->encoder.zlibsettings.btype > 2)
{
CERROR_RETURN_ERROR(state->error, 61); /*error: unexisting btype*/
@ -5675,28 +5734,38 @@ unsigned lodepng_encode(unsigned char** out, size_t* outsize,
{
CERROR_RETURN_ERROR(state->error, 71); /*error: unexisting interlace mode*/
}
state->error = checkColorValidity(info.color.colortype, info.color.bitdepth);
state->error = checkColorValidity(state->info_png.color.colortype, state->info_png.color.bitdepth);
if(state->error) return state->error; /*error: unexisting color type given*/
state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth);
if(state->error) return state->error; /*error: unexisting color type given*/
if(!lodepng_color_mode_equal(&state->info_raw, &info.color))
/* color convert and compute scanline filter types */
lodepng_info_init(&info);
lodepng_info_copy(&info, &state->info_png);
if(state->encoder.auto_convert)
{
unsigned char* converted;
size_t size = (w * h * (size_t)lodepng_get_bpp(&info.color) + 7) / 8;
converted = (unsigned char*)lodepng_malloc(size);
if(!converted && size) state->error = 83; /*alloc fail*/
if(!state->error)
{
state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h);
}
if(!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder);
lodepng_free(converted);
state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw);
}
else preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder);
if (!state->error)
{
if(!lodepng_color_mode_equal(&state->info_raw, &info.color))
{
unsigned char* converted;
size_t size = ((size_t)w * (size_t)h * (size_t)lodepng_get_bpp(&info.color) + 7) / 8;
converted = (unsigned char*)lodepng_malloc(size);
if(!converted && size) state->error = 83; /*alloc fail*/
if(!state->error)
{
state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h);
}
if(!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder);
lodepng_free(converted);
}
else preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder);
}
/* output all PNG chunks */
ucvector_init(&outv);
while(!state->error) /*while only executed once, to break on error*/
{
@ -5995,9 +6064,10 @@ const char* lodepng_error_text(unsigned code)
/*the windowsize in the LodePNGCompressSettings. Requiring POT(==> & instead of %) makes encoding 12% faster.*/
case 90: return "windowsize must be a power of two";
case 91: return "invalid decompressed idat size";
case 92: return "too many pixels, not supported";
case 92: return "integer overflow due to too many pixels";
case 93: return "zero width or height is invalid";
case 94: return "header chunk must have a size of 13 bytes";
case 95: return "integer overflow with combined idat chunk size";
}
return "unknown error code";
}

View File

@ -1,7 +1,7 @@
/*
LodePNG version 20161127
LodePNG version 20180611
Copyright (c) 2005-2016 Lode Vandevenne
Copyright (c) 2005-2018 Lode Vandevenne
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -255,6 +255,7 @@ const char* lodepng_error_text(unsigned code);
typedef struct LodePNGDecompressSettings LodePNGDecompressSettings;
struct LodePNGDecompressSettings
{
/* Check LodePNGDecoderSettings for more ignorable errors */
unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/
/*use custom zlib decoder instead of built in one (default: null)*/
@ -409,7 +410,7 @@ typedef struct LodePNGInfo
/*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/
unsigned compression_method;/*compression method of the original file. Always 0.*/
unsigned filter_method; /*filter method of the original file*/
unsigned interlace_method; /*interlace method of the original file*/
unsigned interlace_method; /*interlace method of the original file: 0=none, 1=Adam7*/
LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
@ -520,7 +521,10 @@ typedef struct LodePNGDecoderSettings
{
LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/
/* Check LodePNGDecompressSettings for more ignorable errors */
unsigned ignore_crc; /*ignore CRC checksums*/
unsigned ignore_critical; /*ignore unknown critical chunks*/
unsigned ignore_end; /*ignore issues at end of file if possible (missing IEND chunk, too large chunk, ...)*/
unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/
@ -1567,6 +1571,8 @@ For decoding:
state.decoder.zlibsettings.ignore_adler32: ignore ADLER32 checksums
state.decoder.zlibsettings.custom_...: use custom inflate function
state.decoder.ignore_crc: ignore CRC checksums
state.decoder.ignore_critical: ignore unknown critical chunks
state.decoder.ignore_end: ignore missing IEND chunk. May fail if this corruption causes other errors
state.decoder.color_convert: convert internal PNG color to chosen one
state.decoder.read_text_chunks: whether to read in text metadata chunks
state.decoder.remember_unknown_chunks: whether to read in unknown chunks
@ -1608,6 +1614,9 @@ yyyymmdd.
Some changes aren't backwards compatible. Those are indicated with a (!)
symbol.
*) 11 jun 2018: less restrictive check for pixel size integer overflow
*) 14 jan 2018: allow optionally ignoring a few more recoverable errors
*) 17 sep 2017: fix memory leak for some encoder input error cases
*) 27 nov 2016: grey+alpha auto color model detection bugfix
*) 18 apr 2016: Changed qsort to custom stable sort (for platforms w/o qsort).
*) 09 apr 2016: Fixed colorkey usage detection, and better file loading (within
@ -1757,5 +1766,5 @@ Domain: gmail dot com.
Account: lode dot vandevenne.
Copyright (c) 2005-2016 Lode Vandevenne
Copyright (c) 2005-2018 Lode Vandevenne
*/