| 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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 | 154 |
| 155 void SkBitmap::reset() { | 155 void SkBitmap::reset() { |
| 156 this->freePixels(); | 156 this->freePixels(); |
| 157 sk_bzero(this, sizeof(*this)); | 157 sk_bzero(this, sizeof(*this)); |
| 158 } | 158 } |
| 159 | 159 |
| 160 int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) { | 160 int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) { |
| 161 int bpp; | 161 int bpp; |
| 162 switch (config) { | 162 switch (config) { |
| 163 case kNo_Config: | 163 case kNo_Config: |
| 164 case kA1_Config: | |
| 165 bpp = 0; // not applicable | 164 bpp = 0; // not applicable |
| 166 break; | 165 break; |
| 167 case kA8_Config: | 166 case kA8_Config: |
| 168 case kIndex8_Config: | 167 case kIndex8_Config: |
| 169 bpp = 1; | 168 bpp = 1; |
| 170 break; | 169 break; |
| 171 case kRGB_565_Config: | 170 case kRGB_565_Config: |
| 172 case kARGB_4444_Config: | 171 case kARGB_4444_Config: |
| 173 bpp = 2; | 172 bpp = 2; |
| 174 break; | 173 break; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 187 if (width < 0) { | 186 if (width < 0) { |
| 188 return 0; | 187 return 0; |
| 189 } | 188 } |
| 190 | 189 |
| 191 Sk64 rowBytes; | 190 Sk64 rowBytes; |
| 192 rowBytes.setZero(); | 191 rowBytes.setZero(); |
| 193 | 192 |
| 194 switch (c) { | 193 switch (c) { |
| 195 case kNo_Config: | 194 case kNo_Config: |
| 196 break; | 195 break; |
| 197 case kA1_Config: | |
| 198 rowBytes.set(width); | |
| 199 rowBytes.add(7); | |
| 200 rowBytes.shiftRight(3); | |
| 201 break; | |
| 202 case kA8_Config: | 196 case kA8_Config: |
| 203 case kIndex8_Config: | 197 case kIndex8_Config: |
| 204 rowBytes.set(width); | 198 rowBytes.set(width); |
| 205 break; | 199 break; |
| 206 case kRGB_565_Config: | 200 case kRGB_565_Config: |
| 207 case kARGB_4444_Config: | 201 case kARGB_4444_Config: |
| 208 rowBytes.set(width); | 202 rowBytes.set(width); |
| 209 rowBytes.shiftLeft(1); | 203 rowBytes.shiftLeft(1); |
| 210 break; | 204 break; |
| 211 case kARGB_8888_Config: | 205 case kARGB_8888_Config: |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 } | 262 } |
| 269 | 263 |
| 270 /////////////////////////////////////////////////////////////////////////////// | 264 /////////////////////////////////////////////////////////////////////////////// |
| 271 | 265 |
| 272 static bool validate_alphaType(SkBitmap::Config config, SkAlphaType alphaType, | 266 static bool validate_alphaType(SkBitmap::Config config, SkAlphaType alphaType, |
| 273 SkAlphaType* canonical = NULL) { | 267 SkAlphaType* canonical = NULL) { |
| 274 switch (config) { | 268 switch (config) { |
| 275 case SkBitmap::kNo_Config: | 269 case SkBitmap::kNo_Config: |
| 276 alphaType = kIgnore_SkAlphaType; | 270 alphaType = kIgnore_SkAlphaType; |
| 277 break; | 271 break; |
| 278 case SkBitmap::kA1_Config: | |
| 279 case SkBitmap::kA8_Config: | 272 case SkBitmap::kA8_Config: |
| 280 if (kUnpremul_SkAlphaType == alphaType) { | 273 if (kUnpremul_SkAlphaType == alphaType) { |
| 281 alphaType = kPremul_SkAlphaType; | 274 alphaType = kPremul_SkAlphaType; |
| 282 } | 275 } |
| 283 // fall-through | 276 // fall-through |
| 284 case SkBitmap::kIndex8_Config: | 277 case SkBitmap::kIndex8_Config: |
| 285 case SkBitmap::kARGB_4444_Config: | 278 case SkBitmap::kARGB_4444_Config: |
| 286 case SkBitmap::kARGB_8888_Config: | 279 case SkBitmap::kARGB_8888_Config: |
| 287 if (kIgnore_SkAlphaType == alphaType) { | 280 if (kIgnore_SkAlphaType == alphaType) { |
| 288 return false; | 281 return false; |
| 289 } | 282 } |
| 290 break; | 283 break; |
| 291 case SkBitmap::kRGB_565_Config: | 284 case SkBitmap::kRGB_565_Config: |
| 292 alphaType = kOpaque_SkAlphaType; | 285 alphaType = kOpaque_SkAlphaType; |
| 293 break; | 286 break; |
| 287 default: |
| 288 return false; |
| 294 } | 289 } |
| 295 if (canonical) { | 290 if (canonical) { |
| 296 *canonical = alphaType; | 291 *canonical = alphaType; |
| 297 } | 292 } |
| 298 return true; | 293 return true; |
| 299 } | 294 } |
| 300 | 295 |
| 301 bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes, | 296 bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes, |
| 302 SkAlphaType alphaType) { | 297 SkAlphaType alphaType) { |
| 303 if ((width | height) < 0) { | 298 if ((width | height) < 0) { |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 base += x << 2; | 594 base += x << 2; |
| 600 break; | 595 break; |
| 601 case SkBitmap::kARGB_4444_Config: | 596 case SkBitmap::kARGB_4444_Config: |
| 602 case SkBitmap::kRGB_565_Config: | 597 case SkBitmap::kRGB_565_Config: |
| 603 base += x << 1; | 598 base += x << 1; |
| 604 break; | 599 break; |
| 605 case SkBitmap::kA8_Config: | 600 case SkBitmap::kA8_Config: |
| 606 case SkBitmap::kIndex8_Config: | 601 case SkBitmap::kIndex8_Config: |
| 607 base += x; | 602 base += x; |
| 608 break; | 603 break; |
| 609 case SkBitmap::kA1_Config: | |
| 610 base += x >> 3; | |
| 611 break; | 604 break; |
| 612 default: | 605 default: |
| 613 SkDEBUGFAIL("Can't return addr for config"); | 606 SkDEBUGFAIL("Can't return addr for config"); |
| 614 base = NULL; | 607 base = NULL; |
| 615 break; | 608 break; |
| 616 } | 609 } |
| 617 } | 610 } |
| 618 return base; | 611 return base; |
| 619 } | 612 } |
| 620 | 613 |
| 621 SkColor SkBitmap::getColor(int x, int y) const { | 614 SkColor SkBitmap::getColor(int x, int y) const { |
| 622 SkASSERT((unsigned)x < (unsigned)this->width()); | 615 SkASSERT((unsigned)x < (unsigned)this->width()); |
| 623 SkASSERT((unsigned)y < (unsigned)this->height()); | 616 SkASSERT((unsigned)y < (unsigned)this->height()); |
| 624 | 617 |
| 625 switch (this->config()) { | 618 switch (this->config()) { |
| 626 case SkBitmap::kA1_Config: { | |
| 627 uint8_t* addr = this->getAddr1(x, y); | |
| 628 uint8_t mask = 1 << (7 - (x % 8)); | |
| 629 if (addr[0] & mask) { | |
| 630 return SK_ColorBLACK; | |
| 631 } else { | |
| 632 return 0; | |
| 633 } | |
| 634 } | |
| 635 case SkBitmap::kA8_Config: { | 619 case SkBitmap::kA8_Config: { |
| 636 uint8_t* addr = this->getAddr8(x, y); | 620 uint8_t* addr = this->getAddr8(x, y); |
| 637 return SkColorSetA(0, addr[0]); | 621 return SkColorSetA(0, addr[0]); |
| 638 } | 622 } |
| 639 case SkBitmap::kIndex8_Config: { | 623 case SkBitmap::kIndex8_Config: { |
| 640 SkPMColor c = this->getIndex8Color(x, y); | 624 SkPMColor c = this->getIndex8Color(x, y); |
| 641 return SkUnPreMultiply::PMColorToColor(c); | 625 return SkUnPreMultiply::PMColorToColor(c); |
| 642 } | 626 } |
| 643 case SkBitmap::kRGB_565_Config: { | 627 case SkBitmap::kRGB_565_Config: { |
| 644 uint16_t* addr = this->getAddr16(x, y); | 628 uint16_t* addr = this->getAddr16(x, y); |
| 645 return SkPixel16ToColor(addr[0]); | 629 return SkPixel16ToColor(addr[0]); |
| 646 } | 630 } |
| 647 case SkBitmap::kARGB_4444_Config: { | 631 case SkBitmap::kARGB_4444_Config: { |
| 648 uint16_t* addr = this->getAddr16(x, y); | 632 uint16_t* addr = this->getAddr16(x, y); |
| 649 SkPMColor c = SkPixel4444ToPixel32(addr[0]); | 633 SkPMColor c = SkPixel4444ToPixel32(addr[0]); |
| 650 return SkUnPreMultiply::PMColorToColor(c); | 634 return SkUnPreMultiply::PMColorToColor(c); |
| 651 } | 635 } |
| 652 case SkBitmap::kARGB_8888_Config: { | 636 case SkBitmap::kARGB_8888_Config: { |
| 653 uint32_t* addr = this->getAddr32(x, y); | 637 uint32_t* addr = this->getAddr32(x, y); |
| 654 return SkUnPreMultiply::PMColorToColor(addr[0]); | 638 return SkUnPreMultiply::PMColorToColor(addr[0]); |
| 655 } | 639 } |
| 656 case kNo_Config: | 640 case kNo_Config: |
| 641 default: |
| 657 SkASSERT(false); | 642 SkASSERT(false); |
| 658 return 0; | 643 return 0; |
| 659 } | 644 } |
| 660 SkASSERT(false); // Not reached. | 645 SkASSERT(false); // Not reached. |
| 661 return 0; | 646 return 0; |
| 662 } | 647 } |
| 663 | 648 |
| 664 bool SkBitmap::ComputeIsOpaque(const SkBitmap& bm) { | 649 bool SkBitmap::ComputeIsOpaque(const SkBitmap& bm) { |
| 665 SkAutoLockPixels alp(bm); | 650 SkAutoLockPixels alp(bm); |
| 666 if (!bm.getPixels()) { | 651 if (!bm.getPixels()) { |
| 667 return false; | 652 return false; |
| 668 } | 653 } |
| 669 | 654 |
| 670 const int height = bm.height(); | 655 const int height = bm.height(); |
| 671 const int width = bm.width(); | 656 const int width = bm.width(); |
| 672 | 657 |
| 673 switch (bm.config()) { | 658 switch (bm.config()) { |
| 674 case SkBitmap::kA1_Config: { | |
| 675 // TODO | |
| 676 } break; | |
| 677 case SkBitmap::kA8_Config: { | 659 case SkBitmap::kA8_Config: { |
| 678 unsigned a = 0xFF; | 660 unsigned a = 0xFF; |
| 679 for (int y = 0; y < height; ++y) { | 661 for (int y = 0; y < height; ++y) { |
| 680 const uint8_t* row = bm.getAddr8(0, y); | 662 const uint8_t* row = bm.getAddr8(0, y); |
| 681 for (int x = 0; x < width; ++x) { | 663 for (int x = 0; x < width; ++x) { |
| 682 a &= row[x]; | 664 a &= row[x]; |
| 683 } | 665 } |
| 684 if (0xFF != a) { | 666 if (0xFF != a) { |
| 685 return false; | 667 return false; |
| 686 } | 668 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 const int rowBytes = fRowBytes; | 754 const int rowBytes = fRowBytes; |
| 773 | 755 |
| 774 // make rgb premultiplied | 756 // make rgb premultiplied |
| 775 if (255 != a) { | 757 if (255 != a) { |
| 776 r = SkAlphaMul(r, a); | 758 r = SkAlphaMul(r, a); |
| 777 g = SkAlphaMul(g, a); | 759 g = SkAlphaMul(g, a); |
| 778 b = SkAlphaMul(b, a); | 760 b = SkAlphaMul(b, a); |
| 779 } | 761 } |
| 780 | 762 |
| 781 switch (fConfig) { | 763 switch (fConfig) { |
| 782 case kA1_Config: { | |
| 783 uint8_t* p = this->getAddr1(area.fLeft, area.fTop); | |
| 784 const int left = area.fLeft >> 3; | |
| 785 const int right = area.fRight >> 3; | |
| 786 | |
| 787 int middle = right - left - 1; | |
| 788 | |
| 789 uint8_t leftMask = 0xFF >> (area.fLeft & 7); | |
| 790 uint8_t rightMask = ~(0xFF >> (area.fRight & 7)); | |
| 791 if (left == right) { | |
| 792 leftMask &= rightMask; | |
| 793 rightMask = 0; | |
| 794 } | |
| 795 | |
| 796 a = (a >> 7) ? 0xFF : 0; | |
| 797 while (--height >= 0) { | |
| 798 uint8_t* startP = p; | |
| 799 | |
| 800 *p = (*p & ~leftMask) | (a & leftMask); | |
| 801 p++; | |
| 802 if (middle > 0) { | |
| 803 memset(p, a, middle); | |
| 804 p += middle; | |
| 805 } | |
| 806 if (rightMask) { | |
| 807 *p = (*p & ~rightMask) | (a & rightMask); | |
| 808 } | |
| 809 | |
| 810 p = startP + rowBytes; | |
| 811 } | |
| 812 break; | |
| 813 } | |
| 814 case kA8_Config: { | 764 case kA8_Config: { |
| 815 uint8_t* p = this->getAddr8(area.fLeft, area.fTop); | 765 uint8_t* p = this->getAddr8(area.fLeft, area.fTop); |
| 816 while (--height >= 0) { | 766 while (--height >= 0) { |
| 817 memset(p, a, width); | 767 memset(p, a, width); |
| 818 p += rowBytes; | 768 p += rowBytes; |
| 819 } | 769 } |
| 820 break; | 770 break; |
| 821 } | 771 } |
| 822 case kARGB_4444_Config: | 772 case kARGB_4444_Config: |
| 823 case kRGB_565_Config: { | 773 case kRGB_565_Config: { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 case SkBitmap::kRGB_565_Config: | 839 case SkBitmap::kRGB_565_Config: |
| 890 case SkBitmap::kARGB_4444_Config: | 840 case SkBitmap::kARGB_4444_Config: |
| 891 x <<= 1; | 841 x <<= 1; |
| 892 break; | 842 break; |
| 893 | 843 |
| 894 case SkBitmap::kARGB_8888_Config: | 844 case SkBitmap::kARGB_8888_Config: |
| 895 x <<= 2; | 845 x <<= 2; |
| 896 break; | 846 break; |
| 897 | 847 |
| 898 case SkBitmap::kNo_Config: | 848 case SkBitmap::kNo_Config: |
| 899 case SkBitmap::kA1_Config: | |
| 900 default: | 849 default: |
| 901 return SUB_OFFSET_FAILURE; | 850 return SUB_OFFSET_FAILURE; |
| 902 } | 851 } |
| 903 return y * bm.rowBytes() + x; | 852 return y * bm.rowBytes() + x; |
| 904 } | 853 } |
| 905 | 854 |
| 906 /** | 855 /** |
| 907 * Using the pixelRefOffset(), rowBytes(), and Config of bm, determine the (x,
y) coordinate of the | 856 * Using the pixelRefOffset(), rowBytes(), and Config of bm, determine the (x,
y) coordinate of the |
| 908 * upper left corner of bm relative to its SkPixelRef. | 857 * upper left corner of bm relative to its SkPixelRef. |
| 909 * x and y must be non-NULL. | 858 * x and y must be non-NULL. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 932 case SkBitmap::kARGB_4444_Config: | 881 case SkBitmap::kARGB_4444_Config: |
| 933 *x >>= 1; | 882 *x >>= 1; |
| 934 break; | 883 break; |
| 935 | 884 |
| 936 case SkBitmap::kARGB_8888_Config: | 885 case SkBitmap::kARGB_8888_Config: |
| 937 *x >>= 2; | 886 *x >>= 2; |
| 938 break; | 887 break; |
| 939 | 888 |
| 940 case SkBitmap::kNo_Config: | 889 case SkBitmap::kNo_Config: |
| 941 // Fall through. | 890 // Fall through. |
| 942 case SkBitmap::kA1_Config: | |
| 943 // Fall through. | |
| 944 default: | 891 default: |
| 945 return false; | 892 return false; |
| 946 } | 893 } |
| 947 return true; | 894 return true; |
| 948 } | 895 } |
| 949 | 896 |
| 950 static bool get_upper_left_from_offset(const SkBitmap& bm, int32_t* x, int32_t*
y) { | 897 static bool get_upper_left_from_offset(const SkBitmap& bm, int32_t* x, int32_t*
y) { |
| 951 return get_upper_left_from_offset(bm.config(), bm.pixelRefOffset(), bm.rowBy
tes(), x, y); | 898 return get_upper_left_from_offset(bm.config(), bm.pixelRefOffset(), bm.rowBy
tes(), x, y); |
| 952 } | 899 } |
| 953 | 900 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1014 if (this->config() == kNo_Config) { | 961 if (this->config() == kNo_Config) { |
| 1015 return false; | 962 return false; |
| 1016 } | 963 } |
| 1017 | 964 |
| 1018 bool sameConfigs = (this->config() == dstConfig); | 965 bool sameConfigs = (this->config() == dstConfig); |
| 1019 switch (dstConfig) { | 966 switch (dstConfig) { |
| 1020 case kA8_Config: | 967 case kA8_Config: |
| 1021 case kRGB_565_Config: | 968 case kRGB_565_Config: |
| 1022 case kARGB_8888_Config: | 969 case kARGB_8888_Config: |
| 1023 break; | 970 break; |
| 1024 case kA1_Config: | |
| 1025 case kIndex8_Config: | 971 case kIndex8_Config: |
| 1026 if (!sameConfigs) { | 972 if (!sameConfigs) { |
| 1027 return false; | 973 return false; |
| 1028 } | 974 } |
| 1029 break; | 975 break; |
| 1030 case kARGB_4444_Config: | 976 case kARGB_4444_Config: |
| 1031 return sameConfigs || kARGB_8888_Config == this->config(); | 977 return sameConfigs || kARGB_8888_Config == this->config(); |
| 1032 default: | 978 default: |
| 1033 return false; | 979 return false; |
| 1034 } | 980 } |
| 1035 | |
| 1036 // do not copy src if srcConfig == kA1_Config while dstConfig != kA1_Config | |
| 1037 if (this->config() == kA1_Config && !sameConfigs) { | |
| 1038 return false; | |
| 1039 } | |
| 1040 | |
| 1041 return true; | 981 return true; |
| 1042 } | 982 } |
| 1043 | 983 |
| 1044 bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { | 984 bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { |
| 1045 if (!this->canCopyTo(dstConfig)) { | 985 if (!this->canCopyTo(dstConfig)) { |
| 1046 return false; | 986 return false; |
| 1047 } | 987 } |
| 1048 | 988 |
| 1049 // if we have a texture, first get those pixels | 989 // if we have a texture, first get those pixels |
| 1050 SkBitmap tmpSrc; | 990 SkBitmap tmpSrc; |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1674 } | 1614 } |
| 1675 } | 1615 } |
| 1676 #endif | 1616 #endif |
| 1677 } | 1617 } |
| 1678 #endif | 1618 #endif |
| 1679 | 1619 |
| 1680 #ifdef SK_DEVELOPER | 1620 #ifdef SK_DEVELOPER |
| 1681 void SkBitmap::toString(SkString* str) const { | 1621 void SkBitmap::toString(SkString* str) const { |
| 1682 | 1622 |
| 1683 static const char* gConfigNames[kConfigCount] = { | 1623 static const char* gConfigNames[kConfigCount] = { |
| 1684 "NONE", "A1", "A8", "INDEX8", "565", "4444", "8888" | 1624 "NONE", "A8", "INDEX8", "565", "4444", "8888" |
| 1685 }; | 1625 }; |
| 1686 | 1626 |
| 1687 str->appendf("bitmap: ((%d, %d) %s", this->width(), this->height(), | 1627 str->appendf("bitmap: ((%d, %d) %s", this->width(), this->height(), |
| 1688 gConfigNames[this->config()]); | 1628 gConfigNames[this->config()]); |
| 1689 | 1629 |
| 1690 str->append(" ("); | 1630 str->append(" ("); |
| 1691 if (this->isOpaque()) { | 1631 if (this->isOpaque()) { |
| 1692 str->append("opaque"); | 1632 str->append("opaque"); |
| 1693 } else { | 1633 } else { |
| 1694 str->append("transparent"); | 1634 str->append("transparent"); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1709 if (NULL != uri) { | 1649 if (NULL != uri) { |
| 1710 str->appendf(" uri:\"%s\"", uri); | 1650 str->appendf(" uri:\"%s\"", uri); |
| 1711 } else { | 1651 } else { |
| 1712 str->appendf(" pixelref:%p", pr); | 1652 str->appendf(" pixelref:%p", pr); |
| 1713 } | 1653 } |
| 1714 } | 1654 } |
| 1715 | 1655 |
| 1716 str->append(")"); | 1656 str->append(")"); |
| 1717 } | 1657 } |
| 1718 #endif | 1658 #endif |
| OLD | NEW |