OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2008 The Android Open Source Project | 3 * Copyright 2008 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 if (!bm.requestLock(&result)) { | 659 if (!bm.requestLock(&result)) { |
660 return false; | 660 return false; |
661 } | 661 } |
662 return compute_is_opaque(result.pixmap()); | 662 return compute_is_opaque(result.pixmap()); |
663 } | 663 } |
664 | 664 |
665 | 665 |
666 /////////////////////////////////////////////////////////////////////////////// | 666 /////////////////////////////////////////////////////////////////////////////// |
667 /////////////////////////////////////////////////////////////////////////////// | 667 /////////////////////////////////////////////////////////////////////////////// |
668 | 668 |
669 void SkBitmap::erase(SkColor c, const SkIRect& area) const { | 669 static uint16_t pack_8888_to_4444(unsigned a, unsigned r, unsigned g, unsigned b
) { |
| 670 unsigned pixel = (SkA32To4444(a) << SK_A4444_SHIFT) | |
| 671 (SkR32To4444(r) << SK_R4444_SHIFT) | |
| 672 (SkG32To4444(g) << SK_G4444_SHIFT) | |
| 673 (SkB32To4444(b) << SK_B4444_SHIFT); |
| 674 return SkToU16(pixel); |
| 675 } |
| 676 |
| 677 static bool internal_erase(const SkPixmap& pmap, const SkIRect& area, |
| 678 U8CPU a, U8CPU r, U8CPU g, U8CPU b) { |
| 679 int height = area.height(); |
| 680 const int width = area.width(); |
| 681 const int rowBytes = pmap.rowBytes(); |
| 682 |
| 683 switch (pmap.colorType()) { |
| 684 case kGray_8_SkColorType: { |
| 685 if (255 != a) { |
| 686 r = SkMulDiv255Round(r, a); |
| 687 g = SkMulDiv255Round(g, a); |
| 688 b = SkMulDiv255Round(b, a); |
| 689 } |
| 690 int gray = SkComputeLuminance(r, g, b); |
| 691 uint8_t* p = pmap.writable_addr8(area.fLeft, area.fTop); |
| 692 while (--height >= 0) { |
| 693 memset(p, gray, width); |
| 694 p += rowBytes; |
| 695 } |
| 696 break; |
| 697 } |
| 698 case kAlpha_8_SkColorType: { |
| 699 uint8_t* p = pmap.writable_addr8(area.fLeft, area.fTop); |
| 700 while (--height >= 0) { |
| 701 memset(p, a, width); |
| 702 p += rowBytes; |
| 703 } |
| 704 break; |
| 705 } |
| 706 case kARGB_4444_SkColorType: |
| 707 case kRGB_565_SkColorType: { |
| 708 uint16_t* p = pmap.writable_addr16(area.fLeft, area.fTop); |
| 709 uint16_t v; |
| 710 |
| 711 // make rgb premultiplied |
| 712 if (255 != a) { |
| 713 r = SkAlphaMul(r, a); |
| 714 g = SkAlphaMul(g, a); |
| 715 b = SkAlphaMul(b, a); |
| 716 } |
| 717 |
| 718 if (kARGB_4444_SkColorType == pmap.colorType()) { |
| 719 v = pack_8888_to_4444(a, r, g, b); |
| 720 } else { |
| 721 v = SkPackRGB16(r >> (8 - SK_R16_BITS), |
| 722 g >> (8 - SK_G16_BITS), |
| 723 b >> (8 - SK_B16_BITS)); |
| 724 } |
| 725 while (--height >= 0) { |
| 726 sk_memset16(p, v, width); |
| 727 p = (uint16_t*)((char*)p + rowBytes); |
| 728 } |
| 729 break; |
| 730 } |
| 731 case kBGRA_8888_SkColorType: |
| 732 case kRGBA_8888_SkColorType: { |
| 733 uint32_t* p = pmap.writable_addr32(area.fLeft, area.fTop); |
| 734 |
| 735 if (255 != a && kPremul_SkAlphaType == pmap.alphaType()) { |
| 736 r = SkAlphaMul(r, a); |
| 737 g = SkAlphaMul(g, a); |
| 738 b = SkAlphaMul(b, a); |
| 739 } |
| 740 uint32_t v = kRGBA_8888_SkColorType == pmap.colorType() ? |
| 741 SkPackARGB_as_RGBA(a, r, g, b) : SkPackARGB_as_BGRA(a, r, g, b); |
| 742 |
| 743 while (--height >= 0) { |
| 744 sk_memset32(p, v, width); |
| 745 p = (uint32_t*)((char*)p + rowBytes); |
| 746 } |
| 747 break; |
| 748 } |
| 749 default: |
| 750 return false; // no change, so don't call notifyPixelsChanged() |
| 751 } |
| 752 return true; |
| 753 } |
| 754 |
| 755 void SkBitmap::internalErase(const SkIRect& area, U8CPU a, U8CPU r, U8CPU g, U8C
PU b) const { |
| 756 #ifdef SK_DEBUG |
670 SkDEBUGCODE(this->validate();) | 757 SkDEBUGCODE(this->validate();) |
| 758 SkASSERT(!area.isEmpty()); |
| 759 { |
| 760 SkIRect total = { 0, 0, this->width(), this->height() }; |
| 761 SkASSERT(total.contains(area)); |
| 762 } |
| 763 #endif |
671 | 764 |
672 switch (fInfo.colorType()) { | 765 switch (fInfo.colorType()) { |
673 case kUnknown_SkColorType: | 766 case kUnknown_SkColorType: |
674 case kIndex_8_SkColorType: | 767 case kIndex_8_SkColorType: |
675 // TODO: can we ASSERT that we never get here? | 768 // TODO: can we ASSERT that we never get here? |
676 return; // can't erase. Should we bzero so the memory is not uniniti
alized? | 769 return; // can't erase. Should we bzero so the memory is not uniniti
alized? |
677 default: | 770 default: |
678 break; | 771 break; |
679 } | 772 } |
680 | 773 |
681 SkAutoPixmapUnlock result; | 774 SkAutoPixmapUnlock result; |
682 if (!this->requestLock(&result)) { | 775 if (!this->requestLock(&result)) { |
683 return; | 776 return; |
684 } | 777 } |
685 | 778 |
686 if (result.pixmap().erase(c, area)) { | 779 if (internal_erase(result.pixmap(), area, a, r, g, b)) { |
687 this->notifyPixelsChanged(); | 780 this->notifyPixelsChanged(); |
688 } | 781 } |
689 } | 782 } |
690 | 783 |
691 void SkBitmap::eraseColor(SkColor c) const { | 784 void SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { |
692 this->erase(c, SkIRect::MakeWH(this->width(), this->height())); | 785 SkIRect area = { 0, 0, this->width(), this->height() }; |
| 786 if (!area.isEmpty()) { |
| 787 this->internalErase(area, a, r, g, b); |
| 788 } |
| 789 } |
| 790 |
| 791 void SkBitmap::eraseArea(const SkIRect& rect, SkColor c) const { |
| 792 SkIRect area = { 0, 0, this->width(), this->height() }; |
| 793 if (area.intersect(rect)) { |
| 794 this->internalErase(area, SkColorGetA(c), SkColorGetR(c), |
| 795 SkColorGetG(c), SkColorGetB(c)); |
| 796 } |
693 } | 797 } |
694 | 798 |
695 ////////////////////////////////////////////////////////////////////////////////
////// | 799 ////////////////////////////////////////////////////////////////////////////////
////// |
696 ////////////////////////////////////////////////////////////////////////////////
////// | 800 ////////////////////////////////////////////////////////////////////////////////
////// |
697 | 801 |
698 bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const { | 802 bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const { |
699 SkDEBUGCODE(this->validate();) | 803 SkDEBUGCODE(this->validate();) |
700 | 804 |
701 if (NULL == result || NULL == fPixelRef) { | 805 if (NULL == result || NULL == fPixelRef) { |
702 return false; // no src pixels | 806 return false; // no src pixels |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1297 /////////////////////////////////////////////////////////////////////////////// | 1401 /////////////////////////////////////////////////////////////////////////////// |
1298 | 1402 |
1299 #ifdef SK_DEBUG | 1403 #ifdef SK_DEBUG |
1300 void SkImageInfo::validate() const { | 1404 void SkImageInfo::validate() const { |
1301 SkASSERT(fWidth >= 0); | 1405 SkASSERT(fWidth >= 0); |
1302 SkASSERT(fHeight >= 0); | 1406 SkASSERT(fHeight >= 0); |
1303 SkASSERT(SkColorTypeIsValid(fColorType)); | 1407 SkASSERT(SkColorTypeIsValid(fColorType)); |
1304 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); | 1408 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); |
1305 } | 1409 } |
1306 #endif | 1410 #endif |
OLD | NEW |