| Index: skia/ext/image_operations_unittest.cc
|
| ===================================================================
|
| --- skia/ext/image_operations_unittest.cc (revision 13970)
|
| +++ skia/ext/image_operations_unittest.cc (working copy)
|
| @@ -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 @@
|
| }
|
| }
|
| }
|
| +
|
| +// 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));
|
| + }
|
| + }
|
| +}
|
| +
|
|
|