/*
 * 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_libgif.h"
#include "SkCodecPriv.h"
#include "SkColorPriv.h"
#include "SkColorTable.h"
#include "SkGifInterlaceIter.h"
#include "SkStream.h"
#include "SkSwizzler.h"
#include "SkUtils.h"

/*
 * Checks the start of the stream to see if the image is a gif
 */
bool SkGifCodec::IsGif(SkStream* stream) {
    char buf[GIF_STAMP_LEN];
    if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) {
        if (memcmp(GIF_STAMP,   buf, GIF_STAMP_LEN) == 0 ||
                memcmp(GIF87_STAMP, buf, GIF_STAMP_LEN) == 0 ||
                memcmp(GIF89_STAMP, buf, GIF_STAMP_LEN) == 0) {
            return true;
        }
    }
    return false;
}

/*
 * Warning reporting function
 */
static void gif_warning(const char* msg) {
    SkCodecPrintf("Gif Warning: %s\n", msg);
}

/*
 * Error function
 */
static SkCodec::Result gif_error(const char* msg,
        SkCodec::Result result = SkCodec::kInvalidInput) {
    SkCodecPrintf("Gif Error: %s\n", msg);
    return result;
}


/*
 * Read function that will be passed to gif_lib
 */
static int32_t read_bytes_callback(GifFileType* fileType, GifByteType* out,
        int32_t size) {
    SkStream* stream = (SkStream*) fileType->UserData;
    return (int32_t) stream->read(out, size);
}

/*
 * Open the gif file
 */
static GifFileType* open_gif(SkStream* stream) {
#if GIFLIB_MAJOR < 5
    return DGifOpen(stream, read_bytes_callback);
#else
    return DGifOpen(stream, read_bytes_callback, NULL);
#endif
}

 /*
 * This function cleans up the gif object after the decode completes
 * It is used in a SkAutoTCallIProc template
 */
void SkGifCodec::CloseGif(GifFileType* gif) {
#if GIFLIB_MAJOR < 5 || (GIFLIB_MAJOR == 5 && GIFLIB_MINOR == 0)
    DGifCloseFile(gif);
#else
    DGifCloseFile(gif, NULL);
#endif
}

/*
 * This function free extension data that has been saved to assist the image
 * decoder
 */
void SkGifCodec::FreeExtension(SavedImage* image) {
    if (NULL != image->ExtensionBlocks) {
#if GIFLIB_MAJOR < 5
        FreeExtension(image);
#else
        GifFreeExtensions(&image->ExtensionBlockCount, &image->ExtensionBlocks);
#endif
    }
}

/*
 * Check if a there is an index of the color table for a transparent pixel
 */
static uint32_t find_trans_index(const SavedImage& image) {
    // If there is a transparent index specified, it will be contained in an
    // extension block.  We will loop through extension blocks in reverse order
    // to check the most recent extension blocks first.
    for (int32_t i = image.ExtensionBlockCount - 1; i >= 0; i--) {
        // Get an extension block
        const ExtensionBlock& extBlock = image.ExtensionBlocks[i];

        // Specifically, we need to check for a graphics control extension,
        // which may contain transparency information.  Also, note that a valid
        // graphics control extension is always four bytes.  The fourth byte
        // is the transparent index (if it exists), so we need at least four
        // bytes.
        if (GRAPHICS_EXT_FUNC_CODE == extBlock.Function &&
                extBlock.ByteCount >= 4) {

            // Check the transparent color flag which indicates whether a
            // transparent index exists.  It is the least significant bit of
            // the first byte of the extension block.
            if (1 == (extBlock.Bytes[0] & 1)) {

                // Use uint32_t to prevent sign extending
                return extBlock.Bytes[3];
            }

            // There should only be one graphics control extension for the image frame
            break;
        }
    }

    // Use maximum unsigned int (surely an invalid index) to indicate that a valid
    // index was not found.
    return SK_MaxU32;
}

/*
 * 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 NULL,
 * codecOut will be set to a new SkGifCodec.
 *
 * @param gifOut
 * If it returned true, and codecOut was NULL,
 * gifOut must be non-NULL 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.
 *
 */
bool SkGifCodec::ReadHeader(SkStream* stream, SkCodec** codecOut, GifFileType** gifOut) {
    SkAutoTDelete<SkStream> streamDeleter(stream);

    // Read gif header, logical screen descriptor, and global color table
    SkAutoTCallVProc<GifFileType, CloseGif> gif(open_gif(stream));

    if (NULL == gif) {
        gif_error("DGifOpen failed.\n");
        return false;
    }

    if (NULL != codecOut) {
        // Get fields from header
        const int32_t width = gif->SWidth;
        const int32_t height = gif->SHeight;
        if (width <= 0 || height <= 0) {
            gif_error("Invalid dimensions.\n");
            return false;
        }

        // Return the codec
        // kIndex is the most natural color type for gifs, so we set this as
        // the default.
        // Many gifs specify a color table index for transparent pixels.  Every
        // other pixel is guaranteed to be opaque.  Despite this, because of the
        // possiblity of transparent pixels, we cannot assume that the image is
        // opaque.  We have the option to set the alpha type as kPremul or
        // kUnpremul.  Both are valid since the alpha component will always be
        // 0xFF or the entire 32-bit pixel will be set to zero.  We prefer
        // kPremul because we support kPremul, and it is more efficient to
        // use kPremul directly even when kUnpremul is supported.
        const SkImageInfo& imageInfo = SkImageInfo::Make(width, height,
                kIndex_8_SkColorType, kPremul_SkAlphaType);
        *codecOut = SkNEW_ARGS(SkGifCodec, (imageInfo, streamDeleter.detach(), gif.detach()));
    } else {
        SkASSERT(NULL != gifOut);
        streamDeleter.detach();
        *gifOut = gif.detach();
    }
    return true;
}

/*
 * Assumes IsGif was called and returned true
 * Creates a gif decoder
 * Reads enough of the stream to determine the image format
 */
SkCodec* SkGifCodec::NewFromStream(SkStream* stream) {
    SkCodec* codec = NULL;
    if (ReadHeader(stream, &codec, NULL)) {
        return codec;
    }
    return NULL;
}

SkGifCodec::SkGifCodec(const SkImageInfo& srcInfo, SkStream* stream,
                       GifFileType* gif)
    : INHERITED(srcInfo, stream)
    , fGif(gif)
{}

/*
 * 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 color and alpha types
    switch (dst.colorType()) {
        case kN32_SkColorType:
            return kPremul_SkAlphaType == dst.alphaType() ||
                    kUnpremul_SkAlphaType == dst.alphaType();
        case kIndex_8_SkColorType:
            return kPremul_SkAlphaType == dst.alphaType() ||
                    kUnpremul_SkAlphaType == dst.alphaType();
        default:
            return false;
    }
}

/*
 * Initiates the gif decode
 */
SkCodec::Result SkGifCodec::onGetPixels(const SkImageInfo& dstInfo,
                                        void* dst, size_t dstRowBytes,
                                        const Options& opts,
                                        SkPMColor* inputColorPtr,
                                        int* inputColorCount) {
    // Rewind if necessary
    SkCodec::RewindState rewindState = this->rewindIfNeeded();
    if (rewindState == kCouldNotRewind_RewindState) {
        return kCouldNotRewind;
    } else if (rewindState == kRewound_RewindState) {
        GifFileType* gifOut = NULL;
        if (!ReadHeader(this->stream(), NULL, &gifOut)) {
            return kCouldNotRewind;
        } else {
            SkASSERT(NULL != gifOut);
            fGif.reset(gifOut);
        }
    }

    // Check for valid input parameters
    if (dstInfo.dimensions() != this->getInfo().dimensions()) {
        return gif_error("Scaling not supported.\n", kInvalidScale);
    }
    if (!conversion_possible(dstInfo, this->getInfo())) {
        return gif_error("Cannot convert input type to output type.\n",
                kInvalidConversion);
    }

    // Use this as a container to hold information about any gif extension
    // blocks.  This generally stores transparency and animation instructions.
    SavedImage saveExt;
    SkAutoTCallVProc<SavedImage, FreeExtension> autoFreeExt(&saveExt);
    saveExt.ExtensionBlocks = NULL;
    saveExt.ExtensionBlockCount = 0;
    GifByteType* extData;
#if GIFLIB_MAJOR >= 5
    int32_t extFunction;
#endif

    // We will loop over components of gif images until we find an image.  Once
    // we find an image, we will decode and return it.  While many gif files
    // contain more than one image, we will simply decode the first image.
    const int32_t width = dstInfo.width();
    const int32_t height = dstInfo.height();
    GifRecordType recordType;
    do {
        // Get the current record type
        if (GIF_ERROR == DGifGetRecordType(fGif, &recordType)) {
            return gif_error("DGifGetRecordType failed.\n", kInvalidInput);
        }

        switch (recordType) {
            case IMAGE_DESC_RECORD_TYPE: {
                // Read the image descriptor
                if (GIF_ERROR == DGifGetImageDesc(fGif)) {
                    return gif_error("DGifGetImageDesc failed.\n",
                            kInvalidInput);
                }

                // If reading the image descriptor is successful, the image
                // count will be incremented
                SkASSERT(fGif->ImageCount >= 1);
                SavedImage* image = &fGif->SavedImages[fGif->ImageCount - 1];

                // Process the descriptor
                const GifImageDesc& desc = image->ImageDesc;
                int32_t imageLeft = desc.Left;
                int32_t imageTop = desc.Top;
                int32_t innerWidth = desc.Width;
                int32_t innerHeight = desc.Height;
                // Fail on non-positive dimensions
                if (innerWidth <= 0 || innerHeight <= 0) {
                    return gif_error("Invalid dimensions for inner image.\n",
                            kInvalidInput);
                }
                // Treat the following cases as warnings and try to fix
                if (innerWidth > width) {
                    gif_warning("Inner image too wide, shrinking.\n");
                    innerWidth = width;
                    imageLeft = 0;
                } else if (imageLeft + innerWidth > width) {
                    gif_warning("Shifting inner image to left to fit.\n");
                    imageLeft = width - innerWidth;
                } else if (imageLeft < 0) {
                    gif_warning("Shifting image to right to fit\n");
                    imageLeft = 0;
                }
                if (innerHeight > height) {
                    gif_warning("Inner image too tall, shrinking.\n");
                    innerHeight = height;
                    imageTop = 0;
                } else if (imageTop + innerHeight > height) {
                    gif_warning("Shifting inner image up to fit.\n");
                    imageTop = height - innerHeight;
                } else if (imageTop < 0) {
                    gif_warning("Shifting image down to fit\n");
                    imageTop = 0;
                }

                // Create a color table to store colors the giflib colorMap
                SkPMColor alternateColorPtr[256];
                SkPMColor* colorTable;
                SkColorType dstColorType = dstInfo.colorType();
                if (kIndex_8_SkColorType == dstColorType) {
                    SkASSERT(NULL != inputColorPtr);
                    SkASSERT(NULL != inputColorCount);
                    SkASSERT(256 == *inputColorCount);
                    colorTable = inputColorPtr;
                } else {
                    colorTable = alternateColorPtr;
                }

                // Set up the color table
                uint32_t colorCount = 0;
                // Allocate maximum storage to deal with invalid indices safely
                const uint32_t maxColors = 256;
                ColorMapObject* colorMap = fGif->Image.ColorMap;
                // If there is no local color table, use the global color table
                if (NULL == colorMap) {
                    colorMap = fGif->SColorMap;
                }
                if (NULL != colorMap) {
                    colorCount = colorMap->ColorCount;
                    SkASSERT(colorCount ==
                            (unsigned) (1 << (colorMap->BitsPerPixel)));
                    SkASSERT(colorCount <= 256);
                    for (uint32_t i = 0; i < colorCount; i++) {
                        colorTable[i] = SkPackARGB32(0xFF,
                                                     colorMap->Colors[i].Red,
                                                     colorMap->Colors[i].Green,
                                                     colorMap->Colors[i].Blue);
                    }
                }

                // This is used to fill unspecified pixels in the image data.
                uint32_t fillIndex = fGif->SBackGroundColor;
                ZeroInitialized zeroInit = opts.fZeroInitialized;

                // Gifs have the option to specify the color at a single
                // index of the color table as transparent.
                {
                    // Get the transparent index.  If the return value of this
                    // function is greater than the colorCount, we know that
                    // there is no valid transparent color in the color table.
                    // This occurs if there is no graphics control extension or
                    // if the index specified by the graphics control extension
                    // is out of range.
                    uint32_t transIndex = find_trans_index(saveExt);

                    if (transIndex < colorCount) {
                        colorTable[transIndex] = SK_ColorTRANSPARENT;
                        // If there is a transparent index, we also use this as
                        // the fill index.
                        fillIndex = transIndex;
                    } else if (fillIndex >= colorCount) {
                        // If the fill index is invalid, we default to 0.  This
                        // behavior is unspecified but matches SkImageDecoder.
                        fillIndex = 0;
                    }
                }

                // Check if we can skip filling the background of the image.  We
                // may be able to if the memory is zero initialized.
                bool skipBackground =
                        ((kN32_SkColorType == dstColorType && colorTable[fillIndex] == 0) ||
                        (kIndex_8_SkColorType == dstColorType && fillIndex == 0)) &&
                        kYes_ZeroInitialized == zeroInit;


                // Fill in the color table for indices greater than color count.
                // This allows for predictable, safe behavior.
                for (uint32_t i = colorCount; i < maxColors; i++) {
                    colorTable[i] = colorTable[fillIndex];
                } 

                // Check if image is only a subset of the image frame
                SkAutoTDelete<SkSwizzler> swizzler(NULL);
                if (innerWidth < width || innerHeight < height) {

                    // Modify the destination info
                    const SkImageInfo subsetDstInfo =
                            dstInfo.makeWH(innerWidth, innerHeight);

                    // Fill the destination with the fill color
                    // FIXME: This may not be the behavior that we want for
                    //        animated gifs where we draw on top of the
                    //        previous frame.
                    if (!skipBackground) {
                        SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, fillIndex, colorTable);
                    }

                    // Modify the dst pointer
                    const int32_t dstBytesPerPixel =
                            SkColorTypeBytesPerPixel(dstColorType);
                    void* subsetDst = SkTAddOffset<void*>(dst,
                            dstRowBytes * imageTop +
                            dstBytesPerPixel * imageLeft);

                    // Create the subset swizzler
                    swizzler.reset(SkSwizzler::CreateSwizzler(
                            SkSwizzler::kIndex, colorTable, subsetDstInfo,
                            subsetDst, dstRowBytes, zeroInit));
                } else {
                    // Create the fully dimensional swizzler
                    swizzler.reset(SkSwizzler::CreateSwizzler(
                            SkSwizzler::kIndex, colorTable, dstInfo, dst,
                            dstRowBytes, zeroInit));
                }

                // Stores output from dgiflib and input to the swizzler
                SkAutoTDeleteArray<uint8_t>
                        buffer(SkNEW_ARRAY(uint8_t, innerWidth));

                // Check the interlace flag and iterate over rows of the input
                if (fGif->Image.Interlace) {
                    // In interlace mode, the rows of input are rearranged in
                    // the output image.  We use an iterator to take care of
                    // the rearranging.
                    SkGifInterlaceIter iter(innerHeight);
                    for (int32_t y = 0; y < innerHeight; y++) {
                        if (GIF_ERROR == DGifGetLine(fGif, buffer.get(),
                                innerWidth)) {
                            // Recover from error by filling remainder of image
                            if (!skipBackground) {
                                memset(buffer.get(), fillIndex, innerWidth);
                                for (; y < innerHeight; y++) {
                                    swizzler->next(buffer.get(), iter.nextY());
                                }
                            }
                            return gif_error(SkStringPrintf(
                                    "Could not decode line %d of %d.\n",
                                    y, height - 1).c_str(), kIncompleteInput);
                        }
                        swizzler->next(buffer.get(), iter.nextY());
                    }
                } else {
                    // Standard mode
                    for (int32_t y = 0; y < innerHeight; y++) {
                        if (GIF_ERROR == DGifGetLine(fGif, buffer.get(),
                                innerWidth)) {
                            if (!skipBackground) {
                                SkSwizzler::Fill(swizzler->getDstRow(), dstInfo, dstRowBytes,
                                        innerHeight - y, fillIndex, colorTable);
                            }
                            return gif_error(SkStringPrintf(
                                    "Could not decode line %d of %d.\n",
                                    y, height - 1).c_str(), kIncompleteInput);
                        }
                        swizzler->next(buffer.get());
                    }
                }

                // FIXME: Gif files may have multiple images stored in a single
                //        file.  This is most commonly used to enable
                //        animations.  Since we are leaving animated gifs as a
                //        TODO, we will return kSuccess after decoding the
                //        first image in the file.  This is the same behavior
                //        as SkImageDecoder_libgif.
                //
                //        Most times this works pretty well, but sometimes it
                //        doesn't.  For example, I have an animated test image
                //        where the first image in the file is 1x1, but the
                //        subsequent images are meaningful.  This currently
                //        displays the 1x1 image, which is not ideal.  Right
                //        now I am leaving this as an issue that will be
                //        addressed when we implement animated gifs.
                //
                //        It is also possible (not explicitly disallowed in the
                //        specification) that gif files provide multiple
                //        images in a single file that are all meant to be
                //        displayed in the same frame together.  I will
                //        currently leave this unimplemented until I find a
                //        test case that expects this behavior.
                return kSuccess;
            }

            // Extensions are used to specify special properties of the image
            // such as transparency or animation.
            case EXTENSION_RECORD_TYPE:
                // Read extension data
#if GIFLIB_MAJOR < 5
                if (GIF_ERROR ==
                        DGifGetExtension(fGif, &saveExt.Function, &extData)) {
#else
                if (GIF_ERROR ==
                        DGifGetExtension(fGif, &extFunction, &extData)) {
#endif
                    return gif_error("Could not get extension.\n",
                            kIncompleteInput);
                }

                // Create an extension block with our data
                while (NULL != extData) {
                    // Add a single block
#if GIFLIB_MAJOR < 5
                    if (GIF_ERROR == AddExtensionBlock(&saveExt, extData[0],
                            &extData[1])) {
#else
                    if (GIF_ERROR ==
                            GifAddExtensionBlock(&saveExt.ExtensionBlockCount,
                            &saveExt.ExtensionBlocks, extFunction, extData[0],
                            &extData[1])) {
#endif
                        return gif_error("Could not add extension block.\n",
                                kIncompleteInput);
                    }
                    // Move to the next block
                    if (GIF_ERROR == DGifGetExtensionNext(fGif, &extData)) {
                        return gif_error("Could not get next extension.\n",
                                kIncompleteInput);
                    }
#if GIFLIB_MAJOR < 5
                    saveExt.Function = 0;
#endif
                }
                break;

            // Signals the end of the gif file
            case TERMINATE_RECORD_TYPE:
                break;

            default:
                // giflib returns an error code if the record type is not known.
                // We should catch this error immediately.
                SkASSERT(false);
                break;
        }
    } while (TERMINATE_RECORD_TYPE != recordType);

    return gif_error("Could not find any images to decode in gif file.\n",
            kInvalidInput);
}
