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
This commit is contained in:
parent
8f88117940
commit
69a0d7a335
@ -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)) {
|
||||
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());
|
||||
return BitmapsEqual(expected, bitmap);
|
||||
|
||||
// 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]);
|
||||
}
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user