OLD | NEW |
---|---|
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <stdlib.h> | 5 #include <stdlib.h> |
6 | 6 |
7 #include <algorithm> | |
8 #include <limits> | |
9 | |
10 #include "base/logging.h" | |
7 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
8 #include "third_party/skia/include/core/SkBitmap.h" | 12 #include "third_party/skia/include/core/SkBitmap.h" |
9 #include "third_party/skia/include/core/SkColorPriv.h" | 13 #include "third_party/skia/include/core/SkColorPriv.h" |
14 #include "ui/gfx/canvas.h" | |
10 #include "ui/gfx/color_utils.h" | 15 #include "ui/gfx/color_utils.h" |
11 | 16 |
17 namespace { | |
18 | |
19 void Calculate8bitBitmapMinMax( | |
Alexei Svitkine (slow)
2013/02/21 16:49:59
ADD comment explaining what this does.
motek.
2013/02/21 18:38:43
Done.
| |
20 const SkBitmap& bitmap, uint8_t* min_gl, uint8_t* max_gl) { | |
Alexei Svitkine (slow)
2013/02/21 16:49:59
Each param on a separate line.
motek.
2013/02/21 18:38:43
Done.
| |
21 SkAutoLockPixels bitmap_lock(bitmap); | |
22 DCHECK(bitmap.getPixels()); | |
23 DCHECK(bitmap.config() == SkBitmap::kA8_Config); | |
24 DCHECK(min_gl); | |
25 DCHECK(max_gl); | |
26 *min_gl = std::numeric_limits<uint8_t>::max(); | |
27 *max_gl = std::numeric_limits<uint8_t>::min(); | |
28 for (int y = 0; y < bitmap.height(); ++y) { | |
29 uint8_t* current_color = bitmap.getAddr8(0, y); | |
30 for (int x = 0; x < bitmap.width(); ++x, ++current_color) { | |
31 *min_gl = std::min(*min_gl, *current_color); | |
32 *max_gl = std::max(*max_gl, *current_color); | |
33 } | |
34 } | |
35 } | |
36 | |
37 } | |
Alexei Svitkine (slow)
2013/02/21 16:49:59
// namespace
motek.
2013/02/21 18:38:43
Done.
| |
38 | |
12 TEST(ColorUtils, SkColorToHSLRed) { | 39 TEST(ColorUtils, SkColorToHSLRed) { |
13 color_utils::HSL hsl = { 0, 0, 0 }; | 40 color_utils::HSL hsl = { 0, 0, 0 }; |
14 color_utils::SkColorToHSL(SK_ColorRED, &hsl); | 41 color_utils::SkColorToHSL(SK_ColorRED, &hsl); |
15 EXPECT_DOUBLE_EQ(hsl.h, 0); | 42 EXPECT_DOUBLE_EQ(hsl.h, 0); |
16 EXPECT_DOUBLE_EQ(hsl.s, 1); | 43 EXPECT_DOUBLE_EQ(hsl.s, 1); |
17 EXPECT_DOUBLE_EQ(hsl.l, 0.5); | 44 EXPECT_DOUBLE_EQ(hsl.l, 0.5); |
18 } | 45 } |
19 | 46 |
20 TEST(ColorUtils, SkColorToHSLGrey) { | 47 TEST(ColorUtils, SkColorToHSLGrey) { |
21 color_utils::HSL hsl = { 0, 0, 0 }; | 48 color_utils::HSL hsl = { 0, 0, 0 }; |
22 color_utils::SkColorToHSL(SkColorSetARGB(255, 128, 128, 128), &hsl); | 49 color_utils::SkColorToHSL(SkColorSetARGB(255, 128, 128, 128), &hsl); |
23 EXPECT_DOUBLE_EQ(hsl.h, 0); | 50 EXPECT_DOUBLE_EQ(hsl.h, 0); |
24 EXPECT_DOUBLE_EQ(hsl.s, 0); | 51 EXPECT_DOUBLE_EQ(hsl.s, 0); |
25 EXPECT_EQ(static_cast<int>(hsl.l * 100), | 52 EXPECT_EQ(static_cast<int>(hsl.l * 100), |
26 static_cast<int>(0.5 * 100)); // Accurate to two decimal places. | 53 static_cast<int>(0.5 * 100)); // Accurate to two decimal places. |
27 } | 54 } |
28 | 55 |
29 TEST(ColorUtils, HSLToSkColorWithAlpha) { | 56 TEST(ColorUtils, HSLToSkColorWithAlpha) { |
30 SkColor red = SkColorSetARGB(128, 255, 0, 0); | 57 SkColor red = SkColorSetARGB(128, 255, 0, 0); |
31 color_utils::HSL hsl = { 0, 1, 0.5 }; | 58 color_utils::HSL hsl = { 0, 1, 0.5 }; |
32 SkColor result = color_utils::HSLToSkColor(hsl, 128); | 59 SkColor result = color_utils::HSLToSkColor(hsl, 128); |
33 EXPECT_EQ(SkColorGetA(red), SkColorGetA(result)); | 60 EXPECT_EQ(SkColorGetA(red), SkColorGetA(result)); |
34 EXPECT_EQ(SkColorGetR(red), SkColorGetR(result)); | 61 EXPECT_EQ(SkColorGetR(red), SkColorGetR(result)); |
35 EXPECT_EQ(SkColorGetG(red), SkColorGetG(result)); | 62 EXPECT_EQ(SkColorGetG(red), SkColorGetG(result)); |
36 EXPECT_EQ(SkColorGetB(red), SkColorGetB(result)); | 63 EXPECT_EQ(SkColorGetB(red), SkColorGetB(result)); |
37 } | 64 } |
38 | 65 |
39 | |
40 TEST(ColorUtils, RGBtoHSLRoundTrip) { | 66 TEST(ColorUtils, RGBtoHSLRoundTrip) { |
41 // Just spot check values near the edges. | 67 // Just spot check values near the edges. |
42 for (int r = 0; r < 10; ++r) { | 68 for (int r = 0; r < 10; ++r) { |
43 for (int g = 0; g < 10; ++g) { | 69 for (int g = 0; g < 10; ++g) { |
44 for (int b = 0; b < 10; ++b) { | 70 for (int b = 0; b < 10; ++b) { |
45 SkColor rgb = SkColorSetARGB(255, r, g, b); | 71 SkColor rgb = SkColorSetARGB(255, r, g, b); |
46 color_utils::HSL hsl = { 0, 0, 0 }; | 72 color_utils::HSL hsl = { 0, 0, 0 }; |
47 color_utils::SkColorToHSL(rgb, &hsl); | 73 color_utils::SkColorToHSL(rgb, &hsl); |
48 SkColor out = color_utils::HSLToSkColor(hsl, 255); | 74 SkColor out = color_utils::HSLToSkColor(hsl, 255); |
49 EXPECT_EQ(SkColorGetR(out), SkColorGetR(rgb)); | 75 EXPECT_EQ(SkColorGetR(out), SkColorGetR(rgb)); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
91 back); | 117 back); |
92 | 118 |
93 // One is fully transparent, result is partially transparent. | 119 // One is fully transparent, result is partially transparent. |
94 back = SkColorSetA(back, 0); | 120 back = SkColorSetA(back, 0); |
95 EXPECT_EQ(136U, SkColorGetA(color_utils::AlphaBlend(fore, back, 136))); | 121 EXPECT_EQ(136U, SkColorGetA(color_utils::AlphaBlend(fore, back, 136))); |
96 | 122 |
97 // Both are fully transparent, result is fully transparent. | 123 // Both are fully transparent, result is fully transparent. |
98 fore = SkColorSetA(fore, 0); | 124 fore = SkColorSetA(fore, 0); |
99 EXPECT_EQ(0U, SkColorGetA(color_utils::AlphaBlend(fore, back, 255))); | 125 EXPECT_EQ(0U, SkColorGetA(color_utils::AlphaBlend(fore, back, 255))); |
100 } | 126 } |
127 | |
128 TEST(ColorUtils, ApplyColorReductionSingleColor) { | |
129 // The test runs color reduction on a single-colot image, where results are | |
130 // bound to be uninteresting. This is an important edge case, though. | |
131 SkBitmap source, result; | |
132 source.setConfig(SkBitmap::kARGB_8888_Config, 300, 200); | |
133 result.setConfig(SkBitmap::kA8_Config, 300, 200); | |
134 | |
135 source.allocPixels(); | |
136 result.allocPixels(); | |
137 source.eraseRGB(50, 150, 200); | |
138 | |
139 gfx::Vector3dF transform(1.0f, .5f, 0.1f); | |
140 // This transform, if not scaled, should result in GL=145. | |
141 gfx::Rect result_rect = color_utils::ApplyColorReduction( | |
142 source, transform, false, &result); | |
143 EXPECT_EQ(source.width(), result_rect.width()); | |
144 EXPECT_EQ(source.height(), result_rect.height()); | |
145 | |
146 uint8_t min_gl = 0; | |
147 uint8_t max_gl = 0; | |
148 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | |
149 EXPECT_EQ(145, min_gl); | |
150 EXPECT_EQ(145, max_gl); | |
151 | |
152 // Now scan requesting rescale. Expect all 0. | |
153 result_rect = color_utils::ApplyColorReduction( | |
154 source, transform, true, &result); | |
155 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | |
156 EXPECT_EQ(0, min_gl); | |
157 EXPECT_EQ(0, max_gl); | |
158 | |
159 // Test cliping to upper limit. | |
160 transform.set_z(1.1f); | |
161 result_rect = color_utils::ApplyColorReduction( | |
162 source, transform, false, &result); | |
163 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | |
164 EXPECT_EQ(0xFF, min_gl); | |
165 EXPECT_EQ(0xFF, max_gl); | |
166 | |
167 // Test cliping to upper limit. | |
168 transform.Scale(-1.0f); | |
169 result_rect = color_utils::ApplyColorReduction( | |
170 source, transform, false, &result); | |
171 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | |
172 EXPECT_EQ(0x0, min_gl); | |
173 EXPECT_EQ(0x0, max_gl); | |
174 } | |
175 | |
176 TEST(ColorUtils, ApplyColorReductionBlackAndWhite) { | |
177 // Check with images with multiple colors. This is really different only when | |
178 // the result is scaled. | |
179 gfx::Canvas canvas(gfx::Size(300, 200), ui::SCALE_FACTOR_100P, true); | |
180 | |
181 // The image consists of vertical non-overlapping stripes 150 pixels wide. | |
182 canvas.FillRect(gfx::Rect(0, 0, 150, 200), SkColorSetRGB(0, 0, 0)); | |
183 canvas.FillRect(gfx::Rect(150, 0, 150, 200), SkColorSetRGB(255, 255, 255)); | |
184 SkBitmap source = | |
185 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false); | |
186 SkBitmap result; | |
187 result.setConfig(SkBitmap::kA8_Config, 300, 200); | |
188 result.allocPixels(); | |
189 | |
190 | |
191 gfx::Vector3dF transform(1.0f, 0.5f, 0.1f); | |
192 gfx::Rect result_rect = color_utils::ApplyColorReduction( | |
193 source, transform, true, &result); | |
194 uint8_t min_gl = 0; | |
195 uint8_t max_gl = 0; | |
196 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | |
197 | |
198 EXPECT_EQ(source.width(), result_rect.width()); | |
199 EXPECT_EQ(source.height(), result_rect.height()); | |
200 EXPECT_EQ(0, min_gl); | |
201 EXPECT_EQ(255, max_gl); | |
202 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(0, 0))); | |
203 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(299, 199))); | |
204 | |
205 // Reverse test. | |
206 transform.Scale(-1.0f); | |
207 result_rect = color_utils::ApplyColorReduction( | |
208 source, transform, true, &result); | |
209 min_gl = 0; | |
210 max_gl = 0; | |
211 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | |
212 | |
213 EXPECT_EQ(0, min_gl); | |
214 EXPECT_EQ(255, max_gl); | |
215 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(0, 0))); | |
216 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(299, 199))); | |
217 } | |
218 | |
219 TEST(ColorUtils, ApplyColorReductionMultiColor) { | |
220 // Check with images with multiple colors. This is really different only when | |
221 // the result is scaled. | |
222 gfx::Canvas canvas(gfx::Size(300, 200), ui::SCALE_FACTOR_100P, true); | |
223 | |
224 // The image consists of vertical non-overlapping stripes 100 pixels wide. | |
225 canvas.FillRect(gfx::Rect(0, 0, 100, 200), SkColorSetRGB(100, 0, 0)); | |
226 canvas.FillRect(gfx::Rect(100, 0, 100, 200), SkColorSetRGB(0, 255, 0)); | |
227 canvas.FillRect(gfx::Rect(200, 0, 100, 200), SkColorSetRGB(0, 0, 128)); | |
228 SkBitmap source = | |
229 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false); | |
230 SkBitmap result; | |
231 result.setConfig(SkBitmap::kA8_Config, 300, 200); | |
232 result.allocPixels(); | |
233 | |
234 | |
235 gfx::Vector3dF transform(1.0f, 0.5f, 0.1f); | |
236 gfx::Rect result_rect = color_utils::ApplyColorReduction( | |
237 source, transform, false, &result); | |
238 uint8_t min_gl = 0; | |
239 uint8_t max_gl = 0; | |
240 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | |
241 | |
242 EXPECT_EQ(source.width(), result_rect.width()); | |
243 EXPECT_EQ(source.height(), result_rect.height()); | |
244 EXPECT_EQ(12, min_gl); | |
245 EXPECT_EQ(127, max_gl); | |
246 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(299, 199))); | |
247 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(150, 0))); | |
248 EXPECT_EQ(100U, SkColorGetA(result.getColor(0, 0))); | |
249 | |
250 result_rect = color_utils::ApplyColorReduction( | |
251 source, transform, true, &result); | |
252 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | |
253 EXPECT_EQ(0, min_gl); | |
254 EXPECT_EQ(255, max_gl); | |
255 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(299, 199))); | |
256 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(150, 0))); | |
257 EXPECT_EQ(193U, SkColorGetA(result.getColor(0, 0))); | |
258 } | |
259 | |
260 TEST(ColorUtils, ComputePrincipalComponentImageNotComputable) { | |
261 SkBitmap source, result; | |
262 source.setConfig(SkBitmap::kARGB_8888_Config, 300, 200); | |
263 result.setConfig(SkBitmap::kA8_Config, 300, 200); | |
264 | |
265 source.allocPixels(); | |
266 result.allocPixels(); | |
267 source.eraseRGB(50, 150, 200); | |
268 | |
269 // This computation should fail since all colors always vary together. | |
270 EXPECT_FALSE(color_utils::ComputePrincipalComponentImage(source, &result)); | |
271 } | |
272 | |
273 TEST(ColorUtils, ComputePrincipalComponentImage) { | |
274 gfx::Canvas canvas(gfx::Size(300, 200), ui::SCALE_FACTOR_100P, true); | |
275 | |
276 // The image consists of vertical non-overlapping stripes 100 pixels wide. | |
277 canvas.FillRect(gfx::Rect(0, 0, 100, 200), SkColorSetRGB(10, 10, 10)); | |
278 canvas.FillRect(gfx::Rect(100, 0, 100, 200), SkColorSetRGB(100, 100, 100)); | |
279 canvas.FillRect(gfx::Rect(200, 0, 100, 200), SkColorSetRGB(255, 255, 255)); | |
280 SkBitmap source = | |
281 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false); | |
282 SkBitmap result; | |
283 result.setConfig(SkBitmap::kA8_Config, 300, 200); | |
284 result.allocPixels(); | |
285 | |
286 // This computation should fail since all colors always vary together. | |
287 EXPECT_TRUE(color_utils::ComputePrincipalComponentImage(source, &result)); | |
288 | |
289 uint8_t min_gl = 0; | |
290 uint8_t max_gl = 0; | |
291 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl); | |
292 | |
293 EXPECT_EQ(0, min_gl); | |
294 EXPECT_EQ(255, max_gl); | |
295 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(0, 0))); | |
296 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(299, 199))); | |
297 EXPECT_EQ(93U, SkColorGetA(result.getColor(150, 0))); | |
298 } | |
OLD | NEW |