/*
 * Copyright (C) 2006 Apple Inc.
 * Copyright (C) 2007-2009 Torch Mobile, Inc.
 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
 *
 * Portions are Copyright (C) 2001 mozilla.org
 *
 * Other contributors:
 *   Stuart Parmenter <stuart@mozilla.com>
 *   Max Stepin <maxstepin@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Alternatively, the contents of this file may be used under the terms
 * of either the Mozilla Public License Version 1.1, found at
 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
 * (the "GPL"), in which case the provisions of the MPL or the GPL are
 * applicable instead of those above.  If you wish to allow use of your
 * version of this file only under the terms of one of those two
 * licenses (the MPL or the GPL) and not to allow others to use your
 * version of this file under the LGPL, indicate your decision by
 * deletingthe provisions above and replace them with the notice and
 * other provisions required by the MPL or the GPL, as the case may be.
 * If you do not delete the provisions above, a recipient may use your
 * version of this file under any of the LGPL, the MPL or the GPL.
 */

#include "config.h"
#include "PNGImageDecoder.h"

#include "Color.h"
#include <png.h>
#include <wtf/StdLibExtras.h>
#include <wtf/UniqueArray.h>

#if defined(PNG_LIBPNG_VER_MAJOR) && defined(PNG_LIBPNG_VER_MINOR) && (PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 4))
#define JMPBUF(png_ptr) png_jmpbuf(png_ptr)
#else
#define JMPBUF(png_ptr) png_ptr->jmpbuf
#endif

namespace WebCore {

// Gamma constants.
const double cMaxGamma = 21474.83;
const double cDefaultGamma = 2.2;
const double cInverseGamma = 0.45455;

// Protect against large PNGs. See Mozilla's bug #251381 for more info.
const unsigned long cMaxPNGSize = 1000000UL;

// Called if the decoding of the image fails.
static void PNGAPI decodingFailed(png_structp png, png_const_charp)
{
    longjmp(JMPBUF(png), 1);
}

// Callbacks given to the read struct.  The first is for warnings (we want to
// treat a particular warning as an error, which is why we have to register this
// callback).
static void PNGAPI decodingWarning(png_structp png, png_const_charp warningMsg)
{
    // Mozilla did this, so we will too.
    // Convert a tRNS warning to be an error (see
    // http://bugzilla.mozilla.org/show_bug.cgi?id=251381 )
    if (!strncmp(warningMsg, "Missing PLTE before tRNS", 24))
        png_error(png, warningMsg);
}

// Called when we have obtained the header information (including the size).
static void PNGAPI headerAvailable(png_structp png, png_infop)
{
    static_cast<PNGImageDecoder*>(png_get_progressive_ptr(png))->headerAvailable();
}

// Called when a row is ready.
static void PNGAPI rowAvailable(png_structp png, png_bytep rowBuffer, png_uint_32 rowIndex, int interlacePass)
{
    static_cast<PNGImageDecoder*>(png_get_progressive_ptr(png))->rowAvailable(rowBuffer, rowIndex, interlacePass);
}

// Called when we have completely finished decoding the image.
static void PNGAPI pngComplete(png_structp png, png_infop)
{
    static_cast<PNGImageDecoder*>(png_get_progressive_ptr(png))->pngComplete();
}

#if ENABLE(APNG)
// Called when we have the frame header.
static void PNGAPI frameHeader(png_structp png, png_infop)
{
    static_cast<PNGImageDecoder*>(png_get_progressive_ptr(png))->frameHeader();
}

// Called when we found user chunks.
static int PNGAPI readChunks(png_structp png, png_unknown_chunkp chunk)
{
    static_cast<PNGImageDecoder*>(png_get_user_chunk_ptr(png))->readChunks(chunk);
    return 1;
}
#endif

class PNGImageReader {
    WTF_MAKE_FAST_ALLOCATED;
public:
    PNGImageReader(PNGImageDecoder* decoder)
        : m_readOffset(0)
        , m_currentBufferSize(0)
        , m_decodingSizeOnly(false)
        , m_hasAlpha(false)
    {
        m_png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, decodingFailed, decodingWarning);
        m_info = png_create_info_struct(m_png);
        png_set_progressive_read_fn(m_png, decoder, headerAvailable, rowAvailable, pngComplete);
#if ENABLE(APNG)
        png_byte apngChunks[]= {"acTL\0fcTL\0fdAT\0"};
        png_set_keep_unknown_chunks(m_png, 1, apngChunks, 3);
        png_set_read_user_chunk_fn(m_png, static_cast<png_voidp>(decoder), readChunks);
        decoder->init();
#endif
    }

    ~PNGImageReader()
    {
        close();
    }

    void close()
    {
        if (m_png && m_info)
            // This will zero the pointers.
            png_destroy_read_struct(&m_png, &m_info, 0);
        m_interlaceBuffer.reset();
        m_readOffset = 0;
    }

    bool decode(const SharedBuffer::DataSegment& data, bool sizeOnly, unsigned haltAtFrame)
    {
        m_decodingSizeOnly = sizeOnly;
        PNGImageDecoder* decoder = static_cast<PNGImageDecoder*>(png_get_progressive_ptr(m_png));

        // We need to do the setjmp here. Otherwise bad things will happen.
        if (setjmp(JMPBUF(m_png)))
            return decoder->setFailed();

        auto bytesToSkip = m_readOffset;
        auto bytesToUse = data.size() - bytesToSkip;
        m_readOffset += bytesToUse;
        m_currentBufferSize = m_readOffset;
        png_process_data(m_png, m_info, reinterpret_cast<png_bytep>(const_cast<char*>(data.data() + bytesToSkip)), bytesToUse);
        // We explicitly specify the superclass encodedDataStatus() because we
        // merely want to check if we've managed to set the size, not
        // (recursively) trigger additional decoding if we haven't.
        if (sizeOnly ? decoder->ScalableImageDecoder::encodedDataStatus() >= EncodedDataStatus::SizeAvailable : decoder->isCompleteAtIndex(haltAtFrame))
            return true;

        return false;
    }

    png_structp pngPtr() const { return m_png; }
    png_infop infoPtr() const { return m_info; }

    void setReadOffset(unsigned offset) { m_readOffset = offset; }
    unsigned currentBufferSize() const { return m_currentBufferSize; }
    bool decodingSizeOnly() const { return m_decodingSizeOnly; }
    void setHasAlpha(bool hasAlpha) { m_hasAlpha = hasAlpha; }
    bool hasAlpha() const { return m_hasAlpha; }

    png_bytep interlaceBuffer() const { return m_interlaceBuffer.get(); }
    void createInterlaceBuffer(int size) { m_interlaceBuffer = makeUniqueArray<png_byte>(size); }

private:
    png_structp m_png;
    png_infop m_info;
    unsigned m_readOffset;
    unsigned m_currentBufferSize;
    bool m_decodingSizeOnly;
    bool m_hasAlpha;
    UniqueArray<png_byte> m_interlaceBuffer;
};

PNGImageDecoder::PNGImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
    : ScalableImageDecoder(alphaOption, gammaAndColorProfileOption)
    , m_doNothingOnFailure(false)
    , m_currentFrame(0)
#if ENABLE(APNG)
    , m_png(nullptr)
    , m_info(nullptr)
    , m_isAnimated(false)
    , m_frameInfo(false)
    , m_frameIsHidden(false)
    , m_hasInfo(false)
    , m_gamma(45455)
    , m_frameCount(1)
    , m_playCount(0)
    , m_totalFrames(0)
    , m_sizePLTE(0)
    , m_sizetRNS(0)
    , m_sequenceNumber(0)
    , m_width(0)
    , m_height(0)
    , m_xOffset(0)
    , m_yOffset(0)
    , m_delayNumerator(1)
    , m_delayDenominator(1)
    , m_dispose(0)
    , m_blend(0)
#endif
{
}

PNGImageDecoder::~PNGImageDecoder() = default;

#if ENABLE(APNG)
RepetitionCount PNGImageDecoder::repetitionCount() const
{
    // Signal no repetition if the PNG image is not animated.
    if (!m_isAnimated)
        return RepetitionCountNone;

    // APNG format uses 0 to indicate that an animation must play indefinitely. But
    // the RepetitionCount enumeration uses RepetitionCountInfinite, so we need to adapt this.
    if (!m_playCount)
        return RepetitionCountInfinite;

    return m_playCount;
}
#endif

ScalableImageDecoderFrame* PNGImageDecoder::frameBufferAtIndex(size_t index)
{
#if ENABLE(APNG)
    if (ScalableImageDecoder::encodedDataStatus() < EncodedDataStatus::SizeAvailable)
        return nullptr;

    if (index >= frameCount())
        index = frameCount() - 1;
#else
    if (index)
        return nullptr;
#endif

    if (m_frameBufferCache.isEmpty())
        m_frameBufferCache.grow(1);

    auto& frame = m_frameBufferCache[index];
    if (!frame.isComplete())
        decode(false, index, isAllDataReceived());
    return &frame;
}

bool PNGImageDecoder::setFailed()
{
    if (m_doNothingOnFailure)
        return false;
    m_reader = nullptr;
    return ScalableImageDecoder::setFailed();
}

void PNGImageDecoder::headerAvailable()
{
    png_structp png = m_reader->pngPtr();
    png_infop info = m_reader->infoPtr();
    png_uint_32 width = png_get_image_width(png, info);
    png_uint_32 height = png_get_image_height(png, info);

    // Protect against large images.
    if (width > cMaxPNGSize || height > cMaxPNGSize) {
        longjmp(JMPBUF(png), 1);
        return;
    }

    // We can fill in the size now that the header is available.  Avoid memory
    // corruption issues by neutering setFailed() during this call; if we don't
    // do this, failures will cause |m_reader| to be deleted, and our jmpbuf
    // will cease to exist.  Note that we'll still properly set the failure flag
    // in this case as soon as we longjmp().
    m_doNothingOnFailure = true;
    bool result = setSize(IntSize(width, height));
    m_doNothingOnFailure = false;
    if (!result) {
        longjmp(JMPBUF(png), 1);
        return;
    }

    int bitDepth, colorType, interlaceType, compressionType, filterType, channels;
    png_get_IHDR(png, info, &width, &height, &bitDepth, &colorType, &interlaceType, &compressionType, &filterType);

    // The options we set here match what Mozilla does.

#if ENABLE(APNG)
    m_hasInfo = true;
    if (m_isAnimated) {
        png_save_uint_32(m_dataIHDR, 13);
        memcpy(m_dataIHDR + 4, "IHDR", 4);
        png_save_uint_32(m_dataIHDR + 8, width);
        png_save_uint_32(m_dataIHDR + 12, height);
        m_dataIHDR[16] = bitDepth;
        m_dataIHDR[17] = colorType;
        m_dataIHDR[18] = compressionType;
        m_dataIHDR[19] = filterType;
        m_dataIHDR[20] = interlaceType;
    }
#endif

    // Expand to ensure we use 24-bit for RGB and 32-bit for RGBA.
    if (colorType == PNG_COLOR_TYPE_PALETTE) {
#if ENABLE(APNG)
        if (m_isAnimated) {
            png_colorp palette;
            int paletteSize = 0;
            png_get_PLTE(png, info, &palette, &paletteSize);
            paletteSize *= 3;
            png_save_uint_32(m_dataPLTE, paletteSize);
            memcpy(m_dataPLTE + 4, "PLTE", 4);
            memcpy(m_dataPLTE + 8, palette, paletteSize);
            m_sizePLTE = paletteSize + 12;
        }
#endif
        png_set_expand(png);
    }

    if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8)
        png_set_expand(png);

    png_bytep trns = 0;
    int trnsCount = 0;
    png_color_16p transValues;
    if (png_get_valid(png, info, PNG_INFO_tRNS)) {
        png_get_tRNS(png, info, &trns, &trnsCount, &transValues);
#if ENABLE(APNG)
        if (m_isAnimated) {
            if (colorType == PNG_COLOR_TYPE_RGB) {
                png_save_uint_16(m_datatRNS + 8, transValues->red);
                png_save_uint_16(m_datatRNS + 10, transValues->green);
                png_save_uint_16(m_datatRNS + 12, transValues->blue);
                trnsCount = 6;
            } else if (colorType == PNG_COLOR_TYPE_GRAY) {
                png_save_uint_16(m_datatRNS + 8, transValues->gray);
                trnsCount = 2;
            } else if (colorType == PNG_COLOR_TYPE_PALETTE)
                memcpy(m_datatRNS + 8, trns, trnsCount);

            png_save_uint_32(m_datatRNS, trnsCount);
            memcpy(m_datatRNS + 4, "tRNS", 4);
            m_sizetRNS = trnsCount + 12;
        }
#endif
        png_set_expand(png);
    }

    if (bitDepth == 16)
        png_set_strip_16(png);

    if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png);

    // Deal with gamma and keep it under our control.
    double gamma;
    if (!m_ignoreGammaAndColorProfile && png_get_gAMA(png, info, &gamma)) {
        if ((gamma <= 0.0) || (gamma > cMaxGamma)) {
            gamma = cInverseGamma;
            png_set_gAMA(png, info, gamma);
        }
        png_set_gamma(png, cDefaultGamma, gamma);
#if ENABLE(APNG)
        m_gamma = static_cast<int>(gamma * 100000);
#endif
    } else
        png_set_gamma(png, cDefaultGamma, cInverseGamma);

    // Tell libpng to send us rows for interlaced pngs.
    if (interlaceType == PNG_INTERLACE_ADAM7)
        png_set_interlace_handling(png);

    // Update our info now.
    png_read_update_info(png, info);
    channels = png_get_channels(png, info);
    ASSERT(channels == 3 || channels == 4);

    m_reader->setHasAlpha(channels == 4);

    if (m_reader->decodingSizeOnly()) {
        // If we only needed the size, halt the reader.
#if defined(PNG_LIBPNG_VER_MAJOR) && defined(PNG_LIBPNG_VER_MINOR) && (PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 5))
        // '0' argument to png_process_data_pause means: Do not cache unprocessed data.
        m_reader->setReadOffset(m_reader->currentBufferSize() - png_process_data_pause(png, 0));
#else
        m_reader->setReadOffset(m_reader->currentBufferSize() - png->buffer_size);
        png->buffer_size = 0;
#endif
    }
}

void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, int)
{
    if (m_frameBufferCache.isEmpty())
        return;

    // Initialize the framebuffer if needed.
#if ENABLE(APNG)
    if (m_currentFrame >= frameCount())
        return;
#endif
    auto& buffer = m_frameBufferCache[m_currentFrame];
    if (buffer.isInvalid()) {
        png_structp png = m_reader->pngPtr();
        if (!buffer.initialize(size(), m_premultiplyAlpha)) {
            longjmp(JMPBUF(png), 1);
            return;
        }

        unsigned colorChannels = m_reader->hasAlpha() ? 4 : 3;
        if (PNG_INTERLACE_ADAM7 == png_get_interlace_type(png, m_reader->infoPtr())
            || m_currentFrame) {
            if (!m_reader->interlaceBuffer())
                m_reader->createInterlaceBuffer(colorChannels * size().width() * size().height());
            if (!m_reader->interlaceBuffer()) {
                longjmp(JMPBUF(png), 1);
                return;
            }
        }

        buffer.setDecodingStatus(DecodingStatus::Partial);
        buffer.setHasAlpha(false);

#if ENABLE(APNG)
        if (m_currentFrame)
            initFrameBuffer(m_currentFrame);
#endif
    }

    /* libpng comments (here to explain what follows).
     *
     * this function is called for every row in the image.  If the
     * image is interlacing, and you turned on the interlace handler,
     * this function will be called for every row in every pass.
     * Some of these rows will not be changed from the previous pass.
     * When the row is not changed, the new_row variable will be NULL.
     * The rows and passes are called in order, so you don't really
     * need the row_num and pass, but I'm supplying them because it
     * may make your life easier.
     */

    // Nothing to do if the row is unchanged, or the row is outside
    // the image bounds: libpng may send extra rows, ignore them to
    // make our lives easier.
    if (!rowBuffer)
        return;
    if (rowIndex >= (unsigned)size().height())
        return;

    /* libpng comments (continued).
     *
     * For the non-NULL rows of interlaced images, you must call
     * png_progressive_combine_row() passing in the row and the
     * old row.  You can call this function for NULL rows (it will
     * just return) and for non-interlaced images (it just does the
     * memcpy for you) if it will make the code easier.  Thus, you
     * can just do this for all cases:
     *
     *    png_progressive_combine_row(png_ptr, old_row, new_row);
     *
     * where old_row is what was displayed for previous rows.  Note
     * that the first pass (pass == 0 really) will completely cover
     * the old row, so the rows do not have to be initialized.  After
     * the first pass (and only for interlaced images), you will have
     * to pass the current row, and the function will combine the
     * old row and the new row.
     */

    bool hasAlpha = m_reader->hasAlpha();
    unsigned colorChannels = hasAlpha ? 4 : 3;
    png_bytep row = rowBuffer;

    if (png_bytep interlaceBuffer = m_reader->interlaceBuffer()) {
        row = interlaceBuffer + (rowIndex * colorChannels * size().width());
#if ENABLE(APNG)
        if (m_currentFrame) {
            png_progressive_combine_row(m_png, row, rowBuffer);
            return; // Only do incremental image display for the first frame.
        }
#endif
        png_progressive_combine_row(m_reader->pngPtr(), row, rowBuffer);
    }

    // Write the decoded row pixels to the frame buffer.
    auto* address = buffer.backingStore()->pixelAt(0, rowIndex);
    int width = size().width();
    unsigned char nonTrivialAlphaMask = 0;

    png_bytep pixel = row;
    if (hasAlpha) {
        for (int x = 0; x < width; ++x, pixel += 4, ++address) {
            unsigned alpha = pixel[3];
            buffer.backingStore()->setPixel(address, pixel[0], pixel[1], pixel[2], alpha);
            nonTrivialAlphaMask |= (255 - alpha);
        }
    } else {
        for (int x = 0; x < width; ++x, pixel += 3, ++address)
            *address = 0xFF000000 | pixel[0] << 16 | pixel[1] << 8 | pixel[2];
    }

    if (nonTrivialAlphaMask && !buffer.hasAlpha())
        buffer.setHasAlpha(true);
}

void PNGImageDecoder::pngComplete()
{
#if ENABLE(APNG)
    if (m_isAnimated) {
        if (!processingFinish() && m_frameCount == m_currentFrame)
            return;

        fallbackNotAnimated();
    }
#endif
    if (!m_frameBufferCache.isEmpty())
        m_frameBufferCache.first().setDecodingStatus(DecodingStatus::Complete);
}

void PNGImageDecoder::decode(bool onlySize, unsigned haltAtFrame, bool allDataReceived)
{
    if (failed())
        return;

    if (!m_reader)
        m_reader = makeUnique<PNGImageReader>(this);

    // If we couldn't decode the image but we've received all the data, decoding
    // has failed.
    if (!m_reader->decode(*m_data, onlySize, haltAtFrame) && allDataReceived)
        setFailed();
    // If we're done decoding the image, we don't need the PNGImageReader
    // anymore.  (If we failed, |m_reader| has already been cleared.)
    else if (isComplete())
        m_reader = nullptr;
}

#if ENABLE(APNG)
void PNGImageDecoder::readChunks(png_unknown_chunkp chunk)
{
    if (!memcmp(chunk->name, "acTL", 4) && chunk->size == 8) {
        if (m_hasInfo || m_isAnimated)
            return;

        m_frameCount = png_get_uint_32(chunk->data);
        m_playCount = png_get_uint_32(chunk->data + 4);

        if (!m_frameCount || m_frameCount > PNG_UINT_31_MAX || m_playCount > PNG_UINT_31_MAX) {
            fallbackNotAnimated();
            return;
        }

        m_isAnimated = true;
        if (!m_frameInfo)
            m_frameIsHidden = true;

        if (m_frameBufferCache.size() == m_frameCount)
            return;

        m_frameBufferCache.resize(m_frameCount);
    } else if (!memcmp(chunk->name, "fcTL", 4) && chunk->size == 26) {
        if (m_hasInfo && !m_isAnimated)
            return;

        m_frameInfo = false;

        if (processingFinish()) {
            fallbackNotAnimated();
            return;
        }

        // At this point the old frame is done. Let's start a new one.
        unsigned sequenceNumber = png_get_uint_32(chunk->data);
        if (sequenceNumber != m_sequenceNumber++) {
            fallbackNotAnimated();
            return;
        }

        m_width = png_get_uint_32(chunk->data + 4);
        m_height = png_get_uint_32(chunk->data + 8);
        m_xOffset = png_get_uint_32(chunk->data + 12);
        m_yOffset = png_get_uint_32(chunk->data + 16);
        m_delayNumerator = png_get_uint_16(chunk->data + 20);
        m_delayDenominator = png_get_uint_16(chunk->data + 22);
        m_dispose = chunk->data[24];
        m_blend = chunk->data[25];

        png_structp png = m_reader->pngPtr();
        png_infop info = m_reader->infoPtr();
        png_uint_32 width = png_get_image_width(png, info);
        png_uint_32 height = png_get_image_height(png, info);

        if (m_width > cMaxPNGSize || m_height > cMaxPNGSize
            || m_xOffset > cMaxPNGSize || m_yOffset > cMaxPNGSize
            || m_xOffset + m_width > width
            || m_yOffset + m_height > height
            || m_dispose > 2 || m_blend > 1) {
            fallbackNotAnimated();
            return;
        }

        if (m_frameBufferCache.isEmpty())
            m_frameBufferCache.grow(1);

        if (m_currentFrame < m_frameBufferCache.size()) {
            auto& buffer = m_frameBufferCache[m_currentFrame];

            if (!m_delayDenominator)
                buffer.setDuration(Seconds::fromMilliseconds(m_delayNumerator * 10));
            else
                buffer.setDuration(Seconds::fromMilliseconds(m_delayNumerator * 1000 / m_delayDenominator));

            if (m_dispose == 2)
                buffer.setDisposalMethod(ScalableImageDecoderFrame::DisposalMethod::RestoreToPrevious);
            else if (m_dispose == 1)
                buffer.setDisposalMethod(ScalableImageDecoderFrame::DisposalMethod::RestoreToBackground);
            else
                buffer.setDisposalMethod(ScalableImageDecoderFrame::DisposalMethod::DoNotDispose);
        }

        m_frameInfo = true;
        m_frameIsHidden = false;

        if (processingStart(chunk)) {
            fallbackNotAnimated();
            return;
        }
    } else if (!memcmp(chunk->name, "fdAT", 4) && chunk->size >= 4) {
        if (!m_frameInfo || !m_isAnimated)
            return;

        unsigned sequenceNumber = png_get_uint_32(chunk->data);
        if (sequenceNumber != m_sequenceNumber++) {
            fallbackNotAnimated();
            return;
        }

        if (setjmp(JMPBUF(m_png))) {
            fallbackNotAnimated();
            return;
        }

        png_save_uint_32(chunk->data, chunk->size - 4);
        png_process_data(m_png, m_info, chunk->data, 4);
        memcpy(chunk->data, "IDAT", 4);
        png_process_data(m_png, m_info, chunk->data, chunk->size);
        png_process_data(m_png, m_info, chunk->data, 4);
    }
}

void PNGImageDecoder::frameHeader()
{
    int colorType = png_get_color_type(m_png, m_info);

    if (colorType == PNG_COLOR_TYPE_PALETTE)
        png_set_expand(m_png);

    int bitDepth = png_get_bit_depth(m_png, m_info);
    if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8)
        png_set_expand(m_png);

    if (png_get_valid(m_png, m_info, PNG_INFO_tRNS))
        png_set_expand(m_png);

    if (bitDepth == 16)
        png_set_strip_16(m_png);

    if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(m_png);

    double gamma;
    if (png_get_gAMA(m_png, m_info, &gamma))
        png_set_gamma(m_png, cDefaultGamma, gamma);

    png_set_interlace_handling(m_png);

    png_read_update_info(m_png, m_info);
}

void PNGImageDecoder::init()
{
    m_isAnimated = false;
    m_frameInfo = false;
    m_frameIsHidden = false;
    m_hasInfo = false;
    m_currentFrame = 0;
    m_totalFrames = 0;
    m_sequenceNumber = 0;
}

void PNGImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame)
{
    if (m_frameBufferCache.isEmpty())
        return;

    // See GIFImageDecoder for full explanation.
    clearBeforeFrame = std::min(clearBeforeFrame, m_frameBufferCache.size() - 1);
    const Vector<ScalableImageDecoderFrame>::iterator end(m_frameBufferCache.begin() + clearBeforeFrame);

    Vector<ScalableImageDecoderFrame>::iterator i(end);
    for (; (i != m_frameBufferCache.begin()) && (i->isInvalid() || (i->disposalMethod() == ScalableImageDecoderFrame::DisposalMethod::RestoreToPrevious)); --i) {
        if (i->isComplete() && (i != end))
            i->clear();
    }

    // Now |i| holds the last frame we need to preserve; clear prior frames.
    for (Vector<ScalableImageDecoderFrame>::iterator j(m_frameBufferCache.begin()); j != i; ++j) {
        ASSERT(!j->isPartial());
        if (j->isInvalid())
            j->clear();
    }
}

void PNGImageDecoder::initFrameBuffer(size_t frameIndex)
{
    if (frameIndex >= frameCount())
        return;

    auto& buffer = m_frameBufferCache[frameIndex];

    // The starting state for this frame depends on the previous frame's
    // disposal method.
    //
    // Frames that use the DisposalMethod::RestoreToPrevious method are effectively
    // no-ops in terms of changing the starting state of a frame compared to
    // the starting state of the previous frame, so skip over them.  (If the
    // first frame specifies this method, it will get treated like
    // DisposeOverwriteBgcolor below and reset to a completely empty image.)
    const auto* prevBuffer = &m_frameBufferCache[--frameIndex];
    auto prevMethod = prevBuffer->disposalMethod();
    while (frameIndex && (prevMethod == ScalableImageDecoderFrame::DisposalMethod::RestoreToPrevious)) {
        prevBuffer = &m_frameBufferCache[--frameIndex];
        prevMethod = prevBuffer->disposalMethod();
    }

    png_structp png = m_reader->pngPtr();
    ASSERT(prevBuffer->isComplete());

    if (prevMethod == ScalableImageDecoderFrame::DisposalMethod::DoNotDispose) {
        // Preserve the last frame as the starting state for this frame.
        if (!prevBuffer->backingStore() || !buffer.initialize(*prevBuffer->backingStore()))
            longjmp(JMPBUF(png), 1);
    } else {
        // We want to clear the previous frame to transparent, without
        // affecting pixels in the image outside of the frame.
        IntRect prevRect = prevBuffer->backingStore()->frameRect();
        if (!frameIndex || prevRect.contains(IntRect(IntPoint(), size()))) {
            // Clearing the first frame, or a frame the size of the whole
            // image, results in a completely empty image.
            buffer.backingStore()->clear();
            buffer.setHasAlpha(true);
        } else {
            // Copy the whole previous buffer, then clear just its frame.
            if (!prevBuffer->backingStore() || !buffer.initialize(*prevBuffer->backingStore())) {
                longjmp(JMPBUF(png), 1);
                return;
            }
            buffer.backingStore()->clearRect(prevRect);
            buffer.setHasAlpha(true);
        }
    }
    
    IntRect frameRect(m_xOffset, m_yOffset, m_width, m_height);

    // Make sure the frameRect doesn't extend outside the buffer.
    if (frameRect.maxX() > size().width())
        frameRect.setWidth(size().width() - m_xOffset);
    if (frameRect.maxY() > size().height())
        frameRect.setHeight(size().height() - m_yOffset);

    buffer.backingStore()->setFrameRect(frameRect);
}

void PNGImageDecoder::frameComplete()
{
    if (m_frameIsHidden || m_currentFrame >= frameCount())
        return;

    auto& buffer = m_frameBufferCache[m_currentFrame];
    buffer.setDecodingStatus(DecodingStatus::Complete);

    png_bytep interlaceBuffer = m_reader->interlaceBuffer();

    if (m_currentFrame && interlaceBuffer) {
        IntRect rect = buffer.backingStore()->frameRect();
        bool hasAlpha = m_reader->hasAlpha();
        unsigned colorChannels = hasAlpha ? 4 : 3;
        bool nonTrivialAlpha = false;
        if (m_blend && !hasAlpha)
            m_blend = 0;

        png_bytep row = interlaceBuffer;
        for (int y = rect.y(); y < rect.maxY(); ++y, row += colorChannels * size().width()) {
            png_bytep pixel = row;
            auto* address = buffer.backingStore()->pixelAt(rect.x(), y);
            for (int x = rect.x(); x < rect.maxX(); ++x, pixel += colorChannels) {
                unsigned alpha = hasAlpha ? pixel[3] : 255;
                nonTrivialAlpha |= alpha < 255;
                if (!m_blend)
                    buffer.backingStore()->setPixel(address++, pixel[0], pixel[1], pixel[2], alpha);
                else
                    buffer.backingStore()->blendPixel(address++, pixel[0], pixel[1], pixel[2], alpha);
            }
        }

        if (!nonTrivialAlpha) {
            IntRect rect = buffer.backingStore()->frameRect();
            if (rect.contains(IntRect(IntPoint(), size())))
                buffer.setHasAlpha(false);
            else {
                size_t frameIndex = m_currentFrame;
                const auto* prevBuffer = &m_frameBufferCache[--frameIndex];
                while (frameIndex && (prevBuffer->disposalMethod() == ScalableImageDecoderFrame::DisposalMethod::RestoreToPrevious))
                    prevBuffer = &m_frameBufferCache[--frameIndex];

                IntRect prevRect = prevBuffer->backingStore()->frameRect();
                if ((prevBuffer->disposalMethod() == ScalableImageDecoderFrame::DisposalMethod::RestoreToBackground) && !prevBuffer->hasAlpha() && rect.contains(prevRect))
                    buffer.setHasAlpha(false);
            }
        } else if (!m_blend && !buffer.hasAlpha())
            buffer.setHasAlpha(nonTrivialAlpha);
    }
    m_currentFrame++;
}

int PNGImageDecoder::processingStart(png_unknown_chunkp chunk)
{
    static png_byte dataPNG[8] = {137, 80, 78, 71, 13, 10, 26, 10};
    static png_byte datagAMA[16] = {0, 0, 0, 4, 103, 65, 77, 65};

    if (!m_hasInfo)
        return 0;

    m_totalFrames++;

    m_png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, decodingFailed, 0);
    m_info = png_create_info_struct(m_png);
    if (setjmp(JMPBUF(m_png)))
        return 1;

    png_set_crc_action(m_png, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
    png_set_progressive_read_fn(m_png, static_cast<png_voidp>(this),
        WebCore::frameHeader, WebCore::rowAvailable, 0);

    memcpy(m_dataIHDR + 8, chunk->data + 4, 8);
    png_save_uint_32(datagAMA + 8, m_gamma);

    png_process_data(m_png, m_info, dataPNG, 8);
    png_process_data(m_png, m_info, m_dataIHDR, 25);
    png_process_data(m_png, m_info, datagAMA, 16);
    if (m_sizePLTE > 0)
        png_process_data(m_png, m_info, m_dataPLTE, m_sizePLTE);
    if (m_sizetRNS > 0)
        png_process_data(m_png, m_info, m_datatRNS, m_sizetRNS);

    return 0;
}

int PNGImageDecoder::processingFinish()
{
    static png_byte dataIEND[12] = {0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130};

    if (!m_hasInfo)
        return 0;

    if (m_totalFrames) {
        if (setjmp(JMPBUF(m_png)))
            return 1;

        png_process_data(m_png, m_info, dataIEND, 12);
        png_destroy_read_struct(&m_png, &m_info, 0);
    }

    frameComplete();
    return 0;
}

void PNGImageDecoder::fallbackNotAnimated()
{
    m_isAnimated = false;
    m_playCount = 0;
    m_currentFrame = 0;
}
#endif

} // namespace WebCore
