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 864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 default: | 875 default: |
876 break; | 876 break; |
877 } | 877 } |
878 return false; | 878 return false; |
879 default: | 879 default: |
880 return false; | 880 return false; |
881 } | 881 } |
882 return true; | 882 return true; |
883 } | 883 } |
884 | 884 |
885 #include "SkConfig8888.h" | |
886 | |
887 bool SkBitmap::readPixels(const SkImageInfo& requestedDstInfo, void* dstPixels,
size_t dstRB, | 885 bool SkBitmap::readPixels(const SkImageInfo& requestedDstInfo, void* dstPixels,
size_t dstRB, |
888 int x, int y) const { | 886 int x, int y) const { |
889 if (kUnknown_SkColorType == requestedDstInfo.colorType()) { | 887 SkAutoPixmapUnlock src; |
| 888 if (!this->requestLock(&src)) { |
890 return false; | 889 return false; |
891 } | 890 } |
892 if (NULL == dstPixels || dstRB < requestedDstInfo.minRowBytes()) { | 891 return src.pixmap().readPixels(requestedDstInfo, dstPixels, dstRB, x, y); |
893 return false; | |
894 } | |
895 if (0 == requestedDstInfo.width() || 0 == requestedDstInfo.height()) { | |
896 return false; | |
897 } | |
898 | |
899 SkIRect srcR = SkIRect::MakeXYWH(x, y, requestedDstInfo.width(), requestedDs
tInfo.height()); | |
900 if (!srcR.intersect(0, 0, this->width(), this->height())) { | |
901 return false; | |
902 } | |
903 | |
904 // the intersect may have shrunk info's logical size | |
905 const SkImageInfo dstInfo = requestedDstInfo.makeWH(srcR.width(), srcR.heigh
t()); | |
906 | |
907 // if x or y are negative, then we have to adjust pixels | |
908 if (x > 0) { | |
909 x = 0; | |
910 } | |
911 if (y > 0) { | |
912 y = 0; | |
913 } | |
914 // here x,y are either 0 or negative | |
915 dstPixels = ((char*)dstPixels - y * dstRB - x * dstInfo.bytesPerPixel()); | |
916 | |
917 ////////////// | |
918 | |
919 SkAutoPixmapUnlock result; | |
920 if (!this->requestLock(&result)) { | |
921 return false; | |
922 } | |
923 const SkPixmap& pmap = result.pixmap(); | |
924 const SkImageInfo srcInfo = pmap.info().makeWH(dstInfo.width(), dstInfo.heig
ht()); | |
925 | |
926 const void* srcPixels = pmap.addr(srcR.x(), srcR.y()); | |
927 return SkPixelInfo::CopyPixels(dstInfo, dstPixels, dstRB, srcInfo, srcPixels
, pmap.rowBytes(), | |
928 pmap.ctable()); | |
929 } | 892 } |
930 | 893 |
931 bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, Allocator* alloc)
const { | 894 bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, Allocator* alloc)
const { |
932 if (!this->canCopyTo(dstColorType)) { | 895 if (!this->canCopyTo(dstColorType)) { |
933 return false; | 896 return false; |
934 } | 897 } |
935 | 898 |
936 // if we have a texture, first get those pixels | 899 // if we have a texture, first get those pixels |
937 SkBitmap tmpSrc; | 900 SkBitmap tmpSrc; |
938 const SkBitmap* src = this; | 901 const SkBitmap* src = this; |
(...skipping 19 matching lines...) Expand all Loading... |
958 dst->pixelRef()->cloneGenID(*fPixelRef); | 921 dst->pixelRef()->cloneGenID(*fPixelRef); |
959 } | 922 } |
960 return true; | 923 return true; |
961 } | 924 } |
962 | 925 |
963 // fall through to the raster case | 926 // fall through to the raster case |
964 src = &tmpSrc; | 927 src = &tmpSrc; |
965 } | 928 } |
966 } | 929 } |
967 | 930 |
968 // we lock this now, since we may need its colortable | 931 SkAutoPixmapUnlock srcUnlocker; |
969 SkAutoLockPixels srclock(*src); | 932 if (!src->requestLock(&srcUnlocker)) { |
970 if (!src->readyToDraw()) { | |
971 return false; | 933 return false; |
972 } | 934 } |
| 935 const SkPixmap& srcPM = srcUnlocker.pixmap(); |
973 | 936 |
974 // The only way to be readyToDraw is if fPixelRef is non NULL. | 937 const SkImageInfo dstInfo = srcPM.info().makeColorType(dstColorType); |
975 SkASSERT(fPixelRef != NULL); | |
976 | |
977 const SkImageInfo dstInfo = src->info().makeColorType(dstColorType); | |
978 | |
979 SkBitmap tmpDst; | 938 SkBitmap tmpDst; |
980 if (!tmpDst.setInfo(dstInfo)) { | 939 if (!tmpDst.setInfo(dstInfo)) { |
981 return false; | 940 return false; |
982 } | 941 } |
983 | 942 |
984 // allocate colortable if srcConfig == kIndex8_Config | 943 // allocate colortable if srcConfig == kIndex8_Config |
985 SkAutoTUnref<SkColorTable> ctable; | 944 SkAutoTUnref<SkColorTable> ctable; |
986 if (dstColorType == kIndex_8_SkColorType) { | 945 if (dstColorType == kIndex_8_SkColorType) { |
987 ctable.reset(SkRef(src->getColorTable())); | 946 ctable.reset(SkRef(srcPM.ctable())); |
988 } | 947 } |
989 if (!tmpDst.tryAllocPixels(alloc, ctable)) { | 948 if (!tmpDst.tryAllocPixels(alloc, ctable)) { |
990 return false; | 949 return false; |
991 } | 950 } |
992 | 951 |
993 if (!tmpDst.readyToDraw()) { | 952 SkAutoPixmapUnlock dstUnlocker; |
994 // allocator/lock failed | 953 if (!tmpDst.requestLock(&dstUnlocker)) { |
995 return false; | 954 return false; |
996 } | 955 } |
997 | 956 |
998 // pixelRef must be non NULL or tmpDst.readyToDraw() would have | 957 if (!srcPM.readPixels(dstUnlocker.pixmap())) { |
999 // returned false. | |
1000 SkASSERT(tmpDst.pixelRef() != NULL); | |
1001 | |
1002 if (!src->readPixels(tmpDst.info(), tmpDst.getPixels(), tmpDst.rowBytes(), 0
, 0)) { | |
1003 return false; | 958 return false; |
1004 } | 959 } |
1005 | 960 |
1006 // (for BitmapHeap) Clone the pixelref genID even though we have a new pixe
lref. | 961 // (for BitmapHeap) Clone the pixelref genID even though we have a new pixe
lref. |
1007 // The old copyTo impl did this, so we continue it for now. | 962 // The old copyTo impl did this, so we continue it for now. |
1008 // | 963 // |
1009 // TODO: should we ignore rowbytes (i.e. getSize)? Then it could just be | 964 // TODO: should we ignore rowbytes (i.e. getSize)? Then it could just be |
1010 // if (src_pixelref->info == dst_pixelref->info) | 965 // if (src_pixelref->info == dst_pixelref->info) |
1011 // | 966 // |
1012 if (src->colorType() == dstColorType && tmpDst.getSize() == src->getSize())
{ | 967 if (srcPM.colorType() == dstColorType && tmpDst.getSize() == srcPM.getSize64
()) { |
1013 SkPixelRef* dstPixelRef = tmpDst.pixelRef(); | 968 SkPixelRef* dstPixelRef = tmpDst.pixelRef(); |
1014 if (dstPixelRef->info() == fPixelRef->info()) { | 969 if (dstPixelRef->info() == fPixelRef->info()) { |
1015 dstPixelRef->cloneGenID(*fPixelRef); | 970 dstPixelRef->cloneGenID(*fPixelRef); |
1016 } | 971 } |
1017 } | 972 } |
1018 | 973 |
1019 dst->swap(tmpDst); | 974 dst->swap(tmpDst); |
1020 return true; | 975 return true; |
1021 } | 976 } |
1022 | 977 |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1424 /////////////////////////////////////////////////////////////////////////////// | 1379 /////////////////////////////////////////////////////////////////////////////// |
1425 | 1380 |
1426 #ifdef SK_DEBUG | 1381 #ifdef SK_DEBUG |
1427 void SkImageInfo::validate() const { | 1382 void SkImageInfo::validate() const { |
1428 SkASSERT(fWidth >= 0); | 1383 SkASSERT(fWidth >= 0); |
1429 SkASSERT(fHeight >= 0); | 1384 SkASSERT(fHeight >= 0); |
1430 SkASSERT(SkColorTypeIsValid(fColorType)); | 1385 SkASSERT(SkColorTypeIsValid(fColorType)); |
1431 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); | 1386 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); |
1432 } | 1387 } |
1433 #endif | 1388 #endif |
OLD | NEW |