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

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: 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& pmap, void* const dst, size_t dstSize ,
434 size_t dstRowBytes, bool preserveDstPad) const { 434 size_t dstRowBytes, bool preserveDstPad) {
435 const SkImageInfo& info = pmap.info();
435 436
436 if (0 == dstRowBytes) { 437 if (0 == dstRowBytes) {
437 dstRowBytes = fRowBytes; 438 dstRowBytes = pmap.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) == pmap.rowBytes() ) {
446 size_t safeSize = this->getSafeSize(); 445 size_t safeSize = pmap.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, pmap.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*>(pmap.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 += pmap.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 SkAutoBitmapLockResult 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 SkAutoBitmapLockResult 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 return; // can't erase. Should we bzero so the memory is not uniniti alized?
758 default:
759 break;
750 } 760 }
751 761
752 this->notifyPixelsChanged(); 762 SkAutoBitmapLockResult result;
763 if (!this->requestLock(&result)) {
764 return;
765 }
766
767 if (internal_erase(result.pixmap(), area, a, r, g, b)) {
768 this->notifyPixelsChanged();
769 }
753 } 770 }
754 771
755 void SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { 772 void SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const {
756 SkIRect area = { 0, 0, this->width(), this->height() }; 773 SkIRect area = { 0, 0, this->width(), this->height() };
757 if (!area.isEmpty()) { 774 if (!area.isEmpty()) {
758 this->internalErase(area, a, r, g, b); 775 this->internalErase(area, a, r, g, b);
759 } 776 }
760 } 777 }
761 778
762 void SkBitmap::eraseArea(const SkIRect& rect, SkColor c) const { 779 void SkBitmap::eraseArea(const SkIRect& rect, SkColor c) const {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 x = 0; 908 x = 0;
892 } 909 }
893 if (y > 0) { 910 if (y > 0) {
894 y = 0; 911 y = 0;
895 } 912 }
896 // here x,y are either 0 or negative 913 // here x,y are either 0 or negative
897 dstPixels = ((char*)dstPixels - y * dstRB - x * dstInfo.bytesPerPixel()); 914 dstPixels = ((char*)dstPixels - y * dstRB - x * dstInfo.bytesPerPixel());
898 915
899 ////////////// 916 //////////////
900 917
901 SkAutoLockPixels alp(*this); 918 SkAutoBitmapLockResult result;
902 919 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; 920 return false;
906 } 921 }
922 const SkPixmap& pmap = result.pixmap();
923 const SkImageInfo srcInfo = pmap.info().makeWH(dstInfo.width(), dstInfo.heig ht());
907 924
908 const SkImageInfo srcInfo = this->info().makeWH(dstInfo.width(), dstInfo.hei ght()); 925 const void* srcPixels = pmap.addr(srcR.x(), srcR.y());
909 926 return SkPixelInfo::CopyPixels(dstInfo, dstPixels, dstRB, srcInfo, srcPixels , pmap.rowBytes(),
910 const void* srcPixels = this->getAddr(srcR.x(), srcR.y()); 927 pmap.ctable());
911 return SkPixelInfo::CopyPixels(dstInfo, dstPixels, dstRB, srcInfo, srcPixels , this->rowBytes(),
912 this->getColorTable());
913 } 928 }
914 929
915 bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, Allocator* alloc) const { 930 bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, Allocator* alloc) const {
916 if (!this->canCopyTo(dstColorType)) { 931 if (!this->canCopyTo(dstColorType)) {
917 return false; 932 return false;
918 } 933 }
919 934
920 // if we have a texture, first get those pixels 935 // if we have a texture, first get those pixels
921 SkBitmap tmpSrc; 936 SkBitmap tmpSrc;
922 const SkBitmap* src = this; 937 const SkBitmap* src = this;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 1056
1042 if (this->getTexture()) { 1057 if (this->getTexture()) {
1043 return false; 1058 return false;
1044 } else { 1059 } else {
1045 return this->copyTo(dst, dstCT, NULL); 1060 return this->copyTo(dst, dstCT, NULL);
1046 } 1061 }
1047 } 1062 }
1048 1063
1049 /////////////////////////////////////////////////////////////////////////////// 1064 ///////////////////////////////////////////////////////////////////////////////
1050 1065
1051 static bool GetBitmapAlpha(const SkBitmap& src, uint8_t* SK_RESTRICT alpha, 1066 static void rect_memset(uint8_t* array, U8CPU value, SkISize size, size_t rowByt es) {
1052 int alphaRowBytes) { 1067 for (int y = 0; y < size.height(); ++y) {
1053 SkASSERT(alpha != NULL); 1068 memset(array, value, size.width());
1054 SkASSERT(alphaRowBytes >= src.width()); 1069 array += rowBytes;
1070 }
1071 }
1055 1072
1056 SkColorType colorType = src.colorType(); 1073 static void get_bitmap_alpha(const SkPixmap& pmap, uint8_t* SK_RESTRICT alpha, i nt alphaRowBytes) {
1057 int w = src.width(); 1074 SkColorType colorType = pmap.colorType();
1058 int h = src.height(); 1075 int w = pmap.width();
1059 size_t rb = src.rowBytes(); 1076 int h = pmap.height();
1077 size_t rb = pmap.rowBytes();
1060 1078
1061 SkAutoLockPixels alp(src); 1079 if (kAlpha_8_SkColorType == colorType && !pmap.isOpaque()) {
1062 if (!src.readyToDraw()) { 1080 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) { 1081 while (--h >= 0) {
1074 memcpy(alpha, s, w); 1082 memcpy(alpha, s, w);
1075 s += rb; 1083 s += rb;
1076 alpha += alphaRowBytes; 1084 alpha += alphaRowBytes;
1077 } 1085 }
1078 } else if (kN32_SkColorType == colorType && !src.isOpaque()) { 1086 } else if (kN32_SkColorType == colorType && !pmap.isOpaque()) {
1079 const SkPMColor* SK_RESTRICT s = src.getAddr32(0, 0); 1087 const SkPMColor* SK_RESTRICT s = pmap.addr32(0, 0);
1080 while (--h >= 0) { 1088 while (--h >= 0) {
1081 for (int x = 0; x < w; x++) { 1089 for (int x = 0; x < w; x++) {
1082 alpha[x] = SkGetPackedA32(s[x]); 1090 alpha[x] = SkGetPackedA32(s[x]);
1083 } 1091 }
1084 s = (const SkPMColor*)((const char*)s + rb); 1092 s = (const SkPMColor*)((const char*)s + rb);
1085 alpha += alphaRowBytes; 1093 alpha += alphaRowBytes;
1086 } 1094 }
1087 } else if (kARGB_4444_SkColorType == colorType && !src.isOpaque()) { 1095 } else if (kARGB_4444_SkColorType == colorType && !pmap.isOpaque()) {
1088 const SkPMColor16* SK_RESTRICT s = src.getAddr16(0, 0); 1096 const SkPMColor16* SK_RESTRICT s = pmap.addr16(0, 0);
1089 while (--h >= 0) { 1097 while (--h >= 0) {
1090 for (int x = 0; x < w; x++) { 1098 for (int x = 0; x < w; x++) {
1091 alpha[x] = SkPacked4444ToA32(s[x]); 1099 alpha[x] = SkPacked4444ToA32(s[x]);
1092 } 1100 }
1093 s = (const SkPMColor16*)((const char*)s + rb); 1101 s = (const SkPMColor16*)((const char*)s + rb);
1094 alpha += alphaRowBytes; 1102 alpha += alphaRowBytes;
1095 } 1103 }
1096 } else if (kIndex_8_SkColorType == colorType && !src.isOpaque()) { 1104 } else if (kIndex_8_SkColorType == colorType && !pmap.isOpaque()) {
1097 SkColorTable* ct = src.getColorTable(); 1105 const SkColorTable* ct = pmap.ctable();
1098 if (ct) { 1106 if (ct) {
1099 const SkPMColor* SK_RESTRICT table = ct->readColors(); 1107 const SkPMColor* SK_RESTRICT table = ct->readColors();
1100 const uint8_t* SK_RESTRICT s = src.getAddr8(0, 0); 1108 const uint8_t* SK_RESTRICT s = pmap.addr8(0, 0);
1101 while (--h >= 0) { 1109 while (--h >= 0) {
1102 for (int x = 0; x < w; x++) { 1110 for (int x = 0; x < w; x++) {
1103 alpha[x] = SkGetPackedA32(table[s[x]]); 1111 alpha[x] = SkGetPackedA32(table[s[x]]);
1104 } 1112 }
1105 s += rb; 1113 s += rb;
1106 alpha += alphaRowBytes; 1114 alpha += alphaRowBytes;
1107 } 1115 }
1108 } 1116 }
1109 } else { // src is opaque, so just fill alpha[] with 0xFF 1117 } else { // src is opaque, so just fill alpha[] with 0xFF
1110 memset(alpha, 0xFF, h * alphaRowBytes); 1118 rect_memset(alpha, 0xFF, pmap.info().dimensions(), alphaRowBytes);
1111 } 1119 }
1120 }
1121
1122 static bool GetBitmapAlpha(const SkBitmap& src, uint8_t* SK_RESTRICT alpha, int alphaRowBytes) {
1123 SkASSERT(alpha != NULL);
1124 SkASSERT(alphaRowBytes >= src.width());
1125
1126 SkAutoBitmapLockResult apl;
1127 if (!src.requestLock(&apl)) {
1128 rect_memset(alpha, 0, src.info().dimensions(), alphaRowBytes);
1129 return false;
1130 }
1131 get_bitmap_alpha(apl.pixmap(), alpha, alphaRowBytes);
1112 return true; 1132 return true;
1113 } 1133 }
1114 1134
1115 #include "SkPaint.h" 1135 #include "SkPaint.h"
1116 #include "SkMaskFilter.h" 1136 #include "SkMaskFilter.h"
1117 #include "SkMatrix.h" 1137 #include "SkMatrix.h"
1118 1138
1119 bool SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint, 1139 bool SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint,
1120 Allocator *allocator, SkIPoint* offset) const { 1140 Allocator *allocator, SkIPoint* offset) const {
1121 SkDEBUGCODE(this->validate();) 1141 SkDEBUGCODE(this->validate();)
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 offset->set(dstM.fBounds.fLeft, dstM.fBounds.fTop); 1196 offset->set(dstM.fBounds.fLeft, dstM.fBounds.fTop);
1177 } 1197 }
1178 SkDEBUGCODE(tmpBitmap.validate();) 1198 SkDEBUGCODE(tmpBitmap.validate();)
1179 1199
1180 tmpBitmap.swap(*dst); 1200 tmpBitmap.swap(*dst);
1181 return true; 1201 return true;
1182 } 1202 }
1183 1203
1184 /////////////////////////////////////////////////////////////////////////////// 1204 ///////////////////////////////////////////////////////////////////////////////
1185 1205
1186 void SkBitmap::WriteRawPixels(SkWriteBuffer* buffer, const SkBitmap& bitmap) { 1206 static void write_raw_pixels(SkWriteBuffer* buffer, const SkPixmap& pmap) {
1187 const SkImageInfo info = bitmap.info(); 1207 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(); 1208 const size_t snugRB = info.width() * info.bytesPerPixel();
1195 const char* src = (const char*)bitmap.getPixels(); 1209 const char* src = (const char*)pmap.addr();
1196 const size_t ramRB = bitmap.rowBytes(); 1210 const size_t ramRB = pmap.rowBytes();
1197 1211
1198 buffer->write32(SkToU32(snugRB)); 1212 buffer->write32(SkToU32(snugRB));
1199 info.flatten(*buffer); 1213 info.flatten(*buffer);
1200 1214
1201 const size_t size = snugRB * info.height(); 1215 const size_t size = snugRB * info.height();
1202 SkAutoMalloc storage(size); 1216 SkAutoMalloc storage(size);
1203 char* dst = (char*)storage.get(); 1217 char* dst = (char*)storage.get();
1204 for (int y = 0; y < info.height(); ++y) { 1218 for (int y = 0; y < info.height(); ++y) {
1205 memcpy(dst, src, snugRB); 1219 memcpy(dst, src, snugRB);
1206 dst += snugRB; 1220 dst += snugRB;
1207 src += ramRB; 1221 src += ramRB;
1208 } 1222 }
1209 buffer->writeByteArray(storage.get(), size); 1223 buffer->writeByteArray(storage.get(), size);
1210 1224
1211 SkColorTable* ct = bitmap.getColorTable(); 1225 const SkColorTable* ct = pmap.ctable();
1212 if (kIndex_8_SkColorType == info.colorType() && ct) { 1226 if (kIndex_8_SkColorType == info.colorType() && ct) {
1213 buffer->writeBool(true); 1227 buffer->writeBool(true);
1214 ct->writeToBuffer(*buffer); 1228 ct->writeToBuffer(*buffer);
1215 } else { 1229 } else {
1216 buffer->writeBool(false); 1230 buffer->writeBool(false);
1217 } 1231 }
1218 } 1232 }
1219 1233
1234 void SkBitmap::WriteRawPixels(SkWriteBuffer* buffer, const SkBitmap& bitmap) {
1235 const SkImageInfo info = bitmap.info();
1236 if (0 == info.width() || 0 == info.height() || NULL == bitmap.pixelRef()) {
1237 buffer->writeUInt(0); // instead of snugRB, signaling no pixels
1238 return;
1239 }
1240
1241 SkAutoBitmapLockResult result;
1242 if (!bitmap.requestLock(&result)) {
1243 buffer->writeUInt(0); // instead of snugRB, signaling no pixels
1244 return;
1245 }
1246
1247 write_raw_pixels(buffer, result.pixmap());
1248 }
1249
1220 bool SkBitmap::ReadRawPixels(SkReadBuffer* buffer, SkBitmap* bitmap) { 1250 bool SkBitmap::ReadRawPixels(SkReadBuffer* buffer, SkBitmap* bitmap) {
1221 const size_t snugRB = buffer->readUInt(); 1251 const size_t snugRB = buffer->readUInt();
1222 if (0 == snugRB) { // no pixels 1252 if (0 == snugRB) { // no pixels
1223 return false; 1253 return false;
1224 } 1254 }
1225 1255
1226 SkImageInfo info; 1256 SkImageInfo info;
1227 info.unflatten(*buffer); 1257 info.unflatten(*buffer);
1228 1258
1229 // If there was an error reading "info", don't use it to compute minRowBytes () 1259 // 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); 1387 str->appendf(" pixelref:%p", pr);
1358 } 1388 }
1359 } 1389 }
1360 1390
1361 str->append(")"); 1391 str->append(")");
1362 } 1392 }
1363 #endif 1393 #endif
1364 1394
1365 /////////////////////////////////////////////////////////////////////////////// 1395 ///////////////////////////////////////////////////////////////////////////////
1366 1396
1397 void SkBitmap::LockResult::unlock() {
1398 SkASSERT(fIsLocked);
1399 if (fUnlockProc) {
1400 fUnlockProc(fUnlockContext);
1401 fUnlockProc = NULL;
1402 fUnlockContext = NULL;
1403 SkDEBUGCODE(fIsLocked = false;)
1404 }
1405 }
1406
1407 bool SkBitmap::requestLock(LockResult* result) const {
1408 SkPixelRef* pr = fPixelRef;
1409 if (NULL == pr) {
1410 return false;
1411 }
1412
1413 SkPixelRef::LockRequest req = { fInfo.dimensions(), kNone_SkFilterQuality };
1414 SkPixelRef::LockResult res;
1415 if (pr->requestLock(req, &res)) {
1416 // The bitmap may be a subset of the pixelref's dimensions
1417 SkASSERT(fPixelRefOrigin.x() + fInfo.width() <= res.fSize.width());
1418 SkASSERT(fPixelRefOrigin.y() + fInfo.height() <= res.fSize.height());
1419 const void* addr = (const char*)res.fPixels + SkColorTypeComputeOffset(f Info.colorType(),
1420 f PixelRefOrigin.x(),
1421 f PixelRefOrigin.y(),
1422 r es.fRowBytes);
1423
1424 new (result) LockResult(SkPixmap(this->info(), addr, res.fRowBytes, res. fCTable),
1425 res.fUnlockProc, res.fUnlockContext);
1426 return true;
1427 }
1428 return false;
1429 }
1430
1431 ///////////////////////////////////////////////////////////////////////////////
1432
1367 #ifdef SK_DEBUG 1433 #ifdef SK_DEBUG
1368 void SkImageInfo::validate() const { 1434 void SkImageInfo::validate() const {
1369 SkASSERT(fWidth >= 0); 1435 SkASSERT(fWidth >= 0);
1370 SkASSERT(fHeight >= 0); 1436 SkASSERT(fHeight >= 0);
1371 SkASSERT(SkColorTypeIsValid(fColorType)); 1437 SkASSERT(SkColorTypeIsValid(fColorType));
1372 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); 1438 SkASSERT(SkAlphaTypeIsValid(fAlphaType));
1373 } 1439 }
1374 #endif 1440 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698