/*
 * 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 "src/codec/SkBmpCodec.h"

#include "include/core/SkImageInfo.h"
#include "include/core/SkSize.h"
#include "include/core/SkStream.h"
#include "include/private/SkEncodedInfo.h"
#include "include/private/base/SkAlign.h"
#include "src/codec/SkBmpMaskCodec.h"
#include "src/codec/SkBmpRLECodec.h"
#include "src/codec/SkBmpStandardCodec.h"
#include "src/codec/SkCodecPriv.h"
#include "src/codec/SkMasks.h"

#include <cstring>
#include <memory>
#include <utility>

/*
 * Defines the version and type of the second bitmap header
 */
enum BmpHeaderType {
    kInfoV1_BmpHeaderType,
    kInfoV2_BmpHeaderType,
    kInfoV3_BmpHeaderType,
    kInfoV4_BmpHeaderType,
    kInfoV5_BmpHeaderType,
    kOS2V1_BmpHeaderType,
    kOS2VX_BmpHeaderType,
    kUnknown_BmpHeaderType
};

/*
 * Possible bitmap compression types
 */
enum BmpCompressionMethod {
    kNone_BmpCompressionMethod =          0,
    k8BitRLE_BmpCompressionMethod =       1,
    k4BitRLE_BmpCompressionMethod =       2,
    kBitMasks_BmpCompressionMethod =      3,
    kJpeg_BmpCompressionMethod =          4,
    kPng_BmpCompressionMethod =           5,
    kAlphaBitMasks_BmpCompressionMethod = 6,
    kCMYK_BmpCompressionMethod =          11,
    kCMYK8BitRLE_BmpCompressionMethod =   12,
    kCMYK4BitRLE_BmpCompressionMethod =   13
};

/*
 * Used to define the input format of the bmp
 */
enum BmpInputFormat {
    kStandard_BmpInputFormat,
    kRLE_BmpInputFormat,
    kBitMask_BmpInputFormat,
    kUnknown_BmpInputFormat
};

/*
 * Checks the start of the stream to see if the image is a bitmap
 */
bool SkBmpCodec::IsBmp(const void* buffer, size_t bytesRead) {
    // TODO: Support "IC", "PT", "CI", "CP", "BA"
    const char bmpSig[] = { 'B', 'M' };
    return bytesRead >= 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
 */
std::unique_ptr<SkCodec> SkBmpCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
                                                    Result* result) {
    return SkBmpCodec::MakeFromStream(std::move(stream), result, false);
}

/*
 * Creates a bmp decoder for a bmp embedded in ico
 * Reads enough of the stream to determine the image format
 */
std::unique_ptr<SkCodec> SkBmpCodec::MakeFromIco(std::unique_ptr<SkStream> stream, Result* result) {
    return SkBmpCodec::MakeFromStream(std::move(stream), result, true);
}

// Header size constants
static constexpr uint32_t kBmpHeaderBytes = 14;
static constexpr uint32_t kBmpHeaderBytesPlusFour = kBmpHeaderBytes + 4;
static constexpr uint32_t kBmpOS2V1Bytes = 12;
static constexpr uint32_t kBmpOS2V2Bytes = 64;
static constexpr uint32_t kBmpInfoBaseBytes = 16;
static constexpr uint32_t kBmpInfoV1Bytes = 40;
static constexpr uint32_t kBmpInfoV2Bytes = 52;
static constexpr uint32_t kBmpInfoV3Bytes = 56;
static constexpr uint32_t kBmpInfoV4Bytes = 108;
static constexpr uint32_t kBmpInfoV5Bytes = 124;
static constexpr uint32_t kBmpMaskBytes = 12;

static BmpHeaderType get_header_type(size_t infoBytes) {
    if (infoBytes >= kBmpInfoBaseBytes) {
        // Check the version of the header
        switch (infoBytes) {
            case kBmpInfoV1Bytes:
                return kInfoV1_BmpHeaderType;
            case kBmpInfoV2Bytes:
                return kInfoV2_BmpHeaderType;
            case kBmpInfoV3Bytes:
                return kInfoV3_BmpHeaderType;
            case kBmpInfoV4Bytes:
                return kInfoV4_BmpHeaderType;
            case kBmpInfoV5Bytes:
                return kInfoV5_BmpHeaderType;
            case 16:
            case 20:
            case 24:
            case 28:
            case 32:
            case 36:
            case 42:
            case 46:
            case 48:
            case 60:
            case kBmpOS2V2Bytes:
                return kOS2VX_BmpHeaderType;
            default:
                SkCodecPrintf("Error: unknown bmp header format.\n");
                return kUnknown_BmpHeaderType;
        }
    } if (infoBytes >= kBmpOS2V1Bytes) {
        // The OS2V1 is treated separately because it has a unique format
        return kOS2V1_BmpHeaderType;
    } else {
        // There are no valid bmp headers
        SkCodecPrintf("Error: second bitmap header size is invalid.\n");
        return kUnknown_BmpHeaderType;
    }
}

SkCodec::Result SkBmpCodec::ReadHeader(SkStream* stream, bool inIco,
        std::unique_ptr<SkCodec>* codecOut) {
    // 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 (!inIco) {
        // Read the first header and the size of the second header
        uint8_t hBuffer[kBmpHeaderBytesPlusFour];
        if (stream->read(hBuffer, kBmpHeaderBytesPlusFour) !=
                kBmpHeaderBytesPlusFour) {
            SkCodecPrintf("Error: unable to read first bitmap header.\n");
            return kIncompleteInput;
        }

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

        // 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, 14);
        if (infoBytes < kBmpOS2V1Bytes) {
            SkCodecPrintf("Error: invalid second header size.\n");
            return kInvalidInput;
        }
    } 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
        uint8_t hBuffer[4];
        if (stream->read(hBuffer, 4) != 4) {
            SkCodecPrintf("Error: unable to read size of second bitmap header.\n");
            return kIncompleteInput;
        }
        infoBytes = get_int(hBuffer, 0);
        if (infoBytes < kBmpOS2V1Bytes) {
            SkCodecPrintf("Error: invalid second header size.\n");
            return kInvalidInput;
        }
    }

    // Determine image information depending on second header format
    const BmpHeaderType headerType = get_header_type(infoBytes);
    if (kUnknown_BmpHeaderType == headerType) {
        return kInvalidInput;
    }

    // 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
    std::unique_ptr<uint8_t[]> iBuffer(new uint8_t[infoBytesRemaining]);
    if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) {
        SkCodecPrintf("Error: unable to read second bitmap header.\n");
        return kIncompleteInput;
    }

    // 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_BmpCompressionMethod;

    // 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;

    switch (headerType) {
        case kInfoV1_BmpHeaderType:
        case kInfoV2_BmpHeaderType:
        case kInfoV3_BmpHeaderType:
        case kInfoV4_BmpHeaderType:
        case kInfoV5_BmpHeaderType:
        case kOS2VX_BmpHeaderType:
            // 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;
            break;
        case kOS2V1_BmpHeaderType:
            // The OS2V1 is treated separately because it has a unique format
            width = (int) get_short(iBuffer.get(), 0);
            height = (int) get_short(iBuffer.get(), 2);
            bitsPerPixel = get_short(iBuffer.get(), 6);
            bytesPerColor = 3;
            break;
        case kUnknown_BmpHeaderType:
            // We'll exit above in this case.
            SkASSERT(false);
            return kInvalidInput;
    }

    // Check for valid dimensions from header
    SkCodec::SkScanlineOrder rowOrder = SkCodec::kBottomUp_SkScanlineOrder;
    if (height < 0) {
        // We can't negate INT32_MIN.
        if (height == INT32_MIN) {
            return kInvalidInput;
        }

        height = -height;
        rowOrder = SkCodec::kTopDown_SkScanlineOrder;
    }
    // The height field for bmp in ico is double the actual height because they
    // contain an XOR mask followed by an AND mask
    if (inIco) {
        height /= 2;
    }

    // Arbitrary maximum. Matches Chromium.
    constexpr int kMaxDim = 1 << 16;
    if (width <= 0 || height <= 0 || width >= kMaxDim || height >= kMaxDim) {
        SkCodecPrintf("Error: invalid bitmap dimensions.\n");
        return kInvalidInput;
    }

    // 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;
    BmpInputFormat inputFormat = kUnknown_BmpInputFormat;
    switch (compression) {
        case kNone_BmpCompressionMethod:
            inputFormat = kStandard_BmpInputFormat;

            // 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.
            if (16 == bitsPerPixel) {
                inputMasks.red = 0x7C00;
                inputMasks.green = 0x03E0;
                inputMasks.blue = 0x001F;
                inputFormat = kBitMask_BmpInputFormat;
            }
            break;
        case k8BitRLE_BmpCompressionMethod:
            if (bitsPerPixel != 8) {
                SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
                bitsPerPixel = 8;
            }
            inputFormat = kRLE_BmpInputFormat;
            break;
        case k4BitRLE_BmpCompressionMethod:
            if (bitsPerPixel != 4) {
                SkCodecPrintf("Warning: correcting invalid bitmap format.\n");
                bitsPerPixel = 4;
            }
            inputFormat = kRLE_BmpInputFormat;
            break;
        case kAlphaBitMasks_BmpCompressionMethod:
        case kBitMasks_BmpCompressionMethod:
            // Load the masks
            inputFormat = kBitMask_BmpInputFormat;
            switch (headerType) {
                case kInfoV1_BmpHeaderType: {
                    // The V1 header stores the bit masks after the header
                    uint8_t buffer[kBmpMaskBytes];
                    if (stream->read(buffer, kBmpMaskBytes) != kBmpMaskBytes) {
                        SkCodecPrintf("Error: unable to read bit inputMasks.\n");
                        return kIncompleteInput;
                    }
                    maskBytes = kBmpMaskBytes;
                    inputMasks.red = get_int(buffer, 0);
                    inputMasks.green = get_int(buffer, 4);
                    inputMasks.blue = get_int(buffer, 8);
                    break;
                }
                case kInfoV2_BmpHeaderType:
                case kInfoV3_BmpHeaderType:
                case kInfoV4_BmpHeaderType:
                case kInfoV5_BmpHeaderType:
                    // 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);

                    if (kInfoV2_BmpHeaderType == headerType ||
                            (kInfoV3_BmpHeaderType == headerType && !inIco)) {
                        break;
                    }

                    // 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 ignore the alpha mask.  For V4+
                    // images in kMask mode, we will use the alpha mask.  Additionally, V3
                    // bmp-in-ico expect us to use the alpha mask.
                    //
                    // skbug.com/4116: We should perhaps also apply the alpha mask in kStandard
                    //                 mode.  We just haven't seen any images that expect this
                    //                 behavior.
                    //
                    // 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);
                    break;
                case kOS2VX_BmpHeaderType:
                    // 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 kUnimplemented;
                default:
                   SkCodecPrintf("Error: invalid bmp bit masks header.\n");
                   return kInvalidInput;
            }
            break;
        case kJpeg_BmpCompressionMethod:
            if (24 == bitsPerPixel) {
                inputFormat = kRLE_BmpInputFormat;
                break;
            }
            [[fallthrough]];
        case kPng_BmpCompressionMethod:
            // 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 kUnimplemented;
        case kCMYK_BmpCompressionMethod:
        case kCMYK8BitRLE_BmpCompressionMethod:
        case kCMYK4BitRLE_BmpCompressionMethod:
            // TODO: Same as above.
            SkCodecPrintf("Error: CMYK not supported for bitmap decoding.\n");
            return kUnimplemented;
        default:
            SkCodecPrintf("Error: invalid format for bitmap decoding.\n");
            return kInvalidInput;
    }
    iBuffer.reset();

    // Calculate the number of bytes read so far
    const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes;
    if (!inIco && offset < bytesRead) {
        // TODO (msarett): Do we really want to fail if the offset in the header is invalid?
        //                 Seems like we can just assume that the offset is zero and try to decode?
        //                 Maybe we don't want to try to decode corrupt images?
        SkCodecPrintf("Error: pixel data offset less than header size.\n");
        return kInvalidInput;
    }



    switch (inputFormat) {
        case kStandard_BmpInputFormat: {
            // BMPs are generally opaque, however BMPs-in-ICOs may contain
            // a transparency mask after the image.  Therefore, we mark the
            // alpha as kBinary if the BMP is contained in an ICO.
            // We use |isOpaque| to indicate if the BMP itself is opaque.
            SkEncodedInfo::Alpha alpha = inIco ? SkEncodedInfo::kBinary_Alpha :
                    SkEncodedInfo::kOpaque_Alpha;
            bool isOpaque = true;

            SkEncodedInfo::Color color;
            uint8_t bitsPerComponent;
            switch (bitsPerPixel) {
                // Palette formats
                case 1:
                case 2:
                case 4:
                case 8:
                    // In the case of ICO, kBGRA is actually the closest match,
                    // since we will need to apply a transparency mask.
                    if (inIco) {
                        color = SkEncodedInfo::kBGRA_Color;
                        bitsPerComponent = 8;
                    } else {
                        color = SkEncodedInfo::kPalette_Color;
                        bitsPerComponent = (uint8_t) bitsPerPixel;
                    }
                    break;
                case 24:
                    // In the case of ICO, kBGRA is actually the closest match,
                    // since we will need to apply a transparency mask.
                    color = inIco ? SkEncodedInfo::kBGRA_Color : SkEncodedInfo::kBGR_Color;
                    bitsPerComponent = 8;
                    break;
                case 32:
                    // 32-bit BMP-in-ICOs actually use the alpha channel in place of a
                    // transparency mask.
                    if (inIco) {
                        isOpaque = false;
                        alpha = SkEncodedInfo::kUnpremul_Alpha;
                        color = SkEncodedInfo::kBGRA_Color;
                    } else {
                        color = SkEncodedInfo::kBGRX_Color;
                    }
                    bitsPerComponent = 8;
                    break;
                default:
                    SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
                    return kInvalidInput;
            }

            if (codecOut) {
                // We require streams to have a memory base for Bmp-in-Ico decodes.
                SkASSERT(!inIco || nullptr != stream->getMemoryBase());

                // Set the image info and create a codec.
                auto info = SkEncodedInfo::Make(width, height, color, alpha, bitsPerComponent);
                *codecOut = std::make_unique<SkBmpStandardCodec>(std::move(info),
                                                       std::unique_ptr<SkStream>(stream),
                                                       bitsPerPixel, numColors, bytesPerColor,
                                                       offset - bytesRead, rowOrder, isOpaque,
                                                       inIco);
                return static_cast<SkBmpStandardCodec*>(codecOut->get())->didCreateSrcBuffer()
                        ? kSuccess : kInvalidInput;
            }
            return kSuccess;
        }

        case kBitMask_BmpInputFormat: {
            // Bmp-in-Ico must be standard mode
            if (inIco) {
                SkCodecPrintf("Error: Icos may not use bit mask format.\n");
                return kInvalidInput;
            }

            switch (bitsPerPixel) {
                case 16:
                case 24:
                case 32:
                    break;
                default:
                    SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
                    return kInvalidInput;
            }

            // Skip to the start of the pixel array.
            // We can do this here because there is no color table to read
            // in bit mask mode.
            if (stream->skip(offset - bytesRead) != offset - bytesRead) {
                SkCodecPrintf("Error: unable to skip to image data.\n");
                return kIncompleteInput;
            }

            if (codecOut) {
                // Check that input bit masks are valid and create the masks object
                SkASSERT(bitsPerPixel % 8 == 0);
                std::unique_ptr<SkMasks> masks(SkMasks::CreateMasks(inputMasks, bitsPerPixel/8));
                if (nullptr == masks) {
                    SkCodecPrintf("Error: invalid input masks.\n");
                    return kInvalidInput;
                }

                // Masked bmps are not a great fit for SkEncodedInfo, since they have
                // arbitrary component orderings and bits per component.  Here we choose
                // somewhat reasonable values - it's ok that we don't match exactly
                // because SkBmpMaskCodec has its own mask swizzler anyway.
                SkEncodedInfo::Color color;
                SkEncodedInfo::Alpha alpha;
                if (masks->getAlphaMask()) {
                    color = SkEncodedInfo::kBGRA_Color;
                    alpha = SkEncodedInfo::kUnpremul_Alpha;
                } else {
                    color = SkEncodedInfo::kBGR_Color;
                    alpha = SkEncodedInfo::kOpaque_Alpha;
                }
                auto info = SkEncodedInfo::Make(width, height, color, alpha, 8);
                *codecOut = std::make_unique<SkBmpMaskCodec>(std::move(info),
                                                   std::unique_ptr<SkStream>(stream), bitsPerPixel,
                                                   masks.release(), rowOrder);
                return static_cast<SkBmpMaskCodec*>(codecOut->get())->didCreateSrcBuffer()
                        ? kSuccess : kInvalidInput;
            }
            return kSuccess;
        }

        case kRLE_BmpInputFormat: {
            // We should not reach this point without a valid value of bitsPerPixel.
            SkASSERT(4 == bitsPerPixel || 8 == bitsPerPixel || 24 == bitsPerPixel);

            // Check for a valid number of total bytes when in RLE mode
            if (totalBytes <= offset) {
                SkCodecPrintf("Error: RLE requires valid input size.\n");
                return kInvalidInput;
            }

            // Bmp-in-Ico must be standard mode
            // When inIco is true, this line cannot be reached, since we
            // require that RLE Bmps have a valid number of totalBytes, and
            // Icos skip the header that contains totalBytes.
            SkASSERT(!inIco);

            if (codecOut) {
                // RLE inputs may skip pixels, leaving them as transparent.  This
                // is uncommon, but we cannot be certain that an RLE bmp will be
                // opaque or that we will be able to represent it with a palette.
                // For that reason, we always indicate that we are kBGRA.
                auto info = SkEncodedInfo::Make(width, height, SkEncodedInfo::kBGRA_Color,
                                                SkEncodedInfo::kBinary_Alpha, 8);
                *codecOut = std::make_unique<SkBmpRLECodec>(std::move(info),
                                                  std::unique_ptr<SkStream>(stream), bitsPerPixel,
                                                  numColors, bytesPerColor, offset - bytesRead,
                                                  rowOrder);
            }
            return kSuccess;
        }
        default:
            SkASSERT(false);
            return kInvalidInput;
    }
}

/*
 * Creates a bmp decoder
 * Reads enough of the stream to determine the image format
 */
std::unique_ptr<SkCodec> SkBmpCodec::MakeFromStream(std::unique_ptr<SkStream> stream,
                                                    Result* result, bool inIco) {
    std::unique_ptr<SkCodec> codec;
    *result = ReadHeader(stream.get(), inIco, &codec);
    if (codec) {
        // codec has taken ownership of stream, so we do not need to delete it.
        stream.release();
    }
    return kSuccess == *result ? std::move(codec) : nullptr;
}

SkBmpCodec::SkBmpCodec(SkEncodedInfo&& info, std::unique_ptr<SkStream> stream,
        uint16_t bitsPerPixel, SkCodec::SkScanlineOrder rowOrder)
    : INHERITED(std::move(info), kXformSrcColorFormat, std::move(stream))
    , fBitsPerPixel(bitsPerPixel)
    , fRowOrder(rowOrder)
    , fSrcRowBytes(SkAlign4(compute_row_bytes(this->dimensions().width(), fBitsPerPixel)))
    , fXformBuffer(nullptr)
{}

bool SkBmpCodec::onRewind() {
    return SkBmpCodec::ReadHeader(this->stream(), this->inIco(), nullptr) == kSuccess;
}

int32_t SkBmpCodec::getDstRow(int32_t y, int32_t height) const {
    if (SkCodec::kTopDown_SkScanlineOrder == fRowOrder) {
        return y;
    }
    SkASSERT(SkCodec::kBottomUp_SkScanlineOrder == fRowOrder);
    return height - y - 1;
}

SkCodec::Result SkBmpCodec::prepareToDecode(const SkImageInfo& dstInfo,
        const SkCodec::Options& options) {
    return this->onPrepareToDecode(dstInfo, options);
}

SkCodec::Result SkBmpCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
        const SkCodec::Options& options) {
    return prepareToDecode(dstInfo, options);
}

int SkBmpCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
    // Create a new image info representing the portion of the image to decode
    SkImageInfo rowInfo = this->dstInfo().makeWH(this->dstInfo().width(), count);

    // Decode the requested rows
    return this->decodeRows(rowInfo, dst, rowBytes, this->options());
}

bool SkBmpCodec::skipRows(int count) {
    const size_t bytesToSkip = count * fSrcRowBytes;
    return this->stream()->skip(bytesToSkip) == bytesToSkip;
}

bool SkBmpCodec::onSkipScanlines(int count) {
    return this->skipRows(count);
}
