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

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

Issue 390693002: Add SkBitmap::readPixels() and reimplement copyTo and SkCanvas::readPixels (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 5 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
« no previous file with comments | « include/core/SkCanvas.h ('k') | src/core/SkBitmapDevice.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 803 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 result->swap(dst); 814 result->swap(dst);
815 return true; 815 return true;
816 } 816 }
817 817
818 /////////////////////////////////////////////////////////////////////////////// 818 ///////////////////////////////////////////////////////////////////////////////
819 819
820 #include "SkCanvas.h" 820 #include "SkCanvas.h"
821 #include "SkPaint.h" 821 #include "SkPaint.h"
822 822
823 bool SkBitmap::canCopyTo(SkColorType dstColorType) const { 823 bool SkBitmap::canCopyTo(SkColorType dstColorType) const {
824 if (this->colorType() == kUnknown_SkColorType) { 824 const SkColorType srcCT = this->colorType();
825
826 if (srcCT == kUnknown_SkColorType) {
825 return false; 827 return false;
826 } 828 }
827 829
828 bool sameConfigs = (this->colorType() == dstColorType); 830 bool sameConfigs = (srcCT == dstColorType);
829 switch (dstColorType) { 831 switch (dstColorType) {
830 case kAlpha_8_SkColorType: 832 case kAlpha_8_SkColorType:
831 case kRGB_565_SkColorType: 833 case kRGB_565_SkColorType:
832 case kRGBA_8888_SkColorType: 834 case kRGBA_8888_SkColorType:
833 case kBGRA_8888_SkColorType: 835 case kBGRA_8888_SkColorType:
834 break; 836 break;
835 case kIndex_8_SkColorType: 837 case kIndex_8_SkColorType:
836 if (!sameConfigs) { 838 if (!sameConfigs) {
837 return false; 839 return false;
838 } 840 }
839 break; 841 break;
840 case kARGB_4444_SkColorType: 842 case kARGB_4444_SkColorType:
841 return sameConfigs || kN32_SkColorType == this->colorType(); 843 return sameConfigs || kN32_SkColorType == srcCT || kIndex_8_SkColorT ype == srcCT;
842 default: 844 default:
843 return false; 845 return false;
844 } 846 }
845 return true; 847 return true;
846 } 848 }
847 849
848 bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, 850 #include "SkConfig8888.h"
849 Allocator* alloc) const { 851
852 bool SkBitmap::readPixels(const SkImageInfo& requestedDstInfo, void* dstPixels, size_t dstRB,
853 int x, int y) const {
854 if (kUnknown_SkColorType == requestedDstInfo.colorType()) {
855 return false;
856 }
857 if (NULL == dstPixels || dstRB < requestedDstInfo.minRowBytes()) {
858 return false;
859 }
860 if (0 == requestedDstInfo.width() || 0 == requestedDstInfo.height()) {
861 return false;
862 }
863
864 SkIRect srcR = SkIRect::MakeXYWH(x, y, requestedDstInfo.width(), requestedDs tInfo.height());
865 if (!srcR.intersect(0, 0, this->width(), this->height())) {
866 return false;
867 }
868
869 SkImageInfo dstInfo = requestedDstInfo;
870 // the intersect may have shrunk info's logical size
871 dstInfo.fWidth = srcR.width();
872 dstInfo.fHeight = srcR.height();
873
874 // if x or y are negative, then we have to adjust pixels
875 if (x > 0) {
876 x = 0;
877 }
878 if (y > 0) {
879 y = 0;
880 }
881 // here x,y are either 0 or negative
882 dstPixels = ((char*)dstPixels - y * dstRB - x * dstInfo.bytesPerPixel());
883
884 //////////////
885
886 SkAutoLockPixels alp(*this);
887
888 // since we don't stop creating un-pixeled devices yet, check for no pixels here
889 if (NULL == this->getPixels()) {
890 return false;
891 }
892
893 SkImageInfo srcInfo = this->info();
894 srcInfo.fWidth = dstInfo.width();
895 srcInfo.fHeight = dstInfo.height();
896
897 const void* srcPixels = this->getAddr(srcR.x(), srcR.y());
898 return SkPixelInfo::CopyPixels(dstInfo, dstPixels, dstRB, srcInfo, srcPixels , this->rowBytes(),
899 this->getColorTable());
900 }
901
902 bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, Allocator* alloc) const {
850 if (!this->canCopyTo(dstColorType)) { 903 if (!this->canCopyTo(dstColorType)) {
851 return false; 904 return false;
852 } 905 }
853 906
854 // if we have a texture, first get those pixels 907 // if we have a texture, first get those pixels
855 SkBitmap tmpSrc; 908 SkBitmap tmpSrc;
856 const SkBitmap* src = this; 909 const SkBitmap* src = this;
857 910
858 if (fPixelRef) { 911 if (fPixelRef) {
859 SkIRect subset; 912 SkIRect subset;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 965
913 if (!tmpDst.readyToDraw()) { 966 if (!tmpDst.readyToDraw()) {
914 // allocator/lock failed 967 // allocator/lock failed
915 return false; 968 return false;
916 } 969 }
917 970
918 // pixelRef must be non NULL or tmpDst.readyToDraw() would have 971 // pixelRef must be non NULL or tmpDst.readyToDraw() would have
919 // returned false. 972 // returned false.
920 SkASSERT(tmpDst.pixelRef() != NULL); 973 SkASSERT(tmpDst.pixelRef() != NULL);
921 974
922 /* do memcpy for the same configs cases, else use drawing 975 if (!src->readPixels(tmpDst.info(), tmpDst.getPixels(), tmpDst.rowBytes(), 0 , 0)) {
923 */ 976 return false;
924 if (src->colorType() == dstColorType) { 977 }
925 if (tmpDst.getSize() == src->getSize()) {
926 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize());
927 978
928 SkPixelRef* dstPixelRef = tmpDst.pixelRef(); 979 // (for BitmapHeap) Clone the pixelref genID even though we have a new pixe lref.
929 if (dstPixelRef->info() == fPixelRef->info()) { 980 // The old copyTo impl did this, so we continue it for now.
930 dstPixelRef->cloneGenID(*fPixelRef); 981 //
931 } 982 // TODO: should we ignore rowbytes (i.e. getSize)? Then it could just be
932 } else { 983 // if (src_pixelref->info == dst_pixelref->info)
933 const char* srcP = reinterpret_cast<const char*>(src->getPixels()); 984 //
934 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels()); 985 if (src->colorType() == dstColorType && tmpDst.getSize() == src->getSize()) {
935 // to be sure we don't read too much, only copy our logical pixels 986 SkPixelRef* dstPixelRef = tmpDst.pixelRef();
936 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel(); 987 if (dstPixelRef->info() == fPixelRef->info()) {
937 for (int y = 0; y < tmpDst.height(); y++) { 988 dstPixelRef->cloneGenID(*fPixelRef);
938 memcpy(dstP, srcP, bytesToCopy);
939 srcP += src->rowBytes();
940 dstP += tmpDst.rowBytes();
941 }
942 } 989 }
943 } else if (kARGB_4444_SkColorType == dstColorType
944 && kN32_SkColorType == src->colorType()) {
945 if (src->alphaType() == kUnpremul_SkAlphaType) {
946 // Our method for converting to 4444 assumes premultiplied.
947 return false;
948 }
949 SkASSERT(src->height() == tmpDst.height());
950 SkASSERT(src->width() == tmpDst.width());
951 for (int y = 0; y < src->height(); ++y) {
952 SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*) tmpDst.getAddr16(0, y);
953 SkPMColor* SK_RESTRICT srcRow = (SkPMColor*) src->getAddr32(0, y);
954 DITHER_4444_SCAN(y);
955 for (int x = 0; x < src->width(); ++x) {
956 dstRow[x] = SkDitherARGB32To4444(srcRow[x],
957 DITHER_VALUE(x));
958 }
959 }
960 } else {
961 if (tmpDst.alphaType() == kUnpremul_SkAlphaType) {
962 // We do not support drawing to unpremultiplied bitmaps.
963 return false;
964 }
965
966 // Always clear the dest in case one of the blitters accesses it
967 // TODO: switch the allocation of tmpDst to call sk_calloc_throw
968 tmpDst.eraseColor(SK_ColorTRANSPARENT);
969
970 SkCanvas canvas(tmpDst);
971 SkPaint paint;
972
973 paint.setDither(true);
974 canvas.drawBitmap(*src, 0, 0, &paint);
975 } 990 }
976 991
977 dst->swap(tmpDst); 992 dst->swap(tmpDst);
978 return true; 993 return true;
979 } 994 }
980 995
981 bool SkBitmap::deepCopyTo(SkBitmap* dst) const { 996 bool SkBitmap::deepCopyTo(SkBitmap* dst) const {
982 const SkColorType dstCT = this->colorType(); 997 const SkColorType dstCT = this->colorType();
983 998
984 if (!this->canCopyTo(dstCT)) { 999 if (!this->canCopyTo(dstCT)) {
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 /////////////////////////////////////////////////////////////////////////////// 1398 ///////////////////////////////////////////////////////////////////////////////
1384 1399
1385 #ifdef SK_DEBUG 1400 #ifdef SK_DEBUG
1386 void SkImageInfo::validate() const { 1401 void SkImageInfo::validate() const {
1387 SkASSERT(fWidth >= 0); 1402 SkASSERT(fWidth >= 0);
1388 SkASSERT(fHeight >= 0); 1403 SkASSERT(fHeight >= 0);
1389 SkASSERT(SkColorTypeIsValid(fColorType)); 1404 SkASSERT(SkColorTypeIsValid(fColorType));
1390 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); 1405 SkASSERT(SkAlphaTypeIsValid(fAlphaType));
1391 } 1406 }
1392 #endif 1407 #endif
OLDNEW
« no previous file with comments | « include/core/SkCanvas.h ('k') | src/core/SkBitmapDevice.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698