/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the WebP plugins in the Qt ImageFormats module.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwebphandler_p.h"
#include "webp/mux.h"
#include "webp/encode.h"
#include <qcolor.h>
#include <qimage.h>
#include <qdebug.h>
#include <qpainter.h>
#include <qvariant.h>

static const int riffHeaderSize = 12; // RIFF_HEADER_SIZE from webp/format_constants.h

QWebpHandler::QWebpHandler() :
    m_quality(75),
    m_scanState(ScanNotScanned),
    m_features(),
    m_formatFlags(0),
    m_loop(0),
    m_frameCount(0),
    m_demuxer(NULL),
    m_composited(NULL)
{
    memset(&m_iter, 0, sizeof(m_iter));
}

QWebpHandler::~QWebpHandler()
{
    WebPDemuxReleaseIterator(&m_iter);
    WebPDemuxDelete(m_demuxer);
    delete m_composited;
}

bool QWebpHandler::canRead() const
{
    if (m_scanState == ScanNotScanned && !canRead(device()))
        return false;

    if (m_scanState != ScanError) {
        setFormat(QByteArrayLiteral("webp"));

        if (m_features.has_animation && m_iter.frame_num >= m_frameCount)
            return false;

        return true;
    }
    return false;
}

bool QWebpHandler::canRead(QIODevice *device)
{
    if (!device) {
        qWarning("QWebpHandler::canRead() called with no device");
        return false;
    }

    QByteArray header = device->peek(riffHeaderSize);
    return header.startsWith("RIFF") && header.endsWith("WEBP");
}

bool QWebpHandler::ensureScanned() const
{
    if (m_scanState != ScanNotScanned)
        return m_scanState == ScanSuccess;

    m_scanState = ScanError;

    if (device()->isSequential()) {
        qWarning() << "Sequential devices are not supported";
        return false;
    }

    qint64 oldPos = device()->pos();
    device()->seek(0);

    QWebpHandler *that = const_cast<QWebpHandler *>(this);
    QByteArray header = device()->peek(sizeof(WebPBitstreamFeatures));
    if (WebPGetFeatures((const uint8_t*)header.constData(), header.size(), &(that->m_features)) == VP8_STATUS_OK) {
        if (m_features.has_animation) {
            // For animation, we have to read and scan whole file to determine loop count and images count
            device()->seek(oldPos);

            if (that->ensureDemuxer()) {
                that->m_loop = WebPDemuxGetI(m_demuxer, WEBP_FF_LOOP_COUNT);
                that->m_frameCount = WebPDemuxGetI(m_demuxer, WEBP_FF_FRAME_COUNT);
                that->m_bgColor = QColor::fromRgba(QRgb(WebPDemuxGetI(m_demuxer, WEBP_FF_BACKGROUND_COLOR)));

                that->m_composited = new QImage(that->m_features.width, that->m_features.height, QImage::Format_ARGB32);
                if (that->m_features.has_alpha)
                    that->m_composited->fill(Qt::transparent);

                // We do not reset device position since we have read in all data
                m_scanState = ScanSuccess;
                return true;
            }
        } else {
            m_scanState = ScanSuccess;
        }
    }

    device()->seek(oldPos);

    return m_scanState == ScanSuccess;
}

bool QWebpHandler::ensureDemuxer()
{
    if (m_demuxer)
        return true;

    m_rawData = device()->readAll();
    m_webpData.bytes = reinterpret_cast<const uint8_t *>(m_rawData.constData());
    m_webpData.size = m_rawData.size();

    m_demuxer = WebPDemux(&m_webpData);
    if (m_demuxer == NULL)
        return false;

    m_formatFlags = WebPDemuxGetI(m_demuxer, WEBP_FF_FORMAT_FLAGS);
    return true;
}

bool QWebpHandler::read(QImage *image)
{
    if (!ensureScanned() || device()->isSequential() || !ensureDemuxer())
        return false;

    if (m_iter.frame_num == 0) {
        // Read global meta-data chunks first
        WebPChunkIterator metaDataIter;
        if ((m_formatFlags & ICCP_FLAG) && WebPDemuxGetChunk(m_demuxer, "ICCP", 1, &metaDataIter)) {
            const QByteArray iccProfile = QByteArray::fromRawData(reinterpret_cast<const char *>(metaDataIter.chunk.bytes),
                                                                  metaDataIter.chunk.size);
            m_colorSpace = QColorSpace::fromIccProfile(iccProfile);
            // ### consider parsing EXIF and/or XMP metadata too.
            WebPDemuxReleaseChunkIterator(&metaDataIter);
        }

        // Go to first frame
        if (!WebPDemuxGetFrame(m_demuxer, 1, &m_iter))
            return false;
    } else {
        // Go to next frame
        if (!WebPDemuxNextFrame(&m_iter))
            return false;
    }

    WebPBitstreamFeatures features;
    VP8StatusCode status = WebPGetFeatures(m_iter.fragment.bytes, m_iter.fragment.size, &features);
    if (status != VP8_STATUS_OK)
        return false;

    QImage::Format format = m_features.has_alpha ? QImage::Format_ARGB32 : QImage::Format_RGB32;
    QImage frame(m_iter.width, m_iter.height, format);
    uint8_t *output = frame.bits();
    size_t output_size = frame.sizeInBytes();
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
    if (!WebPDecodeBGRAInto(
        reinterpret_cast<const uint8_t*>(m_iter.fragment.bytes), m_iter.fragment.size,
        output, output_size, frame.bytesPerLine()))
#else
    if (!WebPDecodeARGBInto(
        reinterpret_cast<const uint8_t*>(m_iter.fragment.bytes), m_iter.fragment.size,
        output, output_size, frame.bytesPerLine()))
#endif
        return false;

    if (!m_features.has_animation) {
        // Single image
        *image = frame;
    } else {
        // Animation
        QPainter painter(m_composited);
        if (m_features.has_alpha && m_iter.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND)
            m_composited->fill(Qt::transparent);
        painter.drawImage(currentImageRect(), frame);

        *image = *m_composited;
    }
    image->setColorSpace(m_colorSpace);

    return true;
}

bool QWebpHandler::write(const QImage &image)
{
    if (image.isNull()) {
        qWarning() << "source image is null.";
        return false;
    }
    if (std::max(image.width(), image.height()) > WEBP_MAX_DIMENSION) {
        qWarning() << "QWebpHandler::write() source image too large for WebP: " << image.size();
        return false;
    }

    QImage srcImage = image;
    bool alpha = srcImage.hasAlphaChannel();
    QImage::Format newFormat = alpha ? QImage::Format_RGBA8888 : QImage::Format_RGB888;
    if (srcImage.format() != newFormat)
        srcImage = srcImage.convertToFormat(newFormat);

    WebPPicture picture;
    WebPConfig config;

    if (!WebPPictureInit(&picture) || !WebPConfigInit(&config)) {
        qWarning() << "failed to init webp picture and config";
        return false;
    }

    picture.width = srcImage.width();
    picture.height = srcImage.height();
    picture.use_argb = 1;
    bool failed = false;
    if (alpha)
        failed = !WebPPictureImportRGBA(&picture, srcImage.bits(), srcImage.bytesPerLine());
    else
        failed = !WebPPictureImportRGB(&picture, srcImage.bits(), srcImage.bytesPerLine());

    if (failed) {
        qWarning() << "failed to import image data to webp picture.";
        WebPPictureFree(&picture);
        return false;
    }

    int reqQuality = m_quality < 0 ? 75 : qMin(m_quality, 100);
    if (reqQuality < 100) {
        config.lossless = 0;
        config.quality = reqQuality;
    } else {
        config.lossless = 1;
        config.quality = 70;  // For lossless, specifies compression effort; 70 is libwebp default
    }
    config.alpha_quality = config.quality;
    WebPMemoryWriter writer;
    WebPMemoryWriterInit(&writer);
    picture.writer = WebPMemoryWrite;
    picture.custom_ptr = &writer;

    if (!WebPEncode(&config, &picture)) {
        qWarning() << "failed to encode webp picture, error code: " << picture.error_code;
        WebPPictureFree(&picture);
        return false;
    }

    bool res = false;
    if (image.colorSpace().isValid()) {
        int copy_data = 0;
        WebPMux *mux = WebPMuxNew();
        WebPData image_data = { writer.mem, writer.size };
        WebPMuxSetImage(mux, &image_data, copy_data);
        uint8_t vp8xChunk[10];
        uint8_t flags = 0x20; // Has ICCP chunk, no XMP, EXIF or animation.
        if (image.hasAlphaChannel())
            flags |= 0x10;
        vp8xChunk[0] = flags;
        vp8xChunk[1] = 0;
        vp8xChunk[2] = 0;
        vp8xChunk[3] = 0;
        const unsigned width = image.width() - 1;
        const unsigned height = image.height() - 1;
        vp8xChunk[4] = width & 0xff;
        vp8xChunk[5] = (width >> 8) & 0xff;
        vp8xChunk[6] = (width >> 16) & 0xff;
        vp8xChunk[7] = height & 0xff;
        vp8xChunk[8] = (height >> 8) & 0xff;
        vp8xChunk[9] = (height >> 16) & 0xff;
        WebPData vp8x_data = { vp8xChunk, 10 };
        if (WebPMuxSetChunk(mux, "VP8X", &vp8x_data, copy_data) == WEBP_MUX_OK) {
            QByteArray iccProfile = image.colorSpace().iccProfile();
            WebPData iccp_data = {
                    reinterpret_cast<const uint8_t *>(iccProfile.constData()),
                    static_cast<size_t>(iccProfile.size())
            };
            if (WebPMuxSetChunk(mux, "ICCP", &iccp_data, copy_data) == WEBP_MUX_OK) {
                WebPData output_data;
                if (WebPMuxAssemble(mux, &output_data) == WEBP_MUX_OK) {
                    res = (output_data.size ==
                               static_cast<size_t>(device()->write(reinterpret_cast<const char *>(output_data.bytes), output_data.size)));
                }
                WebPDataClear(&output_data);
            }
        }
        WebPMuxDelete(mux);
    }
    if (!res) {
        res = (writer.size ==
                   static_cast<size_t>(device()->write(reinterpret_cast<const char *>(writer.mem), writer.size)));
    }
    WebPPictureFree(&picture);

    return res;
}

QVariant QWebpHandler::option(ImageOption option) const
{
    if (!supportsOption(option) || !ensureScanned())
        return QVariant();

    switch (option) {
    case Quality:
        return m_quality;
    case Size:
        return QSize(m_features.width, m_features.height);
    case Animation:
        return m_features.has_animation;
    case BackgroundColor:
        return m_bgColor;
    default:
        return QVariant();
    }
}

void QWebpHandler::setOption(ImageOption option, const QVariant &value)
{
    switch (option) {
    case Quality:
        m_quality = value.toInt();
        return;
    default:
        break;
    }
    QImageIOHandler::setOption(option, value);
}

bool QWebpHandler::supportsOption(ImageOption option) const
{
    return option == Quality
        || option == Size
        || option == Animation
        || option == BackgroundColor;
}

#if QT_DEPRECATED_SINCE(5, 13)
QByteArray QWebpHandler::name() const
{
    return QByteArrayLiteral("webp");
}
#endif

int QWebpHandler::imageCount() const
{
    if (!ensureScanned())
        return 0;

    if (!m_features.has_animation)
        return 1;

    return m_frameCount;
}

int QWebpHandler::currentImageNumber() const
{
    if (!ensureScanned() || !m_features.has_animation)
        return 0;

    // Frame number in WebP starts from 1
    return m_iter.frame_num - 1;
}

QRect QWebpHandler::currentImageRect() const
{
    if (!ensureScanned())
        return QRect();

    return QRect(m_iter.x_offset, m_iter.y_offset, m_iter.width, m_iter.height);
}

int QWebpHandler::loopCount() const
{
    if (!ensureScanned() || !m_features.has_animation)
        return 0;

    // Loop count in WebP starts from 0
    return m_loop - 1;
}

int QWebpHandler::nextImageDelay() const
{
    if (!ensureScanned() || !m_features.has_animation)
        return 0;

    return m_iter.duration;
}
