mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-26 13:48:38 -05:00
Updated LodePNG to 2018.06.11 version
This commit is contained in:
parent
a7e4d911e9
commit
5e8e608a9c
266
external/lodepng/lodepng.cpp
vendored
266
external/lodepng/lodepng.cpp
vendored
@ -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";
|
||||
}
|
||||
|
17
external/lodepng/lodepng.h
vendored
17
external/lodepng/lodepng.h
vendored
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user