summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLode <lvandeve@gmail.com>2018-01-15 01:26:30 +0100
committerLode <lvandeve@gmail.com>2018-01-15 01:26:30 +0100
commitd4d8f1aa786571af4a90a41b3db048043f114629 (patch)
tree9e40c8741cc3b6fa632b4bc3dd1fe8a5ad524358
parentc7bb19ad54a53f0d9917da37de7288b1aadf6d0f (diff)
allow optionally ignoring a few more recoverable errors
-rw-r--r--lodepng.cpp25
-rw-r--r--lodepng.h11
-rw-r--r--lodepng_unittest.cpp2
-rw-r--r--lodepng_util.cpp4
-rw-r--r--lodepng_util.h2
-rw-r--r--pngdetail.cpp49
6 files changed, 68 insertions, 25 deletions
diff --git a/lodepng.cpp b/lodepng.cpp
index 37b0562..6998910 100644
--- a/lodepng.cpp
+++ b/lodepng.cpp
@@ -1,7 +1,7 @@
/*
-LodePNG version 20170917
+LodePNG version 20180114
-Copyright (c) 2005-2017 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 = "20170917";
+const char* LODEPNG_VERSION_STRING = "20180114";
/*
This source file is built up in the following large parts. The code sections
@@ -4565,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)
{
@@ -4657,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
@@ -4822,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);
}
diff --git a/lodepng.h b/lodepng.h
index d633bfa..cf6667c 100644
--- a/lodepng.h
+++ b/lodepng.h
@@ -1,7 +1,7 @@
/*
-LodePNG version 20170917
+LodePNG version 20180114
-Copyright (c) 2005-2017 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)*/
@@ -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,7 @@ yyyymmdd.
Some changes aren't backwards compatible. Those are indicated with a (!)
symbol.
+*) 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).
diff --git a/lodepng_unittest.cpp b/lodepng_unittest.cpp
index 5d11b2d..975f2b4 100644
--- a/lodepng_unittest.cpp
+++ b/lodepng_unittest.cpp
@@ -28,7 +28,7 @@ freely, subject to the following restrictions:
/*
Testing instructions:
-*) Ensure no tests commented out below
+*) Ensure no tests commented out below or early return in doMain
*) Compile with g++ with all warnings and run the unit test
g++ lodepng.cpp lodepng_util.cpp lodepng_unittest.cpp -Wall -Wextra -Wshadow -pedantic -ansi -O3 && ./a.out
diff --git a/lodepng_util.cpp b/lodepng_util.cpp
index 76efdea..9d86686 100644
--- a/lodepng_util.cpp
+++ b/lodepng_util.cpp
@@ -1,7 +1,7 @@
/*
LodePNG Utils
-Copyright (c) 2005-2014 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
@@ -52,9 +52,9 @@ unsigned getChunkInfo(std::vector<std::string>& names, std::vector<size_t>& size
if(std::string(type).size() != 4) return 1;
unsigned length = lodepng_chunk_length(chunk);
- if(chunk + length + 12 > end) return 1;
names.push_back(type);
sizes.push_back(length);
+ if(chunk + length + 12 > end) return 1;
next = lodepng_chunk_next_const(chunk);
if (next <= chunk) return 1; // integer overflow
diff --git a/lodepng_util.h b/lodepng_util.h
index 236ad46..19fcbcb 100644
--- a/lodepng_util.h
+++ b/lodepng_util.h
@@ -1,7 +1,7 @@
/*
LodePNG Utils
-Copyright (c) 2005-2014 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
diff --git a/pngdetail.cpp b/pngdetail.cpp
index f0a5158..00aa9dd 100644
--- a/pngdetail.cpp
+++ b/pngdetail.cpp
@@ -1,7 +1,7 @@
/*
LodePNG pngdetail
-Copyright (c) 2005-2015 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
@@ -797,6 +797,11 @@ unsigned showFileInfo(const std::string& filename, const Options& options)
std::vector<unsigned char> image;
unsigned w, h;
+ if(options.show_png_info)
+ {
+ std::cout << "pngdetail version: " << LODEPNG_VERSION_STRING << std::endl;
+ }
+
unsigned error = lodepng::load_file(buffer, filename); //load the image file with given filename
if(error)
@@ -810,27 +815,45 @@ unsigned showFileInfo(const std::string& filename, const Options& options)
state.info_raw.bitdepth = 16;
error = lodepng::decode(image, w, h, state, buffer);
- // In case of checksum errors, disable checksums
- while (error == 57 || error == 58) {
+ // In case of checksum errors and some other ignorable errors, report it but ignore it and retry
+ while (error) {
+ std::cerr << "Decoder error " << error << ": " << lodepng_error_text(error) << std::endl;
+ unsigned error2 = error;
if(error == 57)
{
- std::cout << "Error: invalid CRC checksum" << std::endl;
+ std::cerr << "Ignoring the error: enabling ignore_crc" << std::endl;
state.decoder.ignore_crc = 1;
error = lodepng::decode(image, w, h, state, buffer);
}
-
- if(error == 58)
+ else if(error == 58)
{
- std::cout << "Error: invalid Adler32 checksum" << std::endl;
+ std::cerr << "Ignoring the error: enabling ignore_adler32" << std::endl;
state.decoder.zlibsettings.ignore_adler32 = 1;
error = lodepng::decode(image, w, h, state, buffer);
}
- }
-
- if(error)
- {
- std::cout << "Decoder error " << error << ": " << lodepng_error_text(error) << std::endl;
- // Do not return: some sections may still show partial info about a corrupted PNG.
+ else if(error == 69)
+ {
+ std::cerr << "Ignoring the error: enabling ignore_critical" << std::endl;
+ state.decoder.ignore_critical = 1;
+ error = lodepng::decode(image, w, h, state, buffer);
+ }
+ else if(error == 30 || error == 63)
+ {
+ std::cerr << "Ignoring the error: enabling ignore_end" << std::endl;
+ state.decoder.ignore_end = 1;
+ error = lodepng::decode(image, w, h, state, buffer);
+ }
+ else
+ {
+ if(error == 0) std::cerr << "This error is unrecoverable" << std::endl;
+ break; // other error that we cannot ignore
+ }
+ if(error == 0) std::cerr << "Successfully ignored the error" << std::endl;
+ if(error == error2)
+ {
+ std::cerr << "Failed to ignore the error" << std::endl;
+ break; // avoid infinite loop if ignoring did not fix the error code
+ }
}
bool extra_newlines = false;