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

struct GifFileType;
struct SavedImage;

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

protected:

    /*
     * Read enough of the stream to initialize the SkGifCodec.
     * Returns a bool representing success or failure.
     *
     * @param codecOut
     * If it returned true, and codecOut was not nullptr,
     * codecOut will be set to a new SkGifCodec.
     *
     * @param gifOut
     * If it returned true, and codecOut was nullptr,
     * gifOut must be non-nullptr and gifOut will be set to a new
     * GifFileType pointer.
     *
     * @param stream
     * Deleted on failure.
     * codecOut will take ownership of it in the case where we created a codec.
     * Ownership is unchanged when we returned a gifOut.
     *
     */
    static bool ReadHeader(SkStream* stream, SkCodec** codecOut,
            GifFileType** gifOut);

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

    uint32_t onGetFillValue(SkColorType) const override;

    int onOutputScanline(int inputScanline) const override;

private:

    /*
     * A gif can contain multiple image frames.  We will only decode the first
     * frame.  This function reads up to the first image frame, processing
     * transparency and/or animation information that comes before the image
     * data.
     *
     * @param gif        Pointer to the library type that manages the gif decode
     * @param transIndex This call will set the transparent index based on the
     *                   extension data.
     */
     static Result ReadUpToFirstImage(GifFileType* gif, uint32_t* transIndex);

     /*
      * A gif may contain many image frames, all of different sizes.
      * This function checks if the gif dimensions are valid, based on the frame
      * dimensions, and corrects the gif dimensions if necessary.
      *
      * @param gif       Pointer to the library type that manages the gif decode
      * @param size      Size of the image that we will decode.
      *                  Will be set by this function if the return value is true.
      * @param frameRect Contains the dimenions and offset of the first image frame.
      *                  Will be set by this function if the return value is true.
      *
      * @return true on success, false otherwise
      */
     static bool GetDimensions(GifFileType* gif, SkISize* size, SkIRect* frameRect);

    /*
     * Initializes the color table that we will use for decoding.
     *
     * @param dstInfo         Contains the requested dst color type.
     * @param inputColorPtr   Copies the encoded color table to the client's
     *                        input color table if the client requests kIndex8.
     * @param inputColorCount If the client requests kIndex8, sets
     *                        inputColorCount to 256.  Since gifs always
     *                        contain 8-bit indices, we need a 256 entry color
     *                        table to ensure that indexing is always in
     *                        bounds.
     */
    void initializeColorTable(const SkImageInfo& dstInfo, SkPMColor* colorPtr,
            int* inputColorCount);

   /*
    * Checks for invalid inputs and calls setFrameDimensions(), and
    * initializeColorTable() in the proper sequence.
    */
    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 options  Informs the swizzler if destination memory is zero initialized.
     *                 Contains subset information.
     */
    void initializeSwizzler(const SkImageInfo& dstInfo,
            const Options& options);

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

    /*
     * @return true if the read is successful and false if the read fails.
     */
    bool readRow();

    Result onStartScanlineDecode(const SkImageInfo& dstInfo, const Options& opts,
                   SkPMColor inputColorPtr[], int* inputColorCount) override;

    int onGetScanlines(void* dst, int count, size_t rowBytes) override;

    bool onSkipScanlines(int count) override;

    /*
     * For a scanline decode of "count" lines, this function indicates how
     * many of the "count" lines should be skipped until we reach the top of
     * the image frame and how many of the "count" lines are actually inside
     * the image frame.
     *
     * @param count           The number of scanlines requested.
     * @param rowsBeforeFrame Output variable.  The number of lines before
     *                        we reach the top of the image frame.
     * @param rowsInFrame     Output variable.  The number of lines to decode
     *                        inside the image frame.
     */
    void handleScanlineFrame(int count, int* rowsBeforeFrame, int* rowsInFrame);

    SkScanlineOrder onGetScanlineOrder() const override;

    /*
     * This function cleans up the gif object after the decode completes
     * It is used in a SkAutoTCallIProc template
     */
    static void CloseGif(GifFileType* gif);

    /*
     * Frees any extension data used in the decode
     * Used in a SkAutoTCallVProc
     */
    static void FreeExtension(SavedImage* image);

    /*
     * Creates an instance of the decoder
     * Called only by NewFromStream
     *
     * @param srcInfo contains the source width and height
     * @param stream the stream of image data
     * @param gif pointer to library type that manages gif decode
     *            takes ownership
     * @param transIndex  The transparent index.  An invalid value
     *            indicates that there is no transparent index.
     */
    SkGifCodec(const SkImageInfo& srcInfo, SkStream* stream, GifFileType* gif, uint32_t transIndex,
            const SkIRect& frameRect, bool frameIsSubset);

    SkAutoTCallVProc<GifFileType, CloseGif> fGif; // owned
    SkAutoTDeleteArray<uint8_t>             fSrcBuffer;
    const SkIRect                           fFrameRect;
    const uint32_t                          fTransIndex;
    uint32_t                                fFillIndex;
    const bool                              fFrameIsSubset;
    SkAutoTDelete<SkSwizzler>               fSwizzler;
    SkAutoTUnref<SkColorTable>              fColorTable;

    typedef SkCodec INHERITED;
};
