diff options
Diffstat (limited to 'skia/ext/image_operations_unittest.cc')
-rw-r--r-- | skia/ext/image_operations_unittest.cc | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/skia/ext/image_operations_unittest.cc b/skia/ext/image_operations_unittest.cc index 27e3fcc..5ed69da 100644 --- a/skia/ext/image_operations_unittest.cc +++ b/skia/ext/image_operations_unittest.cc @@ -5,6 +5,7 @@ #include <stdlib.h> #include "skia/ext/image_operations.h" +#include "skia/include/SkColorPriv.h" #include "testing/gtest/include/gtest/gtest.h" #include "SkBitmap.h" @@ -145,3 +146,256 @@ TEST(ImageOperations, ResampleToSame) { } } } + +// Blend two bitmaps together at 50% alpha and verify that the result +// is the middle-blend of the two. +TEST(ImageOperations, CreateBlendedBitmap) { + int src_w = 16, src_h = 16; + SkBitmap src_a; + src_a.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); + src_a.allocPixels(); + + SkBitmap src_b; + src_b.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); + src_b.allocPixels(); + + for (int y = 0, i = 0; y < src_h; y++) { + for (int x = 0; x < src_w; x++) { + *src_a.getAddr32(x, y) = SkColorSetARGB(255, 0, i * 2 % 255, i % 255); + *src_b.getAddr32(x, y) = + SkColorSetARGB((255 - i) % 255, i % 255, i * 4 % 255, 0); + i++; + } + } + + // Shift to red. + SkBitmap blended = skia::ImageOperations::CreateBlendedBitmap( + src_a, src_b, 0.5); + SkAutoLockPixels srca_lock(src_a); + SkAutoLockPixels srcb_lock(src_b); + SkAutoLockPixels blended_lock(blended); + + for (int y = 0; y < src_h; y++) { + for (int x = 0; x < src_w; x++) { + int i = y * src_w + x; + EXPECT_EQ((255 + ((255 - i) % 255)) / 2, + SkColorGetA(*blended.getAddr32(x, y))); + EXPECT_EQ(i % 255 / 2, + SkColorGetR(*blended.getAddr32(x, y))); + EXPECT_EQ(((i * 2) % 255 + (i * 4) % 255) / 2, + SkColorGetG(*blended.getAddr32(x, y))); + EXPECT_EQ(i % 255 / 2, + SkColorGetB(*blended.getAddr32(x, y))); + } + } +} + +// Test our masking functions. +TEST(ImageOperations, CreateMaskedBitmap) { + int src_w = 16, src_h = 16; + + SkBitmap src; + FillDataToBitmap(src_w, src_h, &src); + + // Generate alpha mask + SkBitmap alpha; + alpha.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); + alpha.allocPixels(); + + unsigned char* src_data = + reinterpret_cast<unsigned char*>(alpha.getAddr32(0, 0)); + for (int i = 0; i < src_w * src_h; i++) { + src_data[i * 4] = SkColorSetARGB(i + 128 % 255, + i + 128 % 255, + i + 64 % 255, + i + 0 % 255); + } + + SkBitmap masked = skia::ImageOperations::CreateMaskedBitmap(src, alpha); + + SkAutoLockPixels src_lock(src); + SkAutoLockPixels masked_lock(masked); + for (int y = 0; y < src_h; y++) { + for (int x = 0; x < src_w; x++) { + // Test that the alpha is equal. + SkColor src_pixel = *src.getAddr32(x, y); + SkColor alpha_pixel = *alpha.getAddr32(x, y); + SkColor masked_pixel = *masked.getAddr32(x, y); + + // Test that the alpha is equal. + int alpha = (alpha_pixel & 0xff000000) >> SK_A32_SHIFT; + EXPECT_EQ(alpha, (masked_pixel & 0xff000000) >> SK_A32_SHIFT); + + // Test that the colors are right - SkBitmaps have premultiplied alpha, + // so we can't just do a direct comparison. + EXPECT_EQ(SkColorGetR(masked_pixel), + SkAlphaMul(SkColorGetR(src_pixel), alpha)); + } + } +} + +// Testing blur without reimplementing the blur algorithm here is tough, +// so we just check to see if the pixels have moved in the direction we +// think they should move in (and also checking the wrapping behavior). +// This will allow us to tweak the blur algorithm to suit speed/visual +// needs without breaking the fundamentals. +TEST(ImageOperations, CreateBlurredBitmap) { + int src_w = 4, src_h = 4; + SkBitmap src; + src.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); + src.allocPixels(); + + for (int y = 0, i = 0; y < src_h; y++) { + for (int x = 0; x < src_w; x++) { + int r = (y == 0) ? 255 : 0; // Make the top row red. + int g = (i % 2 == 0) ? 255 : 0; // Make green alternate in each pixel. + int b = (y == src_h - 1) ? 255 : 0; // Make the bottom row blue. + + *src.getAddr32(x, y) = SkColorSetARGB(255, r, g, b); + i++; + } + } + + // Perform a small blur (enough to shove the values in the direction we + // need - more would just be an unneccessary unit test slowdown). + SkBitmap blurred = skia::ImageOperations::CreateBlurredBitmap(src, 2); + + SkAutoLockPixels src_lock(src); + SkAutoLockPixels blurred_lock(blurred); + for (int y = 0, i = 0; y < src_w; y++) { + for (int x = 0; x < src_h; x++) { + SkColor src_pixel = *src.getAddr32(x, y); + SkColor blurred_pixel = *blurred.getAddr32(x, y); + if (y == 0) { + // We expect our red to have decreased, but our blue to have + // increased (from the wrapping from the bottom line). + EXPECT_TRUE(SkColorGetR(blurred_pixel) < SkColorGetR(src_pixel)); + EXPECT_TRUE(SkColorGetB(blurred_pixel) > SkColorGetB(src_pixel)); + } else if (y == src_h - 1) { + // Now for the opposite. + EXPECT_TRUE(SkColorGetB(blurred_pixel) < SkColorGetB(src_pixel)); + EXPECT_TRUE(SkColorGetR(blurred_pixel) > SkColorGetR(src_pixel)); + } + + // Expect the green channel to have moved towards the center (but + // not past it). + if (i % 2 == 0) { + EXPECT_LT(SkColorGetG(blurred_pixel), SkColorGetG(src_pixel)); + EXPECT_GE(SkColorGetG(blurred_pixel), static_cast<uint32>(128)); + } else { + EXPECT_GT(SkColorGetG(blurred_pixel), SkColorGetG(src_pixel)); + EXPECT_LE(SkColorGetG(blurred_pixel), static_cast<uint32>(128)); + } + + i++; + } + } +} + +// Make sure that when shifting a bitmap without any shift parameters, +// the end result is close enough to the original (rounding errors +// notwithstanding). +TEST(ImageOperations, CreateHSLShiftedBitmapToSame) { + int src_w = 4, src_h = 4; + SkBitmap src; + src.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); + src.allocPixels(); + + for (int y = 0, i = 0; y < src_h; y++) { + for (int x = 0; x < src_w; x++) { + *src.getAddr32(x, y) = SkColorSetARGB(i + 128 % 255, + i + 128 % 255, i + 64 % 255, i + 0 % 255); + i++; + } + } + + float hsl[3] = { -1, -1, -1 }; + + SkBitmap shifted = skia::ImageOperations::CreateHSLShiftedBitmap(src, hsl); + + SkAutoLockPixels src_lock(src); + SkAutoLockPixels shifted_lock(shifted); + + for (int y = 0; y < src_w; y++) { + for (int x = 0; x < src_h; x++) { + SkColor src_pixel = *src.getAddr32(x, y); + SkColor shifted_pixel = *shifted.getAddr32(x, y); + EXPECT_TRUE(ColorsClose(src_pixel, shifted_pixel)); + } + } +} + +// Shift a blue bitmap to red. +TEST(ImageOperations, CreateHSLShiftedBitmapHueOnly) { + int src_w = 16, src_h = 16; + SkBitmap src; + src.setConfig(SkBitmap::kARGB_8888_Config, src_w, src_h); + src.allocPixels(); + + for (int y = 0, i = 0; y < src_h; y++) { + for (int x = 0; x < src_w; x++) { + *src.getAddr32(x, y) = SkColorSetARGB(255, 0, 0, i % 255); + i++; + } + } + + // Shift to red. + float hsl[3] = { 0, -1, -1 }; + + SkBitmap shifted = skia::ImageOperations::CreateHSLShiftedBitmap(src, hsl); + + SkAutoLockPixels src_lock(src); + SkAutoLockPixels shifted_lock(shifted); + + for (int y = 0, i = 0; y < src_h; y++) { + for (int x = 0; x < src_w; x++) { + EXPECT_TRUE(ColorsClose(*shifted.getAddr32(x, y), + SkColorSetARGB(255, i % 255, 0, 0))); + i++; + } + } +} + +// Test our cropping. +TEST(ImageOperations, CreateCroppedBitmap) { + int src_w = 16, src_h = 16; + SkBitmap src; + FillDataToBitmap(src_w, src_h, &src); + + SkBitmap cropped = skia::ImageOperations::CreateTiledBitmap(src, 4, 4, + 8, 8); + ASSERT_EQ(8, cropped.width()); + ASSERT_EQ(8, cropped.height()); + + SkAutoLockPixels src_lock(src); + SkAutoLockPixels cropped_lock(cropped); + for (int y = 4; y < 12; y++) { + for (int x = 4; x < 12; x++) { + EXPECT_EQ(*src.getAddr32(x, y), + *cropped.getAddr32(x - 4, y - 4)); + } + } +} + +// Test whether our cropping correctly wraps across image boundaries. +TEST(ImageOperations, CreateCroppedBitmapWrapping) { + int src_w = 16, src_h = 16; + SkBitmap src; + FillDataToBitmap(src_w, src_h, &src); + + SkBitmap cropped = skia::ImageOperations::CreateTiledBitmap( + src, src_w / 2, src_h / 2, src_w, src_h); + ASSERT_EQ(src_w, cropped.width()); + ASSERT_EQ(src_h, cropped.height()); + + SkAutoLockPixels src_lock(src); + SkAutoLockPixels cropped_lock(cropped); + for (int y = 0; y < src_h; y++) { + for (int x = 0; x < src_w; x++) { + EXPECT_EQ(*src.getAddr32(x, y), + *cropped.getAddr32((x + src_w / 2) % src_w, + (y + src_h / 2) % src_h)); + } + } +} + |