summaryrefslogtreecommitdiff
path: root/pngdetail.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pngdetail.cpp')
-rw-r--r--pngdetail.cpp81
1 files changed, 59 insertions, 22 deletions
diff --git a/pngdetail.cpp b/pngdetail.cpp
index 41952a4..b11d78c 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
@@ -184,7 +184,13 @@ void displayChunkNames(const std::vector<unsigned char>& buffer, const Options&
std::vector<std::string> names;
std::vector<size_t> sizes;
unsigned error = lodepng::getChunkInfo(names, sizes, buffer);
- if(error) std::cout << "Error while identifying chunks. Listing identified chunks anyway." << std::endl;
+ if(error) {
+ if(!names.empty() && names.back() == "IEND" && sizes.back() == 0) {
+ std::cout << "Corruption or superfluous data detected after the IEND chunk" << std::endl;
+ } else {
+ std::cout << "Error while identifying chunks. Listing identified chunks anyway." << std::endl;
+ }
+ }
if(options.show_chunks2)
{
@@ -711,7 +717,7 @@ void showHelp()
"-b: show Zlib blocks\n"
"-B: show Zlib block symbol counts\n"
"-7: show all lz77 values (huge output)\n"
- "-x: print most numbers in hexadecimal\n"
+ "-x: print most integer numbers in hexadecimal (includes e.g. year, num unique colors, ...)\n"
<< std::endl;
}
@@ -797,6 +803,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 +821,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;
@@ -850,15 +879,23 @@ unsigned showFileInfo(const std::string& filename, const Options& options)
std::cout << "Height: " << h << std::endl;
if(options.show_extra_png_info) std::cout << "Num pixels: " << w * h << std::endl;
+ std::cout << "Num unique colors: " << countColors(image, w, h) << std::endl;
if(options.show_extra_png_info && w > 0 && h > 0)
{
- std::ios_base::fmtflags flags = std::cout.flags();
- std::cout << "Top left pixel color: #"
- << std::hex << std::setfill('0')
- << std::setw(2) << (int)image[0] << std::setw(2) << (int)image[1] << std::setw(2) << (int)image[2] << std::setw(2) << (int)image[3]
- << std::endl;
- std::cout.flags(flags);
- std::cout << "Num unique colors: " << countColors(image, w, h) << std::endl;
+ double r = 0, g = 0, b = 0, a = 0;
+ for(unsigned y = 0; y < h; y++) {
+ for(unsigned x = 0; x < w; x++) {
+ r += 256 * image[y * 8 * w + x * 8 + 0] + image[y * 8 * w + x * 8 + 1];
+ g += 256 * image[y * 8 * w + x * 8 + 2] + image[y * 8 * w + x * 8 + 3];
+ b += 256 * image[y * 8 * w + x * 8 + 4] + image[y * 8 * w + x * 8 + 5];
+ a += 256 * image[y * 8 * w + x * 8 + 6] + image[y * 8 * w + x * 8 + 7];
+ }
+ }
+ r /= (w * h * 257.0);
+ g /= (w * h * 257.0);
+ b /= (w * h * 257.0);
+ a /= (w * h * 257.0);
+ std::cout << "Average color: " << r << ", " << g << ", " << b << ", " << a << std::endl;
}
displayPNGInfo(state.info_png, options);