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

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

Powered by Google App Engine
This is Rietveld 408576698