Index: tests/ImageDecodingTest.cpp |
diff --git a/tests/ImageDecodingTest.cpp b/tests/ImageDecodingTest.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d92e7d29eda7f5588d3069d33bdebcad49bf8ecb |
--- /dev/null |
+++ b/tests/ImageDecodingTest.cpp |
@@ -0,0 +1,123 @@ |
+/* |
+ * Copyright 2013 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "SkBitmap.h" |
+#include "SkColorPriv.h" |
+#include "SkForceLinking.h" |
+#include "SkImageDecoder.h" |
+#include "SkOSFile.h" |
+#include "SkStream.h" |
+#include "SkString.h" |
+#include "Test.h" |
+ |
+__SK_FORCE_IMAGE_DECODER_LINKING; |
+ |
+ |
+/** |
+ * Test decoding an image in premultiplied mode and unpremultiplied mode and compare |
+ * them. |
+ */ |
+static void compare_unpremul(skiatest::Reporter* reporter, const SkString& filename) { |
+ // Decode a resource: |
+ SkBitmap bm8888; |
+ SkBitmap bm8888Unpremul; |
+ |
+ SkFILEStream stream(filename.c_str()); |
+ |
+ // JPEG is always opaque, so requesting unpremultiplied does not change anything. |
+ if (SkImageDecoder::GetStreamFormat(&stream) == SkImageDecoder::kJPEG_Format) { |
+ return; |
+ } |
+ |
+ SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream)); |
+ if (NULL == decoder.get()) { |
+ SkDebugf("couldn't decode %s\n", filename.c_str()); |
+ return; |
+ } |
+ |
+ bool success = decoder->decode(&stream, &bm8888, SkBitmap::kARGB_8888_Config, |
+ SkImageDecoder::kDecodePixels_Mode); |
+ if (!success) { |
+ return; |
+ } |
+ |
+ REPORTER_ASSERT(reporter, bm8888.premultiplied()); |
+ |
+ success = stream.rewind(); |
+ REPORTER_ASSERT(reporter, success); |
+ if (!success) { |
+ return; |
+ } |
+ |
+ decoder->setRequestUnpremultipliedColors(true); |
+ success = decoder->decode(&stream, &bm8888Unpremul, SkBitmap::kARGB_8888_Config, |
+ SkImageDecoder::kDecodePixels_Mode); |
+ REPORTER_ASSERT(reporter, success); |
+ |
+ bool dimensionsMatch = bm8888.width() == bm8888Unpremul.width() |
+ && bm8888.height() == bm8888Unpremul.height(); |
+ REPORTER_ASSERT(reporter, dimensionsMatch); |
+ if (!dimensionsMatch) { |
+ return; |
+ } |
+ |
+ // Only do the comparison if the two bitmaps are both 8888 |
+ // and only the first is premultiplied. |
+ if (bm8888.config() != SkBitmap::kARGB_8888_Config |
+ || bm8888Unpremul.config() != SkBitmap::kARGB_8888_Config |
+ || bm8888Unpremul.premultiplied()) { |
+ return; |
+ } |
+ |
+ // Now compare the two bitmaps. |
+ for (int i = 0; i < bm8888.width(); ++i) { |
+ for (int j = 0; j < bm8888.height(); ++j) { |
+ // "c0" is the color of the premultiplied bitmap at (i, j). |
+ const SkPMColor c0 = *bm8888.getAddr32(i, j); |
+ // "c1" is the result of premultiplying the color of the unpremultiplied |
+ // bitmap at (i, j). |
+ const SkPMColor c1 = SkPreMultiplyUnPMColor(*bm8888Unpremul.getAddr32(i, j)); |
+ // Compute the difference for each component. |
+ int da = SkAbs32(SkGetPackedA32(c0) - SkGetPackedA32(c1)); |
+ int dr = SkAbs32(SkGetPackedR32(c0) - SkGetPackedR32(c1)); |
+ int dg = SkAbs32(SkGetPackedG32(c0) - SkGetPackedG32(c1)); |
+ int db = SkAbs32(SkGetPackedB32(c0) - SkGetPackedB32(c1)); |
+ |
+ // Alpha component must be exactly the same. |
+ REPORTER_ASSERT(reporter, 0 == da); |
+ // Other components may differ if rounding is done differently, |
+ // but currently that is not the case. If an image fails here |
+ // in the future, we can change these to account for differences. |
+ REPORTER_ASSERT(reporter, 0 == dr); |
+ REPORTER_ASSERT(reporter, 0 == dg); |
+ REPORTER_ASSERT(reporter, 0 == db); |
+ } |
+ } |
+} |
+ |
+static void test_imageDecodingTests(skiatest::Reporter* reporter) { |
+ // This test cannot run if there is no resource path. |
+ SkString resourcePath = skiatest::Test::GetResourcePath(); |
+ if (resourcePath.isEmpty()) { |
+ return; |
+ } |
+ SkOSFile::Iter iter(resourcePath.c_str()); |
+ SkString basename; |
+ if (iter.next(&basename)) { |
+ do { |
+ SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), basename.c_str()); |
+ //SkDebugf("about to decode \"%s\"\n", filename.c_str()); |
+ compare_unpremul(reporter, filename); |
+ } while (iter.next(&basename)); |
+ } else { |
+ SkDebugf("Failed to find any files :(\n"); |
+ } |
+} |
+ |
+#include "TestClassDef.h" |
+DEFINE_TESTCLASS("ImageDecoding", ImageDecodingTestClass, |
+ test_imageDecodingTests) |