diff options
Diffstat (limited to 'pngdetail.cpp')
-rw-r--r-- | pngdetail.cpp | 81 |
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); |