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

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

Issue 377303002: add readPixels() to SkBitmap (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
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
850 #include "SkConfig8888.h"
851
852 bool SkBitmap::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t ds tRB,
853 int x, int y) const {
854 if (kUnknown_SkColorType == dstInfo.colorType()) {
855 return false;
856 }
857 if (NULL == dstPixels || dstRB < dstInfo.minRowBytes()) {
858 return false;
859 }
860 if (0 == dstInfo.width() || 0 == dstInfo.height()) {
scroggo 2014/07/10 15:09:48 Arguably this could return true.
reed1 2014/07/10 15:32:16 Possibly. Below we return false if the srcR doesn'
861 return false;
862 }
863
864 SkIRect srcR = SkIRect::MakeXYWH(x, y, dstInfo.width(), dstInfo.height());
865 if (!srcR.intersect(0, 0, this->width(), this->height())) {
866 return false;
867 }
868
869 SkImageInfo info = dstInfo;
870 // the intersect may have shrunk info's logical size
871 info.fWidth = srcR.width();
872 info.fHeight = srcR.height();
scroggo 2014/07/10 15:09:48 You never use info after this (except to check byt
reed1 2014/07/10 15:32:16 Good catch.
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 * info.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();
scroggo 2014/07/10 15:09:48 shouldn't this be: srcInfo.fWidth = info.widt
reed1 2014/07/10 15:32:15 Agreed. I will make the suggested change above, an
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
848 bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, 902 bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType,
849 Allocator* alloc) const { 903 Allocator* alloc) const {
850 if (!this->canCopyTo(dstColorType)) { 904 if (!this->canCopyTo(dstColorType)) {
851 return false; 905 return false;
852 } 906 }
853 907
854 // if we have a texture, first get those pixels 908 // if we have a texture, first get those pixels
855 SkBitmap tmpSrc; 909 SkBitmap tmpSrc;
856 const SkBitmap* src = this; 910 const SkBitmap* src = this;
857 911
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 966
913 if (!tmpDst.readyToDraw()) { 967 if (!tmpDst.readyToDraw()) {
914 // allocator/lock failed 968 // allocator/lock failed
915 return false; 969 return false;
916 } 970 }
917 971
918 // pixelRef must be non NULL or tmpDst.readyToDraw() would have 972 // pixelRef must be non NULL or tmpDst.readyToDraw() would have
919 // returned false. 973 // returned false.
920 SkASSERT(tmpDst.pixelRef() != NULL); 974 SkASSERT(tmpDst.pixelRef() != NULL);
921 975
922 /* do memcpy for the same configs cases, else use drawing 976 if (!src->readPixels(tmpDst.info(), tmpDst.getPixels(), tmpDst.rowBytes(), 0 , 0)) {
923 */ 977 return false;
924 if (src->colorType() == dstColorType) { 978 }
925 if (tmpDst.getSize() == src->getSize()) {
926 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize());
927 979
928 SkPixelRef* dstPixelRef = tmpDst.pixelRef(); 980 // Hack (for BitmapHeap) -- clone the pixelref genID even though we have a new pixelref.
929 if (dstPixelRef->info() == fPixelRef->info()) { 981 // The old copyTo impl did this, so we continue it for now.
scroggo 2014/07/10 15:09:48 I don't agree that this is a hack. The point of th
reed1 2014/07/10 15:32:16 I don't agree with the hack either, but BitmapHeap
930 dstPixelRef->cloneGenID(*fPixelRef); 982 //
931 } 983 if (src->colorType() == dstColorType && tmpDst.getSize() == src->getSize()) {
932 } else { 984 SkPixelRef* dstPixelRef = tmpDst.pixelRef();
933 const char* srcP = reinterpret_cast<const char*>(src->getPixels()); 985 if (dstPixelRef->info() == fPixelRef->info()) {
934 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels()); 986 dstPixelRef->cloneGenID(*fPixelRef);
935 // to be sure we don't read too much, only copy our logical pixels
936 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel();
937 for (int y = 0; y < tmpDst.height(); y++) {
938 memcpy(dstP, srcP, bytesToCopy);
939 srcP += src->rowBytes();
940 dstP += tmpDst.rowBytes();
941 }
942 } 987 }
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 } 988 }
976 989
977 dst->swap(tmpDst); 990 dst->swap(tmpDst);
978 return true; 991 return true;
979 } 992 }
980 993
981 bool SkBitmap::deepCopyTo(SkBitmap* dst) const { 994 bool SkBitmap::deepCopyTo(SkBitmap* dst) const {
982 const SkColorType dstCT = this->colorType(); 995 const SkColorType dstCT = this->colorType();
983 996
984 if (!this->canCopyTo(dstCT)) { 997 if (!this->canCopyTo(dstCT)) {
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 /////////////////////////////////////////////////////////////////////////////// 1396 ///////////////////////////////////////////////////////////////////////////////
1384 1397
1385 #ifdef SK_DEBUG 1398 #ifdef SK_DEBUG
1386 void SkImageInfo::validate() const { 1399 void SkImageInfo::validate() const {
1387 SkASSERT(fWidth >= 0); 1400 SkASSERT(fWidth >= 0);
1388 SkASSERT(fHeight >= 0); 1401 SkASSERT(fHeight >= 0);
1389 SkASSERT(SkColorTypeIsValid(fColorType)); 1402 SkASSERT(SkColorTypeIsValid(fColorType));
1390 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); 1403 SkASSERT(SkAlphaTypeIsValid(fAlphaType));
1391 } 1404 }
1392 #endif 1405 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698