Add ColorCodecSrc for testing/comparison on color corrected decodes
authormsarett <msarett@google.com>
Fri, 29 Apr 2016 16:38:40 +0000 (09:38 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 29 Apr 2016 16:38:40 +0000 (09:38 -0700)
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1933753002

Review-Url: https://codereview.chromium.org/1933753002

bench/nanobench.cpp
dm/DM.cpp
dm/DMSrcSink.cpp
dm/DMSrcSink.h
tools/flags/SkCommonFlags.cpp
tools/flags/SkCommonFlags.h

index 5e26b483951db10fc45ef47623907faeb34b1ccc..7999ad5c61915bbeaa42b5983ff406dd923de51f 100644 (file)
@@ -606,7 +606,7 @@ public:
         fUseMPDs.push_back() = false;
 
         // Prepare the images for decoding
-        if (!CollectImages(&fImages)) {
+        if (!CollectImages(FLAGS_images, &fImages)) {
             exit(1);
         }
 
index fe1432bf32f16332750f2d32c358f19d10ab740b..9dbd43adda05367aa7ec1fccbda964de73593d59 100644 (file)
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -779,7 +779,7 @@ static bool gather_srcs() {
     }
 
     SkTArray<SkString> images;
-    if (!CollectImages(&images)) {
+    if (!CollectImages(FLAGS_images, &images)) {
         return false;
     }
 
@@ -795,6 +795,16 @@ static bool gather_srcs() {
         }
     }
 
+    SkTArray<SkString> colorImages;
+    if (!CollectImages(FLAGS_colorImages, &colorImages)) {
+        return false;
+    }
+
+    for (auto colorImage : colorImages) {
+        ColorCodecSrc* src = new ColorCodecSrc(colorImage, ColorCodecSrc::kBaseline_Mode);
+        push_src("image", "color_codec_baseline", src);
+    }
+
     return true;
 }
 
index e8018297b7da6732330265fd91fbd78c21ee46db..f99afe48597247dd015f8c69d3aa1192a5ea39a4 100644 (file)
@@ -932,6 +932,71 @@ Name ImageGenSrc::name() const {
 
 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
+ColorCodecSrc::ColorCodecSrc(Path path, Mode mode)
+    : fPath(path)
+    , fMode(mode)
+{}
+
+bool ColorCodecSrc::veto(SinkFlags flags) const {
+    // Test to direct raster backends (8888 and 565).
+    return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDirect;
+}
+
+Error ColorCodecSrc::draw(SkCanvas* canvas) const {
+    if (kRGB_565_SkColorType == canvas->imageInfo().colorType()) {
+        return Error::Nonfatal("No need to test color correction to 565 backend.");
+    }
+
+    SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str()));
+    if (!encoded) {
+        return SkStringPrintf("Couldn't read %s.", fPath.c_str());
+    }
+
+    SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded));
+    if (nullptr == codec.get()) {
+        return SkStringPrintf("Couldn't create codec for %s.", fPath.c_str());
+    }
+
+    SkImageInfo decodeInfo = codec->getInfo().makeColorType(kN32_SkColorType);
+    SkBitmap bitmap;
+    if (!bitmap.tryAllocPixels(decodeInfo)) {
+        return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(),
+                              decodeInfo.width(), decodeInfo.height());
+    }
+
+    switch (fMode) {
+        case kBaseline_Mode:
+            switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowBytes())) {
+                case SkCodec::kSuccess:
+                    break;
+                default:
+                    // Everything else is considered a failure.
+                    return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str());
+            }
+            canvas->drawBitmap(bitmap, 0, 0);
+            break;
+        default:
+            SkASSERT(false);
+            return "Invalid fMode";
+    }
+    return "";
+}
+
+SkISize ColorCodecSrc::size() const {
+    SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str()));
+    SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded));
+    if (nullptr == codec) {
+        return SkISize::Make(0, 0);
+    }
+    return SkISize::Make(codec->getInfo().width(), codec->getInfo().height());
+}
+
+Name ColorCodecSrc::name() const {
+    return SkOSPath::Basename(fPath.c_str());
+}
+
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
 static const SkRect kSKPViewport = {0,0, 1000,1000};
 
 SKPSrc::SKPSrc(Path path) : fPath(path) {}
index 5f60dc59fdca507301d118e91934a30cf2265a7f..5a734a6f3c854102725101543c4219b0f948b71e 100644 (file)
@@ -208,6 +208,24 @@ private:
     bool        fRunSerially;
 };
 
+class ColorCodecSrc : public Src {
+public:
+    enum Mode {
+        // Mimic legacy behavior and apply no color correction.
+        kBaseline_Mode,
+    };
+
+    ColorCodecSrc(Path, Mode);
+
+    Error draw(SkCanvas*) const override;
+    SkISize size() const override;
+    Name name() const override;
+    bool veto(SinkFlags) const override;
+private:
+    Path                    fPath;
+    Mode                    fMode;
+};
+
 class SKPSrc : public Src {
 public:
     explicit SKPSrc(Path path);
index eb2075c58a4da7b3db3edc30c256f24e7fa08818..1caffd54d6a5b58bca2cd481a6a618c0d57c6bf2 100644 (file)
@@ -18,6 +18,9 @@ DEFINE_bool(gpu, true, "master switch for running GPU-bound work.");
 DEFINE_string(images, "", "List of images and/or directories to decode. A directory with no images"
                           " is treated as a fatal error.");
 
+DEFINE_string(colorImages, "", "List of images and/or directories to decode with color correction. "
+                               "A directory with no images is treated as a fatal error.");
+
 DEFINE_string2(match, m, nullptr,
                "[~][^]substring[$] [...] of GM name to run.\n"
                "Multiple matches may be separated by spaces.\n"
@@ -55,7 +58,7 @@ DEFINE_string(properties, "",
               "Space-separated key/value pairs to add to JSON identifying this run.");
 DEFINE_bool2(pre_log, p, false, "Log before running each test. May be incomprehensible when threading");
 
-bool CollectImages(SkTArray<SkString>* output) {
+bool CollectImages(SkCommandLineFlags::StringArray images, SkTArray<SkString>* output) {
     SkASSERT(output);
 
     static const char* const exts[] = {
@@ -67,8 +70,8 @@ bool CollectImages(SkTArray<SkString>* output) {
 #endif
     };
 
-    for (int i = 0; i < FLAGS_images.count(); ++i) {
-        const char* flag = FLAGS_images[i];
+    for (int i = 0; i < images.count(); ++i) {
+        const char* flag = images[i];
         if (!sk_exists(flag)) {
             SkDebugf("%s does not exist!\n", flag);
             return false;
index c6cbde45ca6270b3b9eed81fc47960c6da4b10dd..ddd0fc89e0c4d8f53c6976ef5e5ec79665c9cfb7 100644 (file)
@@ -16,6 +16,7 @@ DECLARE_bool(cpu);
 DECLARE_bool(dryRun);
 DECLARE_bool(gpu);
 DECLARE_string(images);
+DECLARE_string(colorImages);
 DECLARE_string(match);
 DECLARE_bool(quiet);
 DECLARE_bool(resetGpuContext);
@@ -34,17 +35,16 @@ DECLARE_string(key);
 DECLARE_string(properties);
 
 /**
- *  Helper to assist in collecting image paths from --images.
+ *  Helper to assist in collecting image paths from |dir| specified through a command line flag.
  *
- *  Populates an array of strings with paths to images to test.
+ *  Populates |output|, an array of strings with paths to images to test.
  *
- *  Returns true if each argument to --images is meaningful:
+ *  Returns true if each argument to the images flag is meaningful:
  *  - If the file/directory does not exist, return false.
- *  - If a directory passed to --images does not have any supported images (based on file
- *  type), return false.
- *  - If a file is passed to --images, assume the user is deliberately testing this image,
- *  regardless of file type.
+ *  - If |dir| does not have any supported images (based on file type), return false.
+ *  - If |dir| is a single file, assume the user is deliberately testing this image,
+ *    regardless of file type.
  */
-bool CollectImages(SkTArray<SkString>*);
+bool CollectImages(SkCommandLineFlags::StringArray dir, SkTArray<SkString>* output);
 
 #endif