Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(840)

Side by Side Diff: ui/gfx/color_utils_unittest.cc

Issue 12335009: Implementation of principal-component color reduction. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698