Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: src/core/SkBitmap.cpp

Issue 1074983003: add SkPixmap and external locking to bitmaps (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 } 423 }
424 424
425 dst->setPixelRef(pr)->unref(); 425 dst->setPixelRef(pr)->unref();
426 // since we're already allocated, we lockPixels right away 426 // since we're already allocated, we lockPixels right away
427 dst->lockPixels(); 427 dst->lockPixels();
428 return true; 428 return true;
429 } 429 }
430 430
431 /////////////////////////////////////////////////////////////////////////////// 431 ///////////////////////////////////////////////////////////////////////////////
432 432
433 bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, 433 static bool copy_pixels_to(const SkPixmap& src, void* const dst, size_t dstSize,
434 size_t dstRowBytes, bool preserveDstPad) const { 434 size_t dstRowBytes, bool preserveDstPad) {
435 const SkImageInfo& info = src.info();
435 436
436 if (0 == dstRowBytes) { 437 if (0 == dstRowBytes) {
437 dstRowBytes = fRowBytes; 438 dstRowBytes = src.rowBytes();
438 } 439 }
439 440 if (dstRowBytes < info.minRowBytes()) {
440 if (dstRowBytes < fInfo.minRowBytes() ||
441 dst == NULL || (getPixels() == NULL && pixelRef() == NULL)) {
442 return false; 441 return false;
443 } 442 }
444 443
445 if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) { 444 if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == src.rowBytes()) {
446 size_t safeSize = this->getSafeSize(); 445 size_t safeSize = src.getSafeSize();
447 if (safeSize > dstSize || safeSize == 0) 446 if (safeSize > dstSize || safeSize == 0)
448 return false; 447 return false;
449 else { 448 else {
450 SkAutoLockPixels lock(*this);
451 // This implementation will write bytes beyond the end of each row, 449 // This implementation will write bytes beyond the end of each row,
452 // excluding the last row, if the bitmap's stride is greater than 450 // excluding the last row, if the bitmap's stride is greater than
453 // strictly required by the current config. 451 // strictly required by the current config.
454 memcpy(dst, getPixels(), safeSize); 452 memcpy(dst, src.addr(), safeSize);
455
456 return true; 453 return true;
457 } 454 }
458 } else { 455 } else {
459 // If destination has different stride than us, then copy line by line. 456 // If destination has different stride than us, then copy line by line.
460 if (fInfo.getSafeSize(dstRowBytes) > dstSize) { 457 if (info.getSafeSize(dstRowBytes) > dstSize) {
461 return false; 458 return false;
462 } else { 459 } else {
463 // Just copy what we need on each line. 460 // Just copy what we need on each line.
464 size_t rowBytes = fInfo.minRowBytes(); 461 size_t rowBytes = info.minRowBytes();
465 SkAutoLockPixels lock(*this); 462 const uint8_t* srcP = reinterpret_cast<const uint8_t*>(src.addr());
466 const uint8_t* srcP = reinterpret_cast<const uint8_t*>(getPixels());
467 uint8_t* dstP = reinterpret_cast<uint8_t*>(dst); 463 uint8_t* dstP = reinterpret_cast<uint8_t*>(dst);
468 for (int row = 0; row < fInfo.height(); row++, srcP += fRowBytes, ds tP += dstRowBytes) { 464 for (int row = 0; row < info.height(); ++row) {
469 memcpy(dstP, srcP, rowBytes); 465 memcpy(dstP, srcP, rowBytes);
466 srcP += src.rowBytes();
467 dstP += dstRowBytes;
470 } 468 }
471 469
472 return true; 470 return true;
473 } 471 }
474 } 472 }
475 } 473 }
476 474
475 bool SkBitmap::copyPixelsTo(void* dst, size_t dstSize, size_t dstRB, bool preser veDstPad) const {
476 if (NULL == dst) {
477 return false;
478 }
479 SkAutoPixmapUnlock result;
480 if (!this->requestLock(&result)) {
481 return false;
482 }
483 return copy_pixels_to(result.pixmap(), dst, dstSize, dstRB, preserveDstPad);
484 }
485
477 /////////////////////////////////////////////////////////////////////////////// 486 ///////////////////////////////////////////////////////////////////////////////
478 487
479 bool SkBitmap::isImmutable() const { 488 bool SkBitmap::isImmutable() const {
480 return fPixelRef ? fPixelRef->isImmutable() : false; 489 return fPixelRef ? fPixelRef->isImmutable() : false;
481 } 490 }
482 491
483 void SkBitmap::setImmutable() { 492 void SkBitmap::setImmutable() {
484 if (fPixelRef) { 493 if (fPixelRef) {
485 fPixelRef->setImmutable(); 494 fPixelRef->setImmutable();
486 } 495 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 return SkUnPreMultiply::PMColorToColor(addr[0]); 569 return SkUnPreMultiply::PMColorToColor(addr[0]);
561 } 570 }
562 default: 571 default:
563 SkASSERT(false); 572 SkASSERT(false);
564 return 0; 573 return 0;
565 } 574 }
566 SkASSERT(false); // Not reached. 575 SkASSERT(false); // Not reached.
567 return 0; 576 return 0;
568 } 577 }
569 578
570 bool SkBitmap::ComputeIsOpaque(const SkBitmap& bm) { 579 static bool compute_is_opaque(const SkPixmap& pmap) {
571 SkAutoLockPixels alp(bm); 580 const int height = pmap.height();
572 if (!bm.getPixels()) { 581 const int width = pmap.width();
573 return false;
574 }
575 582
576 const int height = bm.height(); 583 switch (pmap.colorType()) {
577 const int width = bm.width();
578
579 switch (bm.colorType()) {
580 case kAlpha_8_SkColorType: { 584 case kAlpha_8_SkColorType: {
581 unsigned a = 0xFF; 585 unsigned a = 0xFF;
582 for (int y = 0; y < height; ++y) { 586 for (int y = 0; y < height; ++y) {
583 const uint8_t* row = bm.getAddr8(0, y); 587 const uint8_t* row = pmap.addr8(0, y);
584 for (int x = 0; x < width; ++x) { 588 for (int x = 0; x < width; ++x) {
585 a &= row[x]; 589 a &= row[x];
586 } 590 }
587 if (0xFF != a) { 591 if (0xFF != a) {
588 return false; 592 return false;
589 } 593 }
590 } 594 }
591 return true; 595 return true;
592 } break; 596 } break;
593 case kIndex_8_SkColorType: { 597 case kIndex_8_SkColorType: {
594 if (!bm.getColorTable()) { 598 const SkColorTable* ctable = pmap.ctable();
599 if (NULL == ctable) {
595 return false; 600 return false;
596 } 601 }
597 const SkPMColor* table = bm.getColorTable()->readColors(); 602 const SkPMColor* table = ctable->readColors();
598 SkPMColor c = (SkPMColor)~0; 603 SkPMColor c = (SkPMColor)~0;
599 for (int i = bm.getColorTable()->count() - 1; i >= 0; --i) { 604 for (int i = ctable->count() - 1; i >= 0; --i) {
600 c &= table[i]; 605 c &= table[i];
601 } 606 }
602 return 0xFF == SkGetPackedA32(c); 607 return 0xFF == SkGetPackedA32(c);
603 } break; 608 } break;
604 case kRGB_565_SkColorType: 609 case kRGB_565_SkColorType:
605 case kGray_8_SkColorType: 610 case kGray_8_SkColorType:
606 return true; 611 return true;
607 break; 612 break;
608 case kARGB_4444_SkColorType: { 613 case kARGB_4444_SkColorType: {
609 unsigned c = 0xFFFF; 614 unsigned c = 0xFFFF;
610 for (int y = 0; y < height; ++y) { 615 for (int y = 0; y < height; ++y) {
611 const SkPMColor16* row = bm.getAddr16(0, y); 616 const SkPMColor16* row = pmap.addr16(0, y);
612 for (int x = 0; x < width; ++x) { 617 for (int x = 0; x < width; ++x) {
613 c &= row[x]; 618 c &= row[x];
614 } 619 }
615 if (0xF != SkGetPackedA4444(c)) { 620 if (0xF != SkGetPackedA4444(c)) {
616 return false; 621 return false;
617 } 622 }
618 } 623 }
619 return true; 624 return true;
620 } break; 625 } break;
621 case kBGRA_8888_SkColorType: 626 case kBGRA_8888_SkColorType:
622 case kRGBA_8888_SkColorType: { 627 case kRGBA_8888_SkColorType: {
623 SkPMColor c = (SkPMColor)~0; 628 SkPMColor c = (SkPMColor)~0;
624 for (int y = 0; y < height; ++y) { 629 for (int y = 0; y < height; ++y) {
625 const SkPMColor* row = bm.getAddr32(0, y); 630 const SkPMColor* row = pmap.addr32(0, y);
626 for (int x = 0; x < width; ++x) { 631 for (int x = 0; x < width; ++x) {
627 c &= row[x]; 632 c &= row[x];
628 } 633 }
629 if (0xFF != SkGetPackedA32(c)) { 634 if (0xFF != SkGetPackedA32(c)) {
630 return false; 635 return false;
631 } 636 }
632 } 637 }
633 return true; 638 return true;
634 } 639 }
635 default: 640 default:
636 break; 641 break;
637 } 642 }
638 return false; 643 return false;
639 } 644 }
640 645
646 bool SkBitmap::ComputeIsOpaque(const SkBitmap& bm) {
647 SkAutoPixmapUnlock result;
648 if (!bm.requestLock(&result)) {
649 return false;
650 }
651 return compute_is_opaque(result.pixmap());
652 }
653
641 654
642 /////////////////////////////////////////////////////////////////////////////// 655 ///////////////////////////////////////////////////////////////////////////////
643 /////////////////////////////////////////////////////////////////////////////// 656 ///////////////////////////////////////////////////////////////////////////////
644 657
645 static uint16_t pack_8888_to_4444(unsigned a, unsigned r, unsigned g, unsigned b ) { 658 static uint16_t pack_8888_to_4444(unsigned a, unsigned r, unsigned g, unsigned b ) {
646 unsigned pixel = (SkA32To4444(a) << SK_A4444_SHIFT) | 659 unsigned pixel = (SkA32To4444(a) << SK_A4444_SHIFT) |
647 (SkR32To4444(r) << SK_R4444_SHIFT) | 660 (SkR32To4444(r) << SK_R4444_SHIFT) |
648 (SkG32To4444(g) << SK_G4444_SHIFT) | 661 (SkG32To4444(g) << SK_G4444_SHIFT) |
649 (SkB32To4444(b) << SK_B4444_SHIFT); 662 (SkB32To4444(b) << SK_B4444_SHIFT);
650 return SkToU16(pixel); 663 return SkToU16(pixel);
651 } 664 }
652 665
653 void SkBitmap::internalErase(const SkIRect& area, 666 static bool internal_erase(const SkPixmap& pmap, const SkIRect& area,
654 U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { 667 U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
655 #ifdef SK_DEBUG
656 SkDEBUGCODE(this->validate();)
657 SkASSERT(!area.isEmpty());
658 {
659 SkIRect total = { 0, 0, this->width(), this->height() };
660 SkASSERT(total.contains(area));
661 }
662 #endif
663
664 switch (fInfo.colorType()) {
665 case kUnknown_SkColorType:
666 case kIndex_8_SkColorType:
667 return; // can't erase. Should we bzero so the memory is not uniniti alized?
668 default:
669 break;
670 }
671
672 SkAutoLockPixels alp(*this);
673 // perform this check after the lock call
674 if (!this->readyToDraw()) {
675 return;
676 }
677
678 int height = area.height(); 668 int height = area.height();
679 const int width = area.width(); 669 const int width = area.width();
680 const int rowBytes = fRowBytes; 670 const int rowBytes = pmap.rowBytes();
681 671
682 switch (this->colorType()) { 672 switch (pmap.colorType()) {
683 case kGray_8_SkColorType: { 673 case kGray_8_SkColorType: {
684 if (255 != a) { 674 if (255 != a) {
685 r = SkMulDiv255Round(r, a); 675 r = SkMulDiv255Round(r, a);
686 g = SkMulDiv255Round(g, a); 676 g = SkMulDiv255Round(g, a);
687 b = SkMulDiv255Round(b, a); 677 b = SkMulDiv255Round(b, a);
688 } 678 }
689 int gray = SkComputeLuminance(r, g, b); 679 int gray = SkComputeLuminance(r, g, b);
690 uint8_t* p = this->getAddr8(area.fLeft, area.fTop); 680 uint8_t* p = pmap.writable_addr8(area.fLeft, area.fTop);
691 while (--height >= 0) { 681 while (--height >= 0) {
692 memset(p, gray, width); 682 memset(p, gray, width);
693 p += rowBytes; 683 p += rowBytes;
694 } 684 }
695 break; 685 break;
696 } 686 }
697 case kAlpha_8_SkColorType: { 687 case kAlpha_8_SkColorType: {
698 uint8_t* p = this->getAddr8(area.fLeft, area.fTop); 688 uint8_t* p = pmap.writable_addr8(area.fLeft, area.fTop);
699 while (--height >= 0) { 689 while (--height >= 0) {
700 memset(p, a, width); 690 memset(p, a, width);
701 p += rowBytes; 691 p += rowBytes;
702 } 692 }
703 break; 693 break;
704 } 694 }
705 case kARGB_4444_SkColorType: 695 case kARGB_4444_SkColorType:
706 case kRGB_565_SkColorType: { 696 case kRGB_565_SkColorType: {
707 uint16_t* p = this->getAddr16(area.fLeft, area.fTop); 697 uint16_t* p = pmap.writable_addr16(area.fLeft, area.fTop);
708 uint16_t v; 698 uint16_t v;
709 699
710 // make rgb premultiplied 700 // make rgb premultiplied
711 if (255 != a) { 701 if (255 != a) {
712 r = SkAlphaMul(r, a); 702 r = SkAlphaMul(r, a);
713 g = SkAlphaMul(g, a); 703 g = SkAlphaMul(g, a);
714 b = SkAlphaMul(b, a); 704 b = SkAlphaMul(b, a);
715 } 705 }
716 706
717 if (kARGB_4444_SkColorType == this->colorType()) { 707 if (kARGB_4444_SkColorType == pmap.colorType()) {
718 v = pack_8888_to_4444(a, r, g, b); 708 v = pack_8888_to_4444(a, r, g, b);
719 } else { 709 } else {
720 v = SkPackRGB16(r >> (8 - SK_R16_BITS), 710 v = SkPackRGB16(r >> (8 - SK_R16_BITS),
721 g >> (8 - SK_G16_BITS), 711 g >> (8 - SK_G16_BITS),
722 b >> (8 - SK_B16_BITS)); 712 b >> (8 - SK_B16_BITS));
723 } 713 }
724 while (--height >= 0) { 714 while (--height >= 0) {
725 sk_memset16(p, v, width); 715 sk_memset16(p, v, width);
726 p = (uint16_t*)((char*)p + rowBytes); 716 p = (uint16_t*)((char*)p + rowBytes);
727 } 717 }
728 break; 718 break;
729 } 719 }
730 case kBGRA_8888_SkColorType: 720 case kBGRA_8888_SkColorType:
731 case kRGBA_8888_SkColorType: { 721 case kRGBA_8888_SkColorType: {
732 uint32_t* p = this->getAddr32(area.fLeft, area.fTop); 722 uint32_t* p = pmap.writable_addr32(area.fLeft, area.fTop);
733 723
734 if (255 != a && kPremul_SkAlphaType == this->alphaType()) { 724 if (255 != a && kPremul_SkAlphaType == pmap.alphaType()) {
735 r = SkAlphaMul(r, a); 725 r = SkAlphaMul(r, a);
736 g = SkAlphaMul(g, a); 726 g = SkAlphaMul(g, a);
737 b = SkAlphaMul(b, a); 727 b = SkAlphaMul(b, a);
738 } 728 }
739 uint32_t v = kRGBA_8888_SkColorType == this->colorType() ? 729 uint32_t v = kRGBA_8888_SkColorType == pmap.colorType() ?
740 SkPackARGB_as_RGBA(a, r, g, b) : SkPackARGB_as_BGRA(a, r, g, b); 730 SkPackARGB_as_RGBA(a, r, g, b) : SkPackARGB_as_BGRA(a, r, g, b);
741 731
742 while (--height >= 0) { 732 while (--height >= 0) {
743 sk_memset32(p, v, width); 733 sk_memset32(p, v, width);
744 p = (uint32_t*)((char*)p + rowBytes); 734 p = (uint32_t*)((char*)p + rowBytes);
745 } 735 }
746 break; 736 break;
747 } 737 }
748 default: 738 default:
749 return; // no change, so don't call notifyPixelsChanged() 739 return false; // no change, so don't call notifyPixelsChanged()
740 }
741 return true;
742 }
743
744 void SkBitmap::internalErase(const SkIRect& area, U8CPU a, U8CPU r, U8CPU g, U8C PU b) const {
745 #ifdef SK_DEBUG
746 SkDEBUGCODE(this->validate();)
747 SkASSERT(!area.isEmpty());
748 {
749 SkIRect total = { 0, 0, this->width(), this->height() };
750 SkASSERT(total.contains(area));
751 }
752 #endif
753
754 switch (fInfo.colorType()) {
755 case kUnknown_SkColorType:
756 case kIndex_8_SkColorType:
757 // TODO: can we ASSERT that we never get here?
758 return; // can't erase. Should we bzero so the memory is not uniniti alized?
759 default:
760 break;
750 } 761 }
751 762
752 this->notifyPixelsChanged(); 763 SkAutoPixmapUnlock result;
764 if (!this->requestLock(&result)) {
765 return;
766 }
767
768 if (internal_erase(result.pixmap(), area, a, r, g, b)) {
769 this->notifyPixelsChanged();
770 }
753 } 771 }
754 772
755 void SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { 773 void SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const {
756 SkIRect area = { 0, 0, this->width(), this->height() }; 774 SkIRect area = { 0, 0, this->width(), this->height() };
757 if (!area.isEmpty()) { 775 if (!area.isEmpty()) {
758 this->internalErase(area, a, r, g, b); 776 this->internalErase(area, a, r, g, b);
759 } 777 }
760 } 778 }
761 779
762 void SkBitmap::eraseArea(const SkIRect& rect, SkColor c) const { 780 void SkBitmap::eraseArea(const SkIRect& rect, SkColor c) const {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 x = 0; 909 x = 0;
892 } 910 }
893 if (y > 0) { 911 if (y > 0) {
894 y = 0; 912 y = 0;
895 } 913 }
896 // here x,y are either 0 or negative 914 // here x,y are either 0 or negative
897 dstPixels = ((char*)dstPixels - y * dstRB - x * dstInfo.bytesPerPixel()); 915 dstPixels = ((char*)dstPixels - y * dstRB - x * dstInfo.bytesPerPixel());
898 916
899 ////////////// 917 //////////////
900 918
901 SkAutoLockPixels alp(*this); 919 SkAutoPixmapUnlock result;
902 920 if (!this->requestLock(&result)) {
903 // since we don't stop creating un-pixeled devices yet, check for no pixels here
904 if (NULL == this->getPixels()) {
905 return false; 921 return false;
906 } 922 }
923 const SkPixmap& pmap = result.pixmap();
924 const SkImageInfo srcInfo = pmap.info().makeWH(dstInfo.width(), dstInfo.heig ht());
907 925
908 const SkImageInfo srcInfo = this->info().makeWH(dstInfo.width(), dstInfo.hei ght()); 926 const void* srcPixels = pmap.addr(srcR.x(), srcR.y());
909 927 return SkPixelInfo::CopyPixels(dstInfo, dstPixels, dstRB, srcInfo, srcPixels , pmap.rowBytes(),
910 const void* srcPixels = this->getAddr(srcR.x(), srcR.y()); 928 pmap.ctable());
911 return SkPixelInfo::CopyPixels(dstInfo, dstPixels, dstRB, srcInfo, srcPixels , this->rowBytes(),
912 this->getColorTable());
913 } 929 }
914 930
915 bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, Allocator* alloc) const { 931 bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, Allocator* alloc) const {
916 if (!this->canCopyTo(dstColorType)) { 932 if (!this->canCopyTo(dstColorType)) {
917 return false; 933 return false;
918 } 934 }
919 935
920 // if we have a texture, first get those pixels 936 // if we have a texture, first get those pixels
921 SkBitmap tmpSrc; 937 SkBitmap tmpSrc;
922 const SkBitmap* src = this; 938 const SkBitmap* src = this;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 1057
1042 if (this->getTexture()) { 1058 if (this->getTexture()) {
1043 return false; 1059 return false;
1044 } else { 1060 } else {
1045 return this->copyTo(dst, dstCT, NULL); 1061 return this->copyTo(dst, dstCT, NULL);
1046 } 1062 }
1047 } 1063 }
1048 1064
1049 /////////////////////////////////////////////////////////////////////////////// 1065 ///////////////////////////////////////////////////////////////////////////////
1050 1066
1051 static bool GetBitmapAlpha(const SkBitmap& src, uint8_t* SK_RESTRICT alpha, 1067 static void rect_memset(uint8_t* array, U8CPU value, SkISize size, size_t rowByt es) {
1052 int alphaRowBytes) { 1068 for (int y = 0; y < size.height(); ++y) {
1053 SkASSERT(alpha != NULL); 1069 memset(array, value, size.width());
1054 SkASSERT(alphaRowBytes >= src.width()); 1070 array += rowBytes;
1071 }
1072 }
1055 1073
1056 SkColorType colorType = src.colorType(); 1074 static void get_bitmap_alpha(const SkPixmap& pmap, uint8_t* SK_RESTRICT alpha, i nt alphaRowBytes) {
1057 int w = src.width(); 1075 SkColorType colorType = pmap.colorType();
1058 int h = src.height(); 1076 int w = pmap.width();
1059 size_t rb = src.rowBytes(); 1077 int h = pmap.height();
1078 size_t rb = pmap.rowBytes();
1060 1079
1061 SkAutoLockPixels alp(src); 1080 if (kAlpha_8_SkColorType == colorType && !pmap.isOpaque()) {
1062 if (!src.readyToDraw()) { 1081 const uint8_t* s = pmap.addr8(0, 0);
1063 // zero out the alpha buffer and return
1064 while (--h >= 0) {
1065 memset(alpha, 0, w);
1066 alpha += alphaRowBytes;
1067 }
1068 return false;
1069 }
1070
1071 if (kAlpha_8_SkColorType == colorType && !src.isOpaque()) {
1072 const uint8_t* s = src.getAddr8(0, 0);
1073 while (--h >= 0) { 1082 while (--h >= 0) {
1074 memcpy(alpha, s, w); 1083 memcpy(alpha, s, w);
1075 s += rb; 1084 s += rb;
1076 alpha += alphaRowBytes; 1085 alpha += alphaRowBytes;
1077 } 1086 }
1078 } else if (kN32_SkColorType == colorType && !src.isOpaque()) { 1087 } else if (kN32_SkColorType == colorType && !pmap.isOpaque()) {
1079 const SkPMColor* SK_RESTRICT s = src.getAddr32(0, 0); 1088 const SkPMColor* SK_RESTRICT s = pmap.addr32(0, 0);
1080 while (--h >= 0) { 1089 while (--h >= 0) {
1081 for (int x = 0; x < w; x++) { 1090 for (int x = 0; x < w; x++) {
1082 alpha[x] = SkGetPackedA32(s[x]); 1091 alpha[x] = SkGetPackedA32(s[x]);
1083 } 1092 }
1084 s = (const SkPMColor*)((const char*)s + rb); 1093 s = (const SkPMColor*)((const char*)s + rb);
1085 alpha += alphaRowBytes; 1094 alpha += alphaRowBytes;
1086 } 1095 }
1087 } else if (kARGB_4444_SkColorType == colorType && !src.isOpaque()) { 1096 } else if (kARGB_4444_SkColorType == colorType && !pmap.isOpaque()) {
1088 const SkPMColor16* SK_RESTRICT s = src.getAddr16(0, 0); 1097 const SkPMColor16* SK_RESTRICT s = pmap.addr16(0, 0);
1089 while (--h >= 0) { 1098 while (--h >= 0) {
1090 for (int x = 0; x < w; x++) { 1099 for (int x = 0; x < w; x++) {
1091 alpha[x] = SkPacked4444ToA32(s[x]); 1100 alpha[x] = SkPacked4444ToA32(s[x]);
1092 } 1101 }
1093 s = (const SkPMColor16*)((const char*)s + rb); 1102 s = (const SkPMColor16*)((const char*)s + rb);
1094 alpha += alphaRowBytes; 1103 alpha += alphaRowBytes;
1095 } 1104 }
1096 } else if (kIndex_8_SkColorType == colorType && !src.isOpaque()) { 1105 } else if (kIndex_8_SkColorType == colorType && !pmap.isOpaque()) {
1097 SkColorTable* ct = src.getColorTable(); 1106 const SkColorTable* ct = pmap.ctable();
1098 if (ct) { 1107 if (ct) {
1099 const SkPMColor* SK_RESTRICT table = ct->readColors(); 1108 const SkPMColor* SK_RESTRICT table = ct->readColors();
1100 const uint8_t* SK_RESTRICT s = src.getAddr8(0, 0); 1109 const uint8_t* SK_RESTRICT s = pmap.addr8(0, 0);
1101 while (--h >= 0) { 1110 while (--h >= 0) {
1102 for (int x = 0; x < w; x++) { 1111 for (int x = 0; x < w; x++) {
1103 alpha[x] = SkGetPackedA32(table[s[x]]); 1112 alpha[x] = SkGetPackedA32(table[s[x]]);
1104 } 1113 }
1105 s += rb; 1114 s += rb;
1106 alpha += alphaRowBytes; 1115 alpha += alphaRowBytes;
1107 } 1116 }
1108 } 1117 }
1109 } else { // src is opaque, so just fill alpha[] with 0xFF 1118 } else { // src is opaque, so just fill alpha[] with 0xFF
1110 memset(alpha, 0xFF, h * alphaRowBytes); 1119 rect_memset(alpha, 0xFF, pmap.info().dimensions(), alphaRowBytes);
1111 } 1120 }
1121 }
1122
1123 static bool GetBitmapAlpha(const SkBitmap& src, uint8_t* SK_RESTRICT alpha, int alphaRowBytes) {
1124 SkASSERT(alpha != NULL);
1125 SkASSERT(alphaRowBytes >= src.width());
1126
1127 SkAutoPixmapUnlock apl;
1128 if (!src.requestLock(&apl)) {
1129 rect_memset(alpha, 0, src.info().dimensions(), alphaRowBytes);
1130 return false;
1131 }
1132 get_bitmap_alpha(apl.pixmap(), alpha, alphaRowBytes);
1112 return true; 1133 return true;
1113 } 1134 }
1114 1135
1115 #include "SkPaint.h" 1136 #include "SkPaint.h"
1116 #include "SkMaskFilter.h" 1137 #include "SkMaskFilter.h"
1117 #include "SkMatrix.h" 1138 #include "SkMatrix.h"
1118 1139
1119 bool SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint, 1140 bool SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint,
1120 Allocator *allocator, SkIPoint* offset) const { 1141 Allocator *allocator, SkIPoint* offset) const {
1121 SkDEBUGCODE(this->validate();) 1142 SkDEBUGCODE(this->validate();)
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 offset->set(dstM.fBounds.fLeft, dstM.fBounds.fTop); 1197 offset->set(dstM.fBounds.fLeft, dstM.fBounds.fTop);
1177 } 1198 }
1178 SkDEBUGCODE(tmpBitmap.validate();) 1199 SkDEBUGCODE(tmpBitmap.validate();)
1179 1200
1180 tmpBitmap.swap(*dst); 1201 tmpBitmap.swap(*dst);
1181 return true; 1202 return true;
1182 } 1203 }
1183 1204
1184 /////////////////////////////////////////////////////////////////////////////// 1205 ///////////////////////////////////////////////////////////////////////////////
1185 1206
1186 void SkBitmap::WriteRawPixels(SkWriteBuffer* buffer, const SkBitmap& bitmap) { 1207 static void write_raw_pixels(SkWriteBuffer* buffer, const SkPixmap& pmap) {
1187 const SkImageInfo info = bitmap.info(); 1208 const SkImageInfo& info = pmap.info();
1188 SkAutoLockPixels alp(bitmap);
1189 if (0 == info.width() || 0 == info.height() || NULL == bitmap.getPixels()) {
1190 buffer->writeUInt(0); // instead of snugRB, signaling no pixels
1191 return;
1192 }
1193
1194 const size_t snugRB = info.width() * info.bytesPerPixel(); 1209 const size_t snugRB = info.width() * info.bytesPerPixel();
1195 const char* src = (const char*)bitmap.getPixels(); 1210 const char* src = (const char*)pmap.addr();
1196 const size_t ramRB = bitmap.rowBytes(); 1211 const size_t ramRB = pmap.rowBytes();
1197 1212
1198 buffer->write32(SkToU32(snugRB)); 1213 buffer->write32(SkToU32(snugRB));
1199 info.flatten(*buffer); 1214 info.flatten(*buffer);
1200 1215
1201 const size_t size = snugRB * info.height(); 1216 const size_t size = snugRB * info.height();
1202 SkAutoMalloc storage(size); 1217 SkAutoMalloc storage(size);
1203 char* dst = (char*)storage.get(); 1218 char* dst = (char*)storage.get();
1204 for (int y = 0; y < info.height(); ++y) { 1219 for (int y = 0; y < info.height(); ++y) {
1205 memcpy(dst, src, snugRB); 1220 memcpy(dst, src, snugRB);
1206 dst += snugRB; 1221 dst += snugRB;
1207 src += ramRB; 1222 src += ramRB;
1208 } 1223 }
1209 buffer->writeByteArray(storage.get(), size); 1224 buffer->writeByteArray(storage.get(), size);
1210 1225
1211 SkColorTable* ct = bitmap.getColorTable(); 1226 const SkColorTable* ct = pmap.ctable();
1212 if (kIndex_8_SkColorType == info.colorType() && ct) { 1227 if (kIndex_8_SkColorType == info.colorType() && ct) {
1213 buffer->writeBool(true); 1228 buffer->writeBool(true);
1214 ct->writeToBuffer(*buffer); 1229 ct->writeToBuffer(*buffer);
1215 } else { 1230 } else {
1216 buffer->writeBool(false); 1231 buffer->writeBool(false);
1217 } 1232 }
1218 } 1233 }
1219 1234
1235 void SkBitmap::WriteRawPixels(SkWriteBuffer* buffer, const SkBitmap& bitmap) {
1236 const SkImageInfo info = bitmap.info();
1237 if (0 == info.width() || 0 == info.height() || NULL == bitmap.pixelRef()) {
1238 buffer->writeUInt(0); // instead of snugRB, signaling no pixels
1239 return;
1240 }
1241
1242 SkAutoPixmapUnlock result;
1243 if (!bitmap.requestLock(&result)) {
1244 buffer->writeUInt(0); // instead of snugRB, signaling no pixels
1245 return;
1246 }
1247
1248 write_raw_pixels(buffer, result.pixmap());
1249 }
1250
1220 bool SkBitmap::ReadRawPixels(SkReadBuffer* buffer, SkBitmap* bitmap) { 1251 bool SkBitmap::ReadRawPixels(SkReadBuffer* buffer, SkBitmap* bitmap) {
1221 const size_t snugRB = buffer->readUInt(); 1252 const size_t snugRB = buffer->readUInt();
1222 if (0 == snugRB) { // no pixels 1253 if (0 == snugRB) { // no pixels
1223 return false; 1254 return false;
1224 } 1255 }
1225 1256
1226 SkImageInfo info; 1257 SkImageInfo info;
1227 info.unflatten(*buffer); 1258 info.unflatten(*buffer);
1228 1259
1229 // If there was an error reading "info", don't use it to compute minRowBytes () 1260 // If there was an error reading "info", don't use it to compute minRowBytes ()
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 str->appendf(" pixelref:%p", pr); 1388 str->appendf(" pixelref:%p", pr);
1358 } 1389 }
1359 } 1390 }
1360 1391
1361 str->append(")"); 1392 str->append(")");
1362 } 1393 }
1363 #endif 1394 #endif
1364 1395
1365 /////////////////////////////////////////////////////////////////////////////// 1396 ///////////////////////////////////////////////////////////////////////////////
1366 1397
1398 bool SkBitmap::requestLock(SkAutoPixmapUnlock* result) const {
1399 SkASSERT(result);
1400
1401 SkPixelRef* pr = fPixelRef;
1402 if (NULL == pr) {
1403 return false;
1404 }
1405
1406 SkPixelRef::LockRequest req = { fInfo.dimensions(), kNone_SkFilterQuality };
1407 SkPixelRef::LockResult res;
1408 if (pr->requestLock(req, &res)) {
1409 // The bitmap may be a subset of the pixelref's dimensions
1410 SkASSERT(fPixelRefOrigin.x() + fInfo.width() <= res.fSize.width());
1411 SkASSERT(fPixelRefOrigin.y() + fInfo.height() <= res.fSize.height());
1412 const void* addr = (const char*)res.fPixels + SkColorTypeComputeOffset(f Info.colorType(),
1413 f PixelRefOrigin.x(),
1414 f PixelRefOrigin.y(),
1415 r es.fRowBytes);
1416
1417 result->reset(SkPixmap(this->info(), addr, res.fRowBytes, res.fCTable),
1418 res.fUnlockProc, res.fUnlockContext);
1419 return true;
1420 }
1421 return false;
1422 }
1423
1424 ///////////////////////////////////////////////////////////////////////////////
1425
1367 #ifdef SK_DEBUG 1426 #ifdef SK_DEBUG
1368 void SkImageInfo::validate() const { 1427 void SkImageInfo::validate() const {
1369 SkASSERT(fWidth >= 0); 1428 SkASSERT(fWidth >= 0);
1370 SkASSERT(fHeight >= 0); 1429 SkASSERT(fHeight >= 0);
1371 SkASSERT(SkColorTypeIsValid(fColorType)); 1430 SkASSERT(SkColorTypeIsValid(fColorType));
1372 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); 1431 SkASSERT(SkAlphaTypeIsValid(fAlphaType));
1373 } 1432 }
1374 #endif 1433 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698