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 |