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

#include "include/codec/SkCodec.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkTypes.h"
#include "include/private/SkEncodedInfo.h"
#include "src/codec/SkBmpBaseCodec.h"
#include "src/codec/SkColorPalette.h"
#include "src/codec/SkSwizzler.h"

#include <cstddef>
#include <cstdint>
#include <memory>

class SkSampler;
class SkStream;
enum SkAlphaType : int;
enum SkColorType : int;
struct SkImageInfo;

/*
 * This class implements the decoding for bmp images that use "standard" modes,
 * which essentially means they do not contain bit masks or RLE codes.
 */
class SkBmpStandardCodec : public SkBmpBaseCodec {
public:

    /*
     * Creates an instance of the decoder
     *
     * Called only by SkBmpCodec::MakeFromStream
     * There should be no other callers despite this being public
     *
     * @param info contains properties of the encoded data
     * @param stream the stream of encoded image data
     * @param bitsPerPixel the number of bits used to store each pixel
     * @param numColors the number of colors in the color table
     * @param bytesPerColor the number of bytes in the stream used to represent
                            each color in the color table
     * @param offset the offset of the image pixel data from the end of the
     *               headers
     * @param rowOrder indicates whether rows are ordered top-down or bottom-up
     * @param isOpaque indicates if the bmp itself is opaque (before applying
     *                 the icp mask, if there is one)
     * @param inIco    indicates if the bmp is embedded in an ico file
     */
    SkBmpStandardCodec(SkEncodedInfo&& info, std::unique_ptr<SkStream> stream,
                       uint16_t bitsPerPixel, uint32_t numColors, uint32_t bytesPerColor,
                       uint32_t offset, SkCodec::SkScanlineOrder rowOrder,
                       bool isOpaque, bool inIco);

protected:

    Result onGetPixels(const SkImageInfo& dstInfo, void* dst,
                       size_t dstRowBytes, const Options&,
                       int*) override;

    bool onInIco() const override {
        return fInIco;
    }

    SkCodec::Result onPrepareToDecode(const SkImageInfo& dstInfo,
            const SkCodec::Options& options) override;

    SkSampler* getSampler(bool createIfNecessary) override {
        SkASSERT(fSwizzler);
        return fSwizzler.get();
    }

private:
    bool createColorTable(SkColorType colorType, SkAlphaType alphaType);
    SkEncodedInfo swizzlerInfo() const;
    void initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts);

    int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
            const Options& opts) override;

    /*
     * @param stream This may be a pointer to the stream owned by the parent SkCodec
     *               or a sub-stream of the stream owned by the parent SkCodec.
     *               Either way, this stream is unowned.
     */
    void decodeIcoMask(SkStream* stream, const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes);

    sk_sp<SkColorPalette>       fColorTable;
    // fNumColors is the number specified in the header, or 0 if not present in the header.
    const uint32_t              fNumColors;
    const uint32_t              fBytesPerColor;
    const uint32_t              fOffset;
    std::unique_ptr<SkSwizzler> fSwizzler;
    const bool                  fIsOpaque;
    const bool                  fInIco;
    const size_t                fAndMaskRowBytes; // only used for fInIco decodes

    using INHERITED = SkBmpBaseCodec;
};
#endif  // SkBmpStandardCodec_DEFINED
