| Index: src/codec/SkCodec_libbmp.cpp
|
| diff --git a/src/codec/SkCodec_libbmp.cpp b/src/codec/SkCodec_libbmp.cpp
|
| index b553deae6f8c0b14f669d19ee76aa4f8536f19d4..67be0dbe2557678da66ac71df29a4c0f83e1cadf 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,18 +727,30 @@ 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;
|
| }
|
|
|
| /*
|
| *
|
| + * Get the destination row to start filling from
|
| + * Used to fill the remainder of the image on incomplete input
|
| + *
|
| + */
|
| +static inline void* get_dst_start_row(void* dst, size_t dstRowBytes, int32_t y,
|
| + SkBmpCodec::RowOrder rowOrder) {
|
| + return (SkBmpCodec::kTopDown_RowOrder == rowOrder) ?
|
| + SkTAddOffset<void*>(dst, y * dstRowBytes) : dst;
|
| +}
|
| +
|
| +/*
|
| + *
|
| * Performs the bitmap decoding for bit masks input format
|
| *
|
| */
|
| 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 +772,14 @@ 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 = get_dst_start_row(dst, dstRowBytes, y, fRowOrder);
|
| + SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height() - y, 0, NULL);
|
| + }
|
| return kIncompleteInput;
|
| }
|
|
|
| @@ -899,7 +922,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 +1083,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 +1120,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 +1137,16 @@ 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 = get_dst_start_row(dst, dstRowBytes, y, fRowOrder);
|
| + SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height() - y, 0,
|
| + colorPtr);
|
| + }
|
| return kIncompleteInput;
|
| }
|
|
|
|
|