/*
 * 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.h"
#include "SkCodecAnimation.h"
#include "SkColorSpace.h"
#include "SkColorTable.h"
#include "SkImageInfo.h"
#include "SkSwizzler.h"

#include "SkGifImageReader.h"

/*
 *
 * This class implements the decoding for gif images
 *
 */
class SkGifCodec : public SkCodec {
public:
    static bool IsGif(const void*, size_t);

    /*
     * Assumes IsGif was called and returned true
     * Creates a gif decoder
     * Reads enough of the stream to determine the image format
     */
    static SkCodec* NewFromStream(SkStream*);

    // Callback for SkGifImageReader when a row is available.
    bool haveDecodedRow(size_t frameIndex, const unsigned char* rowBegin,
                        size_t rowNumber, unsigned repeatCount, bool writeTransparentPixels);
protected:
    /*
     * Performs the full gif decode
     */
    Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&,
            SkPMColor*, int*, int*) override;

    SkEncodedFormat onGetEncodedFormat() const override {
        return kGIF_SkEncodedFormat;
    }

    bool onRewind() override;

    uint64_t onGetFillValue(const SkImageInfo&) const override;

    std::vector<FrameInfo> onGetFrameInfo() override;
    int onGetRepetitionCount() override;

    Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t,
            const SkCodec::Options&, SkPMColor*, int*) override;

    Result onIncrementalDecode(int*) override;

private:

    /*
     * Initializes the color table that we will use for decoding.
     *
     * @param dstInfo         Contains the requested dst color type.
     * @param frameIndex      Frame whose color table to use.
     */
    void initializeColorTable(const SkImageInfo& dstInfo, size_t frameIndex);

   /*
    * Does necessary setup, including setting up the color table and swizzler,
    * and reports color info to the client.
    */
    Result prepareToDecode(const SkImageInfo& dstInfo, SkPMColor* inputColorPtr,
            int* inputColorCount, const Options& opts);

    /*
     * Initializes the swizzler.
     *
     * @param dstInfo    Output image information.  Dimensions may have been
     *                   adjusted if the image frame size does not match the size
     *                   indicated in the header.
     * @param frameIndex Which frame we are decoding. This determines the frameRect
     *                   to use.
     */
    void initializeSwizzler(const SkImageInfo& dstInfo, size_t frameIndex);

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

    /*
     * Recursive function to decode a frame.
     *
     * @param firstAttempt Whether this is the first call to decodeFrame since
     *                     starting. e.g. true in onGetPixels, and true in the
     *                     first call to onIncrementalDecode after calling
     *                     onStartIncrementalDecode.
     *                     When true, this method may have to initialize the
     *                     frame, for example by filling or decoding the prior
     *                     frame.
     * @param opts         Options for decoding. May be different from
     *                     this->options() for decoding prior frames. Specifies
     *                     the frame to decode and whether the prior frame has
     *                     already been decoded to fDst. If not, and the frame
     *                     is not independent, this method will recursively
     *                     decode the frame it depends on.
     * @param rowsDecoded  Out-parameter to report the total number of rows
     *                     that have been decoded (or at least written to, if
     *                     it had to fill), including rows decoded by prior
     *                     calls to onIncrementalDecode.
     * @return             kSuccess if the frame is complete, kIncompleteInput
     *                     otherwise.
     */
    Result decodeFrame(bool firstAttempt, const Options& opts, int* rowsDecoded);

    /*
     *  Swizzles and color xforms (if necessary) into dst.
     */
    void applyXformRow(const SkImageInfo& dstInfo, void* dst, const uint8_t* src) const;

    /*
     * Creates an instance of the decoder
     * Called only by NewFromStream
     * Takes ownership of the SkGifImageReader
     */
    SkGifCodec(const SkEncodedInfo&, const SkImageInfo&, SkGifImageReader*);

    std::unique_ptr<SkGifImageReader>   fReader;
    std::unique_ptr<uint8_t[]>          fTmpBuffer;
    std::unique_ptr<SkSwizzler>         fSwizzler;
    sk_sp<SkColorTable>                 fCurrColorTable;
    // We may create a dummy table if there is not a Map in the input data. In
    // that case, we set this value to false, and we can skip a lot of decoding
    // work (which would not be meaningful anyway). We create a "fake"/"dummy"
    // one in that case, so the client and the swizzler have something to draw.
    bool                                fCurrColorTableIsReal;
    // Whether the background was filled.
    bool                                fFilledBackground;
    // True on the first call to onIncrementalDecode. This value is passed to
    // decodeFrame.
    bool                                fFirstCallToIncrementalDecode;

    void*                               fDst;
    size_t                              fDstRowBytes;

    // Updated inside haveDecodedRow when rows are decoded, unless we filled
    // the background, in which case it is set once and left alone.
    int                                 fRowsDecoded;
    std::unique_ptr<uint32_t[]>         fXformBuffer;
    bool                                fXformOnDecode;

    typedef SkCodec INHERITED;
};
