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

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

Issue 12335009: Implementation of principal-component color reduction. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moved to another fileset to make iOS build happy. 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
« no previous file with comments | « ui/gfx/color_analysis.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) 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"
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 protected: 128 protected:
129 std::vector<int> prebaked_sample_results_; 129 std::vector<int> prebaked_sample_results_;
130 size_t current_result_index_; 130 size_t current_result_index_;
131 }; 131 };
132 132
133 // Return true if a color channel is approximately equal to an expected value. 133 // Return true if a color channel is approximately equal to an expected value.
134 bool ChannelApproximatelyEqual(int expected, uint8_t channel) { 134 bool ChannelApproximatelyEqual(int expected, uint8_t channel) {
135 return (abs(expected - static_cast<int>(channel)) <= 1); 135 return (abs(expected - static_cast<int>(channel)) <= 1);
136 } 136 }
137 137
138 // Compute minimal and maximal graylevel (or alphalevel) of the input |bitmap|.
139 // |bitmap| has to be allocated and configured to kA8_Config.
140 void Calculate8bitBitmapMinMax(const SkBitmap& bitmap,
141 uint8_t* min_gl,
142 uint8_t* max_gl) {
143 SkAutoLockPixels bitmap_lock(bitmap);
144 DCHECK(bitmap.getPixels());
145 DCHECK(bitmap.config() == SkBitmap::kA8_Config);
146 DCHECK(min_gl);
147 DCHECK(max_gl);
148 *min_gl = std::numeric_limits<uint8_t>::max();
149 *max_gl = std::numeric_limits<uint8_t>::min();
150 for (int y = 0; y < bitmap.height(); ++y) {
151 uint8_t* current_color = bitmap.getAddr8(0, y);
152 for (int x = 0; x < bitmap.width(); ++x, ++current_color) {
153 *min_gl = std::min(*min_gl, *current_color);
154 *max_gl = std::max(*max_gl, *current_color);
155 }
156 }
157 }
158
138 } // namespace 159 } // namespace
139 160
140 class ColorAnalysisTest : public testing::Test { 161 class ColorAnalysisTest : public testing::Test {
141 }; 162 };
142 163
143 TEST_F(ColorAnalysisTest, CalculatePNGKMeanAllWhite) { 164 TEST_F(ColorAnalysisTest, CalculatePNGKMeanAllWhite) {
144 MockKMeanImageSampler test_sampler; 165 MockKMeanImageSampler test_sampler;
145 test_sampler.AddSample(0); 166 test_sampler.AddSample(0);
146 167
147 scoped_refptr<base::RefCountedBytes> png( 168 scoped_refptr<base::RefCountedBytes> png(
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 SkBitmap bitmap = 307 SkBitmap bitmap =
287 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false); 308 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false);
288 gfx::Matrix3F covariance = color_utils::ComputeColorCovariance(bitmap); 309 gfx::Matrix3F covariance = color_utils::ComputeColorCovariance(bitmap);
289 310
290 gfx::Matrix3F expected_covariance = gfx::Matrix3F::Zeros(); 311 gfx::Matrix3F expected_covariance = gfx::Matrix3F::Zeros();
291 expected_covariance.set(2400, 400, -1600, 312 expected_covariance.set(2400, 400, -1600,
292 400, 2400, 400, 313 400, 2400, 400,
293 -1600, 400, 2400); 314 -1600, 400, 2400);
294 EXPECT_EQ(expected_covariance, covariance); 315 EXPECT_EQ(expected_covariance, covariance);
295 } 316 }
317
318 TEST_F(ColorAnalysisTest, ApplyColorReductionSingleColor) {
319 // The test runs color reduction on a single-colot image, where results are
320 // bound to be uninteresting. This is an important edge case, though.
321 SkBitmap source, result;
322 source.setConfig(SkBitmap::kARGB_8888_Config, 300, 200);
323 result.setConfig(SkBitmap::kA8_Config, 300, 200);
324
325 source.allocPixels();
326 result.allocPixels();
327 source.eraseRGB(50, 150, 200);
328
329 gfx::Vector3dF transform(1.0f, .5f, 0.1f);
330 // This transform, if not scaled, should result in GL=145.
331 EXPECT_TRUE(color_utils::ApplyColorReduction(
332 source, transform, false, &result));
333
334 uint8_t min_gl = 0;
335 uint8_t max_gl = 0;
336 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl);
337 EXPECT_EQ(145, min_gl);
338 EXPECT_EQ(145, max_gl);
339
340 // Now scan requesting rescale. Expect all 0.
341 EXPECT_TRUE(color_utils::ApplyColorReduction(
342 source, transform, true, &result));
343 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl);
344 EXPECT_EQ(0, min_gl);
345 EXPECT_EQ(0, max_gl);
346
347 // Test cliping to upper limit.
348 transform.set_z(1.1f);
349 EXPECT_TRUE(color_utils::ApplyColorReduction(
350 source, transform, false, &result));
351 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl);
352 EXPECT_EQ(0xFF, min_gl);
353 EXPECT_EQ(0xFF, max_gl);
354
355 // Test cliping to upper limit.
356 transform.Scale(-1.0f);
357 EXPECT_TRUE(color_utils::ApplyColorReduction(
358 source, transform, false, &result));
359 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl);
360 EXPECT_EQ(0x0, min_gl);
361 EXPECT_EQ(0x0, max_gl);
362 }
363
364 TEST_F(ColorAnalysisTest, ApplyColorReductionBlackAndWhite) {
365 // Check with images with multiple colors. This is really different only when
366 // the result is scaled.
367 gfx::Canvas canvas(gfx::Size(300, 200), ui::SCALE_FACTOR_100P, true);
368
369 // The image consists of vertical non-overlapping stripes 150 pixels wide.
370 canvas.FillRect(gfx::Rect(0, 0, 150, 200), SkColorSetRGB(0, 0, 0));
371 canvas.FillRect(gfx::Rect(150, 0, 150, 200), SkColorSetRGB(255, 255, 255));
372 SkBitmap source =
373 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false);
374 SkBitmap result;
375 result.setConfig(SkBitmap::kA8_Config, 300, 200);
376 result.allocPixels();
377
378 gfx::Vector3dF transform(1.0f, 0.5f, 0.1f);
379 EXPECT_TRUE(color_utils::ApplyColorReduction(
380 source, transform, true, &result));
381 uint8_t min_gl = 0;
382 uint8_t max_gl = 0;
383 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl);
384
385 EXPECT_EQ(0, min_gl);
386 EXPECT_EQ(255, max_gl);
387 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(0, 0)));
388 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(299, 199)));
389
390 // Reverse test.
391 transform.Scale(-1.0f);
392 EXPECT_TRUE(color_utils::ApplyColorReduction(
393 source, transform, true, &result));
394 min_gl = 0;
395 max_gl = 0;
396 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl);
397
398 EXPECT_EQ(0, min_gl);
399 EXPECT_EQ(255, max_gl);
400 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(0, 0)));
401 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(299, 199)));
402 }
403
404 TEST_F(ColorAnalysisTest, ApplyColorReductionMultiColor) {
405 // Check with images with multiple colors. This is really different only when
406 // the result is scaled.
407 gfx::Canvas canvas(gfx::Size(300, 200), ui::SCALE_FACTOR_100P, true);
408
409 // The image consists of vertical non-overlapping stripes 100 pixels wide.
410 canvas.FillRect(gfx::Rect(0, 0, 100, 200), SkColorSetRGB(100, 0, 0));
411 canvas.FillRect(gfx::Rect(100, 0, 100, 200), SkColorSetRGB(0, 255, 0));
412 canvas.FillRect(gfx::Rect(200, 0, 100, 200), SkColorSetRGB(0, 0, 128));
413 SkBitmap source =
414 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false);
415 SkBitmap result;
416 result.setConfig(SkBitmap::kA8_Config, 300, 200);
417 result.allocPixels();
418
419 gfx::Vector3dF transform(1.0f, 0.5f, 0.1f);
420 EXPECT_TRUE(color_utils::ApplyColorReduction(
421 source, transform, false, &result));
422 uint8_t min_gl = 0;
423 uint8_t max_gl = 0;
424 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl);
425 EXPECT_EQ(12, min_gl);
426 EXPECT_EQ(127, max_gl);
427 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(299, 199)));
428 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(150, 0)));
429 EXPECT_EQ(100U, SkColorGetA(result.getColor(0, 0)));
430
431 EXPECT_TRUE(color_utils::ApplyColorReduction(
432 source, transform, true, &result));
433 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl);
434 EXPECT_EQ(0, min_gl);
435 EXPECT_EQ(255, max_gl);
436 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(299, 199)));
437 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(150, 0)));
438 EXPECT_EQ(193U, SkColorGetA(result.getColor(0, 0)));
439 }
440
441 TEST_F(ColorAnalysisTest, ComputePrincipalComponentImageNotComputable) {
442 SkBitmap source, result;
443 source.setConfig(SkBitmap::kARGB_8888_Config, 300, 200);
444 result.setConfig(SkBitmap::kA8_Config, 300, 200);
445
446 source.allocPixels();
447 result.allocPixels();
448 source.eraseRGB(50, 150, 200);
449
450 // This computation should fail since all colors always vary together.
451 EXPECT_FALSE(color_utils::ComputePrincipalComponentImage(source, &result));
452 }
453
454 TEST_F(ColorAnalysisTest, ComputePrincipalComponentImage) {
455 gfx::Canvas canvas(gfx::Size(300, 200), ui::SCALE_FACTOR_100P, true);
456
457 // The image consists of vertical non-overlapping stripes 100 pixels wide.
458 canvas.FillRect(gfx::Rect(0, 0, 100, 200), SkColorSetRGB(10, 10, 10));
459 canvas.FillRect(gfx::Rect(100, 0, 100, 200), SkColorSetRGB(100, 100, 100));
460 canvas.FillRect(gfx::Rect(200, 0, 100, 200), SkColorSetRGB(255, 255, 255));
461 SkBitmap source =
462 skia::GetTopDevice(*canvas.sk_canvas())->accessBitmap(false);
463 SkBitmap result;
464 result.setConfig(SkBitmap::kA8_Config, 300, 200);
465 result.allocPixels();
466
467 // This computation should fail since all colors always vary together.
468 EXPECT_TRUE(color_utils::ComputePrincipalComponentImage(source, &result));
469
470 uint8_t min_gl = 0;
471 uint8_t max_gl = 0;
472 Calculate8bitBitmapMinMax(result, &min_gl, &max_gl);
473
474 EXPECT_EQ(0, min_gl);
475 EXPECT_EQ(255, max_gl);
476 EXPECT_EQ(min_gl, SkColorGetA(result.getColor(0, 0)));
477 EXPECT_EQ(max_gl, SkColorGetA(result.getColor(299, 199)));
478 EXPECT_EQ(93U, SkColorGetA(result.getColor(150, 0)));
479 }
OLDNEW
« no previous file with comments | « ui/gfx/color_analysis.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698