/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkCodec_libbmp.h"
#include "SkCodecPriv.h"
#include "SkColorPriv.h"
#include "SkStream.h"
#include "SkUtils.h"

/*
 *
 * Checks if the conversion between the input image and the requested output
 * image has been implemented
 *
 */
static bool conversion_possible(const SkImageInfo& dst,
                                const SkImageInfo& src) {
    // Ensure that the profile type is unchanged
    if (dst.profileType() != src.profileType()) {
        return false;
    }

    // Check for supported alpha types
    if (src.alphaType() != dst.alphaType()) {
        if (kOpaque_SkAlphaType == src.alphaType()) {
            // If the source is opaque, we must decode to opaque
            return false;
        }

        // The source is not opaque
        switch (dst.alphaType()) {
            case kPremul_SkAlphaType:
            case kUnpremul_SkAlphaType:
                // The source is not opaque, so either of these is okay
                break;
            default:
                // We cannot decode a non-opaque image to opaque (or unknown)
                return false;
        }
    }

    // Check for supported color types
    switch (dst.colorType()) {
        // Allow output to kN32 from any type of input
        case kN32_SkColorType:
            return true;
        // Allow output to kIndex_8 from compatible inputs
        case kIndex_8_SkColorType:
            return kIndex_8_SkColorType == src.colorType();
        default:
            return false;
    }
}

/*
 *
 * Defines the version and type of the second bitmap header
 *
 */
enum BitmapHeaderType {
    kInfoV1_BitmapHeaderType,
    kInfoV2_BitmapHeaderType,
    kInfoV3_BitmapHeaderType,
    kInfoV4_BitmapHeaderType,
    kInfoV5_BitmapHeaderType,
    kOS2V1_BitmapHeaderType,
    kOS2VX_BitmapHeaderType,
    kUnknown_BitmapHeaderType
};

/*
 *
 * Possible bitmap compression types
 *
 */
enum BitmapCompressionMethod {
    kNone_BitmapCompressionMethod =          0,
    k8BitRLE_BitmapCompressionMethod =       1,
    k4BitRLE_BitmapCompressionMethod =       2,
    kBitMasks_BitmapCompressionMethod =      3,
    kJpeg_BitmapCompressionMethod =          4,
    kPng_BitmapCompressionMethod =           5,
    kAlphaBitMasks_BitmapCompressionMethod = 6,
    kCMYK_BitmapCompressionMethod =          11,
    kCMYK8BitRLE_BitmapCompressionMethod =   12,
    kCMYK4BitRLE_BitmapCompressionMethod =   13
};

/*
 *
 * Checks the start of the stream to see if the image is a bitmap
 *
 */
bool SkBmpCodec::IsBmp(SkStream* stream) {
    // TODO: Support "IC", "PT", "CI", "CP", "BA"
    const char bmpSig[] = { 'B', 'M' };
    char buffer[sizeof(bmpSig)];
    return stream->read(buffer, sizeof(bmpSig)) == sizeof(bmpSig) &&
            !memcmp(buffer, bmpSig, sizeof(bmpSig));
}

/*
 *
 * Assumes IsBmp was called and returned true
 * Creates a bmp decoder
 * Reads enough of the stream to determine the image format
 *
 */
SkCodec* SkBmpCodec::NewFromStream(SkStream* stream) {
    return SkBmpCodec::NewFromStream(stream, false);
}

/*
 *
 * Creates a bmp decoder for a bmp embedded in ico
 * Reads enough of the stream to determine the image format
 *
 */
SkCodec* SkBmpCodec::NewFromIco(SkStream* stream) {
    return SkBmpCodec::NewFromStream(stream, true);
}

/*
 *
 * Read enough of the stream to initialize the SkBmpCodec. Returns a bool
 * representing success or failure. If it returned true, and codecOut was
 * not NULL, it will be set to a new SkBmpCodec.
 * Does *not* take ownership of the passed in SkStream.
 *
 */
bool SkBmpCodec::ReadHeader(SkStream* stream, bool isIco, SkCodec** codecOut) {
    // Header size constants
    static const uint32_t kBmpHeaderBytes = 14;
    static const uint32_t kBmpHeaderBytesPlusFour = kBmpHeaderBytes + 4;
    static const uint32_t kBmpOS2V1Bytes = 12;
    static const uint32_t kBmpOS2V2Bytes = 64;
    static const uint32_t kBmpInfoBaseBytes = 16;
    static const uint32_t kBmpInfoV1Bytes = 40;
    static const uint32_t kBmpInfoV2Bytes = 52;
    static const uint32_t kBmpInfoV3Bytes = 56;
    static const uint32_t kBmpInfoV4Bytes = 108;
    static const uint32_t kBmpInfoV5Bytes = 124;
    static const uint32_t kBmpMaskBytes = 12;

    // The total bytes in the bmp file
    // We only need to use this value for RLE decoding, so we will only
    // check that it is valid in the RLE case.
    uint32_t totalBytes;
    // The offset from the start of the file where the pixel data begins
    uint32_t offset;
    // The size of the second (info) header in bytes
    uint32_t infoBytes;

    // Bmps embedded in Icos skip the first Bmp header
    if (!isIco) {
        // Read the first header and the size of the second header
        SkAutoTDeleteArray<uint8_t> hBuffer(
                SkNEW_ARRAY(uint8_t, kBmpHeaderBytesPlusFour));
        if (stream->read(hBuffer.get(), kBmpHeaderBytesPlusFour) !=
                kBmpHeaderBytesPlusFour) {
            SkCodecPrintf("Error: unable to read first bitmap header.\n");
            return false;
        }

        totalBytes = get_int(hBuffer.get(), 2);
        offset = get_int(hBuffer.get(), 10);
        if (offset < kBmpHeaderBytes + kBmpOS2V1Bytes) {
            SkCodecPrintf("Error: invalid starting location for pixel data\n");
            return false;
        }

        // The size of the second (info) header in bytes
        // The size is the first field of the second header, so we have already
        // read the first four infoBytes.
        infoBytes = get_int(hBuffer.get(), 14);
        if (infoBytes < kBmpOS2V1Bytes) {
            SkCodecPrintf("Error: invalid second header size.\n");
            return false;
        }
    } else {
        // This value is only used by RLE compression.  Bmp in Ico files do not
        // use RLE.  If the compression field is incorrectly signaled as RLE,
        // we will catch this and signal an error below.
        totalBytes = 0;

        // Bmps in Ico cannot specify an offset.  We will always assume that
        // pixel data begins immediately after the color table.  This value
        // will be corrected below.
        offset = 0;

        // Read the size of the second header
        SkAutoTDeleteArray<uint8_t> hBuffer(
                SkNEW_ARRAY(uint8_t, 4));
        if (stream->read(hBuffer.get(), 4) != 4) {
            SkCodecPrintf("Error: unable to read size of second bitmap header.\n");
            return false;
        }
        infoBytes = get_int(hBuffer.get(), 0);
        if (infoBytes < kBmpOS2V1Bytes) {
            SkCodecPrintf("Error: invalid second header size.\n");
            return false;
        }
    }

    // We already read the first four bytes of the info header to get the size
    const uint32_t infoBytesRemaining = infoBytes - 4;

    // Read the second header
    SkAutoTDeleteArray<uint8_t> iBuffer(
            SkNEW_ARRAY(uint8_t, infoBytesRemaining));
    if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
        SkCodecPrintf("Error: unable to read second bitmap header.\n");
        return false;
    }

    // The number of bits used per pixel in the pixel data
    uint16_t bitsPerPixel;

    // The compression method for the pixel data
    uint32_t compression = kNone_BitmapCompressionMethod;

    // Number of colors in the color table, defaults to 0 or max (see below)
    uint32_t numColors = 0;

    // Bytes per color in the color table, early versions use 3, most use 4
    uint32_t bytesPerColor;

    // The image width and height
    int width, height;

    // Determine image information depending on second header format
    BitmapHeaderType headerType;
    if (infoBytes >= kBmpInfoBaseBytes) {
        // Check the version of the header
        switch (infoBytes) {
            case kBmpInfoV1Bytes:
                headerType = kInfoV1_BitmapHeaderType;
                break;
            case kBmpInfoV2Bytes:
                headerType = kInfoV2_BitmapHeaderType;
                break;
            case kBmpInfoV3Bytes:
                headerType = kInfoV3_BitmapHeaderType;
                break;
            case kBmpInfoV4Bytes:
                headerType = kInfoV4_BitmapHeaderType;
                break;
            case kBmpInfoV5Bytes:
                headerType = kInfoV5_BitmapHeaderType;
                break;
            case 16:
            case 20:
            case 24:
            case 28:
            case 32:
            case 36:
            case 42:
            case 46:
            case 48:
            case 60:
            case kBmpOS2V2Bytes:
                headerType = kOS2VX_BitmapHeaderType;
                break;
            default:
                // We do not signal an error here because there is the
                // possibility of new or undocumented bmp header types.  Most
                // of the newer versions of bmp headers are similar to and
                // build off of the older versions, so we may still be able to
                // decode the bmp.
                SkCodecPrintf("Warning: unknown bmp header format.\n");
                headerType = kUnknown_BitmapHeaderType;
                break;
        }
        // We check the size of the header before entering the if statement.
        // We should not reach this point unless the size is large enough for
        // these required fields.
        SkASSERT(infoBytesRemaining >= 12);
        width = get_int(iBuffer.get(), 0);
        height = get_int(iBuffer.get(), 4);
        bitsPerPixel = get_short(iBuffer.get(), 10);

        // Some versions do not have these fields, so we check before
        // overwriting the default value.
        if (infoBytesRemaining >= 16) {
            compression = get_int(iBuffer.get(), 12);
            if (infoBytesRemaining >= 32) {
                numColors = get_int(iBuffer.get(), 28);
            }
        }

        // All of the headers that reach this point, store color table entries
        // using 4 bytes per pixel.
        bytesPerColor = 4;
    } else if (infoBytes >= kBmpOS2V1Bytes) {
        // The OS2V1 is treated separately because it has a unique format
        headerType = kOS2V1_BitmapHeaderType;
        width = (int) get_short(iBuffer.get(), 0);
        height = (int) get_short(iBuffer.get(), 2);
        bitsPerPixel = get_short(iBuffer.get(), 6);
        bytesPerColor = 3;
    } else {
        // There are no valid bmp headers
        SkCodecPrintf("Error: second bitmap header size is invalid.\n");
        return false;
    }

    // Check for valid dimensions from header
    RowOrder rowOrder = kBottomUp_RowOrder;
    if (height < 0) {
        height = -height;
        rowOrder = kTopDown_RowOrder;
    }
    // The height field for bmp in ico is double the actual height because they
    // contain an XOR mask followed by an AND mask
    if (isIco) {
        height /= 2;
    }
    if (width <= 0 || height <= 0) {
        // TODO: Decide if we want to disable really large bmps as well.
        // https://code.google.com/p/skia/issues/detail?id=3617
        SkCodecPrintf("Error: invalid bitmap dimensions.\n");
        return false;
    }

    // Create mask struct
    SkMasks::InputMasks inputMasks;
    memset(&inputMasks, 0, sizeof(SkMasks::InputMasks));

    // Determine the input compression format and set bit masks if necessary
    uint32_t maskBytes = 0;
    BitmapInputFormat inputFormat = kUnknown_BitmapInputFormat;
    switch (compression) {
        case kNone_BitmapCompressionMethod:
            inputFormat = kStandard_BitmapInputFormat;
            break;
        case k8BitRLE_BitmapCompressionMethod:
            if (bitsPerPixel != 8) {
                SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
                bitsPerPixel = 8;
            }
            inputFormat = kRLE_BitmapInputFormat;
            break;
        case k4BitRLE_BitmapCompressionMethod:
            if (bitsPerPixel != 4) {
                SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
                bitsPerPixel = 4;
            }
            inputFormat = kRLE_BitmapInputFormat;
            break;
        case kAlphaBitMasks_BitmapCompressionMethod:
        case kBitMasks_BitmapCompressionMethod:
            // Load the masks
            inputFormat = kBitMask_BitmapInputFormat;
            switch (headerType) {
                case kInfoV1_BitmapHeaderType: {
                    // The V1 header stores the bit masks after the header
                    SkAutoTDeleteArray<uint8_t> mBuffer(
                            SkNEW_ARRAY(uint8_t, kBmpMaskBytes));
                    if (stream->read(mBuffer.get(), kBmpMaskBytes) !=
                            kBmpMaskBytes) {
                        SkCodecPrintf("Error: unable to read bit inputMasks.\n");
                        return false;
                    }
                    maskBytes = kBmpMaskBytes;
                    inputMasks.red = get_int(mBuffer.get(), 0);
                    inputMasks.green = get_int(mBuffer.get(), 4);
                    inputMasks.blue = get_int(mBuffer.get(), 8);
                    break;
                }
                case kInfoV2_BitmapHeaderType:
                case kInfoV3_BitmapHeaderType:
                case kInfoV4_BitmapHeaderType:
                case kInfoV5_BitmapHeaderType:
                    // Header types are matched based on size.  If the header
                    // is V2+, we are guaranteed to be able to read at least
                    // this size.
                    SkASSERT(infoBytesRemaining >= 48);
                    inputMasks.red = get_int(iBuffer.get(), 36);
                    inputMasks.green = get_int(iBuffer.get(), 40);
                    inputMasks.blue = get_int(iBuffer.get(), 44);
                    break;
                case kOS2VX_BitmapHeaderType:
                    // TODO: Decide if we intend to support this.
                    //       It is unsupported in the previous version and
                    //       in chromium.  I have not come across a test case
                    //       that uses this format.
                    SkCodecPrintf("Error: huffman format unsupported.\n");
                    return false;
                default:
                   SkCodecPrintf("Error: invalid bmp bit masks header.\n");
                   return false;
            }
            break;
        case kJpeg_BitmapCompressionMethod:
            if (24 == bitsPerPixel) {
                inputFormat = kRLE_BitmapInputFormat;
                break;
            }
            // Fall through
        case kPng_BitmapCompressionMethod:
            // TODO: Decide if we intend to support this.
            //       It is unsupported in the previous version and
            //       in chromium.  I think it is used mostly for printers.
            SkCodecPrintf("Error: compression format not supported.\n");
            return false;
        case kCMYK_BitmapCompressionMethod:
        case kCMYK8BitRLE_BitmapCompressionMethod:
        case kCMYK4BitRLE_BitmapCompressionMethod:
            // TODO: Same as above.
            SkCodecPrintf("Error: CMYK not supported for bitmap decoding.\n");
            return false;
        default:
            SkCodecPrintf("Error: invalid format for bitmap decoding.\n");
            return false;
    }

    // Most versions of bmps should be rendered as opaque.  Either they do
    // not have an alpha channel, or they expect the alpha channel to be
    // ignored.  V3+ bmp files introduce an alpha mask and allow the creator
    // of the image to use the alpha channels.  However, many of these images
    // leave the alpha channel blank and expect to be rendered as opaque.  This
    // is the case for almost all V3 images, so we render these as opaque.  For
    // V4+, we will use the alpha channel, and fix the image later if it turns
    // out to be fully transparent.
    // As an exception, V3 bmp-in-ico may use an alpha mask.
    SkAlphaType alphaType = kOpaque_SkAlphaType;
    if ((kInfoV3_BitmapHeaderType == headerType && isIco) ||
            kInfoV4_BitmapHeaderType == headerType ||
            kInfoV5_BitmapHeaderType == headerType) {
        // Header types are matched based on size.  If the header is
        // V3+, we are guaranteed to be able to read at least this size.
        SkASSERT(infoBytesRemaining > 52);
        inputMasks.alpha = get_int(iBuffer.get(), 48);
        if (inputMasks.alpha != 0) {
            alphaType = kUnpremul_SkAlphaType;
        }
    }
    iBuffer.free();

    // Additionally, 32 bit bmp-in-icos use the alpha channel.
    // And, RLE inputs may skip pixels, leaving them as transparent.  This
    // is uncommon, but we cannot be certain that an RLE bmp will be opaque.
    if ((isIco && 32 == bitsPerPixel) || (kRLE_BitmapInputFormat == inputFormat)) {
        alphaType = kUnpremul_SkAlphaType;
    }

    // Check for valid bits per pixel.
    // At the same time, use this information to choose a suggested color type
    // and to set default masks.
    SkColorType colorType = kN32_SkColorType;
    switch (bitsPerPixel) {
        // In addition to more standard pixel compression formats, bmp supports
        // the use of bit masks to determine pixel components.  The standard
        // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB),
        // which does not map well to any Skia color formats.  For this reason,
        // we will always enable mask mode with 16 bits per pixel.
        case 16:
            if (kBitMask_BitmapInputFormat != inputFormat) {
                inputMasks.red = 0x7C00;
                inputMasks.green = 0x03E0;
                inputMasks.blue = 0x001F;
                inputFormat = kBitMask_BitmapInputFormat;
            }
            break;
        // We want to decode to kIndex_8 for input formats that are already
        // designed in index format.
        case 1:
        case 2:
        case 4:
        case 8:
            // However, we cannot in RLE format since we may need to leave some
            // pixels as transparent.  Similarly, we also cannot for ICO images
            // since we may need to apply a transparent mask.
            if (kRLE_BitmapInputFormat != inputFormat && !isIco) {
                colorType = kIndex_8_SkColorType;
            }
        case 24:
        case 32:
            break;
        default:
            SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
            return false;
    }

    // Check that input bit masks are valid and create the masks object
    SkAutoTDelete<SkMasks>
            masks(SkMasks::CreateMasks(inputMasks, bitsPerPixel));
    if (NULL == masks) {
        SkCodecPrintf("Error: invalid input masks.\n");
        return false;
    }

    // Check for a valid number of total bytes when in RLE mode
    if (totalBytes <= offset && kRLE_BitmapInputFormat == inputFormat) {
        SkCodecPrintf("Error: RLE requires valid input size.\n");
        return false;
    }
    const size_t RLEBytes = totalBytes - offset;

    // Calculate the number of bytes read so far
    const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes;
    if (!isIco && offset < bytesRead) {
        SkCodecPrintf("Error: pixel data offset less than header size.\n");
        return false;
    }

    if (codecOut) {
        // Return the codec
        // We will use ImageInfo to store width, height, suggested color type, and
        // suggested alpha type.
        const SkImageInfo& imageInfo = SkImageInfo::Make(width, height,
                colorType, alphaType);
        *codecOut = SkNEW_ARGS(SkBmpCodec, (imageInfo, stream, bitsPerPixel,
                                            inputFormat, masks.detach(),
                                            numColors, bytesPerColor,
                                            offset - bytesRead, rowOrder,
                                            RLEBytes, isIco));
    }
    return true;
}

/*
 *
 * Creates a bmp decoder
 * Reads enough of the stream to determine the image format
 *
 */
SkCodec* SkBmpCodec::NewFromStream(SkStream* stream, bool isIco) {
    SkAutoTDelete<SkStream> streamDeleter(stream);
    SkCodec* codec = NULL;
    if (ReadHeader(stream, isIco, &codec)) {
        // codec has taken ownership of stream, so we do not need to
        // delete it.
        SkASSERT(codec);
        streamDeleter.detach();
        return codec;
    }
    return NULL;
}

/*
 *
 * Creates an instance of the decoder
 * Called only by NewFromStream
 *
 */
SkBmpCodec::SkBmpCodec(const SkImageInfo& info, SkStream* stream,
                       uint16_t bitsPerPixel, BitmapInputFormat inputFormat,
                       SkMasks* masks, uint32_t numColors,
                       uint32_t bytesPerColor, uint32_t offset,
                       RowOrder rowOrder, size_t RLEBytes, bool isIco)
    : INHERITED(info, stream)
    , fBitsPerPixel(bitsPerPixel)
    , fInputFormat(inputFormat)
    , fMasks(masks)
    , fColorTable(NULL)
    , fNumColors(numColors)
    , fBytesPerColor(bytesPerColor)
    , fOffset(offset)
    , fRowOrder(rowOrder)
    , fRLEBytes(RLEBytes)
    , fIsIco(isIco)

{}

/*
 *
 * Initiates the bitmap decode
 *
 */
SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo,
                                        void* dst, size_t dstRowBytes,
                                        const Options& opts,
                                        SkPMColor* inputColorPtr,
                                        int* inputColorCount) {
    // Check for proper input and output formats
    SkCodec::RewindState rewindState = this->rewindIfNeeded();
    if (rewindState == kCouldNotRewind_RewindState) {
        return kCouldNotRewind;
    } else if (rewindState == kRewound_RewindState) {
        if (!ReadHeader(this->stream(), fIsIco, NULL)) {
            return kCouldNotRewind;
        }
    }
    if (dstInfo.dimensions() != this->getInfo().dimensions()) {
        SkCodecPrintf("Error: scaling not supported.\n");
        return kInvalidScale;
    }
    if (!conversion_possible(dstInfo, this->getInfo())) {
        SkCodecPrintf("Error: cannot convert input type to output type.\n");
        return kInvalidConversion;
    }

    // Create the color table if necessary and prepare the stream for decode
    // Note that if it is non-NULL, inputColorCount will be modified
    if (!createColorTable(dstInfo.alphaType(), inputColorCount)) {
        SkCodecPrintf("Error: could not create color table.\n");
        return kInvalidInput;
    }

    // Copy the color table to the client if necessary
    if (kIndex_8_SkColorType == dstInfo.colorType()) {
        SkASSERT(NULL != inputColorPtr);
        SkASSERT(NULL != inputColorCount);
        SkASSERT(NULL != fColorTable.get());
        sk_memcpy32(inputColorPtr, fColorTable->readColors(), *inputColorCount);
    }

    // Perform the decode
    switch (fInputFormat) {
        case kBitMask_BitmapInputFormat:
            return decodeMask(dstInfo, dst, dstRowBytes, opts);
        case kRLE_BitmapInputFormat:
            return decodeRLE(dstInfo, dst, dstRowBytes, opts);
        case kStandard_BitmapInputFormat:
            return decode(dstInfo, dst, dstRowBytes, opts);
        default:
            SkASSERT(false);
            return kInvalidInput;
    }
}

/*
 *
 * Process the color table for the bmp input
 *
 */
 bool SkBmpCodec::createColorTable(SkAlphaType alphaType, int* numColors) {
    // Allocate memory for color table
    uint32_t colorBytes = 0;
    uint32_t maxColors = 0;
    SkPMColor colorTable[256];
    if (fBitsPerPixel <= 8) {
        // Zero is a default for maxColors
        // Also set fNumColors to maxColors when it is too large
        maxColors = 1 << fBitsPerPixel;
        if (fNumColors == 0 || fNumColors >= maxColors) {
            fNumColors = maxColors;
        }

        // Inform the caller of the number of colors
        if (NULL != numColors) {
            SkASSERT(256 == *numColors);
            // We set the number of colors to maxColors in order to ensure
            // safe memory accesses.  Otherwise, an invalid pixel could
            // access memory outside of our color table array.
            *numColors = maxColors;
        }

        // Read the color table from the stream
        colorBytes = fNumColors * fBytesPerColor;
        SkAutoTDeleteArray<uint8_t> cBuffer(SkNEW_ARRAY(uint8_t, colorBytes));
        if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) {
            SkCodecPrintf("Error: unable to read color table.\n");
            return false;
        }

        // Choose the proper packing function
        SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t);
        switch (alphaType) {
            case kOpaque_SkAlphaType:
            case kUnpremul_SkAlphaType:
                packARGB = &SkPackARGB32NoCheck;
                break;
            case kPremul_SkAlphaType:
                packARGB = &SkPreMultiplyARGB;
                break;
            default:
                // This should not be reached because conversion possible
                // should fail if the alpha type is not one of the above
                // values.
                SkASSERT(false);
                packARGB = NULL;
                break;
        }

        // Fill in the color table
        uint32_t i = 0;
        for (; i < fNumColors; i++) {
            uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor);
            uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1);
            uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2);
            uint8_t alpha;
            if (kOpaque_SkAlphaType == alphaType || kRLE_BitmapInputFormat == fInputFormat) {
                alpha = 0xFF;
            } else {
                alpha = (fMasks->getAlphaMask() >> 24) &
                        get_byte(cBuffer.get(), i*fBytesPerColor + 3);
            }
            colorTable[i] = packARGB(alpha, red, green, blue);
        }

        // To avoid segmentation faults on bad pixel data, fill the end of the
        // color table with black.  This is the same the behavior as the
        // chromium decoder.
        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
    // begins.  Pixel data always begins immediately after the color table.
    if (!fIsIco) {
        // Check that we have not read past the pixel array offset
        if(fOffset < colorBytes) {
            // This may occur on OS 2.1 and other old versions where the color
            // table defaults to max size, and the bmp tries to use a smaller
            // color table.  This is invalid, and our decision is to indicate
            // an error, rather than try to guess the intended size of the
            // color table.
            SkCodecPrintf("Error: pixel data offset less than color table size.\n");
            return false;
        }

        // After reading the color table, skip to the start of the pixel array
        if (stream()->skip(fOffset - colorBytes) != fOffset - colorBytes) {
            SkCodecPrintf("Error: unable to skip to image data.\n");
            return false;
        }
    }

    // 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,
                                       const Options& opts) {
    // Set constant values
    const int width = dstInfo.width();
    const int height = dstInfo.height();
    const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel));

    // Allocate a buffer large enough to hold the full image
    SkAutoTDeleteArray<uint8_t>
        srcBuffer(SkNEW_ARRAY(uint8_t, height*rowBytes));
    uint8_t* srcRow = srcBuffer.get();

    // Create the swizzler
    SkAutoTDelete<SkMaskSwizzler> maskSwizzler(
            SkMaskSwizzler::CreateMaskSwizzler(dstInfo, dst, dstRowBytes,
            fMasks, fBitsPerPixel));

    // Iterate over rows of the image
    bool transparent = true;
    for (int y = 0; y < height; y++) {
        // Read a row of the input
        if (stream()->read(srcRow, rowBytes) != rowBytes) {
            SkCodecPrintf("Warning: incomplete input stream.\n");
            // Fill the destination image on failure
            SkPMColor fillColor = dstInfo.alphaType() == kOpaque_SkAlphaType ?
                    SK_ColorBLACK : SK_ColorTRANSPARENT;
            if (kNo_ZeroInitialized == opts.fZeroInitialized || 0 != fillColor) {
                void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrder);
                SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height() - y, fillColor,
                        NULL);
            }
            return kIncompleteInput;
        }

        // Decode the row in destination format
        int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y;
        SkSwizzler::ResultAlpha r = maskSwizzler->next(srcRow, row);
        transparent &= SkSwizzler::IsTransparent(r);

        // Move to the next row
        srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes);
    }

    // Some fully transparent bmp images are intended to be opaque.  Here, we
    // correct for this possibility.
    if (transparent) {
        const SkImageInfo& opaqueInfo =
                dstInfo.makeAlphaType(kOpaque_SkAlphaType);
        SkAutoTDelete<SkMaskSwizzler> opaqueSwizzler(
                SkMaskSwizzler::CreateMaskSwizzler(opaqueInfo, dst, dstRowBytes,
                                                   fMasks, fBitsPerPixel));
        srcRow = srcBuffer.get();
        for (int y = 0; y < height; y++) {
            // Decode the row in opaque format
            int row = kBottomUp_RowOrder == fRowOrder ? height - 1 - y : y;
            opaqueSwizzler->next(srcRow, row);

            // Move to the next row
            srcRow = SkTAddOffset<uint8_t>(srcRow, rowBytes);
        }
    }

    // Finished decoding the entire image
    return kSuccess;
}

/*
 *
 * Set an RLE pixel using the color table
 *
 */
void SkBmpCodec::setRLEPixel(void* dst, size_t dstRowBytes,
                             const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
                             uint8_t index) {
    // Set the row
    int height = dstInfo.height();
    int row;
    if (kBottomUp_RowOrder == fRowOrder) {
        row = height - y - 1;
    } else {
        row = y;
    }

    // Set the pixel based on destination color type
    switch (dstInfo.colorType()) {
        case kN32_SkColorType: {
            SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
                    row * (int) dstRowBytes);
            dstRow[x] = fColorTable->operator[](index);
            break;
        }
        default:
            // This case should not be reached.  We should catch an invalid
            // color type when we check that the conversion is possible.
            SkASSERT(false);
            break;
    }
}

/*
 *
 * Set an RLE pixel from R, G, B values
 *
 */
void SkBmpCodec::setRLE24Pixel(void* dst, size_t dstRowBytes,
                               const SkImageInfo& dstInfo, uint32_t x,
                               uint32_t y, uint8_t red, uint8_t green,
                               uint8_t blue) {
    // Set the row
    int height = dstInfo.height();
    int row;
    if (kBottomUp_RowOrder == fRowOrder) {
        row = height - y - 1;
    } else {
        row = y;
    }

    // Set the pixel based on destination color type
    switch (dstInfo.colorType()) {
        case kN32_SkColorType: {
            SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
                    row * (int) dstRowBytes);
            dstRow[x] = SkPackARGB32NoCheck(0xFF, red, green, blue);
            break;
        }
        default:
            // This case should not be reached.  We should catch an invalid
            // color type when we check that the conversion is possible.
            SkASSERT(false);
            break;
    }
}

/*
 *
 * Performs the bitmap decoding for RLE input format
 * RLE decoding is performed all at once, rather than a one row at a time
 *
 */
SkCodec::Result SkBmpCodec::decodeRLE(const SkImageInfo& dstInfo,
                                      void* dst, size_t dstRowBytes,
                                      const Options& opts) {
    // Set RLE flags
    static const uint8_t RLE_ESCAPE = 0;
    static const uint8_t RLE_EOL = 0;
    static const uint8_t RLE_EOF = 1;
    static const uint8_t RLE_DELTA = 2;

    // Set constant values
    const int width = dstInfo.width();
    const int height = dstInfo.height();

    // Input buffer parameters
    uint32_t currByte = 0;
    SkAutoTDeleteArray<uint8_t> buffer(SkNEW_ARRAY(uint8_t, fRLEBytes));
    size_t totalBytes = stream()->read(buffer.get(), fRLEBytes);
    if (totalBytes < fRLEBytes) {
        SkCodecPrintf("Warning: incomplete RLE file.\n");
    } else if (totalBytes <= 0) {
        SkCodecPrintf("Error: could not read RLE image data.\n");
        return kInvalidInput;
    }

    // Destination parameters
    int x = 0;
    int y = 0;

    // Set the background as transparent.  Then, if the RLE code skips pixels,
    // the skipped pixels will be transparent.
    // Because of the need for transparent pixels, kN32 is the only color
    // type that makes sense for the destination format.
    SkASSERT(kN32_SkColorType == dstInfo.colorType());
    if (kNo_ZeroInitialized == opts.fZeroInitialized) {
        SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, SK_ColorTRANSPARENT, NULL);
    }

    while (true) {
        // Every entry takes at least two bytes
        if ((int) totalBytes - currByte < 2) {
            SkCodecPrintf("Warning: incomplete RLE input.\n");
            return kIncompleteInput;
        }

        // Read the next two bytes.  These bytes have different meanings
        // depending on their values.  In the first interpretation, the first
        // byte is an escape flag and the second byte indicates what special
        // task to perform.
        const uint8_t flag = buffer.get()[currByte++];
        const uint8_t task = buffer.get()[currByte++];

        // If we have reached a row that is beyond the image size, and the RLE
        // code does not indicate end of file, abort and signal a warning.
        if (y >= height && (flag != RLE_ESCAPE || (task != RLE_EOF))) {
            SkCodecPrintf("Warning: invalid RLE input.\n");
            return kIncompleteInput;
        }

        // Perform decoding
        if (RLE_ESCAPE == flag) {
            switch (task) {
                case RLE_EOL:
                    x = 0;
                    y++;
                    break;
                case RLE_EOF:
                    return kSuccess;
                case RLE_DELTA: {
                    // Two bytes are needed to specify delta
                    if ((int) totalBytes - currByte < 2) {
                        SkCodecPrintf("Warning: incomplete RLE input\n");
                        return kIncompleteInput;
                    }
                    // Modify x and y
                    const uint8_t dx = buffer.get()[currByte++];
                    const uint8_t dy = buffer.get()[currByte++];
                    x += dx;
                    y += dy;
                    if (x > width || y > height) {
                        SkCodecPrintf("Warning: invalid RLE input.\n");
                        return kIncompleteInput;
                    }
                    break;
                }
                default: {
                    // If task does not match any of the above signals, it
                    // indicates that we have a sequence of non-RLE pixels.
                    // Furthermore, the value of task is equal to the number
                    // of pixels to interpret.
                    uint8_t numPixels = task;
                    const size_t rowBytes = compute_row_bytes(numPixels,
                            fBitsPerPixel);
                    // Abort if setting numPixels moves us off the edge of the
                    // image.  Also abort if there are not enough bytes
                    // remaining in the stream to set numPixels.
                    if (x + numPixels > width ||
                            (int) totalBytes - currByte < SkAlign2(rowBytes)) {
                        SkCodecPrintf("Warning: invalid RLE input.\n");
                        return kIncompleteInput;
                    }
                    // Set numPixels number of pixels
                    while (numPixels > 0) {
                        switch(fBitsPerPixel) {
                            case 4: {
                                SkASSERT(currByte < totalBytes);
                                uint8_t val = buffer.get()[currByte++];
                                setRLEPixel(dst, dstRowBytes, dstInfo, x++,
                                        y, val >> 4);
                                numPixels--;
                                if (numPixels != 0) {
                                    setRLEPixel(dst, dstRowBytes, dstInfo,
                                            x++, y, val & 0xF);
                                    numPixels--;
                                }
                                break;
                            }
                            case 8:
                                SkASSERT(currByte < totalBytes);
                                setRLEPixel(dst, dstRowBytes, dstInfo, x++,
                                        y, buffer.get()[currByte++]);
                                numPixels--;
                                break;
                            case 24: {
                                SkASSERT(currByte + 2 < totalBytes);
                                uint8_t blue = buffer.get()[currByte++];
                                uint8_t green = buffer.get()[currByte++];
                                uint8_t red = buffer.get()[currByte++];
                                setRLE24Pixel(dst, dstRowBytes, dstInfo,
                                            x++, y, red, green, blue);
                                numPixels--;
                            }
                            default:
                                SkASSERT(false);
                                return kInvalidInput;
                        }
                    }
                    // Skip a byte if necessary to maintain alignment
                    if (!SkIsAlign2(rowBytes)) {
                        currByte++;
                    }
                    break;
                }
            }
        } else {
            // If the first byte read is not a flag, it indicates the number of
            // pixels to set in RLE mode.
            const uint8_t numPixels = flag;
            const int endX = SkTMin<int>(x + numPixels, width);

            if (24 == fBitsPerPixel) {
                // In RLE24, the second byte read is part of the pixel color.
                // There are two more required bytes to finish encoding the
                // color.
                if ((int) totalBytes - currByte < 2) {
                    SkCodecPrintf("Warning: incomplete RLE input\n");
                    return kIncompleteInput;
                }

                // Fill the pixels up to endX with the specified color
                uint8_t blue = task;
                uint8_t green = buffer.get()[currByte++];
                uint8_t red = buffer.get()[currByte++];
                while (x < endX) {
                    setRLE24Pixel(dst, dstRowBytes, dstInfo, x++, y, red,
                            green, blue);
                }
            } else {
                // In RLE8 or RLE4, the second byte read gives the index in the
                // color table to look up the pixel color.
                // RLE8 has one color index that gets repeated
                // RLE4 has two color indexes in the upper and lower 4 bits of
                // the bytes, which are alternated
                uint8_t indices[2] = { task, task };
                if (4 == fBitsPerPixel) {
                    indices[0] >>= 4;
                    indices[1] &= 0xf;
                }

                // Set the indicated number of pixels
                for (int which = 0; x < endX; x++) {
                    setRLEPixel(dst, dstRowBytes, dstInfo, x, y,
                            indices[which]);
                    which = !which;
                }
            }
        }
    }
}

/*
 *
 * Performs the bitmap decoding for standard input format
 *
 */
SkCodec::Result SkBmpCodec::decode(const SkImageInfo& dstInfo,
                                   void* dst, size_t dstRowBytes,
                                   const Options& opts) {
    // Set constant values
    const int width = dstInfo.width();
    const int height = dstInfo.height();
    const size_t rowBytes = SkAlign4(compute_row_bytes(width, fBitsPerPixel));

    // Get swizzler configuration and choose the fill value for failures.  We will use
    // zero as the default palette index, black for opaque images, and transparent for
    // non-opaque images.
    SkSwizzler::SrcConfig config;
    uint32_t fillColorOrIndex;
    bool zeroFill = true;
    switch (fBitsPerPixel) {
        case 1:
            config = SkSwizzler::kIndex1;
            fillColorOrIndex = 0;
            break;
        case 2:
            config = SkSwizzler::kIndex2;
            fillColorOrIndex = 0;
            break;
        case 4:
            config = SkSwizzler::kIndex4;
            fillColorOrIndex = 0;
            break;
        case 8:
            config = SkSwizzler::kIndex;
            fillColorOrIndex = 0;
            break;
        case 24:
            config = SkSwizzler::kBGR;
            fillColorOrIndex = SK_ColorBLACK;
            zeroFill = false;
            break;
        case 32:
            if (kOpaque_SkAlphaType == dstInfo.alphaType()) {
                config = SkSwizzler::kBGRX;
                fillColorOrIndex = SK_ColorBLACK;
                zeroFill = false;
            } else {
                config = SkSwizzler::kBGRA;
                fillColorOrIndex = SK_ColorTRANSPARENT;
            }
            break;
        default:
            SkASSERT(false);
            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,
            colorPtr, dstInfo, dst, dstRowBytes,
            SkImageGenerator::kNo_ZeroInitialized));

    // Allocate space for a row buffer and a source for the swizzler
    SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes));

    // Iterate over rows of the image
    // FIXME: bool transparent = true;
    for (int y = 0; y < height; y++) {
        // 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
            if (kNo_ZeroInitialized == opts.fZeroInitialized || !zeroFill) {
                void* dstStart = get_dst_start_row(dst, dstRowBytes, y, fRowOrder);
                SkSwizzler::Fill(dstStart, dstInfo, dstRowBytes, dstInfo.height() - y,
                        fillColorOrIndex, colorPtr);
            }
            return kIncompleteInput;
        }

        // Decode the row in destination format
        uint32_t row;
        if (kTopDown_RowOrder == fRowOrder) {
            row = y;
        } else {
            row = height - 1 - y;
        }

        swizzler->next(srcBuffer.get(), row);
        // FIXME: SkSwizzler::ResultAlpha r =
        //        swizzler->next(srcBuffer.get(), row);
        // FIXME: transparent &= SkSwizzler::IsTransparent(r);
    }

    // FIXME: This code exists to match the behavior in the chromium decoder
    // and to follow the bmp specification as it relates to alpha masks.  It is
    // commented out because we have yet to discover a test image that provides
    // an alpha mask and uses this decode mode.

    // Now we adjust the output image with some additional behavior that
    // SkSwizzler does not support.  Firstly, all bmp images that contain
    // alpha are masked by the alpha mask.  Secondly, many fully transparent
    // bmp images are intended to be opaque.  Here, we make those corrections
    // in the kN32 case.
    /*
    SkPMColor* dstRow = (SkPMColor*) dst;
    if (SkSwizzler::kBGRA == config) {
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if (transparent) {
                    dstRow[x] |= 0xFF000000;
                } else {
                    dstRow[x] &= alphaMask;
                }
                dstRow = SkTAddOffset<SkPMColor>(dstRow, dstRowBytes);
            }
        }
    }
    */

    // Finally, apply the AND mask for bmp-in-ico images
    if (fIsIco) {
        // The AND mask is always 1 bit per pixel
        const size_t rowBytes = SkAlign4(compute_row_bytes(width, 1));

        SkPMColor* dstPtr = (SkPMColor*) dst;
        for (int y = 0; y < height; y++) {
            // The srcBuffer will at least be large enough
            if (stream()->read(srcBuffer.get(), rowBytes) != rowBytes) {
                SkCodecPrintf("Warning: incomplete AND mask for bmp-in-ico.\n");
                return kIncompleteInput;
            }

            int row;
            if (kBottomUp_RowOrder == fRowOrder) {
                row = height - y - 1;
            } else {
                row = y;
            }

            SkPMColor* dstRow =
                    SkTAddOffset<SkPMColor>(dstPtr, row * dstRowBytes);

            for (int x = 0; x < width; x++) {
                int quotient;
                int modulus;
                SkTDivMod(x, 8, &quotient, &modulus);
                uint32_t shift = 7 - modulus;
                uint32_t alphaBit =
                        (srcBuffer.get()[quotient] >> shift) & 0x1;
                dstRow[x] &= alphaBit - 1;
            }
        }
    }

    // Finished decoding the entire image
    return kSuccess;
}
