| OLD | NEW |
| 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/skbitmap_operations.h" | 5 #include "ui/gfx/skbitmap_operations.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 #include <algorithm> | 10 #include <algorithm> |
| 11 | 11 |
| 12 #include "base/logging.h" | 12 #include "base/logging.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/SkCanvas.h" | 14 #include "third_party/skia/include/core/SkCanvas.h" |
| 15 #include "third_party/skia/include/core/SkColorFilter.h" | 15 #include "third_party/skia/include/core/SkColorFilter.h" |
| 16 #include "third_party/skia/include/core/SkColorPriv.h" | 16 #include "third_party/skia/include/core/SkColorPriv.h" |
| 17 #include "third_party/skia/include/core/SkUnPreMultiply.h" | 17 #include "third_party/skia/include/core/SkUnPreMultiply.h" |
| 18 #include "third_party/skia/include/effects/SkBlurImageFilter.h" | 18 #include "third_party/skia/include/effects/SkBlurImageFilter.h" |
| 19 #include "ui/gfx/geometry/insets.h" | 19 #include "ui/gfx/geometry/insets.h" |
| 20 #include "ui/gfx/geometry/point.h" | 20 #include "ui/gfx/geometry/point.h" |
| 21 #include "ui/gfx/geometry/size.h" | 21 #include "ui/gfx/geometry/size.h" |
| 22 | 22 |
| 23 // static | 23 // static |
| 24 SkBitmap SkBitmapOperations::CreateInvertedBitmap(const SkBitmap& image) { | 24 SkBitmap SkBitmapOperations::CreateInvertedBitmap(const SkBitmap& image) { |
| 25 DCHECK(image.colorType() == kN32_SkColorType); | 25 DCHECK(image.colorType() == kN32_SkColorType); |
| 26 | 26 |
| 27 SkAutoLockPixels lock_image(image); | |
| 28 | |
| 29 SkBitmap inverted; | 27 SkBitmap inverted; |
| 30 inverted.allocN32Pixels(image.width(), image.height()); | 28 inverted.allocN32Pixels(image.width(), image.height()); |
| 31 | 29 |
| 32 for (int y = 0; y < image.height(); ++y) { | 30 for (int y = 0; y < image.height(); ++y) { |
| 33 uint32_t* image_row = image.getAddr32(0, y); | 31 uint32_t* image_row = image.getAddr32(0, y); |
| 34 uint32_t* dst_row = inverted.getAddr32(0, y); | 32 uint32_t* dst_row = inverted.getAddr32(0, y); |
| 35 | 33 |
| 36 for (int x = 0; x < image.width(); ++x) { | 34 for (int x = 0; x < image.width(); ++x) { |
| 37 uint32_t image_pixel = image_row[x]; | 35 uint32_t image_pixel = image_row[x]; |
| 38 dst_row[x] = (image_pixel & 0xFF000000) | | 36 dst_row[x] = (image_pixel & 0xFF000000) | |
| (...skipping 15 matching lines...) Expand all Loading... |
| 54 DCHECK(first.colorType() == kN32_SkColorType); | 52 DCHECK(first.colorType() == kN32_SkColorType); |
| 55 | 53 |
| 56 // Optimize for case where we won't need to blend anything. | 54 // Optimize for case where we won't need to blend anything. |
| 57 static const double alpha_min = 1.0 / 255; | 55 static const double alpha_min = 1.0 / 255; |
| 58 static const double alpha_max = 254.0 / 255; | 56 static const double alpha_max = 254.0 / 255; |
| 59 if (alpha < alpha_min) | 57 if (alpha < alpha_min) |
| 60 return first; | 58 return first; |
| 61 else if (alpha > alpha_max) | 59 else if (alpha > alpha_max) |
| 62 return second; | 60 return second; |
| 63 | 61 |
| 64 SkAutoLockPixels lock_first(first); | |
| 65 SkAutoLockPixels lock_second(second); | |
| 66 | |
| 67 SkBitmap blended; | 62 SkBitmap blended; |
| 68 blended.allocN32Pixels(first.width(), first.height()); | 63 blended.allocN32Pixels(first.width(), first.height()); |
| 69 | 64 |
| 70 double first_alpha = 1 - alpha; | 65 double first_alpha = 1 - alpha; |
| 71 | 66 |
| 72 for (int y = 0; y < first.height(); ++y) { | 67 for (int y = 0; y < first.height(); ++y) { |
| 73 uint32_t* first_row = first.getAddr32(0, y); | 68 uint32_t* first_row = first.getAddr32(0, y); |
| 74 uint32_t* second_row = second.getAddr32(0, y); | 69 uint32_t* second_row = second.getAddr32(0, y); |
| 75 uint32_t* dst_row = blended.getAddr32(0, y); | 70 uint32_t* dst_row = blended.getAddr32(0, y); |
| 76 | 71 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 99 const SkBitmap& alpha) { | 94 const SkBitmap& alpha) { |
| 100 DCHECK(rgb.width() == alpha.width()); | 95 DCHECK(rgb.width() == alpha.width()); |
| 101 DCHECK(rgb.height() == alpha.height()); | 96 DCHECK(rgb.height() == alpha.height()); |
| 102 DCHECK(rgb.bytesPerPixel() == alpha.bytesPerPixel()); | 97 DCHECK(rgb.bytesPerPixel() == alpha.bytesPerPixel()); |
| 103 DCHECK(rgb.colorType() == kN32_SkColorType); | 98 DCHECK(rgb.colorType() == kN32_SkColorType); |
| 104 DCHECK(alpha.colorType() == kN32_SkColorType); | 99 DCHECK(alpha.colorType() == kN32_SkColorType); |
| 105 | 100 |
| 106 SkBitmap masked; | 101 SkBitmap masked; |
| 107 masked.allocN32Pixels(rgb.width(), rgb.height()); | 102 masked.allocN32Pixels(rgb.width(), rgb.height()); |
| 108 | 103 |
| 109 SkAutoLockPixels lock_rgb(rgb); | |
| 110 SkAutoLockPixels lock_alpha(alpha); | |
| 111 SkAutoLockPixels lock_masked(masked); | |
| 112 | |
| 113 for (int y = 0; y < masked.height(); ++y) { | 104 for (int y = 0; y < masked.height(); ++y) { |
| 114 uint32_t* rgb_row = rgb.getAddr32(0, y); | 105 uint32_t* rgb_row = rgb.getAddr32(0, y); |
| 115 uint32_t* alpha_row = alpha.getAddr32(0, y); | 106 uint32_t* alpha_row = alpha.getAddr32(0, y); |
| 116 uint32_t* dst_row = masked.getAddr32(0, y); | 107 uint32_t* dst_row = masked.getAddr32(0, y); |
| 117 | 108 |
| 118 for (int x = 0; x < masked.width(); ++x) { | 109 for (int x = 0; x < masked.width(); ++x) { |
| 119 unsigned alpha = SkGetPackedA32(alpha_row[x]); | 110 unsigned alpha = SkGetPackedA32(alpha_row[x]); |
| 120 unsigned scale = SkAlpha255To256(alpha); | 111 unsigned scale = SkAlpha255To256(alpha); |
| 121 dst_row[x] = SkAlphaMulQ(rgb_row[x], scale); | 112 dst_row[x] = SkAlphaMulQ(rgb_row[x], scale); |
| 122 } | 113 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 136 DCHECK(mask.colorType() == kN32_SkColorType); | 127 DCHECK(mask.colorType() == kN32_SkColorType); |
| 137 | 128 |
| 138 SkBitmap background; | 129 SkBitmap background; |
| 139 background.allocN32Pixels(mask.width(), mask.height()); | 130 background.allocN32Pixels(mask.width(), mask.height()); |
| 140 | 131 |
| 141 double bg_a = SkColorGetA(color); | 132 double bg_a = SkColorGetA(color); |
| 142 double bg_r = SkColorGetR(color) * (bg_a / 255.0); | 133 double bg_r = SkColorGetR(color) * (bg_a / 255.0); |
| 143 double bg_g = SkColorGetG(color) * (bg_a / 255.0); | 134 double bg_g = SkColorGetG(color) * (bg_a / 255.0); |
| 144 double bg_b = SkColorGetB(color) * (bg_a / 255.0); | 135 double bg_b = SkColorGetB(color) * (bg_a / 255.0); |
| 145 | 136 |
| 146 SkAutoLockPixels lock_mask(mask); | |
| 147 SkAutoLockPixels lock_image(image); | |
| 148 SkAutoLockPixels lock_background(background); | |
| 149 | |
| 150 for (int y = 0; y < mask.height(); ++y) { | 137 for (int y = 0; y < mask.height(); ++y) { |
| 151 uint32_t* dst_row = background.getAddr32(0, y); | 138 uint32_t* dst_row = background.getAddr32(0, y); |
| 152 uint32_t* image_row = image.getAddr32(0, y % image.height()); | 139 uint32_t* image_row = image.getAddr32(0, y % image.height()); |
| 153 uint32_t* mask_row = mask.getAddr32(0, y); | 140 uint32_t* mask_row = mask.getAddr32(0, y); |
| 154 | 141 |
| 155 for (int x = 0; x < mask.width(); ++x) { | 142 for (int x = 0; x < mask.width(); ++x) { |
| 156 uint32_t image_pixel = image_row[x % image.width()]; | 143 uint32_t image_pixel = image_row[x % image.width()]; |
| 157 | 144 |
| 158 double img_a = SkColorGetA(image_pixel); | 145 double img_a = SkColorGetA(image_pixel); |
| 159 double img_r = SkColorGetR(image_pixel); | 146 double img_r = SkColorGetR(image_pixel); |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 | 498 |
| 512 HSLShift::LineProcessor line_proc = | 499 HSLShift::LineProcessor line_proc = |
| 513 HSLShift::kLineProcessors[H_op][S_op][L_op]; | 500 HSLShift::kLineProcessors[H_op][S_op][L_op]; |
| 514 | 501 |
| 515 DCHECK(bitmap.empty() == false); | 502 DCHECK(bitmap.empty() == false); |
| 516 DCHECK(bitmap.colorType() == kN32_SkColorType); | 503 DCHECK(bitmap.colorType() == kN32_SkColorType); |
| 517 | 504 |
| 518 SkBitmap shifted; | 505 SkBitmap shifted; |
| 519 shifted.allocN32Pixels(bitmap.width(), bitmap.height()); | 506 shifted.allocN32Pixels(bitmap.width(), bitmap.height()); |
| 520 | 507 |
| 521 SkAutoLockPixels lock_bitmap(bitmap); | |
| 522 SkAutoLockPixels lock_shifted(shifted); | |
| 523 | |
| 524 // Loop through the pixels of the original bitmap. | 508 // Loop through the pixels of the original bitmap. |
| 525 for (int y = 0; y < bitmap.height(); ++y) { | 509 for (int y = 0; y < bitmap.height(); ++y) { |
| 526 SkPMColor* pixels = bitmap.getAddr32(0, y); | 510 SkPMColor* pixels = bitmap.getAddr32(0, y); |
| 527 SkPMColor* tinted_pixels = shifted.getAddr32(0, y); | 511 SkPMColor* tinted_pixels = shifted.getAddr32(0, y); |
| 528 | 512 |
| 529 (*line_proc)(hsl_shift, pixels, tinted_pixels, bitmap.width()); | 513 (*line_proc)(hsl_shift, pixels, tinted_pixels, bitmap.width()); |
| 530 } | 514 } |
| 531 | 515 |
| 532 return shifted; | 516 return shifted; |
| 533 } | 517 } |
| 534 | 518 |
| 535 // static | 519 // static |
| 536 SkBitmap SkBitmapOperations::CreateTiledBitmap(const SkBitmap& source, | 520 SkBitmap SkBitmapOperations::CreateTiledBitmap(const SkBitmap& source, |
| 537 int src_x, int src_y, | 521 int src_x, int src_y, |
| 538 int dst_w, int dst_h) { | 522 int dst_w, int dst_h) { |
| 539 DCHECK(source.colorType() == kN32_SkColorType); | 523 DCHECK(source.colorType() == kN32_SkColorType); |
| 540 | 524 |
| 541 SkBitmap cropped; | 525 SkBitmap cropped; |
| 542 cropped.allocN32Pixels(dst_w, dst_h); | 526 cropped.allocN32Pixels(dst_w, dst_h); |
| 543 | 527 |
| 544 SkAutoLockPixels lock_source(source); | |
| 545 SkAutoLockPixels lock_cropped(cropped); | |
| 546 | |
| 547 // Loop through the pixels of the original bitmap. | 528 // Loop through the pixels of the original bitmap. |
| 548 for (int y = 0; y < dst_h; ++y) { | 529 for (int y = 0; y < dst_h; ++y) { |
| 549 int y_pix = (src_y + y) % source.height(); | 530 int y_pix = (src_y + y) % source.height(); |
| 550 while (y_pix < 0) | 531 while (y_pix < 0) |
| 551 y_pix += source.height(); | 532 y_pix += source.height(); |
| 552 | 533 |
| 553 uint32_t* source_row = source.getAddr32(0, y_pix); | 534 uint32_t* source_row = source.getAddr32(0, y_pix); |
| 554 uint32_t* dst_row = cropped.getAddr32(0, y); | 535 uint32_t* dst_row = cropped.getAddr32(0, y); |
| 555 | 536 |
| 556 for (int x = 0; x < dst_w; ++x) { | 537 for (int x = 0; x < dst_w; ++x) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 582 | 563 |
| 583 // static | 564 // static |
| 584 SkBitmap SkBitmapOperations::DownsampleByTwo(const SkBitmap& bitmap) { | 565 SkBitmap SkBitmapOperations::DownsampleByTwo(const SkBitmap& bitmap) { |
| 585 // Handle the nop case. | 566 // Handle the nop case. |
| 586 if ((bitmap.width() <= 1) || (bitmap.height() <= 1)) | 567 if ((bitmap.width() <= 1) || (bitmap.height() <= 1)) |
| 587 return bitmap; | 568 return bitmap; |
| 588 | 569 |
| 589 SkBitmap result; | 570 SkBitmap result; |
| 590 result.allocN32Pixels((bitmap.width() + 1) / 2, (bitmap.height() + 1) / 2); | 571 result.allocN32Pixels((bitmap.width() + 1) / 2, (bitmap.height() + 1) / 2); |
| 591 | 572 |
| 592 SkAutoLockPixels lock(bitmap); | |
| 593 | |
| 594 const int resultLastX = result.width() - 1; | 573 const int resultLastX = result.width() - 1; |
| 595 const int srcLastX = bitmap.width() - 1; | 574 const int srcLastX = bitmap.width() - 1; |
| 596 | 575 |
| 597 for (int dest_y = 0; dest_y < result.height(); ++dest_y) { | 576 for (int dest_y = 0; dest_y < result.height(); ++dest_y) { |
| 598 const int src_y = dest_y << 1; | 577 const int src_y = dest_y << 1; |
| 599 const SkPMColor* SK_RESTRICT cur_src0 = bitmap.getAddr32(0, src_y); | 578 const SkPMColor* SK_RESTRICT cur_src0 = bitmap.getAddr32(0, src_y); |
| 600 const SkPMColor* SK_RESTRICT cur_src1 = cur_src0; | 579 const SkPMColor* SK_RESTRICT cur_src1 = cur_src0; |
| 601 if (src_y + 1 < bitmap.height()) | 580 if (src_y + 1 < bitmap.height()) |
| 602 cur_src1 = bitmap.getAddr32(0, src_y + 1); | 581 cur_src1 = bitmap.getAddr32(0, src_y + 1); |
| 603 | 582 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 if (bitmap.isNull()) | 629 if (bitmap.isNull()) |
| 651 return bitmap; | 630 return bitmap; |
| 652 if (bitmap.isOpaque()) | 631 if (bitmap.isOpaque()) |
| 653 return bitmap; | 632 return bitmap; |
| 654 | 633 |
| 655 const SkImageInfo& opaque_info = | 634 const SkImageInfo& opaque_info = |
| 656 bitmap.info().makeAlphaType(kOpaque_SkAlphaType); | 635 bitmap.info().makeAlphaType(kOpaque_SkAlphaType); |
| 657 SkBitmap opaque_bitmap; | 636 SkBitmap opaque_bitmap; |
| 658 opaque_bitmap.allocPixels(opaque_info); | 637 opaque_bitmap.allocPixels(opaque_info); |
| 659 | 638 |
| 660 { | 639 for (int y = 0; y < opaque_bitmap.height(); y++) { |
| 661 SkAutoLockPixels bitmap_lock(bitmap); | 640 for (int x = 0; x < opaque_bitmap.width(); x++) { |
| 662 SkAutoLockPixels opaque_bitmap_lock(opaque_bitmap); | 641 uint32_t src_pixel = *bitmap.getAddr32(x, y); |
| 663 for (int y = 0; y < opaque_bitmap.height(); y++) { | 642 uint32_t* dst_pixel = opaque_bitmap.getAddr32(x, y); |
| 664 for (int x = 0; x < opaque_bitmap.width(); x++) { | 643 SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(src_pixel); |
| 665 uint32_t src_pixel = *bitmap.getAddr32(x, y); | 644 *dst_pixel = unmultiplied; |
| 666 uint32_t* dst_pixel = opaque_bitmap.getAddr32(x, y); | |
| 667 SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(src_pixel); | |
| 668 *dst_pixel = unmultiplied; | |
| 669 } | |
| 670 } | 645 } |
| 671 } | 646 } |
| 672 | 647 |
| 673 return opaque_bitmap; | 648 return opaque_bitmap; |
| 674 } | 649 } |
| 675 | 650 |
| 676 // static | 651 // static |
| 677 SkBitmap SkBitmapOperations::CreateTransposedBitmap(const SkBitmap& image) { | 652 SkBitmap SkBitmapOperations::CreateTransposedBitmap(const SkBitmap& image) { |
| 678 DCHECK(image.colorType() == kN32_SkColorType); | 653 DCHECK(image.colorType() == kN32_SkColorType); |
| 679 | 654 |
| 680 SkBitmap transposed; | 655 SkBitmap transposed; |
| 681 transposed.allocN32Pixels(image.height(), image.width()); | 656 transposed.allocN32Pixels(image.height(), image.width()); |
| 682 | 657 |
| 683 SkAutoLockPixels lock_image(image); | |
| 684 SkAutoLockPixels lock_transposed(transposed); | |
| 685 | |
| 686 for (int y = 0; y < image.height(); ++y) { | 658 for (int y = 0; y < image.height(); ++y) { |
| 687 uint32_t* image_row = image.getAddr32(0, y); | 659 uint32_t* image_row = image.getAddr32(0, y); |
| 688 for (int x = 0; x < image.width(); ++x) { | 660 for (int x = 0; x < image.width(); ++x) { |
| 689 uint32_t* dst = transposed.getAddr32(y, x); | 661 uint32_t* dst = transposed.getAddr32(y, x); |
| 690 *dst = image_row[x]; | 662 *dst = image_row[x]; |
| 691 } | 663 } |
| 692 } | 664 } |
| 693 | 665 |
| 694 return transposed; | 666 return transposed; |
| 695 } | 667 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 canvas.translate(SkFloatToScalar(result.width() * 0.5f), | 755 canvas.translate(SkFloatToScalar(result.width() * 0.5f), |
| 784 SkFloatToScalar(result.height() * 0.5f)); | 756 SkFloatToScalar(result.height() * 0.5f)); |
| 785 canvas.rotate(angle); | 757 canvas.rotate(angle); |
| 786 canvas.translate(-SkFloatToScalar(source.width() * 0.5f), | 758 canvas.translate(-SkFloatToScalar(source.width() * 0.5f), |
| 787 -SkFloatToScalar(source.height() * 0.5f)); | 759 -SkFloatToScalar(source.height() * 0.5f)); |
| 788 canvas.drawBitmap(source, 0, 0); | 760 canvas.drawBitmap(source, 0, 0); |
| 789 canvas.flush(); | 761 canvas.flush(); |
| 790 | 762 |
| 791 return result; | 763 return result; |
| 792 } | 764 } |
| OLD | NEW |