| 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/color_utils.h" |
| 14 #include "ui/gfx/image/image.h" |
| 13 #include "ui/gfx/rect.h" | 15 #include "ui/gfx/rect.h" |
| 14 | 16 |
| 15 using color_utils::FindClosestColor; | 17 using color_utils::FindClosestColor; |
| 16 | 18 |
| 17 namespace { | 19 namespace { |
| 18 | 20 |
| 19 const unsigned char k1x1White[] = { | 21 const unsigned char k1x1White[] = { |
| 20 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, | 22 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, |
| 21 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, | 23 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, |
| 22 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, | 24 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, | 82 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, |
| 81 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, | 83 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, |
| 82 0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x14, 0x49, | 84 0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x14, 0x49, |
| 83 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xcf, | 85 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xcf, |
| 84 0xc0, 0xc0, 0xc4, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, | 86 0xc0, 0xc0, 0xc4, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, |
| 85 0xf0, 0x1f, 0x00, 0x0c, 0x10, 0x02, 0x01, 0x2c, | 87 0xf0, 0x1f, 0x00, 0x0c, 0x10, 0x02, 0x01, 0x2c, |
| 86 0x8f, 0x8b, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x49, | 88 0x8f, 0x8b, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x49, |
| 87 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 | 89 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 |
| 88 }; | 90 }; |
| 89 | 91 |
| 92 const color_utils::HSL kDefaultLowerBound = {-1, -1, 0.15}; |
| 93 const color_utils::HSL kDefaultUpperBound = {-1, -1, 0.85}; |
| 94 |
| 95 // Creates a 1-dimensional png of the pixel colors found in |colors|. |
| 96 scoped_refptr<base::RefCountedMemory> CreateTestPNG( |
| 97 const std::vector<SkColor>& colors) { |
| 98 SkBitmap bitmap; |
| 99 bitmap.setConfig(SkBitmap::kARGB_8888_Config, colors.size(), 1); |
| 100 bitmap.allocPixels(); |
| 101 SkAutoLockPixels lock(bitmap); |
| 102 for (size_t i = 0; i < colors.size(); ++i) { |
| 103 bitmap.eraseArea(SkIRect::MakeXYWH(i, 0, 1, 1), colors[i]); |
| 104 } |
| 105 return gfx::Image::CreateFrom1xBitmap(bitmap).As1xPNGBytes(); |
| 106 } |
| 107 |
| 90 class MockKMeanImageSampler : public color_utils::KMeanImageSampler { | 108 class MockKMeanImageSampler : public color_utils::KMeanImageSampler { |
| 91 public: | 109 public: |
| 92 MockKMeanImageSampler() : current_result_index_(0) { | 110 MockKMeanImageSampler() : current_result_index_(0) { |
| 93 } | 111 } |
| 94 | 112 |
| 95 explicit MockKMeanImageSampler(const std::vector<int>& samples) | 113 explicit MockKMeanImageSampler(const std::vector<int>& samples) |
| 96 : prebaked_sample_results_(samples), | 114 : prebaked_sample_results_(samples), |
| 97 current_result_index_(0) { | 115 current_result_index_(0) { |
| 98 } | 116 } |
| 99 | 117 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 TEST_F(ColorAnalysisTest, CalculatePNGKMeanAllWhite) { | 173 TEST_F(ColorAnalysisTest, CalculatePNGKMeanAllWhite) { |
| 156 MockKMeanImageSampler test_sampler; | 174 MockKMeanImageSampler test_sampler; |
| 157 test_sampler.AddSample(0); | 175 test_sampler.AddSample(0); |
| 158 | 176 |
| 159 scoped_refptr<base::RefCountedBytes> png( | 177 scoped_refptr<base::RefCountedBytes> png( |
| 160 new base::RefCountedBytes( | 178 new base::RefCountedBytes( |
| 161 std::vector<unsigned char>( | 179 std::vector<unsigned char>( |
| 162 k1x1White, | 180 k1x1White, |
| 163 k1x1White + sizeof(k1x1White) / sizeof(unsigned char)))); | 181 k1x1White + sizeof(k1x1White) / sizeof(unsigned char)))); |
| 164 | 182 |
| 165 SkColor color = | 183 SkColor color = color_utils::CalculateKMeanColorOfPNG( |
| 166 color_utils::CalculateKMeanColorOfPNG(png, 100, 600, &test_sampler); | 184 png, kDefaultLowerBound, kDefaultUpperBound, &test_sampler); |
| 167 | 185 |
| 168 EXPECT_EQ(color, SK_ColorWHITE); | 186 EXPECT_EQ(color, SK_ColorWHITE); |
| 169 } | 187 } |
| 170 | 188 |
| 171 TEST_F(ColorAnalysisTest, CalculatePNGKMeanIgnoreWhite) { | 189 TEST_F(ColorAnalysisTest, CalculatePNGKMeanIgnoreWhiteLightness) { |
| 172 MockKMeanImageSampler test_sampler; | 190 MockKMeanImageSampler test_sampler; |
| 173 test_sampler.AddSample(0); | 191 test_sampler.AddSample(0); |
| 174 test_sampler.AddSample(1); | 192 test_sampler.AddSample(1); |
| 175 test_sampler.AddSample(2); | 193 test_sampler.AddSample(2); |
| 176 | 194 |
| 177 scoped_refptr<base::RefCountedBytes> png( | 195 scoped_refptr<base::RefCountedBytes> png( |
| 178 new base::RefCountedBytes( | 196 new base::RefCountedBytes( |
| 179 std::vector<unsigned char>( | 197 std::vector<unsigned char>( |
| 180 k1x3BlueWhite, | 198 k1x3BlueWhite, |
| 181 k1x3BlueWhite + sizeof(k1x3BlueWhite) / sizeof(unsigned char)))); | 199 k1x3BlueWhite + sizeof(k1x3BlueWhite) / sizeof(unsigned char)))); |
| 182 | 200 |
| 183 SkColor color = | 201 SkColor color = color_utils::CalculateKMeanColorOfPNG( |
| 184 color_utils::CalculateKMeanColorOfPNG(png, 100, 600, &test_sampler); | 202 png, kDefaultLowerBound, kDefaultUpperBound, &test_sampler); |
| 185 | 203 |
| 186 EXPECT_EQ(color, SkColorSetARGB(0xFF, 0x00, 0x00, 0xFF)); | 204 EXPECT_EQ(SkColorSetARGB(0xFF, 0x00, 0x00, 0xFF), color); |
| 187 } | 205 } |
| 188 | 206 |
| 189 TEST_F(ColorAnalysisTest, CalculatePNGKMeanPickMostCommon) { | 207 TEST_F(ColorAnalysisTest, CalculatePNGKMeanPickMostCommon) { |
| 190 MockKMeanImageSampler test_sampler; | 208 MockKMeanImageSampler test_sampler; |
| 191 test_sampler.AddSample(0); | 209 test_sampler.AddSample(0); |
| 192 test_sampler.AddSample(1); | 210 test_sampler.AddSample(1); |
| 193 test_sampler.AddSample(2); | 211 test_sampler.AddSample(2); |
| 194 | 212 |
| 195 scoped_refptr<base::RefCountedBytes> png( | 213 scoped_refptr<base::RefCountedBytes> png( |
| 196 new base::RefCountedBytes( | 214 new base::RefCountedBytes( |
| 197 std::vector<unsigned char>( | 215 std::vector<unsigned char>( |
| 198 k1x3BlueRed, | 216 k1x3BlueRed, |
| 199 k1x3BlueRed + sizeof(k1x3BlueRed) / sizeof(unsigned char)))); | 217 k1x3BlueRed + sizeof(k1x3BlueRed) / sizeof(unsigned char)))); |
| 200 | 218 |
| 219 SkColor color = color_utils::CalculateKMeanColorOfPNG( |
| 220 png, kDefaultLowerBound, kDefaultUpperBound, &test_sampler); |
| 221 |
| 222 EXPECT_EQ(SkColorSetARGB(0xFF, 0xFF, 0x00, 0x00), color); |
| 223 } |
| 224 |
| 225 TEST_F(ColorAnalysisTest, CalculatePNGKMeanIgnoreRedHue) { |
| 226 MockKMeanImageSampler test_sampler; |
| 227 test_sampler.AddSample(0); |
| 228 test_sampler.AddSample(1); |
| 229 test_sampler.AddSample(2); |
| 230 |
| 231 std::vector<SkColor> colors(4, SK_ColorRED); |
| 232 colors[1] = SK_ColorBLUE; |
| 233 |
| 234 scoped_refptr<base::RefCountedMemory> png = CreateTestPNG(colors); |
| 235 |
| 201 SkColor color = | 236 SkColor color = |
| 202 color_utils::CalculateKMeanColorOfPNG(png, 100, 600, &test_sampler); | 237 color_utils::CalculateKMeanColorOfPNG(png, |
| 238 color_utils::HSL{0.2, -1, 0.15}, |
| 239 color_utils::HSL{0.8, -1, 0.85}, |
| 240 &test_sampler); |
| 203 | 241 |
| 204 EXPECT_EQ(color, SkColorSetARGB(0xFF, 0xFF, 0x00, 0x00)); | 242 EXPECT_EQ(SK_ColorBLUE, color); |
| 243 } |
| 244 |
| 245 TEST_F(ColorAnalysisTest, CalculatePNGKMeanIgnoreGreySaturation) { |
| 246 MockKMeanImageSampler test_sampler; |
| 247 test_sampler.AddSample(0); |
| 248 test_sampler.AddSample(1); |
| 249 test_sampler.AddSample(2); |
| 250 |
| 251 std::vector<SkColor> colors(4, SK_ColorGRAY); |
| 252 colors[1] = SK_ColorBLUE; |
| 253 |
| 254 scoped_refptr<base::RefCountedMemory> png = CreateTestPNG(colors); |
| 255 SkColor color = |
| 256 color_utils::CalculateKMeanColorOfPNG(png, |
| 257 color_utils::HSL{-1, 0.3, -1}, |
| 258 color_utils::HSL{-1, 1, -1}, |
| 259 &test_sampler); |
| 260 |
| 261 EXPECT_EQ(SK_ColorBLUE, color); |
| 205 } | 262 } |
| 206 | 263 |
| 207 TEST_F(ColorAnalysisTest, GridSampler) { | 264 TEST_F(ColorAnalysisTest, GridSampler) { |
| 208 color_utils::GridSampler sampler; | 265 color_utils::GridSampler sampler; |
| 209 const int kWidth = 16; | 266 const int kWidth = 16; |
| 210 const int kHeight = 16; | 267 const int kHeight = 16; |
| 211 // Sample starts at 1,1. | 268 // Sample starts at 1,1. |
| 212 EXPECT_EQ(1 + 1 * kWidth, sampler.GetSample(kWidth, kHeight)); | 269 EXPECT_EQ(1 + 1 * kWidth, sampler.GetSample(kWidth, kHeight)); |
| 213 EXPECT_EQ(1 + 4 * kWidth, sampler.GetSample(kWidth, kHeight)); | 270 EXPECT_EQ(1 + 4 * kWidth, sampler.GetSample(kWidth, kHeight)); |
| 214 EXPECT_EQ(1 + 7 * kWidth, sampler.GetSample(kWidth, kHeight)); | 271 EXPECT_EQ(1 + 7 * kWidth, sampler.GetSample(kWidth, kHeight)); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 uint8_t min_gl = 0; | 518 uint8_t min_gl = 0; |
| 462 uint8_t max_gl = 0; | 519 uint8_t max_gl = 0; |
| 463 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | 520 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); |
| 464 | 521 |
| 465 EXPECT_EQ(0, min_gl); | 522 EXPECT_EQ(0, min_gl); |
| 466 EXPECT_EQ(255, max_gl); | 523 EXPECT_EQ(255, max_gl); |
| 467 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(0, 0))); | 524 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(0, 0))); |
| 468 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(299, 199))); | 525 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(299, 199))); |
| 469 EXPECT_EQ(93U, SkColorGetA(result.getColor(150, 0))); | 526 EXPECT_EQ(93U, SkColorGetA(result.getColor(150, 0))); |
| 470 } | 527 } |
| OLD | NEW |