summaryrefslogtreecommitdiff
path: root/lodepng.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lodepng.cpp')
-rw-r--r--lodepng.cpp87
1 files changed, 51 insertions, 36 deletions
diff --git a/lodepng.cpp b/lodepng.cpp
index 70381fb..c62a22f 100644
--- a/lodepng.cpp
+++ b/lodepng.cpp
@@ -1,7 +1,7 @@
/*
-LodePNG version 20161127
+LodePNG version 20180114
-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 = "20180114";
/*
This source file is built up in the following large parts. The code sections
@@ -1171,7 +1171,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)*/
@@ -3463,6 +3463,7 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
size_t i;
ColorTree tree;
size_t numpixels = w * h;
+ unsigned error = 0;
if(lodepng_color_mode_equal(mode_out, mode_in))
{
@@ -3516,7 +3517,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 +3527,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
@@ -4563,12 +4565,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)
{
@@ -4655,7 +4665,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
@@ -4820,6 +4833,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);
}
@@ -5651,22 +5666,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))
- {
- state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/
- return state->error;
- }
-
- if(state->encoder.auto_convert)
+ /*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 = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw);
+ CERROR_RETURN_ERROR(state->error, 68); /*invalid palette size, it is only allowed to be 1-256*/
}
- if(state->error) return state->error;
-
if(state->encoder.zlibsettings.btype > 2)
{
CERROR_RETURN_ERROR(state->error, 61); /*error: unexisting btype*/
@@ -5675,28 +5680,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_auto_choose_color(&info.color, image, w, h, &state->info_raw);
+ }
+ if (!state->error)
+ {
+ if(!lodepng_color_mode_equal(&state->info_raw, &info.color))
{
- state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h);
+ 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);
}
- 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);
}
- 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*/
{