Chromium Code Reviews| Index: src/codec/SkCodec_libbmp.cpp |
| diff --git a/src/codec/SkCodec_libbmp.cpp b/src/codec/SkCodec_libbmp.cpp |
| index b553deae6f8c0b14f669d19ee76aa4f8536f19d4..33a3015e73f05e646b2aafb957fdd5daefb12626 100644 |
| --- a/src/codec/SkCodec_libbmp.cpp |
| +++ b/src/codec/SkCodec_libbmp.cpp |
| @@ -614,11 +614,11 @@ SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo, |
| // Perform the decode |
| switch (fInputFormat) { |
| case kBitMask_BitmapInputFormat: |
| - return decodeMask(dstInfo, dst, dstRowBytes); |
| + return decodeMask(dstInfo, dst, dstRowBytes, opts); |
| case kRLE_BitmapInputFormat: |
| return decodeRLE(dstInfo, dst, dstRowBytes, opts); |
| case kStandard_BitmapInputFormat: |
| - return decode(dstInfo, dst, dstRowBytes); |
| + return decode(dstInfo, dst, dstRowBytes, opts); |
| default: |
| SkASSERT(false); |
| return kInvalidInput; |
| @@ -701,6 +701,9 @@ SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo, |
| for (; i < maxColors; i++) { |
| colorTable[i] = SkPackARGB32NoCheck(0xFF, 0, 0, 0); |
| } |
| + |
| + // Set the color table |
| + fColorTable.reset(SkNEW_ARGS(SkColorTable, (colorTable, maxColors))); |
| } |
| // Bmp-in-Ico files do not use an offset to indicate where the pixel data |
| @@ -724,8 +727,7 @@ SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo, |
| } |
| } |
| - // Set the color table and return true on success |
| - fColorTable.reset(SkNEW_ARGS(SkColorTable, (colorTable, maxColors))); |
| + // Return true on success |
| return true; |
| } |
| @@ -735,7 +737,8 @@ SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo, |
| * |
| */ |
| SkCodec::Result SkBmpCodec::decodeMask(const SkImageInfo& dstInfo, |
| - void* dst, size_t dstRowBytes) { |
| + void* dst, size_t dstRowBytes, |
| + const Options& opts) { |
| // Set constant values |
| const int width = dstInfo.width(); |
| const int height = dstInfo.height(); |
| @@ -757,6 +760,15 @@ SkCodec::Result SkBmpCodec::decodeMask(const SkImageInfo& dstInfo, |
| // Read a row of the input |
| if (stream()->read(srcRow, rowBytes) != rowBytes) { |
| SkCodecPrintf("Warning: incomplete input stream.\n"); |
| + // Fill the destination image on failure |
| + // By using zero as the fill value, we will fill with transparent |
| + // pixels for non-opaque images and white for opaque images. |
| + // These are arbitrary choices but allow for consistent behavior. |
| + if (kNo_ZeroInitialized == opts.fZeroInitialized) { |
| + void* dstStart = (kTopDown_RowOrder == fRowOrder) ? |
| + SkTAddOffset<void*>(dst, y * dstRowBytes) : dst; |
| + SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height() - y, 0, NULL); |
| + } |
| return kIncompleteInput; |
| } |
| @@ -899,7 +911,7 @@ SkCodec::Result SkBmpCodec::decodeRLE(const SkImageInfo& dstInfo, |
| // type that makes sense for the destination format. |
| SkASSERT(kN32_SkColorType == dstInfo.colorType()); |
| if (kNo_ZeroInitialized == opts.fZeroInitialized) { |
| - SkSwizzler::Fill(dst, dstInfo, dstRowBytes, 0, SK_ColorTRANSPARENT, NULL); |
| + SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, SK_ColorTRANSPARENT, NULL); |
| } |
| while (true) { |
| @@ -1060,7 +1072,8 @@ SkCodec::Result SkBmpCodec::decodeRLE(const SkImageInfo& dstInfo, |
| * |
| */ |
| SkCodec::Result SkBmpCodec::decode(const SkImageInfo& dstInfo, |
| - void* dst, size_t dstRowBytes) { |
| + void* dst, size_t dstRowBytes, |
| + const Options& opts) { |
| // Set constant values |
| const int width = dstInfo.width(); |
| const int height = dstInfo.height(); |
| @@ -1096,9 +1109,12 @@ SkCodec::Result SkBmpCodec::decode(const SkImageInfo& dstInfo, |
| return kInvalidInput; |
| } |
| + // Get a pointer to the color table if it exists |
| + const SkPMColor* colorPtr = NULL != fColorTable.get() ? fColorTable->readColors() : NULL; |
| + |
| // Create swizzler |
| SkAutoTDelete<SkSwizzler> swizzler(SkSwizzler::CreateSwizzler(config, |
| - fColorTable->readColors(), dstInfo, dst, dstRowBytes, |
| + colorPtr, dstInfo, dst, dstRowBytes, |
| SkImageGenerator::kNo_ZeroInitialized)); |
| // Allocate space for a row buffer and a source for the swizzler |
| @@ -1110,6 +1126,17 @@ SkCodec::Result SkBmpCodec::decode(const SkImageInfo& dstInfo, |
| // Read a row of the input |
| if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) { |
| SkCodecPrintf("Warning: incomplete input stream.\n"); |
| + // Fill the destination image on failure |
| + // By using zero as the fill value, we will fill with the first |
| + // color in the color table for palette images, transparent |
| + // pixels for non-opaque images, and white for opaque images. |
| + // These are arbitrary choices but allow for consistent behavior. |
| + if (kNo_ZeroInitialized == opts.fZeroInitialized) { |
| + void* dstStart = (kTopDown_RowOrder == fRowOrder) ? |
|
scroggo
2015/04/10 21:08:32
nit: It seems like you could use a macro/static fu
msarett
2015/04/10 21:22:32
Done.
|
| + SkTAddOffset<void*>(dst, y * dstRowBytes) : dst; |
| + SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height() - y, 0, |
| + colorPtr); |
| + } |
| return kIncompleteInput; |
| } |