| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gfx/color_analysis.h" | 5 #include "ui/gfx/color_analysis.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 #include "third_party/skia/include/core/SkBitmap.h" | 10 #include "third_party/skia/include/core/SkBitmap.h" |
| 11 #include "third_party/skia/include/core/SkColor.h" | 11 #include "third_party/skia/include/core/SkColor.h" |
| 12 #include "ui/gfx/canvas.h" | 12 #include "ui/gfx/canvas.h" |
| 13 #include "ui/gfx/rect.h" | 13 #include "ui/gfx/rect.h" |
| 14 | 14 |
| 15 using color_utils::FindClosestColor; | 15 namespace color_utils { |
| 16 | |
| 17 namespace { | |
| 18 | 16 |
| 19 const unsigned char k1x1White[] = { | 17 const unsigned char k1x1White[] = { |
| 20 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, | 18 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, |
| 21 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, | 19 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, |
| 22 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, | 20 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, |
| 23 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, | 21 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, |
| 24 0xde, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, | 22 0xde, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, |
| 25 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, | 23 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, |
| 26 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, | 24 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, |
| 27 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, | 25 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, | 78 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, |
| 81 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, | 79 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, |
| 82 0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x14, 0x49, | 80 0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x14, 0x49, |
| 83 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xcf, | 81 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xcf, |
| 84 0xc0, 0xc0, 0xc4, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, | 82 0xc0, 0xc0, 0xc4, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, |
| 85 0xf0, 0x1f, 0x00, 0x0c, 0x10, 0x02, 0x01, 0x2c, | 83 0xf0, 0x1f, 0x00, 0x0c, 0x10, 0x02, 0x01, 0x2c, |
| 86 0x8f, 0x8b, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x49, | 84 0x8f, 0x8b, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x49, |
| 87 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 | 85 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 |
| 88 }; | 86 }; |
| 89 | 87 |
| 90 class MockKMeanImageSampler : public color_utils::KMeanImageSampler { | 88 class MockKMeanImageSampler : public KMeanImageSampler { |
| 91 public: | 89 public: |
| 92 MockKMeanImageSampler() : current_result_index_(0) { | 90 MockKMeanImageSampler() : current_result_index_(0) { |
| 93 } | 91 } |
| 94 | 92 |
| 95 explicit MockKMeanImageSampler(const std::vector<int>& samples) | 93 explicit MockKMeanImageSampler(const std::vector<int>& samples) |
| 96 : prebaked_sample_results_(samples), | 94 : prebaked_sample_results_(samples), |
| 97 current_result_index_(0) { | 95 current_result_index_(0) { |
| 98 } | 96 } |
| 99 | 97 |
| 100 virtual ~MockKMeanImageSampler() { | 98 virtual ~MockKMeanImageSampler() { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 *max_gl = std::numeric_limits<uint8_t>::min(); | 138 *max_gl = std::numeric_limits<uint8_t>::min(); |
| 141 for (int y = 0; y < bitmap.height(); ++y) { | 139 for (int y = 0; y < bitmap.height(); ++y) { |
| 142 uint8_t* current_color = bitmap.getAddr8(0, y); | 140 uint8_t* current_color = bitmap.getAddr8(0, y); |
| 143 for (int x = 0; x < bitmap.width(); ++x, ++current_color) { | 141 for (int x = 0; x < bitmap.width(); ++x, ++current_color) { |
| 144 *min_gl = std::min(*min_gl, *current_color); | 142 *min_gl = std::min(*min_gl, *current_color); |
| 145 *max_gl = std::max(*max_gl, *current_color); | 143 *max_gl = std::max(*max_gl, *current_color); |
| 146 } | 144 } |
| 147 } | 145 } |
| 148 } | 146 } |
| 149 | 147 |
| 150 } // namespace | |
| 151 | |
| 152 class ColorAnalysisTest : public testing::Test { | 148 class ColorAnalysisTest : public testing::Test { |
| 153 }; | 149 }; |
| 154 | 150 |
| 155 TEST_F(ColorAnalysisTest, CalculatePNGKMeanAllWhite) { | 151 TEST_F(ColorAnalysisTest, CalculatePNGKMeanAllWhite) { |
| 156 MockKMeanImageSampler test_sampler; | 152 MockKMeanImageSampler test_sampler; |
| 157 test_sampler.AddSample(0); | 153 test_sampler.AddSample(0); |
| 158 | 154 |
| 159 scoped_refptr<base::RefCountedBytes> png( | 155 scoped_refptr<base::RefCountedBytes> png( |
| 160 new base::RefCountedBytes( | 156 new base::RefCountedBytes( |
| 161 std::vector<unsigned char>( | 157 std::vector<unsigned char>( |
| 162 k1x1White, | 158 k1x1White, |
| 163 k1x1White + sizeof(k1x1White) / sizeof(unsigned char)))); | 159 k1x1White + sizeof(k1x1White) / sizeof(unsigned char)))); |
| 164 | 160 |
| 165 SkColor color = | 161 SkColor color = CalculateKMeanColorOfPNG(png, 100, 600, &test_sampler); |
| 166 color_utils::CalculateKMeanColorOfPNG(png, 100, 600, &test_sampler); | |
| 167 | 162 |
| 168 EXPECT_EQ(color, SK_ColorWHITE); | 163 EXPECT_EQ(color, SK_ColorWHITE); |
| 169 } | 164 } |
| 170 | 165 |
| 171 TEST_F(ColorAnalysisTest, CalculatePNGKMeanIgnoreWhite) { | 166 TEST_F(ColorAnalysisTest, CalculatePNGKMeanIgnoreWhite) { |
| 172 MockKMeanImageSampler test_sampler; | 167 MockKMeanImageSampler test_sampler; |
| 173 test_sampler.AddSample(0); | 168 test_sampler.AddSample(0); |
| 174 test_sampler.AddSample(1); | 169 test_sampler.AddSample(1); |
| 175 test_sampler.AddSample(2); | 170 test_sampler.AddSample(2); |
| 176 | 171 |
| 177 scoped_refptr<base::RefCountedBytes> png( | 172 scoped_refptr<base::RefCountedBytes> png( |
| 178 new base::RefCountedBytes( | 173 new base::RefCountedBytes( |
| 179 std::vector<unsigned char>( | 174 std::vector<unsigned char>( |
| 180 k1x3BlueWhite, | 175 k1x3BlueWhite, |
| 181 k1x3BlueWhite + sizeof(k1x3BlueWhite) / sizeof(unsigned char)))); | 176 k1x3BlueWhite + sizeof(k1x3BlueWhite) / sizeof(unsigned char)))); |
| 182 | 177 |
| 183 SkColor color = | 178 SkColor color = CalculateKMeanColorOfPNG(png, 100, 600, &test_sampler); |
| 184 color_utils::CalculateKMeanColorOfPNG(png, 100, 600, &test_sampler); | |
| 185 | 179 |
| 186 EXPECT_EQ(color, SkColorSetARGB(0xFF, 0x00, 0x00, 0xFF)); | 180 EXPECT_EQ(color, SkColorSetARGB(0xFF, 0x00, 0x00, 0xFF)); |
| 187 } | 181 } |
| 188 | 182 |
| 189 TEST_F(ColorAnalysisTest, CalculatePNGKMeanPickMostCommon) { | 183 TEST_F(ColorAnalysisTest, CalculatePNGKMeanPickMostCommon) { |
| 190 MockKMeanImageSampler test_sampler; | 184 MockKMeanImageSampler test_sampler; |
| 191 test_sampler.AddSample(0); | 185 test_sampler.AddSample(0); |
| 192 test_sampler.AddSample(1); | 186 test_sampler.AddSample(1); |
| 193 test_sampler.AddSample(2); | 187 test_sampler.AddSample(2); |
| 194 | 188 |
| 195 scoped_refptr<base::RefCountedBytes> png( | 189 scoped_refptr<base::RefCountedBytes> png( |
| 196 new base::RefCountedBytes( | 190 new base::RefCountedBytes( |
| 197 std::vector<unsigned char>( | 191 std::vector<unsigned char>( |
| 198 k1x3BlueRed, | 192 k1x3BlueRed, |
| 199 k1x3BlueRed + sizeof(k1x3BlueRed) / sizeof(unsigned char)))); | 193 k1x3BlueRed + sizeof(k1x3BlueRed) / sizeof(unsigned char)))); |
| 200 | 194 |
| 201 SkColor color = | 195 SkColor color = CalculateKMeanColorOfPNG(png, 100, 600, &test_sampler); |
| 202 color_utils::CalculateKMeanColorOfPNG(png, 100, 600, &test_sampler); | |
| 203 | 196 |
| 204 EXPECT_EQ(color, SkColorSetARGB(0xFF, 0xFF, 0x00, 0x00)); | 197 EXPECT_EQ(color, SkColorSetARGB(0xFF, 0xFF, 0x00, 0x00)); |
| 205 } | 198 } |
| 206 | 199 |
| 207 TEST_F(ColorAnalysisTest, GridSampler) { | 200 TEST_F(ColorAnalysisTest, GridSampler) { |
| 208 color_utils::GridSampler sampler; | 201 GridSampler sampler; |
| 209 const int kWidth = 16; | 202 const int kWidth = 16; |
| 210 const int kHeight = 16; | 203 const int kHeight = 16; |
| 211 // Sample starts at 1,1. | 204 // Sample starts at 1,1. |
| 212 EXPECT_EQ(1 + 1 * kWidth, sampler.GetSample(kWidth, kHeight)); | 205 EXPECT_EQ(1 + 1 * kWidth, sampler.GetSample(kWidth, kHeight)); |
| 213 EXPECT_EQ(1 + 4 * kWidth, sampler.GetSample(kWidth, kHeight)); | 206 EXPECT_EQ(1 + 4 * kWidth, sampler.GetSample(kWidth, kHeight)); |
| 214 EXPECT_EQ(1 + 7 * kWidth, sampler.GetSample(kWidth, kHeight)); | 207 EXPECT_EQ(1 + 7 * kWidth, sampler.GetSample(kWidth, kHeight)); |
| 215 EXPECT_EQ(1 + 10 * kWidth, sampler.GetSample(kWidth, kHeight)); | 208 EXPECT_EQ(1 + 10 * kWidth, sampler.GetSample(kWidth, kHeight)); |
| 216 // Step over by 3. | 209 // Step over by 3. |
| 217 EXPECT_EQ(4 + 1 * kWidth, sampler.GetSample(kWidth, kHeight)); | 210 EXPECT_EQ(4 + 1 * kWidth, sampler.GetSample(kWidth, kHeight)); |
| 218 EXPECT_EQ(4 + 4 * kWidth, sampler.GetSample(kWidth, kHeight)); | 211 EXPECT_EQ(4 + 4 * kWidth, sampler.GetSample(kWidth, kHeight)); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 247 EXPECT_EQ(SK_ColorBLACK, color); | 240 EXPECT_EQ(SK_ColorBLACK, color); |
| 248 } | 241 } |
| 249 | 242 |
| 250 TEST_F(ColorAnalysisTest, CalculateKMeanColorOfBitmap) { | 243 TEST_F(ColorAnalysisTest, CalculateKMeanColorOfBitmap) { |
| 251 // Create a 16x16 bitmap to represent a favicon. | 244 // Create a 16x16 bitmap to represent a favicon. |
| 252 SkBitmap bitmap; | 245 SkBitmap bitmap; |
| 253 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 16, 16); | 246 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 16, 16); |
| 254 bitmap.allocPixels(); | 247 bitmap.allocPixels(); |
| 255 bitmap.eraseARGB(255, 100, 150, 200); | 248 bitmap.eraseARGB(255, 100, 150, 200); |
| 256 | 249 |
| 257 SkColor color = color_utils::CalculateKMeanColorOfBitmap(bitmap); | 250 SkColor color = CalculateKMeanColorOfBitmap(bitmap); |
| 258 EXPECT_EQ(255u, SkColorGetA(color)); | 251 EXPECT_EQ(255u, SkColorGetA(color)); |
| 259 // Color values are not exactly equal due to reversal of premultiplied alpha. | 252 // Color values are not exactly equal due to reversal of premultiplied alpha. |
| 260 EXPECT_TRUE(ChannelApproximatelyEqual(100, SkColorGetR(color))); | 253 EXPECT_TRUE(ChannelApproximatelyEqual(100, SkColorGetR(color))); |
| 261 EXPECT_TRUE(ChannelApproximatelyEqual(150, SkColorGetG(color))); | 254 EXPECT_TRUE(ChannelApproximatelyEqual(150, SkColorGetG(color))); |
| 262 EXPECT_TRUE(ChannelApproximatelyEqual(200, SkColorGetB(color))); | 255 EXPECT_TRUE(ChannelApproximatelyEqual(200, SkColorGetB(color))); |
| 263 | 256 |
| 264 // Test a bitmap with an alpha channel. | 257 // Test a bitmap with an alpha channel. |
| 265 bitmap.eraseARGB(128, 100, 150, 200); | 258 bitmap.eraseARGB(128, 100, 150, 200); |
| 266 color = color_utils::CalculateKMeanColorOfBitmap(bitmap); | 259 color = CalculateKMeanColorOfBitmap(bitmap); |
| 267 | 260 |
| 268 // Alpha channel should be ignored for dominant color calculation. | 261 // Alpha channel should be ignored for dominant color calculation. |
| 269 EXPECT_EQ(255u, SkColorGetA(color)); | 262 EXPECT_EQ(255u, SkColorGetA(color)); |
| 270 EXPECT_TRUE(ChannelApproximatelyEqual(100, SkColorGetR(color))); | 263 EXPECT_TRUE(ChannelApproximatelyEqual(100, SkColorGetR(color))); |
| 271 EXPECT_TRUE(ChannelApproximatelyEqual(150, SkColorGetG(color))); | 264 EXPECT_TRUE(ChannelApproximatelyEqual(150, SkColorGetG(color))); |
| 272 EXPECT_TRUE(ChannelApproximatelyEqual(200, SkColorGetB(color))); | 265 EXPECT_TRUE(ChannelApproximatelyEqual(200, SkColorGetB(color))); |
| 273 } | 266 } |
| 274 | 267 |
| 275 TEST_F(ColorAnalysisTest, ComputeColorCovarianceTrivial) { | 268 TEST_F(ColorAnalysisTest, ComputeColorCovarianceTrivial) { |
| 276 SkBitmap bitmap; | 269 SkBitmap bitmap; |
| 277 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 100, 200); | 270 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 100, 200); |
| 278 | 271 |
| 279 EXPECT_EQ(gfx::Matrix3F::Zeros(), | 272 EXPECT_EQ(gfx::Matrix3F::Zeros(), ComputeColorCovariance(bitmap)); |
| 280 color_utils::ComputeColorCovariance(bitmap)); | |
| 281 bitmap.allocPixels(); | 273 bitmap.allocPixels(); |
| 282 bitmap.eraseARGB(255, 50, 150, 200); | 274 bitmap.eraseARGB(255, 50, 150, 200); |
| 283 gfx::Matrix3F covariance = color_utils::ComputeColorCovariance(bitmap); | 275 gfx::Matrix3F covariance = ComputeColorCovariance(bitmap); |
| 284 // The answer should be all zeros. | 276 // The answer should be all zeros. |
| 285 EXPECT_TRUE(covariance == gfx::Matrix3F::Zeros()); | 277 EXPECT_TRUE(covariance == gfx::Matrix3F::Zeros()); |
| 286 } | 278 } |
| 287 | 279 |
| 288 TEST_F(ColorAnalysisTest, ComputeColorCovarianceWithCanvas) { | 280 TEST_F(ColorAnalysisTest, ComputeColorCovarianceWithCanvas) { |
| 289 gfx::Canvas canvas(gfx::Size(250, 200), 1.0f, true); | 281 gfx::Canvas canvas(gfx::Size(250, 200), 1.0f, true); |
| 290 // The image consists of vertical stripes, with color bands set to 100 | 282 // The image consists of vertical stripes, with color bands set to 100 |
| 291 // in overlapping stripes 150 pixels wide. | 283 // in overlapping stripes 150 pixels wide. |
| 292 canvas.FillRect(gfx::Rect(0, 0, 50, 200), SkColorSetRGB(100, 0, 0)); | 284 canvas.FillRect(gfx::Rect(0, 0, 50, 200), SkColorSetRGB(100, 0, 0)); |
| 293 canvas.FillRect(gfx::Rect(50, 0, 50, 200), SkColorSetRGB(100, 100, 0)); | 285 canvas.FillRect(gfx::Rect(50, 0, 50, 200), SkColorSetRGB(100, 100, 0)); |
| 294 canvas.FillRect(gfx::Rect(100, 0, 50, 200), SkColorSetRGB(100, 100, 100)); | 286 canvas.FillRect(gfx::Rect(100, 0, 50, 200), SkColorSetRGB(100, 100, 100)); |
| 295 canvas.FillRect(gfx::Rect(150, 0, 50, 200), SkColorSetRGB(0, 100, 100)); | 287 canvas.FillRect(gfx::Rect(150, 0, 50, 200), SkColorSetRGB(0, 100, 100)); |
| 296 canvas.FillRect(gfx::Rect(200, 0, 50, 200), SkColorSetRGB(0, 0, 100)); | 288 canvas.FillRect(gfx::Rect(200, 0, 50, 200), SkColorSetRGB(0, 0, 100)); |
| 297 | 289 |
| 298 SkBitmap bitmap = | 290 SkBitmap bitmap = |
| 299 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false); | 291 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false); |
| 300 gfx::Matrix3F covariance = color_utils::ComputeColorCovariance(bitmap); | 292 gfx::Matrix3F covariance = ComputeColorCovariance(bitmap); |
| 301 | 293 |
| 302 gfx::Matrix3F expected_covariance = gfx::Matrix3F::Zeros(); | 294 gfx::Matrix3F expected_covariance = gfx::Matrix3F::Zeros(); |
| 303 expected_covariance.set(2400, 400, -1600, | 295 expected_covariance.set(2400, 400, -1600, |
| 304 400, 2400, 400, | 296 400, 2400, 400, |
| 305 -1600, 400, 2400); | 297 -1600, 400, 2400); |
| 306 EXPECT_EQ(expected_covariance, covariance); | 298 EXPECT_EQ(expected_covariance, covariance); |
| 307 } | 299 } |
| 308 | 300 |
| 309 TEST_F(ColorAnalysisTest, ApplyColorReductionSingleColor) { | 301 TEST_F(ColorAnalysisTest, ApplyColorReductionSingleColor) { |
| 310 // The test runs color reduction on a single-colot image, where results are | 302 // The test runs color reduction on a single-colot image, where results are |
| 311 // bound to be uninteresting. This is an important edge case, though. | 303 // bound to be uninteresting. This is an important edge case, though. |
| 312 SkBitmap source, result; | 304 SkBitmap source, result; |
| 313 source.setConfig(SkBitmap::kARGB_8888_Config, 300, 200); | 305 source.setConfig(SkBitmap::kARGB_8888_Config, 300, 200); |
| 314 result.setConfig(SkBitmap::kA8_Config, 300, 200); | 306 result.setConfig(SkBitmap::kA8_Config, 300, 200); |
| 315 | 307 |
| 316 source.allocPixels(); | 308 source.allocPixels(); |
| 317 result.allocPixels(); | 309 result.allocPixels(); |
| 318 source.eraseARGB(255, 50, 150, 200); | 310 source.eraseARGB(255, 50, 150, 200); |
| 319 | 311 |
| 320 gfx::Vector3dF transform(1.0f, .5f, 0.1f); | 312 gfx::Vector3dF transform(1.0f, .5f, 0.1f); |
| 321 // This transform, if not scaled, should result in GL=145. | 313 // This transform, if not scaled, should result in GL=145. |
| 322 EXPECT_TRUE(color_utils::ApplyColorReduction( | 314 EXPECT_TRUE(ApplyColorReduction(source, transform, false, &result)); |
| 323 source, transform, false, &result)); | |
| 324 | 315 |
| 325 uint8_t min_gl = 0; | 316 uint8_t min_gl = 0; |
| 326 uint8_t max_gl = 0; | 317 uint8_t max_gl = 0; |
| 327 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | 318 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); |
| 328 EXPECT_EQ(145, min_gl); | 319 EXPECT_EQ(145, min_gl); |
| 329 EXPECT_EQ(145, max_gl); | 320 EXPECT_EQ(145, max_gl); |
| 330 | 321 |
| 331 // Now scan requesting rescale. Expect all 0. | 322 // Now scan requesting rescale. Expect all 0. |
| 332 EXPECT_TRUE(color_utils::ApplyColorReduction( | 323 EXPECT_TRUE(ApplyColorReduction(source, transform, true, &result)); |
| 333 source, transform, true, &result)); | |
| 334 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | 324 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); |
| 335 EXPECT_EQ(0, min_gl); | 325 EXPECT_EQ(0, min_gl); |
| 336 EXPECT_EQ(0, max_gl); | 326 EXPECT_EQ(0, max_gl); |
| 337 | 327 |
| 338 // Test cliping to upper limit. | 328 // Test cliping to upper limit. |
| 339 transform.set_z(1.1f); | 329 transform.set_z(1.1f); |
| 340 EXPECT_TRUE(color_utils::ApplyColorReduction( | 330 EXPECT_TRUE(ApplyColorReduction(source, transform, false, &result)); |
| 341 source, transform, false, &result)); | |
| 342 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | 331 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); |
| 343 EXPECT_EQ(0xFF, min_gl); | 332 EXPECT_EQ(0xFF, min_gl); |
| 344 EXPECT_EQ(0xFF, max_gl); | 333 EXPECT_EQ(0xFF, max_gl); |
| 345 | 334 |
| 346 // Test cliping to upper limit. | 335 // Test cliping to upper limit. |
| 347 transform.Scale(-1.0f); | 336 transform.Scale(-1.0f); |
| 348 EXPECT_TRUE(color_utils::ApplyColorReduction( | 337 EXPECT_TRUE(ApplyColorReduction(source, transform, false, &result)); |
| 349 source, transform, false, &result)); | |
| 350 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | 338 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); |
| 351 EXPECT_EQ(0x0, min_gl); | 339 EXPECT_EQ(0x0, min_gl); |
| 352 EXPECT_EQ(0x0, max_gl); | 340 EXPECT_EQ(0x0, max_gl); |
| 353 } | 341 } |
| 354 | 342 |
| 355 TEST_F(ColorAnalysisTest, ApplyColorReductionBlackAndWhite) { | 343 TEST_F(ColorAnalysisTest, ApplyColorReductionBlackAndWhite) { |
| 356 // Check with images with multiple colors. This is really different only when | 344 // Check with images with multiple colors. This is really different only when |
| 357 // the result is scaled. | 345 // the result is scaled. |
| 358 gfx::Canvas canvas(gfx::Size(300, 200), 1.0f, true); | 346 gfx::Canvas canvas(gfx::Size(300, 200), 1.0f, true); |
| 359 | 347 |
| 360 // The image consists of vertical non-overlapping stripes 150 pixels wide. | 348 // The image consists of vertical non-overlapping stripes 150 pixels wide. |
| 361 canvas.FillRect(gfx::Rect(0, 0, 150, 200), SkColorSetRGB(0, 0, 0)); | 349 canvas.FillRect(gfx::Rect(0, 0, 150, 200), SkColorSetRGB(0, 0, 0)); |
| 362 canvas.FillRect(gfx::Rect(150, 0, 150, 200), SkColorSetRGB(255, 255, 255)); | 350 canvas.FillRect(gfx::Rect(150, 0, 150, 200), SkColorSetRGB(255, 255, 255)); |
| 363 SkBitmap source = | 351 SkBitmap source = |
| 364 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false); | 352 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false); |
| 365 SkBitmap result; | 353 SkBitmap result; |
| 366 result.setConfig(SkBitmap::kA8_Config, 300, 200); | 354 result.setConfig(SkBitmap::kA8_Config, 300, 200); |
| 367 result.allocPixels(); | 355 result.allocPixels(); |
| 368 | 356 |
| 369 gfx::Vector3dF transform(1.0f, 0.5f, 0.1f); | 357 gfx::Vector3dF transform(1.0f, 0.5f, 0.1f); |
| 370 EXPECT_TRUE(color_utils::ApplyColorReduction( | 358 EXPECT_TRUE(ApplyColorReduction(source, transform, true, &result)); |
| 371 source, transform, true, &result)); | |
| 372 uint8_t min_gl = 0; | 359 uint8_t min_gl = 0; |
| 373 uint8_t max_gl = 0; | 360 uint8_t max_gl = 0; |
| 374 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | 361 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); |
| 375 | 362 |
| 376 EXPECT_EQ(0, min_gl); | 363 EXPECT_EQ(0, min_gl); |
| 377 EXPECT_EQ(255, max_gl); | 364 EXPECT_EQ(255, max_gl); |
| 378 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(0, 0))); | 365 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(0, 0))); |
| 379 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(299, 199))); | 366 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(299, 199))); |
| 380 | 367 |
| 381 // Reverse test. | 368 // Reverse test. |
| 382 transform.Scale(-1.0f); | 369 transform.Scale(-1.0f); |
| 383 EXPECT_TRUE(color_utils::ApplyColorReduction( | 370 EXPECT_TRUE(ApplyColorReduction(source, transform, true, &result)); |
| 384 source, transform, true, &result)); | |
| 385 min_gl = 0; | 371 min_gl = 0; |
| 386 max_gl = 0; | 372 max_gl = 0; |
| 387 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | 373 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); |
| 388 | 374 |
| 389 EXPECT_EQ(0, min_gl); | 375 EXPECT_EQ(0, min_gl); |
| 390 EXPECT_EQ(255, max_gl); | 376 EXPECT_EQ(255, max_gl); |
| 391 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(0, 0))); | 377 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(0, 0))); |
| 392 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(299, 199))); | 378 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(299, 199))); |
| 393 } | 379 } |
| 394 | 380 |
| 395 TEST_F(ColorAnalysisTest, ApplyColorReductionMultiColor) { | 381 TEST_F(ColorAnalysisTest, ApplyColorReductionMultiColor) { |
| 396 // Check with images with multiple colors. This is really different only when | 382 // Check with images with multiple colors. This is really different only when |
| 397 // the result is scaled. | 383 // the result is scaled. |
| 398 gfx::Canvas canvas(gfx::Size(300, 200), 1.0f, true); | 384 gfx::Canvas canvas(gfx::Size(300, 200), 1.0f, true); |
| 399 | 385 |
| 400 // The image consists of vertical non-overlapping stripes 100 pixels wide. | 386 // The image consists of vertical non-overlapping stripes 100 pixels wide. |
| 401 canvas.FillRect(gfx::Rect(0, 0, 100, 200), SkColorSetRGB(100, 0, 0)); | 387 canvas.FillRect(gfx::Rect(0, 0, 100, 200), SkColorSetRGB(100, 0, 0)); |
| 402 canvas.FillRect(gfx::Rect(100, 0, 100, 200), SkColorSetRGB(0, 255, 0)); | 388 canvas.FillRect(gfx::Rect(100, 0, 100, 200), SkColorSetRGB(0, 255, 0)); |
| 403 canvas.FillRect(gfx::Rect(200, 0, 100, 200), SkColorSetRGB(0, 0, 128)); | 389 canvas.FillRect(gfx::Rect(200, 0, 100, 200), SkColorSetRGB(0, 0, 128)); |
| 404 SkBitmap source = | 390 SkBitmap source = |
| 405 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false); | 391 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false); |
| 406 SkBitmap result; | 392 SkBitmap result; |
| 407 result.setConfig(SkBitmap::kA8_Config, 300, 200); | 393 result.setConfig(SkBitmap::kA8_Config, 300, 200); |
| 408 result.allocPixels(); | 394 result.allocPixels(); |
| 409 | 395 |
| 410 gfx::Vector3dF transform(1.0f, 0.5f, 0.1f); | 396 gfx::Vector3dF transform(1.0f, 0.5f, 0.1f); |
| 411 EXPECT_TRUE(color_utils::ApplyColorReduction( | 397 EXPECT_TRUE(ApplyColorReduction(source, transform, false, &result)); |
| 412 source, transform, false, &result)); | |
| 413 uint8_t min_gl = 0; | 398 uint8_t min_gl = 0; |
| 414 uint8_t max_gl = 0; | 399 uint8_t max_gl = 0; |
| 415 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | 400 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); |
| 416 EXPECT_EQ(12, min_gl); | 401 EXPECT_EQ(12, min_gl); |
| 417 EXPECT_EQ(127, max_gl); | 402 EXPECT_EQ(127, max_gl); |
| 418 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(299, 199))); | 403 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(299, 199))); |
| 419 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(150, 0))); | 404 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(150, 0))); |
| 420 EXPECT_EQ(100U, SkColorGetA(result.getColor(0, 0))); | 405 EXPECT_EQ(100U, SkColorGetA(result.getColor(0, 0))); |
| 421 | 406 |
| 422 EXPECT_TRUE(color_utils::ApplyColorReduction( | 407 EXPECT_TRUE(ApplyColorReduction(source, transform, true, &result)); |
| 423 source, transform, true, &result)); | |
| 424 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | 408 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); |
| 425 EXPECT_EQ(0, min_gl); | 409 EXPECT_EQ(0, min_gl); |
| 426 EXPECT_EQ(255, max_gl); | 410 EXPECT_EQ(255, max_gl); |
| 427 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(299, 199))); | 411 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(299, 199))); |
| 428 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(150, 0))); | 412 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(150, 0))); |
| 429 EXPECT_EQ(193U, SkColorGetA(result.getColor(0, 0))); | 413 EXPECT_EQ(193U, SkColorGetA(result.getColor(0, 0))); |
| 430 } | 414 } |
| 431 | 415 |
| 432 TEST_F(ColorAnalysisTest, ComputePrincipalComponentImageNotComputable) { | 416 TEST_F(ColorAnalysisTest, ComputePrincipalComponentImageNotComputable) { |
| 433 SkBitmap source, result; | 417 SkBitmap source, result; |
| 434 source.setConfig(SkBitmap::kARGB_8888_Config, 300, 200); | 418 source.setConfig(SkBitmap::kARGB_8888_Config, 300, 200); |
| 435 result.setConfig(SkBitmap::kA8_Config, 300, 200); | 419 result.setConfig(SkBitmap::kA8_Config, 300, 200); |
| 436 | 420 |
| 437 source.allocPixels(); | 421 source.allocPixels(); |
| 438 result.allocPixels(); | 422 result.allocPixels(); |
| 439 source.eraseARGB(255, 50, 150, 200); | 423 source.eraseARGB(255, 50, 150, 200); |
| 440 | 424 |
| 441 // This computation should fail since all colors always vary together. | 425 // This computation should fail since all colors always vary together. |
| 442 EXPECT_FALSE(color_utils::ComputePrincipalComponentImage(source, &result)); | 426 EXPECT_FALSE(ComputePrincipalComponentImage(source, &result)); |
| 443 } | 427 } |
| 444 | 428 |
| 445 TEST_F(ColorAnalysisTest, ComputePrincipalComponentImage) { | 429 TEST_F(ColorAnalysisTest, ComputePrincipalComponentImage) { |
| 446 gfx::Canvas canvas(gfx::Size(300, 200), 1.0f, true); | 430 gfx::Canvas canvas(gfx::Size(300, 200), 1.0f, true); |
| 447 | 431 |
| 448 // The image consists of vertical non-overlapping stripes 100 pixels wide. | 432 // The image consists of vertical non-overlapping stripes 100 pixels wide. |
| 449 canvas.FillRect(gfx::Rect(0, 0, 100, 200), SkColorSetRGB(10, 10, 10)); | 433 canvas.FillRect(gfx::Rect(0, 0, 100, 200), SkColorSetRGB(10, 10, 10)); |
| 450 canvas.FillRect(gfx::Rect(100, 0, 100, 200), SkColorSetRGB(100, 100, 100)); | 434 canvas.FillRect(gfx::Rect(100, 0, 100, 200), SkColorSetRGB(100, 100, 100)); |
| 451 canvas.FillRect(gfx::Rect(200, 0, 100, 200), SkColorSetRGB(255, 255, 255)); | 435 canvas.FillRect(gfx::Rect(200, 0, 100, 200), SkColorSetRGB(255, 255, 255)); |
| 452 SkBitmap source = | 436 SkBitmap source = |
| 453 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false); | 437 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false); |
| 454 SkBitmap result; | 438 SkBitmap result; |
| 455 result.setConfig(SkBitmap::kA8_Config, 300, 200); | 439 result.setConfig(SkBitmap::kA8_Config, 300, 200); |
| 456 result.allocPixels(); | 440 result.allocPixels(); |
| 457 | 441 |
| 458 // This computation should fail since all colors always vary together. | 442 // This computation should fail since all colors always vary together. |
| 459 EXPECT_TRUE(color_utils::ComputePrincipalComponentImage(source, &result)); | 443 EXPECT_TRUE(ComputePrincipalComponentImage(source, &result)); |
| 460 | 444 |
| 461 uint8_t min_gl = 0; | 445 uint8_t min_gl = 0; |
| 462 uint8_t max_gl = 0; | 446 uint8_t max_gl = 0; |
| 463 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | 447 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); |
| 464 | 448 |
| 465 EXPECT_EQ(0, min_gl); | 449 EXPECT_EQ(0, min_gl); |
| 466 EXPECT_EQ(255, max_gl); | 450 EXPECT_EQ(255, max_gl); |
| 467 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(0, 0))); | 451 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(0, 0))); |
| 468 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(299, 199))); | 452 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(299, 199))); |
| 469 EXPECT_EQ(93U, SkColorGetA(result.getColor(150, 0))); | 453 EXPECT_EQ(93U, SkColorGetA(result.getColor(150, 0))); |
| 470 } | 454 } |
| 455 |
| 456 } // namespace color_utils |
| OLD | NEW |