aboutsummaryrefslogtreecommitdiffhomepage
path: root/dm
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-01-06 20:24:21 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-01-06 20:24:21 +0000
commit69a0d7a3356823f979d890ced848b708e08ad927 (patch)
tree8edd9b804a160da12b845fee929300af9acec14b /dm
parent8f88117940ebb0a7f514194a4ad3384073c1f145 (diff)
DM: fix failures when using -r by comparing unpremultiplied.
PNGs store unpremultiplied colors, so we have to convert back and forth with SkBitmap. This is lossy. GM solves this problem by stripping the alpha channel before writing the PNG. This flips it around, converting the GM's output to unpremultiplied as needed. This way each pixel goes from premul to unpremul once, never back. Tested: out/Release/dm -w /tmp/w --config 565 8888 gpu out/Release/dm -r /tmp/w --config 565 8888 gpu BUG= R=bsalomon@google.com Author: mtklein@google.com Review URL: https://codereview.chromium.org/122923003 git-svn-id: http://skia.googlecode.com/svn/trunk@12926 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'dm')
-rw-r--r--dm/DMWriteTask.cpp62
1 files changed, 52 insertions, 10 deletions
diff --git a/dm/DMWriteTask.cpp b/dm/DMWriteTask.cpp
index 11b9fd3470..326d454150 100644
--- a/dm/DMWriteTask.cpp
+++ b/dm/DMWriteTask.cpp
@@ -5,6 +5,7 @@
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkString.h"
+#include "SkUnPreMultiply.h"
DEFINE_string2(writePath, w, "", "If set, write GMs here as .pngs.");
@@ -89,22 +90,63 @@ static SkString path_to_expected_image(const char* root, const Task& task) {
}
bool WriteTask::Expectations::check(const Task& task, SkBitmap bitmap) const {
+ // PNG is stored unpremultiplied, and going from premul to unpremul to premul is lossy. To
+ // skirt this problem, we decode the PNG into an unpremul bitmap, convert our bitmap to unpremul
+ // if needed, and compare those. Each image goes once from premul to unpremul, never back.
const SkString path = path_to_expected_image(fRoot, task);
+ SkAutoTUnref<SkStreamRewindable> stream(SkStream::NewFromFile(path.c_str()));
+ if (NULL == stream.get()) {
+ SkDebugf("Could not read %s.\n", path.c_str());
+ return false;
+ }
+
+ SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream));
+ if (NULL == decoder.get()) {
+ SkDebugf("Could not find a decoder for %s.\n", path.c_str());
+ return false;
+ }
+
+ SkImageInfo info;
+ SkAssertResult(bitmap.asImageInfo(&info));
+
SkBitmap expected;
- if (SkImageDecoder::DecodeFile(path.c_str(), &expected)) {
- if (expected.config() != bitmap.config()) {
- SkBitmap converted;
- SkAssertResult(expected.copyTo(&converted, bitmap.config()));
- expected.swap(converted);
+ expected.setConfig(info);
+ expected.allocPixels();
+
+ // expected will be unpremultiplied.
+ decoder->setRequireUnpremultipliedColors(true);
+ if (!decoder->decode(stream, &expected, SkImageDecoder::kDecodePixels_Mode)) {
+ SkDebugf("Could not decode %s.\n", path.c_str());
+ return false;
+ }
+
+ // We always seem to decode to 8888. This puts 565 back in 565.
+ if (expected.config() != bitmap.config()) {
+ SkBitmap converted;
+ SkAssertResult(expected.copyTo(&converted, bitmap.config()));
+ expected.swap(converted);
+ }
+ SkASSERT(expected.config() == bitmap.config());
+
+ // Manually unpremultiply 8888 bitmaps to match expected.
+ // Their pixels are shared, concurrently even, so we must copy them.
+ if (info.fColorType == kPMColor_SkColorType) {
+ SkBitmap unpremul;
+ unpremul.setConfig(info);
+ unpremul.allocPixels();
+
+ SkAutoLockPixels lockSrc(bitmap), lockDst(unpremul);
+ const SkPMColor* src = (SkPMColor*)bitmap.getPixels();
+ SkColor* dst = (SkColor*)unpremul.getPixels();
+
+ for (size_t i = 0; i < bitmap.getSize()/4; i++) {
+ dst[i] = SkUnPreMultiply::PMColorToColor(src[i]);
}
- SkASSERT(expected.config() == bitmap.config());
- return BitmapsEqual(expected, bitmap);
+ bitmap.swap(unpremul);
}
- // Couldn't read the file, etc.
- SkDebugf("Problem decoding %s to SkBitmap.\n", path.c_str());
- return false;
+ return BitmapsEqual(expected, bitmap);
}
} // namespace DM