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

Side by Side Diff: ui/gfx/color_utils.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
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_utils.h" 5 #include "ui/gfx/color_utils.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 #if defined(OS_WIN) 8 #if defined(OS_WIN)
9 #include <windows.h> 9 #include <windows.h>
10 #endif 10 #endif
11 11
12 #include <algorithm> 12 #include <algorithm>
13 #include <limits>
13 14
14 #include "base/basictypes.h" 15 #include "base/basictypes.h"
15 #include "base/logging.h" 16 #include "base/logging.h"
16 #include "build/build_config.h" 17 #include "build/build_config.h"
17 #if defined(OS_WIN) 18 #if defined(OS_WIN)
18 #include "skia/ext/skia_utils_win.h" 19 #include "skia/ext/skia_utils_win.h"
19 #endif 20 #endif
20 #include "third_party/skia/include/core/SkBitmap.h" 21 #include "third_party/skia/include/core/SkBitmap.h"
22 #include "third_party/skia/include/core/SkUnPreMultiply.h"
23 #include "ui/gfx/color_analysis.h"
24 #include "ui/gfx/matrix3_f.h"
25 #include "ui/gfx/vector3d_f.h"
21 26
22 namespace color_utils { 27 namespace color_utils {
23 28
24 // Helper functions ----------------------------------------------------------- 29 // Helper functions -----------------------------------------------------------
25 30
26 namespace { 31 namespace {
27 32
28 int calcHue(double temp1, double temp2, double hue) { 33 int calcHue(double temp1, double temp2, double hue) {
29 if (hue < 0.0) 34 if (hue < 0.0)
30 ++hue; 35 ++hue;
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 259
255 SkColor GetSysSkColor(int which) { 260 SkColor GetSysSkColor(int which) {
256 #if defined(OS_WIN) 261 #if defined(OS_WIN)
257 return skia::COLORREFToSkColor(GetSysColor(which)); 262 return skia::COLORREFToSkColor(GetSysColor(which));
258 #else 263 #else
259 NOTIMPLEMENTED(); 264 NOTIMPLEMENTED();
260 return SK_ColorLTGRAY; 265 return SK_ColorLTGRAY;
261 #endif 266 #endif
262 } 267 }
263 268
269 bool ApplyColorReduction(const SkBitmap& source_bitmap,
270 const gfx::Vector3dF& color_transform,
271 bool fit_to_range,
272 SkBitmap* target_bitmap) {
273 DCHECK(target_bitmap);
274 SkAutoLockPixels source_lock(source_bitmap);
275 SkAutoLockPixels target_lock(*target_bitmap);
276
277 DCHECK(source_bitmap.getPixels());
278 DCHECK(target_bitmap->getPixels());
279 DCHECK(source_bitmap.config() == SkBitmap::kARGB_8888_Config);
Alexei Svitkine (slow) 2013/02/22 02:24:06 I am assuming DCHECK_EQ() results in a compile fai
motek. 2013/02/22 15:42:56 Done.
280 DCHECK(target_bitmap->config() == SkBitmap::kA8_Config);
281 DCHECK_EQ(source_bitmap.height(), target_bitmap->height());
282 DCHECK_EQ(source_bitmap.width(), target_bitmap->width());
283
284 DCHECK(source_bitmap.height() > 0 && source_bitmap.width() > 0);
Alexei Svitkine (slow) 2013/02/22 02:24:06 Nit: DCHECK(!source_bitmap.empty()) instead
motek. 2013/02/22 15:42:56 Done.
285
286 // Elements of color_transform are explicitly off-loaded to local values for
287 // efficiency reasons. Note that in practice images may correspond to entire
288 // tab captures.
289 float t0 = 0.0;
290 float tr = color_transform.x();
291 float tg = color_transform.y();
292 float tb = color_transform.z();
293
294 if (fit_to_range) {
295 // We will figure out min/max in a preprocessing step and adjust
296 // actual_transform as required.
297 float max_val = std::numeric_limits<float>::min();
298 float min_val = std::numeric_limits<float>::max();
299 for (int y = 0; y < source_bitmap.height(); ++y) {
300 SkPMColor* current_color = static_cast<SkPMColor*>(
301 source_bitmap.getAddr32(0, y));
302 for (int x = 0; x < source_bitmap.width(); ++x, ++current_color) {
303 SkColor c = SkUnPreMultiply::PMColorToColor(*current_color);
304 float r = SkColorGetR(c);
305 float g = SkColorGetG(c);
306 float b = SkColorGetB(c);
307 float gray_level = tr * r + tg * g + tb * b;
308 max_val = std::max(max_val, gray_level);
309 min_val = std::min(min_val, gray_level);
310 }
311 }
312
313 // Adjust the transform so that the result is scaling.
314 float scale = 0.0;
315 t0 = -min_val;
316 if (max_val > min_val)
317 scale = 255.0 / (max_val - min_val);
318 t0 *= scale;
319 tr *= scale;
320 tg *= scale;
321 tb *= scale;
322 }
323
324 for (int y = 0; y < source_bitmap.height(); ++y) {
325 SkPMColor* current_color = static_cast<SkPMColor*>(
Alexei Svitkine (slow) 2013/02/22 02:24:06 Nit: How about |source_color_row| and make it cons
motek. 2013/02/22 15:42:56 Done.
326 source_bitmap.getAddr32(0, y));
327 uint8_t* target_color = target_bitmap->getAddr8(0, y);
Alexei Svitkine (slow) 2013/02/22 02:24:06 Nit: How about |target_color_row| Here and in the
motek. 2013/02/22 15:42:56 Done.
328 for (int x = 0; x < source_bitmap.width(); ++x, ++current_color) {
329 SkColor c = SkUnPreMultiply::PMColorToColor(*current_color);
Alexei Svitkine (slow) 2013/02/22 02:24:06 Nit: How about source_color_row[x] instead of doin
motek. 2013/02/22 15:42:56 Done.
330 float r = SkColorGetR(c);
331 float g = SkColorGetG(c);
332 float b = SkColorGetB(c);
333
334 float gl = t0 + tr * r + tg * g + tb * b;
335 if (gl < 0)
336 gl = 0;
337 if (gl > 0xFF)
338 gl = 0xFF;
339 target_color[x] = static_cast<uint8_t>(gl);
340 }
341 }
342
343 return true;
344 }
345
346 bool ComputePrincipalComponentImage(const SkBitmap& source_bitmap,
347 SkBitmap* target_bitmap) {
348 if (!target_bitmap) {
349 NOTREACHED();
350 return false;
351 }
352
353 gfx::Matrix3F covariance = ComputeColorCovariance(source_bitmap);
354 gfx::Matrix3F eigenvectors = gfx::Matrix3F::Zeros();
355 gfx::Vector3dF eigenvals = covariance.SolveEigenproblem(&eigenvectors);
356 gfx::Vector3dF principal = eigenvectors.get_column(0);
357 if (eigenvals == gfx::Vector3dF() || principal == gfx::Vector3dF())
358 return false; // This may happen for some edge cases.
359 return ApplyColorReduction(source_bitmap, principal, true, target_bitmap);
360 }
361
264 } // namespace color_utils 362 } // namespace color_utils
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698