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

Side by Side Diff: skia/ext/image_operations.cc

Issue 100097: Reverting 14712. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 8 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 | « skia/ext/image_operations.h ('k') | skia/ext/image_operations_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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 #define _USE_MATH_DEFINES 5 #define _USE_MATH_DEFINES
6 #include <cmath> 6 #include <cmath>
7 #include <limits> 7 #include <limits>
8 #include <vector> 8 #include <vector>
9 9
10 #include "skia/ext/image_operations.h" 10 #include "skia/ext/image_operations.h"
11 11
12 #include "base/gfx/rect.h" 12 #include "base/gfx/rect.h"
13 #include "base/gfx/size.h" 13 #include "base/gfx/size.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/stack_container.h" 15 #include "base/stack_container.h"
16 #include "SkBitmap.h" 16 #include "SkBitmap.h"
17 #include "skia/ext/convolver.h" 17 #include "skia/ext/convolver.h"
18 #include "skia/include/SkColorPriv.h"
19 #include "skia/ext/skia_utils.h"
20 18
21 namespace skia { 19 namespace skia {
22 20
23 // TODO(brettw) remove this and put this file in the skia namespace. 21 // TODO(brettw) remove this and put this file in the skia namespace.
24 using namespace gfx; 22 using namespace gfx;
25 23
26 namespace { 24 namespace {
27 25
28 // Returns the ceiling/floor as an integer. 26 // Returns the ceiling/floor as an integer.
29 inline int CeilInt(float val) { 27 inline int CeilInt(float val) {
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 256
259 // static 257 // static
260 SkBitmap ImageOperations::Resize(const SkBitmap& source, 258 SkBitmap ImageOperations::Resize(const SkBitmap& source,
261 ResizeMethod method, 259 ResizeMethod method,
262 int dest_width, int dest_height, 260 int dest_width, int dest_height,
263 const gfx::Rect& dest_subset) { 261 const gfx::Rect& dest_subset) {
264 DCHECK(gfx::Rect(dest_width, dest_height).Contains(dest_subset)) << 262 DCHECK(gfx::Rect(dest_width, dest_height).Contains(dest_subset)) <<
265 "The supplied subset does not fall within the destination image."; 263 "The supplied subset does not fall within the destination image.";
266 264
267 // If the size of source or destination is 0, i.e. 0x0, 0xN or Nx0, just 265 // If the size of source or destination is 0, i.e. 0x0, 0xN or Nx0, just
268 // return empty. 266 // return empty
269 if (source.width() < 1 || source.height() < 1 || 267 if (source.width() < 1 || source.height() < 1 ||
270 dest_width < 1 || dest_height < 1) 268 dest_width < 1 || dest_height < 1)
271 return SkBitmap(); 269 return SkBitmap();
272 270
273 SkAutoLockPixels locker(source); 271 SkAutoLockPixels locker(source);
274 272
275 ResizeFilter filter(method, source.width(), source.height(), 273 ResizeFilter filter(method, source.width(), source.height(),
276 dest_width, dest_height, dest_subset); 274 dest_width, dest_height, dest_subset);
277 275
278 // Get a source bitmap encompassing this touched area. We construct the 276 // Get a source bitmap encompassing this touched area. We construct the
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 double alpha) { 308 double alpha) {
311 DCHECK(alpha <= 1 && alpha >= 0); 309 DCHECK(alpha <= 1 && alpha >= 0);
312 DCHECK(first.width() == second.width()); 310 DCHECK(first.width() == second.width());
313 DCHECK(first.height() == second.height()); 311 DCHECK(first.height() == second.height());
314 DCHECK(first.bytesPerPixel() == second.bytesPerPixel()); 312 DCHECK(first.bytesPerPixel() == second.bytesPerPixel());
315 DCHECK(first.config() == SkBitmap::kARGB_8888_Config); 313 DCHECK(first.config() == SkBitmap::kARGB_8888_Config);
316 314
317 // Optimize for case where we won't need to blend anything. 315 // Optimize for case where we won't need to blend anything.
318 static const double alpha_min = 1.0 / 255; 316 static const double alpha_min = 1.0 / 255;
319 static const double alpha_max = 254.0 / 255; 317 static const double alpha_max = 254.0 / 255;
320 if (alpha < alpha_min) 318 if (alpha < alpha_min) {
321 return first; 319 return first;
322 else if (alpha > alpha_max) 320 } else if (alpha > alpha_max) {
323 return second; 321 return second;
322 }
324 323
325 SkAutoLockPixels lock_first(first); 324 SkAutoLockPixels lock_first(first);
326 SkAutoLockPixels lock_second(second); 325 SkAutoLockPixels lock_second(second);
327 326
328 SkBitmap blended; 327 SkBitmap blended;
329 blended.setConfig(SkBitmap::kARGB_8888_Config, first.width(), 328 blended.setConfig(SkBitmap::kARGB_8888_Config, first.width(),
330 first.height(), 0); 329 first.height(), 0);
331 blended.allocPixels(); 330 blended.allocPixels();
332 blended.eraseARGB(0, 0, 0, 0); 331 blended.eraseARGB(0, 0, 0, 0);
333 332
(...skipping 21 matching lines...) Expand all
355 SkColorGetB(first_pixel) * first_alpha + 354 SkColorGetB(first_pixel) * first_alpha +
356 SkColorGetB(second_pixel) * alpha); 355 SkColorGetB(second_pixel) * alpha);
357 356
358 dst_row[x] = SkColorSetARGB(a, r, g, b); 357 dst_row[x] = SkColorSetARGB(a, r, g, b);
359 } 358 }
360 } 359 }
361 360
362 return blended; 361 return blended;
363 } 362 }
364 363
365 // static
366 SkBitmap ImageOperations::CreateMaskedBitmap(const SkBitmap& rgb,
367 const SkBitmap& alpha) {
368 DCHECK(rgb.width() == alpha.width());
369 DCHECK(rgb.height() == alpha.height());
370 DCHECK(rgb.bytesPerPixel() == alpha.bytesPerPixel());
371 DCHECK(rgb.config() == SkBitmap::kARGB_8888_Config);
372 DCHECK(alpha.config() == SkBitmap::kARGB_8888_Config);
373
374 SkBitmap masked;
375 masked.setConfig(SkBitmap::kARGB_8888_Config, rgb.width(), rgb.height(), 0);
376 masked.allocPixels();
377 masked.eraseARGB(0, 0, 0, 0);
378
379 SkAutoLockPixels lock_rgb(rgb);
380 SkAutoLockPixels lock_alpha(alpha);
381 SkAutoLockPixels lock_masked(masked);
382
383 for (int y = 0; y < rgb.height(); y++) {
384 uint32* rgb_row = rgb.getAddr32(0, y);
385 uint32* alpha_row = alpha.getAddr32(0, y);
386 uint32* dst_row = masked.getAddr32(0, y);
387
388 for (int x = 0; x < rgb.width(); x++) {
389 uint32 alpha_pixel = alpha_row[x];
390 uint32 rgb_pixel = rgb_row[x];
391
392 int alpha = SkColorGetA(alpha_pixel);
393 dst_row[x] = SkColorSetARGB(alpha,
394 SkAlphaMul(SkColorGetR(rgb_pixel), alpha),
395 SkAlphaMul(SkColorGetG(rgb_pixel), alpha),
396 SkAlphaMul(SkColorGetB(rgb_pixel), alpha));
397 }
398 }
399
400 return masked;
401 }
402
403 SkBitmap ImageOperations::CreateBlurredBitmap(const SkBitmap& bitmap,
404 int blur_amount ) {
405 DCHECK(bitmap.config() == SkBitmap::kARGB_8888_Config);
406
407 // Blur factor (1 divided by how many pixels the blur takes place over).
408 double v = 1.0 / pow(static_cast<double>(blur_amount * 2 + 1), 2);
409
410 SkBitmap blurred;
411 blurred.setConfig(SkBitmap::kARGB_8888_Config, bitmap.width(),
412 bitmap.height(), 0);
413 blurred.allocPixels();
414 blurred.eraseARGB(0, 0, 0, 0);
415
416 SkAutoLockPixels lock_bitmap(bitmap);
417 SkAutoLockPixels lock_blurred(blurred);
418
419 // Loop through every pixel in the image.
420 for (int y = 0; y < bitmap.height(); y++) { // Skip top and bottom edges.
421 uint32* dst_row = blurred.getAddr32(0, y);
422
423 for (int x = 0; x < bitmap.width(); x++) { // Skip left and right edges.
424 // Sums for this pixel.
425 double a = 0;
426 double r = 0;
427 double g = 0;
428 double b = 0;
429
430 for (int ky = -blur_amount; ky <= blur_amount; ky++) {
431 for (int kx = -blur_amount; kx <= blur_amount; kx++) {
432 // Calculate the adjacent pixel for this kernel point. Blurs
433 // are wrapped.
434 int bx = (x + kx) % bitmap.width();
435 while (bx < 0)
436 bx += bitmap.width();
437 int by = (y + ky) % bitmap.height();
438 while (by < 0)
439 by += bitmap.height();
440
441 uint32 src_pixel = bitmap.getAddr32(0, by)[bx];
442
443 a += v * static_cast<double>(SkColorGetA(src_pixel));
444 r += v * static_cast<double>(SkColorGetR(src_pixel));
445 g += v * static_cast<double>(SkColorGetG(src_pixel));
446 b += v * static_cast<double>(SkColorGetB(src_pixel));
447 }
448 }
449
450 dst_row[x] = SkColorSetARGB(
451 static_cast<int>(a),
452 static_cast<int>(r),
453 static_cast<int>(g),
454 static_cast<int>(b));
455 }
456 }
457
458 return blurred;
459 }
460
461 // static
462 SkBitmap ImageOperations::CreateHSLShiftedBitmap(const SkBitmap& bitmap,
463 float hsl_shift[3]) {
464 DCHECK(bitmap.config() == SkBitmap::kARGB_8888_Config);
465
466 SkBitmap shifted;
467 shifted.setConfig(SkBitmap::kARGB_8888_Config, bitmap.width(),
468 bitmap.height(), 0);
469 shifted.allocPixels();
470 shifted.eraseARGB(0, 0, 0, 0);
471 shifted.setIsOpaque(false);
472
473 SkAutoLockPixels lock_bitmap(bitmap);
474 SkAutoLockPixels lock_shifted(shifted);
475
476 // Loop through the pixels of the original bitmap.
477 for (int y = 0; y < bitmap.height(); y++) {
478 SkColor* pixels = bitmap.getAddr32(0, y);
479 SkColor* tinted_pixels = shifted.getAddr32(0, y);
480
481 for (int x = 0; x < bitmap.width(); x++) {
482 // Convert the color of this pixel to HSL.
483 SkPMColor color = pixels[x];
484 int alpha = SkColorGetA(color);
485 if (alpha != 255) {
486 // We have to normalize the colors as they're pre-multiplied.
487 double r = SkColorGetR(color) / static_cast<double>(alpha);
488 double g = SkColorGetG(color) / static_cast<double>(alpha);
489 double b = SkColorGetB(color) / static_cast<double>(alpha);
490 color = SkColorSetARGB(255,
491 static_cast<int>(r * 255.0),
492 static_cast<int>(g * 255.0),
493 static_cast<int>(b * 255.0));
494 }
495
496 float pixel_hsl[3];
497 SkColorToHSL(color, pixel_hsl);
498
499 // Replace the hue with the tint's hue.
500 if (hsl_shift[0] >= 0)
501 pixel_hsl[0] = hsl_shift[0];
502
503 // Change the saturation.
504 if (hsl_shift[1] >= 0) {
505 if (hsl_shift[1] <= 0.5) {
506 pixel_hsl[1] *= hsl_shift[1] * 2.0;
507 } else {
508 pixel_hsl[1] = pixel_hsl[1] + (1.0 - pixel_hsl[1]) *
509 ((hsl_shift[1] - 0.5) * 2.0);
510 }
511 }
512
513 // Change the lightness.
514 if (hsl_shift[2] >= 0) {
515 if (hsl_shift[2] <= 0.5) {
516 pixel_hsl[2] *= hsl_shift[2] * 2.0;
517 } else {
518 pixel_hsl[2] = pixel_hsl[2] + (1.0 - pixel_hsl[2]) *
519 ((hsl_shift[2] - 0.5) * 2.0);
520 }
521 }
522
523 // Convert back to RGB.
524 tinted_pixels[x] = HSLToSKColor(alpha, pixel_hsl);
525 }
526 }
527
528 return shifted;
529 }
530
531 // static
532 SkBitmap ImageOperations::CreateTiledBitmap(const SkBitmap& source,
533 int src_x, int src_y,
534 int dst_w, int dst_h) {
535 DCHECK(source.getConfig() == SkBitmap::kARGB_8888_Config);
536
537 SkBitmap cropped;
538 cropped.setConfig(SkBitmap::kARGB_8888_Config, dst_w, dst_h, 0);
539 cropped.allocPixels();
540 cropped.eraseARGB(0, 0, 0, 0);
541
542 SkAutoLockPixels lock_source(source);
543 SkAutoLockPixels lock_cropped(cropped);
544
545 // Loop through the pixels of the original bitmap.
546 for (int y = 0; y < dst_h; y++) {
547 int y_pix = (src_y + y) % source.height();
548 while (y_pix < 0)
549 y_pix += source.height();
550
551 uint32* source_row = source.getAddr32(0, y_pix);
552 uint32* dst_row = cropped.getAddr32(0, y);
553
554 for (int x = 0; x < dst_w; x++) {
555 int x_pix = (src_x + x) % source.width();
556 while (x_pix < 0)
557 x_pix += source.width();
558
559 dst_row[x] = source_row[x_pix];
560 }
561 }
562
563 return cropped;
564 }
565
566 } // namespace skia 364 } // namespace skia
567 365
OLDNEW
« no previous file with comments | « skia/ext/image_operations.h ('k') | skia/ext/image_operations_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698