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

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

Issue 399053002: ui/gfx: optimize UnPreMultiply operation by checking alpha value (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 5 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
« no previous file with comments | « no previous file | 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 <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "third_party/skia/include/core/SkBitmap.h" 13 #include "third_party/skia/include/core/SkBitmap.h"
14 #include "third_party/skia/include/core/SkColorPriv.h"
14 #include "third_party/skia/include/core/SkUnPreMultiply.h" 15 #include "third_party/skia/include/core/SkUnPreMultiply.h"
15 #include "ui/gfx/codec/png_codec.h" 16 #include "ui/gfx/codec/png_codec.h"
16 #include "ui/gfx/color_utils.h" 17 #include "ui/gfx/color_utils.h"
17 18
18 namespace color_utils { 19 namespace color_utils {
19 namespace { 20 namespace {
20 21
21 // RGBA KMean Constants 22 // RGBA KMean Constants
22 const uint32_t kNumberOfClusters = 4; 23 const uint32_t kNumberOfClusters = 4;
23 const int kNumberOfIterations = 50; 24 const int kNumberOfIterations = 50;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 // Holds the sum of all the points that make up this cluster. Used to 123 // Holds the sum of all the points that make up this cluster. Used to
123 // generate the next centroid as well as to check for convergence. 124 // generate the next centroid as well as to check for convergence.
124 uint32_t aggregate[3]; 125 uint32_t aggregate[3];
125 uint32_t counter; 126 uint32_t counter;
126 127
127 // The weight of the cluster, determined by how many points were used 128 // The weight of the cluster, determined by how many points were used
128 // to generate the previous centroid. 129 // to generate the previous centroid.
129 uint32_t weight; 130 uint32_t weight;
130 }; 131 };
131 132
132 // Un-premultiplies each pixel in |bitmap| into an output |buffer|. Requires 133 // Un-premultiplies each pixel in |bitmap| into an output |buffer|.
133 // approximately 10 microseconds for a 16x16 icon on an Intel Core i5.
134 void UnPreMultiply(const SkBitmap& bitmap, uint32_t* buffer, int buffer_size) { 134 void UnPreMultiply(const SkBitmap& bitmap, uint32_t* buffer, int buffer_size) {
135 SkAutoLockPixels auto_lock(bitmap); 135 SkAutoLockPixels auto_lock(bitmap);
136 uint32_t* in = static_cast<uint32_t*>(bitmap.getPixels()); 136 uint32_t* in = static_cast<uint32_t*>(bitmap.getPixels());
137 uint32_t* out = buffer; 137 uint32_t* out = buffer;
138 int pixel_count = std::min(bitmap.width() * bitmap.height(), buffer_size); 138 int pixel_count = std::min(bitmap.width() * bitmap.height(), buffer_size);
139 for (int i = 0; i < pixel_count; ++i) 139 for (int i = 0; i < pixel_count; ++i) {
140 *out++ = SkUnPreMultiply::PMColorToColor(*in++); 140 int alpha = SkGetPackedA32(*in);
141 if (alpha != 0 && alpha != 255)
142 *out++ = SkUnPreMultiply::PMColorToColor(*in++);
143 else
144 *out++ = *in++;
145 }
141 } 146 }
142 147
143 } // namespace 148 } // namespace
144 149
145 KMeanImageSampler::KMeanImageSampler() { 150 KMeanImageSampler::KMeanImageSampler() {
146 } 151 }
147 152
148 KMeanImageSampler::~KMeanImageSampler() { 153 KMeanImageSampler::~KMeanImageSampler() {
149 } 154 }
150 155
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 int64_t rr_sum = 0; 432 int64_t rr_sum = 0;
428 int64_t gg_sum = 0; 433 int64_t gg_sum = 0;
429 int64_t bb_sum = 0; 434 int64_t bb_sum = 0;
430 int64_t rg_sum = 0; 435 int64_t rg_sum = 0;
431 int64_t rb_sum = 0; 436 int64_t rb_sum = 0;
432 int64_t gb_sum = 0; 437 int64_t gb_sum = 0;
433 438
434 for (int y = 0; y < bitmap.height(); ++y) { 439 for (int y = 0; y < bitmap.height(); ++y) {
435 SkPMColor* current_color = static_cast<uint32_t*>(bitmap.getAddr32(0, y)); 440 SkPMColor* current_color = static_cast<uint32_t*>(bitmap.getAddr32(0, y));
436 for (int x = 0; x < bitmap.width(); ++x, ++current_color) { 441 for (int x = 0; x < bitmap.width(); ++x, ++current_color) {
437 SkColor c = SkUnPreMultiply::PMColorToColor(*current_color); 442 SkColor c;
443 int alpha = SkGetPackedA32(*current_color);
444 if (alpha != 0 && alpha != 255)
445 c = SkUnPreMultiply::PMColorToColor(*current_color);
446 else
447 c = *current_color;
448
438 SkColor r = SkColorGetR(c); 449 SkColor r = SkColorGetR(c);
439 SkColor g = SkColorGetG(c); 450 SkColor g = SkColorGetG(c);
440 SkColor b = SkColorGetB(c); 451 SkColor b = SkColorGetB(c);
441 452
442 r_sum += r; 453 r_sum += r;
443 g_sum += g; 454 g_sum += g;
444 b_sum += b; 455 b_sum += b;
445 rr_sum += r * r; 456 rr_sum += r * r;
446 gg_sum += g * g; 457 gg_sum += g * g;
447 bb_sum += b * b; 458 bb_sum += b * b;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 515
505 if (fit_to_range) { 516 if (fit_to_range) {
506 // We will figure out min/max in a preprocessing step and adjust 517 // We will figure out min/max in a preprocessing step and adjust
507 // actual_transform as required. 518 // actual_transform as required.
508 float max_val = std::numeric_limits<float>::min(); 519 float max_val = std::numeric_limits<float>::min();
509 float min_val = std::numeric_limits<float>::max(); 520 float min_val = std::numeric_limits<float>::max();
510 for (int y = 0; y < source_bitmap.height(); ++y) { 521 for (int y = 0; y < source_bitmap.height(); ++y) {
511 const SkPMColor* source_color_row = static_cast<SkPMColor*>( 522 const SkPMColor* source_color_row = static_cast<SkPMColor*>(
512 source_bitmap.getAddr32(0, y)); 523 source_bitmap.getAddr32(0, y));
513 for (int x = 0; x < source_bitmap.width(); ++x) { 524 for (int x = 0; x < source_bitmap.width(); ++x) {
514 SkColor c = SkUnPreMultiply::PMColorToColor(source_color_row[x]); 525 SkColor c;
526 int alpha = SkGetPackedA32(source_color_row[x]);
527 if (alpha != 0 && alpha != 255)
528 c = SkUnPreMultiply::PMColorToColor(source_color_row[x]);
529 else
530 c = source_color_row[x];
531
515 float r = SkColorGetR(c); 532 float r = SkColorGetR(c);
516 float g = SkColorGetG(c); 533 float g = SkColorGetG(c);
517 float b = SkColorGetB(c); 534 float b = SkColorGetB(c);
518 float gray_level = tr * r + tg * g + tb * b; 535 float gray_level = tr * r + tg * g + tb * b;
519 max_val = std::max(max_val, gray_level); 536 max_val = std::max(max_val, gray_level);
520 min_val = std::min(min_val, gray_level); 537 min_val = std::min(min_val, gray_level);
521 } 538 }
522 } 539 }
523 540
524 // Adjust the transform so that the result is scaling. 541 // Adjust the transform so that the result is scaling.
525 float scale = 0.0; 542 float scale = 0.0;
526 t0 = -min_val; 543 t0 = -min_val;
527 if (max_val > min_val) 544 if (max_val > min_val)
528 scale = 255.0 / (max_val - min_val); 545 scale = 255.0 / (max_val - min_val);
529 t0 *= scale; 546 t0 *= scale;
530 tr *= scale; 547 tr *= scale;
531 tg *= scale; 548 tg *= scale;
532 tb *= scale; 549 tb *= scale;
533 } 550 }
534 551
535 for (int y = 0; y < source_bitmap.height(); ++y) { 552 for (int y = 0; y < source_bitmap.height(); ++y) {
536 const SkPMColor* source_color_row = static_cast<SkPMColor*>( 553 const SkPMColor* source_color_row = static_cast<SkPMColor*>(
537 source_bitmap.getAddr32(0, y)); 554 source_bitmap.getAddr32(0, y));
538 uint8_t* target_color_row = target_bitmap->getAddr8(0, y); 555 uint8_t* target_color_row = target_bitmap->getAddr8(0, y);
539 for (int x = 0; x < source_bitmap.width(); ++x) { 556 for (int x = 0; x < source_bitmap.width(); ++x) {
540 SkColor c = SkUnPreMultiply::PMColorToColor(source_color_row[x]); 557 SkColor c;
558 int alpha = SkGetPackedA32(source_color_row[x]);
559 if (alpha != 0 && alpha != 255)
560 c = SkUnPreMultiply::PMColorToColor(source_color_row[x]);
561 else
562 c = source_color_row[x];
563
541 float r = SkColorGetR(c); 564 float r = SkColorGetR(c);
542 float g = SkColorGetG(c); 565 float g = SkColorGetG(c);
543 float b = SkColorGetB(c); 566 float b = SkColorGetB(c);
544 567
545 float gl = t0 + tr * r + tg * g + tb * b; 568 float gl = t0 + tr * r + tg * g + tb * b;
546 if (gl < 0) 569 if (gl < 0)
547 gl = 0; 570 gl = 0;
548 if (gl > 0xFF) 571 if (gl > 0xFF)
549 gl = 0xFF; 572 gl = 0xFF;
550 target_color_row[x] = static_cast<uint8_t>(gl); 573 target_color_row[x] = static_cast<uint8_t>(gl);
(...skipping 13 matching lines...) Expand all
564 gfx::Matrix3F covariance = ComputeColorCovariance(source_bitmap); 587 gfx::Matrix3F covariance = ComputeColorCovariance(source_bitmap);
565 gfx::Matrix3F eigenvectors = gfx::Matrix3F::Zeros(); 588 gfx::Matrix3F eigenvectors = gfx::Matrix3F::Zeros();
566 gfx::Vector3dF eigenvals = covariance.SolveEigenproblem(&eigenvectors); 589 gfx::Vector3dF eigenvals = covariance.SolveEigenproblem(&eigenvectors);
567 gfx::Vector3dF principal = eigenvectors.get_column(0); 590 gfx::Vector3dF principal = eigenvectors.get_column(0);
568 if (eigenvals == gfx::Vector3dF() || principal == gfx::Vector3dF()) 591 if (eigenvals == gfx::Vector3dF() || principal == gfx::Vector3dF())
569 return false; // This may happen for some edge cases. 592 return false; // This may happen for some edge cases.
570 return ApplyColorReduction(source_bitmap, principal, true, target_bitmap); 593 return ApplyColorReduction(source_bitmap, principal, true, target_bitmap);
571 } 594 }
572 595
573 } // color_utils 596 } // color_utils
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698