| 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 |