From 9e8a594905316d14aeb55ab5ab5f50e03cb847c6 Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Wed, 28 Feb 2018 16:24:18 -0500 Subject: Support pngs with incorrect CMF bytes Bug: chromium:807324 Though these pngs are technically incorrect, many such PNGs exist, and they are supported in Chromium. Ensure that users of SkCodec (e.g. Android, Flutter) display them as well. Change-Id: I2f1e573b4b7039cea81f96397cc0aa4cbc9461c3 Reviewed-on: https://skia-review.googlesource.com/111082 Commit-Queue: Leon Scroggins Reviewed-by: Derek Sollenberger --- resources/images/crbug807324.png | Bin 0 -> 2194 bytes src/codec/SkPngCodec.cpp | 5 +++++ tests/CodecTest.cpp | 35 +++++++++++++++++++++++++++++++++++ third_party/libpng/BUILD.gn | 2 +- 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 resources/images/crbug807324.png diff --git a/resources/images/crbug807324.png b/resources/images/crbug807324.png new file mode 100644 index 0000000000..f58aab7231 Binary files /dev/null and b/resources/images/crbug807324.png differ diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp index 9df7bc67e1..df22121b4c 100644 --- a/src/codec/SkPngCodec.cpp +++ b/src/codec/SkPngCodec.cpp @@ -22,6 +22,7 @@ #include "SkTemplates.h" #include "SkUtils.h" +#define PNG_SET_OPTION_SUPPORTED #include "png.h" #include @@ -787,6 +788,10 @@ static SkCodec::Result read_header(SkStream* stream, SkPngChunkReader* chunkRead return SkCodec::kInternalError; } + // This setting ensures that we display images with incorrect CMF bytes. + // See crbug.com/807324. + png_set_option(png_ptr, PNG_MAXIMUM_INFLATE_WINDOW, PNG_OPTION_ON); + AutoCleanPng autoClean(png_ptr, stream, chunkReader, outCodec); png_infop info_ptr = png_create_info_struct(png_ptr); diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp index e3362f5815..d8dab25a90 100644 --- a/tests/CodecTest.cpp +++ b/tests/CodecTest.cpp @@ -1566,3 +1566,38 @@ DEF_TEST(Codec_ossfuzz6274, r) { } } } + +DEF_TEST(Codec_crbug807324, r) { + if (GetResourcePath().isEmpty()) { + return; + } + + const char* file = "images/crbug807324.png"; + auto image = GetResourceAsImage(file); + if (!image) { + ERRORF(r, "Missing %s", file); + return; + } + + const int kWidth = image->width(); + const int kHeight = image->height(); + + SkBitmap bm; + if (!bm.tryAllocPixels(SkImageInfo::MakeN32Premul(kWidth, kHeight))) { + ERRORF(r, "Could not allocate pixels (%i x %i)", kWidth, kHeight); + return; + } + + bm.eraseColor(SK_ColorTRANSPARENT); + + SkCanvas canvas(bm); + canvas.drawImage(image, 0, 0, nullptr); + + for (int i = 0; i < kWidth; ++i) + for (int j = 0; j < kHeight; ++j) { + if (*bm.getAddr32(i, j) == SK_ColorTRANSPARENT) { + ERRORF(r, "image should not be transparent! %i, %i is 0", i, j); + return; + } + } +} diff --git a/third_party/libpng/BUILD.gn b/third_party/libpng/BUILD.gn index a01ede6501..2b2d72a0e6 100644 --- a/third_party/libpng/BUILD.gn +++ b/third_party/libpng/BUILD.gn @@ -20,7 +20,7 @@ if (skia_use_system_libpng) { "../externals/libpng", ] - defines = [] + defines = [ "PNG_SET_OPTION_SUPPORTED" ] deps = [ "//third_party/zlib", ] -- cgit v1.2.3