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

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: 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 gfx::Rect ApplyColorReduction(const SkBitmap& source_bitmap,
270 const gfx::Vector3dF& color_transform,
271 bool scale_result,
272 SkBitmap* target_bitmap) {
273 gfx::Rect result_rect;
274 if (!target_bitmap) {
275 NOTREACHED();
276 return result_rect;
277 }
278
279 SkAutoLockPixels source_lock(source_bitmap);
280 SkAutoLockPixels target_lock(*target_bitmap);
281
282 if (!source_bitmap.getPixels())
283 return result_rect;
284
285 if (!target_bitmap->getPixels()) {
286 NOTREACHED();
287 return result_rect;
288 }
289
290 DCHECK(source_bitmap.config() == SkBitmap::kARGB_8888_Config);
291 DCHECK(target_bitmap->config() == SkBitmap::kA8_Config);
292 DCHECK_EQ(source_bitmap.height(), target_bitmap->height());
293 DCHECK_EQ(source_bitmap.width(), target_bitmap->width());
294
295 int height = std::min(source_bitmap.height(), target_bitmap->height());
296 int width = std::min(source_bitmap.width(), target_bitmap->width());
Alexei Svitkine (slow) 2013/02/21 16:49:59 Instead of doing this, why not create the target_b
motek. 2013/02/21 18:38:43 As explained in the header, I believe the conventi
Alexei Svitkine (slow) 2013/02/21 19:49:33 Got it. Given that you already have DCHECKs() abou
297 DCHECK(height > 0 && width > 0);
298
299 result_rect.SetRect(0, 0, width, height);
300 float a0 = 0.0;
301 float scale = 1.0;
302 if (scale_result) {
303 // We will figure out min/max in a preprocessing step and adjust
304 // actual_transform as required.
305 float max_val = std::numeric_limits<float>::min();
306 float min_val = std::numeric_limits<float>::max();
307 for (int y = 0; y < height; ++y) {
308 SkPMColor* current_color = static_cast<uint32_t*>(
309 source_bitmap.getAddr32(0, y));
310 for (int x = 0; x < width; ++x, ++current_color) {
311 SkColor c = SkUnPreMultiply::PMColorToColor(*current_color);
312 float r = SkColorGetR(c);
313 float g = SkColorGetG(c);
314 float b = SkColorGetB(c);
315 float gray_level = gfx::DotProduct(color_transform, r, g, b);
316 max_val = std::max(max_val, gray_level);
317 min_val = std::min(min_val, gray_level);
318 }
319 }
320
321 // Adjust the transform so that the result is scalling.
322 a0 = -min_val;
323 if (max_val > min_val)
324 scale = 255.0 / (max_val - min_val);
325 else
326 scale = 0.0; // If min==max, uniform 0-level image is expected.
327 }
328
329 for (int y = 0; y < height; ++y) {
330 SkPMColor* current_color = static_cast<uint32_t*>(
331 source_bitmap.getAddr32(0, y));
332 uint8_t* target_color = target_bitmap->getAddr8(0, y);
333 for (int x = 0; x < width; ++x, ++current_color) {
334 SkColor c = SkUnPreMultiply::PMColorToColor(*current_color);
335 float r = SkColorGetR(c);
336 float g = SkColorGetG(c);
337 float b = SkColorGetB(c);
338
339 float gl = (a0 + gfx::DotProduct(color_transform, r, g, b)) * scale;
340 if (gl < 0)
341 gl = 0;
342 if (gl > 0xFF)
343 gl = 0xFF;
344 target_color[x] = static_cast<uint8_t>(gl);
345 }
346 }
347
348 return result_rect;
349 }
350
351 bool ComputePrincipalComponentImage(const SkBitmap& source_bitmap,
352 SkBitmap* target_bitmap) {
353 if (!target_bitmap) {
354 NOTREACHED();
355 return false;
356 }
357
358 gfx::Matrix3F covariance = ComputeColorCovariance(source_bitmap);
359 gfx::Matrix3F eigenvectors = gfx::Matrix3F::Zeros();
360 gfx::Vector3dF eigenvals = covariance.SolveEigenproblem(&eigenvectors);
361 gfx::Vector3dF principal = eigenvectors.get_column(0);
362 if (eigenvals == gfx::Vector3dF() || principal == gfx::Vector3dF())
363 return false; // This may happen for some edge cases.
364 gfx::Rect result_rect = ApplyColorReduction(
365 source_bitmap, principal, true, target_bitmap);
366 return !result_rect.IsEmpty();
367 }
368
264 } // namespace color_utils 369 } // namespace color_utils
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698