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

Side by Side Diff: ui/gfx/color_analysis.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.h ('k') | ui/gfx/color_analysis_unittest.cc » ('j') | 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 <algorithm> 7 #include <algorithm>
8 #include <limits>
8 #include <vector> 9 #include <vector>
9 10
10 #include "base/logging.h" 11 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
12 #include "third_party/skia/include/core/SkBitmap.h" 13 #include "third_party/skia/include/core/SkBitmap.h"
13 #include "third_party/skia/include/core/SkUnPreMultiply.h" 14 #include "third_party/skia/include/core/SkUnPreMultiply.h"
14 #include "ui/gfx/codec/png_codec.h" 15 #include "ui/gfx/codec/png_codec.h"
15 16
16 namespace { 17 namespace {
17 18
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n), 461 static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n),
461 (static_cast<double>(rb_sum) / pixel_n - 462 (static_cast<double>(rb_sum) / pixel_n -
462 static_cast<double>(r_sum * b_sum) / pixel_n / pixel_n), 463 static_cast<double>(r_sum * b_sum) / pixel_n / pixel_n),
463 (static_cast<double>(gb_sum) / pixel_n - 464 (static_cast<double>(gb_sum) / pixel_n -
464 static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n), 465 static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n),
465 (static_cast<double>(bb_sum) / pixel_n - 466 (static_cast<double>(bb_sum) / pixel_n -
466 static_cast<double>(b_sum * b_sum) / pixel_n / pixel_n)); 467 static_cast<double>(b_sum * b_sum) / pixel_n / pixel_n));
467 return covariance; 468 return covariance;
468 } 469 }
469 470
471 bool ApplyColorReduction(const SkBitmap& source_bitmap,
472 const gfx::Vector3dF& color_transform,
473 bool fit_to_range,
474 SkBitmap* target_bitmap) {
475 DCHECK(target_bitmap);
476 SkAutoLockPixels source_lock(source_bitmap);
477 SkAutoLockPixels target_lock(*target_bitmap);
478
479 DCHECK(source_bitmap.getPixels());
480 DCHECK(target_bitmap->getPixels());
481 DCHECK_EQ(SkBitmap::kARGB_8888_Config, source_bitmap.config());
482 DCHECK_EQ(SkBitmap::kA8_Config, target_bitmap->config());
483 DCHECK_EQ(source_bitmap.height(), target_bitmap->height());
484 DCHECK_EQ(source_bitmap.width(), target_bitmap->width());
485 DCHECK(!source_bitmap.empty());
486
487 // Elements of color_transform are explicitly off-loaded to local values for
488 // efficiency reasons. Note that in practice images may correspond to entire
489 // tab captures.
490 float t0 = 0.0;
491 float tr = color_transform.x();
492 float tg = color_transform.y();
493 float tb = color_transform.z();
494
495 if (fit_to_range) {
496 // We will figure out min/max in a preprocessing step and adjust
497 // actual_transform as required.
498 float max_val = std::numeric_limits<float>::min();
499 float min_val = std::numeric_limits<float>::max();
500 for (int y = 0; y < source_bitmap.height(); ++y) {
501 const SkPMColor* source_color_row = static_cast<SkPMColor*>(
502 source_bitmap.getAddr32(0, y));
503 for (int x = 0; x < source_bitmap.width(); ++x) {
504 SkColor c = SkUnPreMultiply::PMColorToColor(source_color_row[x]);
505 float r = SkColorGetR(c);
506 float g = SkColorGetG(c);
507 float b = SkColorGetB(c);
508 float gray_level = tr * r + tg * g + tb * b;
509 max_val = std::max(max_val, gray_level);
510 min_val = std::min(min_val, gray_level);
511 }
512 }
513
514 // Adjust the transform so that the result is scaling.
515 float scale = 0.0;
516 t0 = -min_val;
517 if (max_val > min_val)
518 scale = 255.0 / (max_val - min_val);
519 t0 *= scale;
520 tr *= scale;
521 tg *= scale;
522 tb *= scale;
523 }
524
525 for (int y = 0; y < source_bitmap.height(); ++y) {
526 const SkPMColor* source_color_row = static_cast<SkPMColor*>(
527 source_bitmap.getAddr32(0, y));
528 uint8_t* target_color_row = target_bitmap->getAddr8(0, y);
529 for (int x = 0; x < source_bitmap.width(); ++x) {
530 SkColor c = SkUnPreMultiply::PMColorToColor(source_color_row[x]);
531 float r = SkColorGetR(c);
532 float g = SkColorGetG(c);
533 float b = SkColorGetB(c);
534
535 float gl = t0 + tr * r + tg * g + tb * b;
536 if (gl < 0)
537 gl = 0;
538 if (gl > 0xFF)
539 gl = 0xFF;
540 target_color_row[x] = static_cast<uint8_t>(gl);
541 }
542 }
543
544 return true;
545 }
546
547 bool ComputePrincipalComponentImage(const SkBitmap& source_bitmap,
548 SkBitmap* target_bitmap) {
549 if (!target_bitmap) {
550 NOTREACHED();
551 return false;
552 }
553
554 gfx::Matrix3F covariance = ComputeColorCovariance(source_bitmap);
555 gfx::Matrix3F eigenvectors = gfx::Matrix3F::Zeros();
556 gfx::Vector3dF eigenvals = covariance.SolveEigenproblem(&eigenvectors);
557 gfx::Vector3dF principal = eigenvectors.get_column(0);
558 if (eigenvals == gfx::Vector3dF() || principal == gfx::Vector3dF())
559 return false; // This may happen for some edge cases.
560 return ApplyColorReduction(source_bitmap, principal, true, target_bitmap);
561 }
562
470 } // color_utils 563 } // color_utils
OLDNEW
« no previous file with comments | « ui/gfx/color_analysis.h ('k') | ui/gfx/color_analysis_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698