| 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 sk_bzero(this, sizeof(*this)); | 154 sk_bzero(this, sizeof(*this)); |
| 155 } | 155 } |
| 156 | 156 |
| 157 int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) { | 157 int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) { |
| 158 int bpp; | 158 int bpp; |
| 159 switch (config) { | 159 switch (config) { |
| 160 case kNo_Config: | 160 case kNo_Config: |
| 161 case kA1_Config: | 161 case kA1_Config: |
| 162 bpp = 0; // not applicable | 162 bpp = 0; // not applicable |
| 163 break; | 163 break; |
| 164 case kRLE_Index8_Config: | |
| 165 case kA8_Config: | 164 case kA8_Config: |
| 166 case kIndex8_Config: | 165 case kIndex8_Config: |
| 167 bpp = 1; | 166 bpp = 1; |
| 168 break; | 167 break; |
| 169 case kRGB_565_Config: | 168 case kRGB_565_Config: |
| 170 case kARGB_4444_Config: | 169 case kARGB_4444_Config: |
| 171 bpp = 2; | 170 bpp = 2; |
| 172 break; | 171 break; |
| 173 case kARGB_8888_Config: | 172 case kARGB_8888_Config: |
| 174 bpp = 4; | 173 bpp = 4; |
| 175 break; | 174 break; |
| 176 default: | 175 default: |
| 177 SkDEBUGFAIL("unknown config"); | 176 SkDEBUGFAIL("unknown config"); |
| 178 bpp = 0; // error | 177 bpp = 0; // error |
| 179 break; | 178 break; |
| 180 } | 179 } |
| 181 return bpp; | 180 return bpp; |
| 182 } | 181 } |
| 183 | 182 |
| 184 size_t SkBitmap::ComputeRowBytes(Config c, int width) { | 183 size_t SkBitmap::ComputeRowBytes(Config c, int width) { |
| 185 if (width < 0) { | 184 if (width < 0) { |
| 186 return 0; | 185 return 0; |
| 187 } | 186 } |
| 188 | 187 |
| 189 Sk64 rowBytes; | 188 Sk64 rowBytes; |
| 190 rowBytes.setZero(); | 189 rowBytes.setZero(); |
| 191 | 190 |
| 192 switch (c) { | 191 switch (c) { |
| 193 case kNo_Config: | 192 case kNo_Config: |
| 194 case kRLE_Index8_Config: | |
| 195 break; | 193 break; |
| 196 case kA1_Config: | 194 case kA1_Config: |
| 197 rowBytes.set(width); | 195 rowBytes.set(width); |
| 198 rowBytes.add(7); | 196 rowBytes.add(7); |
| 199 rowBytes.shiftRight(3); | 197 rowBytes.shiftRight(3); |
| 200 break; | 198 break; |
| 201 case kA8_Config: | 199 case kA8_Config: |
| 202 case kIndex8_Config: | 200 case kIndex8_Config: |
| 203 rowBytes.set(width); | 201 rowBytes.set(width); |
| 204 break; | 202 break; |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 return ComputeSafeSize64(getConfig(), fWidth, fHeight, fRowBytes); | 464 return ComputeSafeSize64(getConfig(), fWidth, fHeight, fRowBytes); |
| 467 } | 465 } |
| 468 | 466 |
| 469 bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, | 467 bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, |
| 470 size_t dstRowBytes, bool preserveDstPad) const { | 468 size_t dstRowBytes, bool preserveDstPad) const { |
| 471 | 469 |
| 472 if (0 == dstRowBytes) { | 470 if (0 == dstRowBytes) { |
| 473 dstRowBytes = fRowBytes; | 471 dstRowBytes = fRowBytes; |
| 474 } | 472 } |
| 475 | 473 |
| 476 if (getConfig() == kRLE_Index8_Config || | 474 if (dstRowBytes < ComputeRowBytes(getConfig(), fWidth) || |
| 477 dstRowBytes < ComputeRowBytes(getConfig(), fWidth) || | |
| 478 dst == NULL || (getPixels() == NULL && pixelRef() == NULL)) | 475 dst == NULL || (getPixels() == NULL && pixelRef() == NULL)) |
| 479 return false; | 476 return false; |
| 480 | 477 |
| 481 if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) { | 478 if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) { |
| 482 size_t safeSize = getSafeSize(); | 479 size_t safeSize = getSafeSize(); |
| 483 if (safeSize > dstSize || safeSize == 0) | 480 if (safeSize > dstSize || safeSize == 0) |
| 484 return false; | 481 return false; |
| 485 else { | 482 else { |
| 486 SkAutoLockPixels lock(*this); | 483 SkAutoLockPixels lock(*this); |
| 487 // This implementation will write bytes beyond the end of each row, | 484 // This implementation will write bytes beyond the end of each row, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 switch (fConfig) { | 528 switch (fConfig) { |
| 532 case kNo_Config: | 529 case kNo_Config: |
| 533 return true; | 530 return true; |
| 534 | 531 |
| 535 case kA1_Config: | 532 case kA1_Config: |
| 536 case kA8_Config: | 533 case kA8_Config: |
| 537 case kARGB_4444_Config: | 534 case kARGB_4444_Config: |
| 538 case kARGB_8888_Config: | 535 case kARGB_8888_Config: |
| 539 return (fFlags & kImageIsOpaque_Flag) != 0; | 536 return (fFlags & kImageIsOpaque_Flag) != 0; |
| 540 | 537 |
| 541 case kIndex8_Config: | 538 case kIndex8_Config: { |
| 542 case kRLE_Index8_Config: { | 539 uint32_t flags = 0; |
| 543 uint32_t flags = 0; | |
| 544 | 540 |
| 545 this->lockPixels(); | 541 this->lockPixels(); |
| 546 // if lockPixels failed, we may not have a ctable ptr | 542 // if lockPixels failed, we may not have a ctable ptr |
| 547 if (fColorTable) { | 543 if (fColorTable) { |
| 548 flags = fColorTable->getFlags(); | 544 flags = fColorTable->getFlags(); |
| 549 } | 545 } |
| 550 this->unlockPixels(); | 546 this->unlockPixels(); |
| 551 | 547 |
| 552 return (flags & SkColorTable::kColorsAreOpaque_Flag) != 0; | 548 return (flags & SkColorTable::kColorsAreOpaque_Flag) != 0; |
| 553 } | 549 } |
| 554 | 550 |
| 555 case kRGB_565_Config: | 551 case kRGB_565_Config: |
| 556 return true; | 552 return true; |
| 557 | 553 |
| 558 default: | 554 default: |
| 559 SkDEBUGFAIL("unknown bitmap config pased to isOpaque"); | 555 SkDEBUGFAIL("unknown bitmap config pased to isOpaque"); |
| 560 return false; | 556 return false; |
| 561 } | 557 } |
| 562 } | 558 } |
| 563 | 559 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 case SkBitmap::kRGB_565_Config: | 595 case SkBitmap::kRGB_565_Config: |
| 600 base += x << 1; | 596 base += x << 1; |
| 601 break; | 597 break; |
| 602 case SkBitmap::kA8_Config: | 598 case SkBitmap::kA8_Config: |
| 603 case SkBitmap::kIndex8_Config: | 599 case SkBitmap::kIndex8_Config: |
| 604 base += x; | 600 base += x; |
| 605 break; | 601 break; |
| 606 case SkBitmap::kA1_Config: | 602 case SkBitmap::kA1_Config: |
| 607 base += x >> 3; | 603 base += x >> 3; |
| 608 break; | 604 break; |
| 609 case kRLE_Index8_Config: | |
| 610 SkDEBUGFAIL("Can't return addr for kRLE_Index8_Config"); | |
| 611 base = NULL; | |
| 612 break; | |
| 613 default: | 605 default: |
| 614 SkDEBUGFAIL("Can't return addr for config"); | 606 SkDEBUGFAIL("Can't return addr for config"); |
| 615 base = NULL; | 607 base = NULL; |
| 616 break; | 608 break; |
| 617 } | 609 } |
| 618 } | 610 } |
| 619 return base; | 611 return base; |
| 620 } | 612 } |
| 621 | 613 |
| 622 SkColor SkBitmap::getColor(int x, int y) const { | 614 SkColor SkBitmap::getColor(int x, int y) const { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 647 } | 639 } |
| 648 case SkBitmap::kARGB_4444_Config: { | 640 case SkBitmap::kARGB_4444_Config: { |
| 649 uint16_t* addr = this->getAddr16(x, y); | 641 uint16_t* addr = this->getAddr16(x, y); |
| 650 SkPMColor c = SkPixel4444ToPixel32(addr[0]); | 642 SkPMColor c = SkPixel4444ToPixel32(addr[0]); |
| 651 return SkUnPreMultiply::PMColorToColor(c); | 643 return SkUnPreMultiply::PMColorToColor(c); |
| 652 } | 644 } |
| 653 case SkBitmap::kARGB_8888_Config: { | 645 case SkBitmap::kARGB_8888_Config: { |
| 654 uint32_t* addr = this->getAddr32(x, y); | 646 uint32_t* addr = this->getAddr32(x, y); |
| 655 return SkUnPreMultiply::PMColorToColor(addr[0]); | 647 return SkUnPreMultiply::PMColorToColor(addr[0]); |
| 656 } | 648 } |
| 657 case kRLE_Index8_Config: { | |
| 658 uint8_t dst; | |
| 659 const SkBitmap::RLEPixels* rle = | |
| 660 (const SkBitmap::RLEPixels*)this->getPixels(); | |
| 661 SkPackBits::Unpack8(&dst, x, 1, rle->packedAtY(y)); | |
| 662 return SkUnPreMultiply::PMColorToColor((*fColorTable)[dst]); | |
| 663 } | |
| 664 case kNo_Config: | 649 case kNo_Config: |
| 665 SkASSERT(false); | 650 SkASSERT(false); |
| 666 return 0; | 651 return 0; |
| 667 } | 652 } |
| 668 SkASSERT(false); // Not reached. | 653 SkASSERT(false); // Not reached. |
| 669 return 0; | 654 return 0; |
| 670 } | 655 } |
| 671 | 656 |
| 672 bool SkBitmap::ComputeIsOpaque(const SkBitmap& bm) { | 657 bool SkBitmap::ComputeIsOpaque(const SkBitmap& bm) { |
| 673 SkAutoLockPixels alp(bm); | 658 SkAutoLockPixels alp(bm); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 688 const uint8_t* row = bm.getAddr8(0, y); | 673 const uint8_t* row = bm.getAddr8(0, y); |
| 689 for (int x = 0; x < width; ++x) { | 674 for (int x = 0; x < width; ++x) { |
| 690 a &= row[x]; | 675 a &= row[x]; |
| 691 } | 676 } |
| 692 if (0xFF != a) { | 677 if (0xFF != a) { |
| 693 return false; | 678 return false; |
| 694 } | 679 } |
| 695 } | 680 } |
| 696 return true; | 681 return true; |
| 697 } break; | 682 } break; |
| 698 case kRLE_Index8_Config: | |
| 699 case SkBitmap::kIndex8_Config: { | 683 case SkBitmap::kIndex8_Config: { |
| 700 SkAutoLockColors alc(bm); | 684 SkAutoLockColors alc(bm); |
| 701 const SkPMColor* table = alc.colors(); | 685 const SkPMColor* table = alc.colors(); |
| 702 if (!table) { | 686 if (!table) { |
| 703 return false; | 687 return false; |
| 704 } | 688 } |
| 705 SkPMColor c = (SkPMColor)~0; | 689 SkPMColor c = (SkPMColor)~0; |
| 706 for (int i = bm.getColorTable()->count() - 1; i >= 0; --i) { | 690 for (int i = bm.getColorTable()->count() - 1; i >= 0; --i) { |
| 707 c &= table[i]; | 691 c &= table[i]; |
| 708 } | 692 } |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 dst.setConfig(this->config(), subset.width(), subset.height()); | 923 dst.setConfig(this->config(), subset.width(), subset.height()); |
| 940 dst.setIsVolatile(this->isVolatile()); | 924 dst.setIsVolatile(this->isVolatile()); |
| 941 dst.setIsOpaque(this->isOpaque()); | 925 dst.setIsOpaque(this->isOpaque()); |
| 942 dst.setPixelRef(pixelRef)->unref(); | 926 dst.setPixelRef(pixelRef)->unref(); |
| 943 SkDEBUGCODE(dst.validate()); | 927 SkDEBUGCODE(dst.validate()); |
| 944 result->swap(dst); | 928 result->swap(dst); |
| 945 return true; | 929 return true; |
| 946 } | 930 } |
| 947 } | 931 } |
| 948 | 932 |
| 949 if (kRLE_Index8_Config == fConfig) { | |
| 950 SkAutoLockPixels alp(*this); | |
| 951 // don't call readyToDraw(), since we can operate w/o a colortable | |
| 952 // at this stage | |
| 953 if (this->getPixels() == NULL) { | |
| 954 return false; | |
| 955 } | |
| 956 SkBitmap bm; | |
| 957 | |
| 958 bm.setConfig(kIndex8_Config, r.width(), r.height()); | |
| 959 bm.allocPixels(this->getColorTable()); | |
| 960 if (NULL == bm.getPixels()) { | |
| 961 return false; | |
| 962 } | |
| 963 | |
| 964 const RLEPixels* rle = (const RLEPixels*)this->getPixels(); | |
| 965 uint8_t* dst = bm.getAddr8(0, 0); | |
| 966 const int width = bm.width(); | |
| 967 const size_t rowBytes = bm.rowBytes(); | |
| 968 | |
| 969 for (int y = r.fTop; y < r.fBottom; y++) { | |
| 970 SkPackBits::Unpack8(dst, r.fLeft, width, rle->packedAtY(y)); | |
| 971 dst += rowBytes; | |
| 972 } | |
| 973 result->swap(bm); | |
| 974 return true; | |
| 975 } | |
| 976 | |
| 977 // If the upper left of the rectangle was outside the bounds of this SkBitma
p, we should have | 933 // If the upper left of the rectangle was outside the bounds of this SkBitma
p, we should have |
| 978 // exited above. | 934 // exited above. |
| 979 SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width(
))); | 935 SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width(
))); |
| 980 SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height(
))); | 936 SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height(
))); |
| 981 | 937 |
| 982 size_t offset = get_sub_offset(*this, r.fLeft, r.fTop); | 938 size_t offset = get_sub_offset(*this, r.fLeft, r.fTop); |
| 983 if (SUB_OFFSET_FAILURE == offset) { | 939 if (SUB_OFFSET_FAILURE == offset) { |
| 984 return false; // config not supported | 940 return false; // config not supported |
| 985 } | 941 } |
| 986 | 942 |
| (...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1687 if (NULL != uri) { | 1643 if (NULL != uri) { |
| 1688 str->appendf(" uri:\"%s\"", uri); | 1644 str->appendf(" uri:\"%s\"", uri); |
| 1689 } else { | 1645 } else { |
| 1690 str->appendf(" pixelref:%p", pr); | 1646 str->appendf(" pixelref:%p", pr); |
| 1691 } | 1647 } |
| 1692 } | 1648 } |
| 1693 | 1649 |
| 1694 str->append(")"); | 1650 str->append(")"); |
| 1695 } | 1651 } |
| 1696 #endif | 1652 #endif |
| OLD | NEW |