| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkBitmap.h" | 8 #include "SkBitmap.h" |
| 9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 numColors - numColorsWithAlpha); | 260 numColors - numColorsWithAlpha); |
| 261 } else { | 261 } else { |
| 262 SkOpts::RGB_to_BGR1(colorTable + numColorsWithAlpha, palette, | 262 SkOpts::RGB_to_BGR1(colorTable + numColorsWithAlpha, palette, |
| 263 numColors - numColorsWithAlpha); | 263 numColors - numColorsWithAlpha); |
| 264 } | 264 } |
| 265 } | 265 } |
| 266 | 266 |
| 267 // If we are not decoding to F16, we can color xform now and store the resul
ts | 267 // If we are not decoding to F16, we can color xform now and store the resul
ts |
| 268 // in the color table. | 268 // in the color table. |
| 269 if (fColorXform && kRGBA_F16_SkColorType != dstInfo.colorType()) { | 269 if (fColorXform && kRGBA_F16_SkColorType != dstInfo.colorType()) { |
| 270 SkColorSpaceXform::ColorFormat xformColorFormat = is_rgba(dstInfo.colorT
ype()) ? | 270 SkColorType xformColorType = is_rgba(dstInfo.colorType()) ? |
| 271 SkColorSpaceXform::kRGBA_8888_ColorFormat : | 271 kRGBA_8888_SkColorType : kBGRA_8888_SkColorType; |
| 272 SkColorSpaceXform::kBGRA_8888_ColorFormat; | 272 SkAlphaType xformAlphaType = select_alpha_xform(dstInfo.alphaType(), |
| 273 SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(), | |
| 274 this->getInfo().alphaTyp
e()); | 273 this->getInfo().alphaTyp
e()); |
| 275 fColorXform->apply(colorTable, colorTable, numColors, xformColorFormat,
xformAlphaType); | 274 fColorXform->apply(colorTable, colorTable, numColors, xformColorType, xf
ormAlphaType); |
| 276 } | 275 } |
| 277 | 276 |
| 278 // Pad the color table with the last color in the table (or black) in the ca
se that | 277 // Pad the color table with the last color in the table (or black) in the ca
se that |
| 279 // invalid pixel indices exceed the number of colors in the table. | 278 // invalid pixel indices exceed the number of colors in the table. |
| 280 const int maxColors = 1 << fBitDepth; | 279 const int maxColors = 1 << fBitDepth; |
| 281 if (numColors < maxColors) { | 280 if (numColors < maxColors) { |
| 282 SkPMColor lastColor = numColors > 0 ? colorTable[numColors - 1] : SK_Col
orBLACK; | 281 SkPMColor lastColor = numColors > 0 ? colorTable[numColors - 1] : SK_Col
orBLACK; |
| 283 sk_memset32(colorTable + numColors, lastColor, maxColors - numColors); | 282 sk_memset32(colorTable + numColors, lastColor, maxColors - numColors); |
| 284 } | 283 } |
| 285 | 284 |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 case kSwizzleColor_XformMode: { | 485 case kSwizzleColor_XformMode: { |
| 487 const size_t colorXformBytes = dstInfo.width() * sizeof(uint32_t); | 486 const size_t colorXformBytes = dstInfo.width() * sizeof(uint32_t); |
| 488 fStorage.reset(colorXformBytes); | 487 fStorage.reset(colorXformBytes); |
| 489 fColorXformSrcRow = (uint32_t*) fStorage.get(); | 488 fColorXformSrcRow = (uint32_t*) fStorage.get(); |
| 490 break; | 489 break; |
| 491 } | 490 } |
| 492 } | 491 } |
| 493 } | 492 } |
| 494 | 493 |
| 495 void SkPngCodec::applyXformRow(void* dst, const void* src) { | 494 void SkPngCodec::applyXformRow(void* dst, const void* src) { |
| 495 const SkColorType colorType = this->dstInfo().colorType(); |
| 496 switch (fXformMode) { | 496 switch (fXformMode) { |
| 497 case kSwizzleOnly_XformMode: | 497 case kSwizzleOnly_XformMode: |
| 498 fSwizzler->swizzle(dst, (const uint8_t*) src); | 498 fSwizzler->swizzle(dst, (const uint8_t*) src); |
| 499 break; | 499 break; |
| 500 case kColorOnly_XformMode: | 500 case kColorOnly_XformMode: |
| 501 fColorXform->apply(dst, (const uint32_t*) src, fXformWidth, fXformCo
lorFormat, | 501 fColorXform->apply(dst, (const uint32_t*) src, fXformWidth, colorTyp
e, fXformAlphaType); |
| 502 fXformAlphaType); | |
| 503 break; | 502 break; |
| 504 case kSwizzleColor_XformMode: | 503 case kSwizzleColor_XformMode: |
| 505 fSwizzler->swizzle(fColorXformSrcRow, (const uint8_t*) src); | 504 fSwizzler->swizzle(fColorXformSrcRow, (const uint8_t*) src); |
| 506 fColorXform->apply(dst, fColorXformSrcRow, fXformWidth, fXformColorF
ormat, | 505 fColorXform->apply(dst, fColorXformSrcRow, fXformWidth, colorType, f
XformAlphaType); |
| 507 fXformAlphaType); | |
| 508 break; | 506 break; |
| 509 } | 507 } |
| 510 } | 508 } |
| 511 | 509 |
| 512 class SkPngNormalDecoder : public SkPngCodec { | 510 class SkPngNormalDecoder : public SkPngCodec { |
| 513 public: | 511 public: |
| 514 SkPngNormalDecoder(const SkEncodedInfo& info, const SkImageInfo& imageInfo,
SkStream* stream, | 512 SkPngNormalDecoder(const SkEncodedInfo& info, const SkImageInfo& imageInfo,
SkStream* stream, |
| 515 SkPngChunkReader* reader, png_structp png_ptr, png_infop info_ptr, i
nt bitDepth) | 513 SkPngChunkReader* reader, png_structp png_ptr, png_infop info_ptr, i
nt bitDepth) |
| 516 : INHERITED(info, imageInfo, stream, reader, png_ptr, info_ptr, bitDepth
) | 514 : INHERITED(info, imageInfo, stream, reader, png_ptr, info_ptr, bitDepth
) |
| 517 , fLinesDecoded(0) | 515 , fLinesDecoded(0) |
| (...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 } | 1130 } |
| 1133 } | 1131 } |
| 1134 | 1132 |
| 1135 // Copy the color table to the client if they request kIndex8 mode. | 1133 // Copy the color table to the client if they request kIndex8 mode. |
| 1136 copy_color_table(dstInfo, fColorTable, ctable, ctableCount); | 1134 copy_color_table(dstInfo, fColorTable, ctable, ctableCount); |
| 1137 | 1135 |
| 1138 this->initializeSwizzler(dstInfo, options); | 1136 this->initializeSwizzler(dstInfo, options); |
| 1139 return true; | 1137 return true; |
| 1140 } | 1138 } |
| 1141 | 1139 |
| 1142 void SkPngCodec::initializeXformParams() { | 1140 void SkPngCodec::initializeXformAlphaAndWidth() { |
| 1143 switch (fXformMode) { | 1141 fXformAlphaType = select_alpha_xform(this->dstInfo().alphaType(), this->getI
nfo().alphaType()); |
| 1144 case kColorOnly_XformMode: | 1142 fXformWidth = this->swizzler() ? this->swizzler()->swizzleWidth() : this->ds
tInfo().width(); |
| 1145 fXformColorFormat = select_xform_format(this->dstInfo().colorType())
; | |
| 1146 fXformAlphaType = select_xform_alpha(this->dstInfo().alphaType(), | |
| 1147 this->getInfo().alphaType()); | |
| 1148 fXformWidth = this->dstInfo().width(); | |
| 1149 break; | |
| 1150 case kSwizzleColor_XformMode: | |
| 1151 fXformColorFormat = select_xform_format(this->dstInfo().colorType())
; | |
| 1152 fXformAlphaType = select_xform_alpha(this->dstInfo().alphaType(), | |
| 1153 this->getInfo().alphaType()); | |
| 1154 fXformWidth = this->swizzler()->swizzleWidth(); | |
| 1155 break; | |
| 1156 default: | |
| 1157 break; | |
| 1158 } | |
| 1159 } | 1143 } |
| 1160 | 1144 |
| 1161 static inline bool apply_xform_on_decode(SkColorType dstColorType, SkEncodedInfo
::Color srcColor) { | 1145 static inline bool apply_xform_on_decode(SkColorType dstColorType, SkEncodedInfo
::Color srcColor) { |
| 1162 // We will apply the color xform when reading the color table, unless F16 is
requested. | 1146 // We will apply the color xform when reading the color table, unless F16 is
requested. |
| 1163 return SkEncodedInfo::kPalette_Color != srcColor || kRGBA_F16_SkColorType ==
dstColorType; | 1147 return SkEncodedInfo::kPalette_Color != srcColor || kRGBA_F16_SkColorType ==
dstColorType; |
| 1164 } | 1148 } |
| 1165 | 1149 |
| 1166 void SkPngCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& o
ptions) { | 1150 void SkPngCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& o
ptions) { |
| 1167 SkImageInfo swizzlerInfo = dstInfo; | 1151 SkImageInfo swizzlerInfo = dstInfo; |
| 1168 Options swizzlerOptions = options; | 1152 Options swizzlerOptions = options; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1235 if (!this->rereadHeaderIfNecessary()) { | 1219 if (!this->rereadHeaderIfNecessary()) { |
| 1236 return kCouldNotRewind; | 1220 return kCouldNotRewind; |
| 1237 } | 1221 } |
| 1238 #endif | 1222 #endif |
| 1239 | 1223 |
| 1240 if (options.fSubset) { | 1224 if (options.fSubset) { |
| 1241 return kUnimplemented; | 1225 return kUnimplemented; |
| 1242 } | 1226 } |
| 1243 | 1227 |
| 1244 this->allocateStorage(dstInfo); | 1228 this->allocateStorage(dstInfo); |
| 1245 this->initializeXformParams(); | 1229 this->initializeXformAlphaAndWidth(); |
| 1246 return this->decodeAllRows(dst, rowBytes, rowsDecoded); | 1230 return this->decodeAllRows(dst, rowBytes, rowsDecoded); |
| 1247 } | 1231 } |
| 1248 | 1232 |
| 1249 SkCodec::Result SkPngCodec::onStartIncrementalDecode(const SkImageInfo& dstInfo, | 1233 SkCodec::Result SkPngCodec::onStartIncrementalDecode(const SkImageInfo& dstInfo, |
| 1250 void* dst, size_t rowBytes, const SkCodec::Options& options, | 1234 void* dst, size_t rowBytes, const SkCodec::Options& options, |
| 1251 SkPMColor* ctable, int* ctableCount) { | 1235 SkPMColor* ctable, int* ctableCount) { |
| 1252 if (!conversion_possible(dstInfo, this->getInfo()) || | 1236 if (!conversion_possible(dstInfo, this->getInfo()) || |
| 1253 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) | 1237 !this->initializeXforms(dstInfo, options, ctable, ctableCount)) |
| 1254 { | 1238 { |
| 1255 return kInvalidConversion; | 1239 return kInvalidConversion; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1270 } else { | 1254 } else { |
| 1271 firstRow = 0; | 1255 firstRow = 0; |
| 1272 lastRow = dstInfo.height() - 1; | 1256 lastRow = dstInfo.height() - 1; |
| 1273 } | 1257 } |
| 1274 this->setRange(firstRow, lastRow, dst, rowBytes); | 1258 this->setRange(firstRow, lastRow, dst, rowBytes); |
| 1275 return kSuccess; | 1259 return kSuccess; |
| 1276 } | 1260 } |
| 1277 | 1261 |
| 1278 SkCodec::Result SkPngCodec::onIncrementalDecode(int* rowsDecoded) { | 1262 SkCodec::Result SkPngCodec::onIncrementalDecode(int* rowsDecoded) { |
| 1279 // FIXME: Only necessary on the first call. | 1263 // FIXME: Only necessary on the first call. |
| 1280 this->initializeXformParams(); | 1264 this->initializeXformAlphaAndWidth(); |
| 1281 | 1265 |
| 1282 return this->decode(rowsDecoded); | 1266 return this->decode(rowsDecoded); |
| 1283 } | 1267 } |
| 1284 | 1268 |
| 1285 uint64_t SkPngCodec::onGetFillValue(const SkImageInfo& dstInfo) const { | 1269 uint64_t SkPngCodec::onGetFillValue(const SkImageInfo& dstInfo) const { |
| 1286 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); | 1270 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); |
| 1287 if (colorPtr) { | 1271 if (colorPtr) { |
| 1288 SkAlphaType alphaType = select_xform_alpha(dstInfo.alphaType(), | 1272 SkAlphaType alphaType = select_alpha_xform(dstInfo.alphaType(), |
| 1289 this->getInfo().alphaType()); | 1273 this->getInfo().alphaType()); |
| 1290 return get_color_table_fill_value(dstInfo.colorType(), alphaType, colorP
tr, 0, | 1274 return get_color_table_fill_value(dstInfo.colorType(), alphaType, colorP
tr, 0, |
| 1291 fColorXform.get()); | 1275 fColorXform.get()); |
| 1292 } | 1276 } |
| 1293 return INHERITED::onGetFillValue(dstInfo); | 1277 return INHERITED::onGetFillValue(dstInfo); |
| 1294 } | 1278 } |
| 1295 | 1279 |
| 1296 SkCodec* SkPngCodec::NewFromStream(SkStream* stream, SkPngChunkReader* chunkRead
er) { | 1280 SkCodec* SkPngCodec::NewFromStream(SkStream* stream, SkPngChunkReader* chunkRead
er) { |
| 1297 SkAutoTDelete<SkStream> streamDeleter(stream); | 1281 SkAutoTDelete<SkStream> streamDeleter(stream); |
| 1298 | 1282 |
| 1299 SkCodec* outCodec = nullptr; | 1283 SkCodec* outCodec = nullptr; |
| 1300 if (read_header(streamDeleter.get(), chunkReader, &outCodec, nullptr, nullpt
r)) { | 1284 if (read_header(streamDeleter.get(), chunkReader, &outCodec, nullptr, nullpt
r)) { |
| 1301 // Codec has taken ownership of the stream. | 1285 // Codec has taken ownership of the stream. |
| 1302 SkASSERT(outCodec); | 1286 SkASSERT(outCodec); |
| 1303 streamDeleter.release(); | 1287 streamDeleter.release(); |
| 1304 return outCodec; | 1288 return outCodec; |
| 1305 } | 1289 } |
| 1306 | 1290 |
| 1307 return nullptr; | 1291 return nullptr; |
| 1308 } | 1292 } |
| OLD | NEW |