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

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

Issue 649203003: Type conversion fixes, ui/gfx/ edition. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix test Created 6 years, 2 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
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
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 inline bool IsAtCentroid(uint8_t r, uint8_t g, uint8_t b) { 61 inline bool IsAtCentroid(uint8_t r, uint8_t g, uint8_t b) {
62 return r == centroid[0] && g == centroid[1] && b == centroid[2]; 62 return r == centroid[0] && g == centroid[1] && b == centroid[2];
63 } 63 }
64 64
65 // Recomputes the centroid of the cluster based on the aggregate data. The 65 // Recomputes the centroid of the cluster based on the aggregate data. The
66 // number of points used to calculate this center is stored for weighting 66 // number of points used to calculate this center is stored for weighting
67 // purposes. The aggregate and counter are then cleared to be ready for the 67 // purposes. The aggregate and counter are then cleared to be ready for the
68 // next iteration. 68 // next iteration.
69 inline void RecomputeCentroid() { 69 inline void RecomputeCentroid() {
70 if (counter > 0) { 70 if (counter > 0) {
71 centroid[0] = aggregate[0] / counter; 71 centroid[0] = static_cast<uint8_t>(aggregate[0] / counter);
72 centroid[1] = aggregate[1] / counter; 72 centroid[1] = static_cast<uint8_t>(aggregate[1] / counter);
73 centroid[2] = aggregate[2] / counter; 73 centroid[2] = static_cast<uint8_t>(aggregate[2] / counter);
74 74
75 aggregate[0] = aggregate[1] = aggregate[2] = 0; 75 aggregate[0] = aggregate[1] = aggregate[2] = 0;
76 weight = counter; 76 weight = counter;
77 counter = 0; 77 counter = 0;
78 } 78 }
79 } 79 }
80 80
81 inline void AddPoint(uint8_t r, uint8_t g, uint8_t b) { 81 inline void AddPoint(uint8_t r, uint8_t g, uint8_t b) {
82 aggregate[0] += r; 82 aggregate[0] += r;
83 aggregate[1] += g; 83 aggregate[1] += g;
(...skipping 27 matching lines...) Expand all
111 inline uint32_t GetWeight() const { 111 inline uint32_t GetWeight() const {
112 return weight; 112 return weight;
113 } 113 }
114 114
115 static bool SortKMeanClusterByWeight(const KMeanCluster& a, 115 static bool SortKMeanClusterByWeight(const KMeanCluster& a,
116 const KMeanCluster& b) { 116 const KMeanCluster& b) {
117 return a.GetWeight() > b.GetWeight(); 117 return a.GetWeight() > b.GetWeight();
118 } 118 }
119 119
120 private: 120 private:
121 uint8_t centroid[3]; 121 uint8_t centroid[3];
danakj 2014/10/18 18:40:06 huh, these should be _ suffix'd..
Peter Kasting 2014/10/20 23:38:56 Done.
122 122
123 // 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
124 // generate the next centroid as well as to check for convergence. 124 // generate the next centroid as well as to check for convergence.
125 uint32_t aggregate[3]; 125 uint32_t aggregate[3];
126 uint32_t counter; 126 uint32_t counter;
127 127
128 // 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
129 // to generate the previous centroid. 129 // to generate the previous centroid.
130 uint32_t weight; 130 uint32_t weight;
131 }; 131 };
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 gb_sum += g * b; 461 gb_sum += g * b;
462 } 462 }
463 } 463 }
464 464
465 // Covariance (not normalized) is E(X*X.t) - m * m.t and this is how it 465 // Covariance (not normalized) is E(X*X.t) - m * m.t and this is how it
466 // is calculated below. 466 // is calculated below.
467 // Each row below represents a row of the matrix describing (co)variances 467 // Each row below represents a row of the matrix describing (co)variances
468 // of R, G and B channels with (R, G, B) 468 // of R, G and B channels with (R, G, B)
469 int pixel_n = bitmap.width() * bitmap.height(); 469 int pixel_n = bitmap.width() * bitmap.height();
470 covariance.set( 470 covariance.set(
471 (static_cast<double>(rr_sum) / pixel_n - 471 static_cast<float>(
472 static_cast<double>(r_sum * r_sum) / pixel_n / pixel_n), 472 static_cast<double>(rr_sum) / pixel_n -
473 (static_cast<double>(rg_sum) / pixel_n - 473 static_cast<double>(r_sum * r_sum) / pixel_n / pixel_n),
474 static_cast<double>(r_sum * g_sum) / pixel_n / pixel_n), 474 static_cast<float>(
475 (static_cast<double>(rb_sum) / pixel_n - 475 static_cast<double>(rg_sum) / pixel_n -
476 static_cast<double>(r_sum * b_sum) / pixel_n / pixel_n), 476 static_cast<double>(r_sum * g_sum) / pixel_n / pixel_n),
477 (static_cast<double>(rg_sum) / pixel_n - 477 static_cast<float>(
478 static_cast<double>(r_sum * g_sum) / pixel_n / pixel_n), 478 static_cast<double>(rb_sum) / pixel_n -
479 (static_cast<double>(gg_sum) / pixel_n - 479 static_cast<double>(r_sum * b_sum) / pixel_n / pixel_n),
480 static_cast<double>(g_sum * g_sum) / pixel_n / pixel_n), 480 static_cast<float>(
481 (static_cast<double>(gb_sum) / pixel_n - 481 static_cast<double>(rg_sum) / pixel_n -
482 static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n), 482 static_cast<double>(r_sum * g_sum) / pixel_n / pixel_n),
483 (static_cast<double>(rb_sum) / pixel_n - 483 static_cast<float>(
484 static_cast<double>(r_sum * b_sum) / pixel_n / pixel_n), 484 static_cast<double>(gg_sum) / pixel_n -
485 (static_cast<double>(gb_sum) / pixel_n - 485 static_cast<double>(g_sum * g_sum) / pixel_n / pixel_n),
486 static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n), 486 static_cast<float>(
487 (static_cast<double>(bb_sum) / pixel_n - 487 static_cast<double>(gb_sum) / pixel_n -
488 static_cast<double>(b_sum * b_sum) / pixel_n / pixel_n)); 488 static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n),
489 static_cast<float>(
490 static_cast<double>(rb_sum) / pixel_n -
491 static_cast<double>(r_sum * b_sum) / pixel_n / pixel_n),
492 static_cast<float>(
493 static_cast<double>(gb_sum) / pixel_n -
494 static_cast<double>(g_sum * b_sum) / pixel_n / pixel_n),
495 static_cast<float>(
496 static_cast<double>(bb_sum) / pixel_n -
497 static_cast<double>(b_sum * b_sum) / pixel_n / pixel_n));
489 return covariance; 498 return covariance;
490 } 499 }
491 500
492 bool ApplyColorReduction(const SkBitmap& source_bitmap, 501 bool ApplyColorReduction(const SkBitmap& source_bitmap,
493 const gfx::Vector3dF& color_transform, 502 const gfx::Vector3dF& color_transform,
494 bool fit_to_range, 503 bool fit_to_range,
495 SkBitmap* target_bitmap) { 504 SkBitmap* target_bitmap) {
496 DCHECK(target_bitmap); 505 DCHECK(target_bitmap);
497 SkAutoLockPixels source_lock(source_bitmap); 506 SkAutoLockPixels source_lock(source_bitmap);
498 SkAutoLockPixels target_lock(*target_bitmap); 507 SkAutoLockPixels target_lock(*target_bitmap);
(...skipping 23 matching lines...) Expand all
522 const SkPMColor* source_color_row = static_cast<SkPMColor*>( 531 const SkPMColor* source_color_row = static_cast<SkPMColor*>(
523 source_bitmap.getAddr32(0, y)); 532 source_bitmap.getAddr32(0, y));
524 for (int x = 0; x < source_bitmap.width(); ++x) { 533 for (int x = 0; x < source_bitmap.width(); ++x) {
525 SkColor c; 534 SkColor c;
526 int alpha = SkGetPackedA32(source_color_row[x]); 535 int alpha = SkGetPackedA32(source_color_row[x]);
527 if (alpha != 0 && alpha != 255) 536 if (alpha != 0 && alpha != 255)
528 c = SkUnPreMultiply::PMColorToColor(source_color_row[x]); 537 c = SkUnPreMultiply::PMColorToColor(source_color_row[x]);
529 else 538 else
530 c = source_color_row[x]; 539 c = source_color_row[x];
531 540
532 float r = SkColorGetR(c); 541 U8CPU r = SkColorGetR(c);
danakj 2014/10/18 18:40:06 uint8?
Peter Kasting 2014/10/20 23:38:56 Done.
533 float g = SkColorGetG(c); 542 U8CPU g = SkColorGetG(c);
534 float b = SkColorGetB(c); 543 U8CPU b = SkColorGetB(c);
535 float gray_level = tr * r + tg * g + tb * b; 544 float gray_level = tr * r + tg * g + tb * b;
536 max_val = std::max(max_val, gray_level); 545 max_val = std::max(max_val, gray_level);
537 min_val = std::min(min_val, gray_level); 546 min_val = std::min(min_val, gray_level);
538 } 547 }
539 } 548 }
540 549
541 // Adjust the transform so that the result is scaling. 550 // Adjust the transform so that the result is scaling.
542 float scale = 0.0; 551 float scale = 0.0;
543 t0 = -min_val; 552 t0 = -min_val;
544 if (max_val > min_val) 553 if (max_val > min_val)
545 scale = 255.0 / (max_val - min_val); 554 scale = 255.0f / (max_val - min_val);
546 t0 *= scale; 555 t0 *= scale;
547 tr *= scale; 556 tr *= scale;
548 tg *= scale; 557 tg *= scale;
549 tb *= scale; 558 tb *= scale;
550 } 559 }
551 560
552 for (int y = 0; y < source_bitmap.height(); ++y) { 561 for (int y = 0; y < source_bitmap.height(); ++y) {
553 const SkPMColor* source_color_row = static_cast<SkPMColor*>( 562 const SkPMColor* source_color_row = static_cast<SkPMColor*>(
554 source_bitmap.getAddr32(0, y)); 563 source_bitmap.getAddr32(0, y));
555 uint8_t* target_color_row = target_bitmap->getAddr8(0, y); 564 uint8_t* target_color_row = target_bitmap->getAddr8(0, y);
556 for (int x = 0; x < source_bitmap.width(); ++x) { 565 for (int x = 0; x < source_bitmap.width(); ++x) {
557 SkColor c; 566 SkColor c;
558 int alpha = SkGetPackedA32(source_color_row[x]); 567 int alpha = SkGetPackedA32(source_color_row[x]);
559 if (alpha != 0 && alpha != 255) 568 if (alpha != 0 && alpha != 255)
560 c = SkUnPreMultiply::PMColorToColor(source_color_row[x]); 569 c = SkUnPreMultiply::PMColorToColor(source_color_row[x]);
561 else 570 else
562 c = source_color_row[x]; 571 c = source_color_row[x];
563 572
564 float r = SkColorGetR(c); 573 U8CPU r = SkColorGetR(c);
danakj 2014/10/18 18:40:06 uint8?
Peter Kasting 2014/10/20 23:38:56 Done.
565 float g = SkColorGetG(c); 574 U8CPU g = SkColorGetG(c);
566 float b = SkColorGetB(c); 575 U8CPU b = SkColorGetB(c);
567 576
568 float gl = t0 + tr * r + tg * g + tb * b; 577 float gl = t0 + tr * r + tg * g + tb * b;
569 if (gl < 0) 578 if (gl < 0)
570 gl = 0; 579 gl = 0;
571 if (gl > 0xFF) 580 if (gl > 0xFF)
572 gl = 0xFF; 581 gl = 0xFF;
573 target_color_row[x] = static_cast<uint8_t>(gl); 582 target_color_row[x] = static_cast<uint8_t>(gl);
574 } 583 }
575 } 584 }
576 585
(...skipping 10 matching lines...) Expand all
587 gfx::Matrix3F covariance = ComputeColorCovariance(source_bitmap); 596 gfx::Matrix3F covariance = ComputeColorCovariance(source_bitmap);
588 gfx::Matrix3F eigenvectors = gfx::Matrix3F::Zeros(); 597 gfx::Matrix3F eigenvectors = gfx::Matrix3F::Zeros();
589 gfx::Vector3dF eigenvals = covariance.SolveEigenproblem(&eigenvectors); 598 gfx::Vector3dF eigenvals = covariance.SolveEigenproblem(&eigenvectors);
590 gfx::Vector3dF principal = eigenvectors.get_column(0); 599 gfx::Vector3dF principal = eigenvectors.get_column(0);
591 if (eigenvals == gfx::Vector3dF() || principal == gfx::Vector3dF()) 600 if (eigenvals == gfx::Vector3dF() || principal == gfx::Vector3dF())
592 return false; // This may happen for some edge cases. 601 return false; // This may happen for some edge cases.
593 return ApplyColorReduction(source_bitmap, principal, true, target_bitmap); 602 return ApplyColorReduction(source_bitmap, principal, true, target_bitmap);
594 } 603 }
595 604
596 } // color_utils 605 } // color_utils
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698