Chromium Code Reviews| 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 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 975 // we know we're good, so commit to result | 975 // we know we're good, so commit to result |
| 976 result->swap(dst); | 976 result->swap(dst); |
| 977 return true; | 977 return true; |
| 978 } | 978 } |
| 979 | 979 |
| 980 /////////////////////////////////////////////////////////////////////////////// | 980 /////////////////////////////////////////////////////////////////////////////// |
| 981 | 981 |
| 982 #include "SkCanvas.h" | 982 #include "SkCanvas.h" |
| 983 #include "SkPaint.h" | 983 #include "SkPaint.h" |
| 984 | 984 |
| 985 bool SkBitmap::canCopyTo(Config dstConfig) const { | 985 #ifdef SK_SUPPORT_LEGACY_COPYTO_CONFIG |
| 986 if (this->config() == kNo_Config) { | 986 bool SkBitmap::copyTo(SkBitmap* dst, Config c, Allocator* allocator) const { |
| 987 return this->copyTo(dst, SkBitmapConfigToSkColorType(c), allocator); | |
| 988 } | |
| 989 | |
| 990 bool SkBitmap::canCopyTo(Config newConfig) const { | |
| 991 return this->canCopyTo(SkBitmapConfigToSkColorType(c)); | |
| 992 } | |
| 993 #endif | |
| 994 | |
| 995 bool SkBitmap::canCopyTo(SkColorType dstColorType) const { | |
| 996 if (this->colorType() == kUnknown_SkColorType) { | |
| 987 return false; | 997 return false; |
| 988 } | 998 } |
| 989 | 999 |
| 990 bool sameConfigs = (this->config() == dstConfig); | 1000 bool sameConfigs = (this->colorType() == dstColorType); |
| 991 switch (dstConfig) { | 1001 switch (dstColorType) { |
| 992 case kA8_Config: | 1002 case kAlpha_8_SkColorType: |
| 993 case kRGB_565_Config: | 1003 case kRGB_565_SkColorType: |
| 994 case kARGB_8888_Config: | 1004 case kPMColor_SkColorType: |
| 995 break; | 1005 break; |
| 996 case kIndex8_Config: | 1006 case kIndex_8_SkColorType: |
| 997 if (!sameConfigs) { | 1007 if (!sameConfigs) { |
| 998 return false; | 1008 return false; |
| 999 } | 1009 } |
| 1000 break; | 1010 break; |
| 1001 case kARGB_4444_Config: | 1011 case kARGB_4444_SkColorType: |
| 1002 return sameConfigs || kARGB_8888_Config == this->config(); | 1012 return sameConfigs || kPMColor_SkColorType == this->colorType(); |
| 1003 default: | 1013 default: |
| 1004 return false; | 1014 return false; |
| 1005 } | 1015 } |
| 1006 return true; | 1016 return true; |
| 1007 } | 1017 } |
| 1008 | 1018 |
| 1009 bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { | 1019 bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, |
| 1010 if (!this->canCopyTo(dstConfig)) { | 1020 Allocator* alloc) const { |
| 1021 if (!this->canCopyTo(dstColorType)) { | |
| 1011 return false; | 1022 return false; |
| 1012 } | 1023 } |
| 1013 | 1024 |
| 1014 // if we have a texture, first get those pixels | 1025 // if we have a texture, first get those pixels |
| 1015 SkBitmap tmpSrc; | 1026 SkBitmap tmpSrc; |
| 1016 const SkBitmap* src = this; | 1027 const SkBitmap* src = this; |
| 1017 | 1028 |
| 1018 if (fPixelRef) { | 1029 if (fPixelRef) { |
| 1019 SkIRect subset; | 1030 SkIRect subset; |
| 1020 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, | 1031 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, |
| 1021 fInfo.width(), fInfo.height()); | 1032 fInfo.width(), fInfo.height()); |
| 1022 if (fPixelRef->readPixels(&tmpSrc, &subset)) { | 1033 if (fPixelRef->readPixels(&tmpSrc, &subset)) { |
| 1023 SkASSERT(tmpSrc.width() == this->width()); | 1034 SkASSERT(tmpSrc.width() == this->width()); |
| 1024 SkASSERT(tmpSrc.height() == this->height()); | 1035 SkASSERT(tmpSrc.height() == this->height()); |
| 1025 | 1036 |
| 1026 // did we get lucky and we can just return tmpSrc? | 1037 // did we get lucky and we can just return tmpSrc? |
| 1027 if (tmpSrc.config() == dstConfig && NULL == alloc) { | 1038 if (tmpSrc.colorType() == dstColorType && NULL == alloc) { |
| 1028 dst->swap(tmpSrc); | 1039 dst->swap(tmpSrc); |
| 1029 // If the result is an exact copy, clone the gen ID. | 1040 // If the result is an exact copy, clone the gen ID. |
| 1030 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf o()) { | 1041 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf o()) { |
| 1031 dst->pixelRef()->cloneGenID(*fPixelRef); | 1042 dst->pixelRef()->cloneGenID(*fPixelRef); |
| 1032 } | 1043 } |
| 1033 return true; | 1044 return true; |
| 1034 } | 1045 } |
| 1035 | 1046 |
| 1036 // fall through to the raster case | 1047 // fall through to the raster case |
| 1037 src = &tmpSrc; | 1048 src = &tmpSrc; |
| 1038 } | 1049 } |
| 1039 } | 1050 } |
| 1040 | 1051 |
| 1041 // we lock this now, since we may need its colortable | 1052 // we lock this now, since we may need its colortable |
| 1042 SkAutoLockPixels srclock(*src); | 1053 SkAutoLockPixels srclock(*src); |
| 1043 if (!src->readyToDraw()) { | 1054 if (!src->readyToDraw()) { |
| 1044 return false; | 1055 return false; |
| 1045 } | 1056 } |
| 1046 | 1057 |
| 1047 // The only way to be readyToDraw is if fPixelRef is non NULL. | 1058 // The only way to be readyToDraw is if fPixelRef is non NULL. |
| 1048 SkASSERT(fPixelRef != NULL); | 1059 SkASSERT(fPixelRef != NULL); |
| 1049 | 1060 |
| 1061 SkImageInfo dstInfo = src->info(); | |
| 1062 dstInfo.fColorType = dstColorType; | |
| 1063 | |
| 1050 SkBitmap tmpDst; | 1064 SkBitmap tmpDst; |
| 1051 tmpDst.setConfig(dstConfig, src->width(), src->height(), 0, | 1065 if (!tmpDst.setConfig(dstInfo)) { |
| 1052 src->alphaType()); | 1066 return false; |
| 1067 } | |
| 1053 | 1068 |
| 1054 // allocate colortable if srcConfig == kIndex8_Config | 1069 // allocate colortable if srcConfig == kIndex8_Config |
| 1055 SkColorTable* ctable = (dstConfig == kIndex8_Config) ? | 1070 SkAutoTUnref<SkColorTable> ctable; |
| 1056 new SkColorTable(*src->getColorTable()) : NULL; | 1071 if (dstColorType == kIndex_8_SkColorType) { |
| 1057 SkAutoUnref au(ctable); | 1072 ctable.reset(new SkColorTable(*src->getColorTable())); |
|
scroggo
2014/02/20 22:14:43
nit: SkNEW_ARGS.
I know the old code did the same
reed1
2014/02/21 19:17:53
Are we convinced ctables are thread-safe-immutable
reed1
2014/02/21 19:17:53
Done.
| |
| 1073 } | |
| 1058 if (!tmpDst.allocPixels(alloc, ctable)) { | 1074 if (!tmpDst.allocPixels(alloc, ctable)) { |
| 1059 return false; | 1075 return false; |
| 1060 } | 1076 } |
| 1061 | 1077 |
| 1062 if (!tmpDst.readyToDraw()) { | 1078 if (!tmpDst.readyToDraw()) { |
| 1063 // allocator/lock failed | 1079 // allocator/lock failed |
| 1064 return false; | 1080 return false; |
| 1065 } | 1081 } |
| 1066 | 1082 |
| 1067 // pixelRef must be non NULL or tmpDst.readyToDraw() would have | 1083 // pixelRef must be non NULL or tmpDst.readyToDraw() would have |
| 1068 // returned false. | 1084 // returned false. |
| 1069 SkASSERT(tmpDst.pixelRef() != NULL); | 1085 SkASSERT(tmpDst.pixelRef() != NULL); |
| 1070 | 1086 |
| 1071 /* do memcpy for the same configs cases, else use drawing | 1087 /* do memcpy for the same configs cases, else use drawing |
| 1072 */ | 1088 */ |
| 1073 if (src->config() == dstConfig) { | 1089 if (src->colorType() == dstColorType) { |
| 1074 if (tmpDst.getSize() == src->getSize()) { | 1090 if (tmpDst.getSize() == src->getSize()) { |
| 1075 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize()); | 1091 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize()); |
| 1076 SkPixelRef* pixelRef = tmpDst.pixelRef(); | 1092 SkPixelRef* pixelRef = tmpDst.pixelRef(); |
| 1077 | 1093 |
| 1078 // In order to reach this point, we know that the width, config and | 1094 // In order to reach this point, we know that the width, config and |
| 1079 // rowbytes of the SkPixelRefs are the same, but it is possible for | 1095 // rowbytes of the SkPixelRefs are the same, but it is possible for |
| 1080 // the heights to differ, if this SkBitmap's height is a subset of | 1096 // the heights to differ, if this SkBitmap's height is a subset of |
| 1081 // fPixelRef. Only if the SkPixelRefs' heights match are we | 1097 // fPixelRef. Only if the SkPixelRefs' heights match are we |
| 1082 // guaranteed that this is an exact copy, meaning we should clone | 1098 // guaranteed that this is an exact copy, meaning we should clone |
| 1083 // the genID. | 1099 // the genID. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1095 const char* srcP = reinterpret_cast<const char*>(src->getPixels()); | 1111 const char* srcP = reinterpret_cast<const char*>(src->getPixels()); |
| 1096 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels()); | 1112 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels()); |
| 1097 // to be sure we don't read too much, only copy our logical pixels | 1113 // to be sure we don't read too much, only copy our logical pixels |
| 1098 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel(); | 1114 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel(); |
| 1099 for (int y = 0; y < tmpDst.height(); y++) { | 1115 for (int y = 0; y < tmpDst.height(); y++) { |
| 1100 memcpy(dstP, srcP, bytesToCopy); | 1116 memcpy(dstP, srcP, bytesToCopy); |
| 1101 srcP += src->rowBytes(); | 1117 srcP += src->rowBytes(); |
| 1102 dstP += tmpDst.rowBytes(); | 1118 dstP += tmpDst.rowBytes(); |
| 1103 } | 1119 } |
| 1104 } | 1120 } |
| 1105 } else if (SkBitmap::kARGB_4444_Config == dstConfig | 1121 } else if (kARGB_4444_SkColorType == dstColorType |
| 1106 && SkBitmap::kARGB_8888_Config == src->config()) { | 1122 && kPMColor_SkColorType == src->colorType()) { |
| 1107 SkASSERT(src->height() == tmpDst.height()); | 1123 SkASSERT(src->height() == tmpDst.height()); |
| 1108 SkASSERT(src->width() == tmpDst.width()); | 1124 SkASSERT(src->width() == tmpDst.width()); |
| 1109 for (int y = 0; y < src->height(); ++y) { | 1125 for (int y = 0; y < src->height(); ++y) { |
| 1110 SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*) tmpDst.getAddr16(0, y); | 1126 SkPMColor16* SK_RESTRICT dstRow = (SkPMColor16*) tmpDst.getAddr16(0, y); |
| 1111 SkPMColor* SK_RESTRICT srcRow = (SkPMColor*) src->getAddr32(0, y); | 1127 SkPMColor* SK_RESTRICT srcRow = (SkPMColor*) src->getAddr32(0, y); |
| 1112 DITHER_4444_SCAN(y); | 1128 DITHER_4444_SCAN(y); |
| 1113 for (int x = 0; x < src->width(); ++x) { | 1129 for (int x = 0; x < src->width(); ++x) { |
| 1114 dstRow[x] = SkDitherARGB32To4444(srcRow[x], | 1130 dstRow[x] = SkDitherARGB32To4444(srcRow[x], |
| 1115 DITHER_VALUE(x)); | 1131 DITHER_VALUE(x)); |
| 1116 } | 1132 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1127 canvas.drawBitmap(*src, 0, 0, &paint); | 1143 canvas.drawBitmap(*src, 0, 0, &paint); |
| 1128 } | 1144 } |
| 1129 | 1145 |
| 1130 dst->swap(tmpDst); | 1146 dst->swap(tmpDst); |
| 1131 return true; | 1147 return true; |
| 1132 } | 1148 } |
| 1133 | 1149 |
| 1134 bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { | 1150 bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { |
| 1135 const SkColorType dstCT = SkBitmapConfigToColorType(dstConfig); | 1151 const SkColorType dstCT = SkBitmapConfigToColorType(dstConfig); |
| 1136 | 1152 |
| 1137 if (!this->canCopyTo(dstConfig)) { | 1153 if (!this->canCopyTo(dstCT)) { |
| 1138 return false; | 1154 return false; |
| 1139 } | 1155 } |
| 1140 | 1156 |
| 1141 // If we have a PixelRef, and it supports deep copy, use it. | 1157 // If we have a PixelRef, and it supports deep copy, use it. |
| 1142 // Currently supported only by texture-backed bitmaps. | 1158 // Currently supported only by texture-backed bitmaps. |
| 1143 if (fPixelRef) { | 1159 if (fPixelRef) { |
| 1144 SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig); | 1160 SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig); |
| 1145 if (pixelRef) { | 1161 if (pixelRef) { |
| 1146 uint32_t rowBytes; | 1162 uint32_t rowBytes; |
| 1147 if (this->colorType() == dstCT) { | 1163 if (this->colorType() == dstCT) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1162 return false; | 1178 return false; |
| 1163 } | 1179 } |
| 1164 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); | 1180 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); |
| 1165 return true; | 1181 return true; |
| 1166 } | 1182 } |
| 1167 } | 1183 } |
| 1168 | 1184 |
| 1169 if (this->getTexture()) { | 1185 if (this->getTexture()) { |
| 1170 return false; | 1186 return false; |
| 1171 } else { | 1187 } else { |
| 1172 return this->copyTo(dst, dstConfig, NULL); | 1188 return this->copyTo(dst, dstCT, NULL); |
| 1173 } | 1189 } |
| 1174 } | 1190 } |
| 1175 | 1191 |
| 1176 bool SkBitmap::deepCopyTo(SkBitmap* dst) const { | 1192 bool SkBitmap::deepCopyTo(SkBitmap* dst) const { |
| 1177 return this->deepCopyTo(dst, this->config()); | 1193 return this->deepCopyTo(dst, this->config()); |
| 1178 } | 1194 } |
| 1179 | 1195 |
| 1180 /////////////////////////////////////////////////////////////////////////////// | 1196 /////////////////////////////////////////////////////////////////////////////// |
| 1181 /////////////////////////////////////////////////////////////////////////////// | 1197 /////////////////////////////////////////////////////////////////////////////// |
| 1182 | 1198 |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1718 /////////////////////////////////////////////////////////////////////////////// | 1734 /////////////////////////////////////////////////////////////////////////////// |
| 1719 | 1735 |
| 1720 #ifdef SK_DEBUG | 1736 #ifdef SK_DEBUG |
| 1721 void SkImageInfo::validate() const { | 1737 void SkImageInfo::validate() const { |
| 1722 SkASSERT(fWidth >= 0); | 1738 SkASSERT(fWidth >= 0); |
| 1723 SkASSERT(fHeight >= 0); | 1739 SkASSERT(fHeight >= 0); |
| 1724 SkASSERT(SkColorTypeIsValid(fColorType)); | 1740 SkASSERT(SkColorTypeIsValid(fColorType)); |
| 1725 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); | 1741 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); |
| 1726 } | 1742 } |
| 1727 #endif | 1743 #endif |
| OLD | NEW |