/****************************************************************************
**
** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $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 "private/qpnghandler_p.h"

#ifndef QT_NO_IMAGEFORMAT_PNG
#include <qcoreapplication.h>
#include <qdebug.h>
#include <qiodevice.h>
#include <qimage.h>
#include <qlist.h>
#include <qvariant.h>
#include <qvector.h>

#include <private/qimage_p.h> // for qt_getImageText

#include <qcolorspace.h>
#include <private/qcolorspace_p.h>

#include <png.h>
#include <pngconf.h>

#if PNG_LIBPNG_VER >= 10400 && PNG_LIBPNG_VER <= 10502 \
        && defined(PNG_PEDANTIC_WARNINGS_SUPPORTED)
/*
    Versions 1.4.0 to 1.5.2 of libpng declare png_longjmp_ptr to
    have a noreturn attribute if PNG_PEDANTIC_WARNINGS_SUPPORTED
    is enabled, but most declarations of longjmp in the wild do
    not add this attribute. This causes problems when the png_jmpbuf
    macro expands to calling png_set_longjmp_fn with a mismatched
    longjmp, as compilers such as Clang will treat this as an error.

    To work around this we override the png_jmpbuf macro to cast
    longjmp to a png_longjmp_ptr.
*/
#   undef png_jmpbuf
#   ifdef PNG_SETJMP_SUPPORTED
#       define png_jmpbuf(png_ptr) \
            (*png_set_longjmp_fn((png_ptr), (png_longjmp_ptr)longjmp, sizeof(jmp_buf)))
#   else
#       define png_jmpbuf(png_ptr) \
            (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP)
#   endif
#endif

QT_BEGIN_NAMESPACE

// avoid going through QImage::scanLine() which calls detach
#define FAST_SCAN_LINE(data, bpl, y) (data + (y) * bpl)

/*
  All PNG files load to the minimal QImage equivalent.

  All QImage formats output to reasonably efficient PNG equivalents.
*/

class QPngHandlerPrivate
{
public:
    enum State {
        Ready,
        ReadHeader,
        ReadingEnd,
        Error
    };
    // Defines the order of how the various ways of setting colorspace overrides eachother:
    enum ColorSpaceState {
        Undefined = 0,
        GammaChrm = 1, // gAMA+cHRM chunks
        Srgb = 2,      // sRGB chunk
        Icc = 3        // iCCP chunk
    };

    QPngHandlerPrivate(QPngHandler *qq)
        : gamma(0.0), fileGamma(0.0), quality(50), compression(50), colorSpaceState(Undefined), png_ptr(nullptr), info_ptr(nullptr), end_info(nullptr), state(Ready), q(qq)
    { }

    float gamma;
    float fileGamma;
    int quality; // quality is used for backward compatibility, maps to compression
    int compression;
    QString description;
    QSize scaledSize;
    QStringList readTexts;
    QColorSpace colorSpace;
    ColorSpaceState colorSpaceState;

    png_struct *png_ptr;
    png_info *info_ptr;
    png_info *end_info;

    bool readPngHeader();
    bool readPngImage(QImage *image);
    void readPngTexts(png_info *info);

    QImage::Format readImageFormat();

    struct AllocatedMemoryPointers {
        AllocatedMemoryPointers()
            : row_pointers(nullptr), accRow(nullptr), inRow(nullptr), outRow(nullptr)
        { }
        void deallocate()
        {
            delete [] row_pointers;
            row_pointers = nullptr;
            delete [] accRow;
            accRow = nullptr;
            delete [] inRow;
            inRow = nullptr;
            delete [] outRow;
            outRow = nullptr;
        }

        png_byte **row_pointers;
        quint32 *accRow;
        png_byte *inRow;
        uchar *outRow;
    };

    AllocatedMemoryPointers amp;

    State state;

    QPngHandler *q;
};


class QPNGImageWriter {
public:
    explicit QPNGImageWriter(QIODevice*);
    ~QPNGImageWriter();

    enum DisposalMethod { Unspecified, NoDisposal, RestoreBackground, RestoreImage };
    void setDisposalMethod(DisposalMethod);
    void setLooping(int loops=0); // 0 == infinity
    void setFrameDelay(int msecs);
    void setGamma(float);

    bool writeImage(const QImage& img, int x, int y);
    bool writeImage(const QImage& img, int compression_in, const QString &description, int x, int y);
    bool writeImage(const QImage& img)
        { return writeImage(img, 0, 0); }
    bool writeImage(const QImage& img, int compression, const QString &description)
        { return writeImage(img, compression, description, 0, 0); }

    QIODevice* device() { return dev; }

private:
    QIODevice* dev;
    int frames_written;
    DisposalMethod disposal;
    int looping;
    int ms_delay;
    float gamma;
};

extern "C" {
static
void iod_read_fn(png_structp png_ptr, png_bytep data, png_size_t length)
{
    QPngHandlerPrivate *d = (QPngHandlerPrivate *)png_get_io_ptr(png_ptr);
    QIODevice *in = d->q->device();

    if (d->state == QPngHandlerPrivate::ReadingEnd && !in->isSequential() && (in->size() - in->pos()) < 4 && length == 4) {
        // Workaround for certain malformed PNGs that lack the final crc bytes
        uchar endcrc[4] = { 0xae, 0x42, 0x60, 0x82 };
        memcpy(data, endcrc, 4);
        in->seek(in->size());
        return;
    }

    while (length) {
        int nr = in->read((char*)data, length);
        if (nr <= 0) {
            png_error(png_ptr, "Read Error");
            return;
        }
        length -= nr;
    }
}


static
void qpiw_write_fn(png_structp png_ptr, png_bytep data, png_size_t length)
{
    QPNGImageWriter* qpiw = (QPNGImageWriter*)png_get_io_ptr(png_ptr);
    QIODevice* out = qpiw->device();

    uint nr = out->write((char*)data, length);
    if (nr != length) {
        png_error(png_ptr, "Write Error");
        return;
    }
}


static
void qpiw_flush_fn(png_structp /* png_ptr */)
{
}

}

static
void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead)
{
    png_uint_32 width = 0;
    png_uint_32 height = 0;
    int bit_depth = 0;
    int color_type = 0;
    png_bytep trans_alpha = nullptr;
    png_color_16p trans_color_p = nullptr;
    int num_trans;
    png_colorp palette = nullptr;
    int num_palette;
    int interlace_method = PNG_INTERLACE_LAST;
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_method, nullptr, nullptr);
    png_set_interlace_handling(png_ptr);

    if (color_type == PNG_COLOR_TYPE_GRAY) {
        // Black & White or grayscale
        if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) {
            png_set_invert_mono(png_ptr);
            png_read_update_info(png_ptr, info_ptr);
            if (image.size() != QSize(width, height) || image.format() != QImage::Format_Mono) {
                image = QImage(width, height, QImage::Format_Mono);
                if (image.isNull())
                    return;
            }
            image.setColorCount(2);
            image.setColor(1, qRgb(0,0,0));
            image.setColor(0, qRgb(255,255,255));
            if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_color_p) {
                const int g = trans_color_p->gray;
                // the image has white in the first position of the color table,
                // black in the second. g is 0 for black, 1 for white.
                if (g == 0)
                    image.setColor(1, qRgba(0, 0, 0, 0));
                else if (g == 1)
                    image.setColor(0, qRgba(255, 255, 255, 0));
            }
        } else if (bit_depth == 16
                   && png_get_channels(png_ptr, info_ptr) == 1
                   && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
            if (image.size() != QSize(width, height) || image.format() != QImage::Format_Grayscale16) {
                image = QImage(width, height, QImage::Format_Grayscale16);
                if (image.isNull())
                    return;
            }

            png_read_update_info(png_ptr, info_ptr);
            if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
                png_set_swap(png_ptr);
        } else if (bit_depth == 16) {
            bool hasMask = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS);
            if (!hasMask)
                png_set_filler(png_ptr, 0xffff, PNG_FILLER_AFTER);
            else
                png_set_expand(png_ptr);
            png_set_gray_to_rgb(png_ptr);
            QImage::Format format = hasMask ? QImage::Format_RGBA64 : QImage::Format_RGBX64;
            if (image.size() != QSize(width, height) || image.format() != format) {
                image = QImage(width, height, format);
                if (image.isNull())
                    return;
            }
            png_read_update_info(png_ptr, info_ptr);
            if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
                png_set_swap(png_ptr);
        } else if (bit_depth == 8 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
            png_set_expand(png_ptr);
            if (image.size() != QSize(width, height) || image.format() != QImage::Format_Grayscale8) {
                image = QImage(width, height, QImage::Format_Grayscale8);
                if (image.isNull())
                    return;
            }

            png_read_update_info(png_ptr, info_ptr);
        } else {
            if (bit_depth < 8)
                png_set_packing(png_ptr);
            int ncols = bit_depth < 8 ? 1 << bit_depth : 256;
            png_read_update_info(png_ptr, info_ptr);
            if (image.size() != QSize(width, height) || image.format() != QImage::Format_Indexed8) {
                image = QImage(width, height, QImage::Format_Indexed8);
                if (image.isNull())
                    return;
            }
            image.setColorCount(ncols);
            for (int i=0; i<ncols; i++) {
                int c = i*255/(ncols-1);
                image.setColor(i, qRgba(c,c,c,0xff));
            }
            if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_color_p) {
                const int g = trans_color_p->gray;
                if (g < ncols) {
                    image.setColor(g, 0);
                }
            }
        }
    } else if (color_type == PNG_COLOR_TYPE_PALETTE
               && png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)
               && num_palette <= 256)
    {
        // 1-bit and 8-bit color
        if (bit_depth != 1)
            png_set_packing(png_ptr);
        png_read_update_info(png_ptr, info_ptr);
        png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, nullptr, nullptr, nullptr);
        QImage::Format format = bit_depth == 1 ? QImage::Format_Mono : QImage::Format_Indexed8;
        if (image.size() != QSize(width, height) || image.format() != format) {
            image = QImage(width, height, format);
            if (image.isNull())
                return;
        }
        png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
        image.setColorCount((format == QImage::Format_Mono) ? 2 : num_palette);
        int i = 0;
        if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_alpha) {
            while (i < num_trans) {
                image.setColor(i, qRgba(
                    palette[i].red,
                    palette[i].green,
                    palette[i].blue,
                    trans_alpha[i]
                   )
               );
                i++;
            }
        }
        while (i < num_palette) {
            image.setColor(i, qRgba(
                palette[i].red,
                palette[i].green,
                palette[i].blue,
                0xff
               )
           );
            i++;
        }
        // Qt==ARGB==Big(ARGB)==Little(BGRA)
        if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
            png_set_bgr(png_ptr);
        }
    } else if (bit_depth == 16 && !(color_type & PNG_COLOR_MASK_PALETTE)) {
        QImage::Format format = QImage::Format_RGBA64;
        if (!(color_type & PNG_COLOR_MASK_ALPHA) && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
            png_set_filler(png_ptr, 0xffff, PNG_FILLER_AFTER);
            format = QImage::Format_RGBX64;
        }
        if (!(color_type & PNG_COLOR_MASK_COLOR))
            png_set_gray_to_rgb(png_ptr);
        if (image.size() != QSize(width, height) || image.format() != format) {
            image = QImage(width, height, format);
            if (image.isNull())
                return;
        }
        png_read_update_info(png_ptr, info_ptr);
        if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
            png_set_swap(png_ptr);
    } else {
        // 32-bit
        if (bit_depth == 16)
            png_set_strip_16(png_ptr);

        png_set_expand(png_ptr);

        if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
            png_set_gray_to_rgb(png_ptr);

        QImage::Format format = QImage::Format_ARGB32;
        // Only add filler if no alpha, or we can get 5 channel data.
        if (!(color_type & PNG_COLOR_MASK_ALPHA)
            && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
            png_set_filler(png_ptr, 0xff, QSysInfo::ByteOrder == QSysInfo::BigEndian ?
                           PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
            // We want 4 bytes, but it isn't an alpha channel
            format = QImage::Format_RGB32;
        }
        QSize outSize(width,height);
        if (!scaledSize.isEmpty() && quint32(scaledSize.width()) <= width &&
            quint32(scaledSize.height()) <= height && scaledSize != outSize && interlace_method == PNG_INTERLACE_NONE) {
            // Do inline downscaling
            outSize = scaledSize;
            if (doScaledRead)
                *doScaledRead = true;
        }
        if (image.size() != outSize || image.format() != format) {
            image = QImage(outSize, format);
            if (image.isNull())
                return;
        }

        if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
            png_set_swap_alpha(png_ptr);

        // Qt==ARGB==Big(ARGB)==Little(BGRA)
        if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
            png_set_bgr(png_ptr);
        }

        png_read_update_info(png_ptr, info_ptr);
    }
}

static void read_image_scaled(QImage *outImage, png_structp png_ptr, png_infop info_ptr,
                              QPngHandlerPrivate::AllocatedMemoryPointers &amp, QSize scaledSize)
{

    png_uint_32 width = 0;
    png_uint_32 height = 0;
    png_int_32 offset_x = 0;
    png_int_32 offset_y = 0;

    int bit_depth = 0;
    int color_type = 0;
    int unit_type = PNG_OFFSET_PIXEL;
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, nullptr, nullptr, nullptr);
    png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, &unit_type);
    uchar *data = outImage->bits();
    int bpl = outImage->bytesPerLine();

    if (scaledSize.isEmpty() || !width || !height)
        return;

    const quint32 iysz = height;
    const quint32 ixsz = width;
    const quint32 oysz = scaledSize.height();
    const quint32 oxsz = scaledSize.width();
    const quint32 ibw = 4*width;
    amp.accRow = new quint32[ibw];
    memset(amp.accRow, 0, ibw*sizeof(quint32));
    amp.inRow = new png_byte[ibw];
    memset(amp.inRow, 0, ibw*sizeof(png_byte));
    amp.outRow = new uchar[ibw];
    memset(amp.outRow, 0, ibw*sizeof(uchar));
    qint32 rval = 0;
    for (quint32 oy=0; oy<oysz; oy++) {
        // Store the rest of the previous input row, if any
        for (quint32 i=0; i < ibw; i++)
            amp.accRow[i] = rval*amp.inRow[i];
        // Accumulate the next input rows
        for (rval = iysz-rval; rval > 0; rval-=oysz) {
            png_read_row(png_ptr, amp.inRow, nullptr);
            quint32 fact = qMin(oysz, quint32(rval));
            for (quint32 i=0; i < ibw; i++)
                amp.accRow[i] += fact*amp.inRow[i];
        }
        rval *= -1;

        // We have a full output row, store it
        for (quint32 i=0; i < ibw; i++)
            amp.outRow[i] = uchar(amp.accRow[i]/iysz);

        quint32 a[4] = {0, 0, 0, 0};
        qint32 cval = oxsz;
        quint32 ix = 0;
        for (quint32 ox=0; ox<oxsz; ox++) {
            for (quint32 i=0; i < 4; i++)
                a[i] = cval * amp.outRow[ix+i];
            for (cval = ixsz - cval; cval > 0; cval-=oxsz) {
                ix += 4;
                if (ix >= ibw)
                    break;            // Safety belt, should not happen
                quint32 fact = qMin(oxsz, quint32(cval));
                for (quint32 i=0; i < 4; i++)
                    a[i] += fact * amp.outRow[ix+i];
            }
            cval *= -1;
            for (quint32 i=0; i < 4; i++)
                data[(4*ox)+i] = uchar(a[i]/ixsz);
        }
        data += bpl;
    }
    amp.deallocate();

    outImage->setDotsPerMeterX((png_get_x_pixels_per_meter(png_ptr,info_ptr)*oxsz)/ixsz);
    outImage->setDotsPerMeterY((png_get_y_pixels_per_meter(png_ptr,info_ptr)*oysz)/iysz);

    if (unit_type == PNG_OFFSET_PIXEL)
        outImage->setOffset(QPoint(offset_x*oxsz/ixsz, offset_y*oysz/iysz));

}

extern "C" {
static void qt_png_warning(png_structp /*png_ptr*/, png_const_charp message)
{
    qWarning("libpng warning: %s", message);
}

}


void QPngHandlerPrivate::readPngTexts(png_info *info)
{
#ifndef QT_NO_IMAGEIO_TEXT_LOADING
    png_textp text_ptr;
    int num_text=0;
    png_get_text(png_ptr, info, &text_ptr, &num_text);

    while (num_text--) {
        QString key, value;
        key = QString::fromLatin1(text_ptr->key);
#if defined(PNG_iTXt_SUPPORTED)
        if (text_ptr->itxt_length) {
            value = QString::fromUtf8(text_ptr->text, int(text_ptr->itxt_length));
        } else
#endif
        {
            value = QString::fromLatin1(text_ptr->text, int(text_ptr->text_length));
        }
        if (!description.isEmpty())
            description += QLatin1String("\n\n");
        description += key + QLatin1String(": ") + value.simplified();
        readTexts.append(key);
        readTexts.append(value);
        text_ptr++;
    }
#else
    Q_UNUSED(info)
#endif
}


bool QPngHandlerPrivate::readPngHeader()
{
    state = Error;
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,nullptr,nullptr,nullptr);
    if (!png_ptr)
        return false;

    png_set_error_fn(png_ptr, nullptr, nullptr, qt_png_warning);

#if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW)
    // Trade off a little bit of memory for better compatibility with existing images
    // Ref. "invalid distance too far back" explanation in libpng-manual.txt
    png_set_option(png_ptr, PNG_MAXIMUM_INFLATE_WINDOW, PNG_OPTION_ON);
#endif

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, nullptr, nullptr);
        png_ptr = nullptr;
        return false;
    }

    end_info = png_create_info_struct(png_ptr);
    if (!end_info) {
        png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
        png_ptr = nullptr;
        return false;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        png_ptr = nullptr;
        return false;
    }

    png_set_read_fn(png_ptr, this, iod_read_fn);
    png_read_info(png_ptr, info_ptr);

    readPngTexts(info_ptr);

#ifdef PNG_iCCP_SUPPORTED
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP)) {
        png_charp name = nullptr;
        int compressionType = 0;
#if (PNG_LIBPNG_VER < 10500)
        png_charp profileData = nullptr;
#else
        png_bytep profileData = nullptr;
#endif
        png_uint_32 profLen;
        png_get_iCCP(png_ptr, info_ptr, &name, &compressionType, &profileData, &profLen);
        colorSpace = QColorSpace::fromIccProfile(QByteArray((const char *)profileData, profLen));
        if (!colorSpace.isValid()) {
            qWarning() << "QPngHandler: Failed to parse ICC profile";
        } else {
            QColorSpacePrivate *csD = QColorSpacePrivate::getWritable(colorSpace);
            if (csD->description.isEmpty())
                csD->description = QString::fromLatin1((const char *)name);
            colorSpaceState = Icc;
        }
    }
#endif
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) {
        int rendering_intent = -1;
        png_get_sRGB(png_ptr, info_ptr, &rendering_intent);
        // We don't actually care about the rendering_intent, just that it is valid
        if (rendering_intent >= 0 && rendering_intent <= 3 && colorSpaceState <= Srgb) {
            colorSpace = QColorSpace::SRgb;
            colorSpaceState = Srgb;
        }
    }
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
        double file_gamma = 0.0;
        png_get_gAMA(png_ptr, info_ptr, &file_gamma);
        fileGamma = file_gamma;
        if (fileGamma > 0.0f && colorSpaceState <= GammaChrm) {
            QColorSpacePrimaries primaries;
            if (png_get_valid(png_ptr, info_ptr, PNG_INFO_cHRM)) {
                double white_x, white_y, red_x, red_y;
                double green_x, green_y, blue_x, blue_y;
                png_get_cHRM(png_ptr, info_ptr,
                             &white_x, &white_y, &red_x, &red_y,
                             &green_x, &green_y, &blue_x, &blue_y);
                primaries.whitePoint = QPointF(white_x, white_y);
                primaries.redPoint = QPointF(red_x, red_y);
                primaries.greenPoint = QPointF(green_x, green_y);
                primaries.bluePoint = QPointF(blue_x, blue_y);
            }
            if (primaries.areValid()) {
                colorSpace = QColorSpace(primaries.whitePoint, primaries.redPoint, primaries.greenPoint, primaries.bluePoint,
                                         QColorSpace::TransferFunction::Gamma, fileGamma);
            } else {
                colorSpace = QColorSpace(QColorSpace::Primaries::SRgb,
                                         QColorSpace::TransferFunction::Gamma, fileGamma);
            }
            colorSpaceState = GammaChrm;
        }
    }

    state = ReadHeader;
    return true;
}

bool QPngHandlerPrivate::readPngImage(QImage *outImage)
{
    if (state == Error)
        return false;

    if (state == Ready && !readPngHeader()) {
        state = Error;
        return false;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        png_ptr = nullptr;
        amp.deallocate();
        state = Error;
        return false;
    }

    if (gamma != 0.0 && fileGamma != 0.0) {
        // This configuration forces gamma correction and
        // thus changes the output colorspace
        png_set_gamma(png_ptr, 1.0f / gamma, fileGamma);
        colorSpace = colorSpace.withTransferFunction(QColorSpace::TransferFunction::Gamma, 1.0f / gamma);
        colorSpaceState = GammaChrm;
    }

    bool doScaledRead = false;
    setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead);

    if (outImage->isNull()) {
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        png_ptr = nullptr;
        amp.deallocate();
        state = Error;
        return false;
    }

    if (doScaledRead) {
        read_image_scaled(outImage, png_ptr, info_ptr, amp, scaledSize);
    } else {
        png_uint_32 width = 0;
        png_uint_32 height = 0;
        png_int_32 offset_x = 0;
        png_int_32 offset_y = 0;

        int bit_depth = 0;
        int color_type = 0;
        int unit_type = PNG_OFFSET_PIXEL;
        png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, nullptr, nullptr, nullptr);
        png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, &unit_type);
        uchar *data = outImage->bits();
        int bpl = outImage->bytesPerLine();
        amp.row_pointers = new png_bytep[height];

        for (uint y = 0; y < height; y++)
            amp.row_pointers[y] = data + y * bpl;

        png_read_image(png_ptr, amp.row_pointers);
        amp.deallocate();

        outImage->setDotsPerMeterX(png_get_x_pixels_per_meter(png_ptr,info_ptr));
        outImage->setDotsPerMeterY(png_get_y_pixels_per_meter(png_ptr,info_ptr));

        if (unit_type == PNG_OFFSET_PIXEL)
            outImage->setOffset(QPoint(offset_x, offset_y));

        // sanity check palette entries
        if (color_type == PNG_COLOR_TYPE_PALETTE && outImage->format() == QImage::Format_Indexed8) {
            int color_table_size = outImage->colorCount();
            for (int y=0; y<(int)height; ++y) {
                uchar *p = FAST_SCAN_LINE(data, bpl, y);
                uchar *end = p + width;
                while (p < end) {
                    if (*p >= color_table_size)
                        *p = 0;
                    ++p;
                }
            }
        }
    }

    state = ReadingEnd;
    png_read_end(png_ptr, end_info);

    readPngTexts(end_info);
    for (int i = 0; i < readTexts.size()-1; i+=2)
        outImage->setText(readTexts.at(i), readTexts.at(i+1));

    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    png_ptr = nullptr;
    amp.deallocate();
    state = Ready;

    if (scaledSize.isValid() && outImage->size() != scaledSize)
        *outImage = outImage->scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

    if (colorSpaceState > Undefined && colorSpace.isValid())
        outImage->setColorSpace(colorSpace);

    return true;
}

QImage::Format QPngHandlerPrivate::readImageFormat()
{
        QImage::Format format = QImage::Format_Invalid;
        png_uint_32 width = 0, height = 0;
        int bit_depth = 0, color_type = 0;
        png_colorp palette;
        int num_palette;
        png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, nullptr, nullptr, nullptr);
        if (color_type == PNG_COLOR_TYPE_GRAY) {
            // Black & White or grayscale
            if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) {
                format = QImage::Format_Mono;
            } else if (bit_depth == 16) {
                format = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ? QImage::Format_RGBA64 : QImage::Format_Grayscale16;
            } else if (bit_depth == 8 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
                format = QImage::Format_Grayscale8;
            } else {
                format = QImage::Format_Indexed8;
            }
        } else if (color_type == PNG_COLOR_TYPE_PALETTE
                   && png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)
                   && num_palette <= 256)
        {
            // 1-bit and 8-bit color
            format = bit_depth == 1 ? QImage::Format_Mono : QImage::Format_Indexed8;
        } else if (bit_depth == 16 && !(color_type & PNG_COLOR_MASK_PALETTE)) {
            format = QImage::Format_RGBA64;
            if (!(color_type & PNG_COLOR_MASK_ALPHA) && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
                format = QImage::Format_RGBX64;
        } else {
            // 32-bit
            format = QImage::Format_ARGB32;
            // Only add filler if no alpha, or we can get 5 channel data.
            if (!(color_type & PNG_COLOR_MASK_ALPHA)
                && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
                // We want 4 bytes, but it isn't an alpha channel
                format = QImage::Format_RGB32;
            }
        }

        return format;
}

QPNGImageWriter::QPNGImageWriter(QIODevice* iod) :
    dev(iod),
    frames_written(0),
    disposal(Unspecified),
    looping(-1),
    ms_delay(-1),
    gamma(0.0)
{
}

QPNGImageWriter::~QPNGImageWriter()
{
}

void QPNGImageWriter::setDisposalMethod(DisposalMethod dm)
{
    disposal = dm;
}

void QPNGImageWriter::setLooping(int loops)
{
    looping = loops;
}

void QPNGImageWriter::setFrameDelay(int msecs)
{
    ms_delay = msecs;
}

void QPNGImageWriter::setGamma(float g)
{
    gamma = g;
}

static void set_text(const QImage &image, png_structp png_ptr, png_infop info_ptr,
                     const QString &description)
{
    const QMap<QString, QString> text = qt_getImageText(image, description);

    if (text.isEmpty())
        return;

    png_textp text_ptr = new png_text[text.size()];
    memset(text_ptr, 0, text.size() * sizeof(png_text));

    QMap<QString, QString>::ConstIterator it = text.constBegin();
    int i = 0;
    while (it != text.constEnd()) {
        text_ptr[i].key = qstrdup(it.key().leftRef(79).toLatin1().constData());
        bool noCompress = (it.value().length() < 40);

#ifdef PNG_iTXt_SUPPORTED
        bool needsItxt = false;
        for (const QChar c : it.value()) {
            uchar ch = c.cell();
            if (c.row() || (ch < 0x20 && ch != '\n') || (ch > 0x7e && ch < 0xa0)) {
                needsItxt = true;
                break;
            }
        }

        if (needsItxt) {
            text_ptr[i].compression = noCompress ? PNG_ITXT_COMPRESSION_NONE : PNG_ITXT_COMPRESSION_zTXt;
            QByteArray value = it.value().toUtf8();
            text_ptr[i].text = qstrdup(value.constData());
            text_ptr[i].itxt_length = value.size();
            text_ptr[i].lang = const_cast<char*>("UTF-8");
            text_ptr[i].lang_key = qstrdup(it.key().toUtf8().constData());
        }
        else
#endif
        {
            text_ptr[i].compression = noCompress ? PNG_TEXT_COMPRESSION_NONE : PNG_TEXT_COMPRESSION_zTXt;
            QByteArray value = it.value().toLatin1();
            text_ptr[i].text = qstrdup(value.constData());
            text_ptr[i].text_length = value.size();
        }
        ++i;
        ++it;
    }

    png_set_text(png_ptr, info_ptr, text_ptr, i);
    for (i = 0; i < text.size(); ++i) {
        delete [] text_ptr[i].key;
        delete [] text_ptr[i].text;
#ifdef PNG_iTXt_SUPPORTED
        delete [] text_ptr[i].lang_key;
#endif
    }
    delete [] text_ptr;
}

bool QPNGImageWriter::writeImage(const QImage& image, int off_x, int off_y)
{
    return writeImage(image, -1, QString(), off_x, off_y);
}

bool QPNGImageWriter::writeImage(const QImage& image, int compression_in, const QString &description,
                                 int off_x_in, int off_y_in)
{
    QPoint offset = image.offset();
    int off_x = off_x_in + offset.x();
    int off_y = off_y_in + offset.y();

    png_structp png_ptr;
    png_infop info_ptr;

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,nullptr,nullptr,nullptr);
    if (!png_ptr) {
        return false;
    }

    png_set_error_fn(png_ptr, nullptr, nullptr, qt_png_warning);
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
    png_set_benign_errors(png_ptr, 1);
#endif

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_write_struct(&png_ptr, nullptr);
        return false;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        return false;
    }

    int compression = compression_in;
    if (compression >= 0) {
        if (compression > 9) {
            qWarning("PNG: Compression %d out of range", compression);
            compression = 9;
        }
        png_set_compression_level(png_ptr, compression);
    }

    png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn);


    int color_type = 0;
    if (image.format() <= QImage::Format_Indexed8) {
        if (image.isGrayscale())
            color_type = PNG_COLOR_TYPE_GRAY;
        else
            color_type = PNG_COLOR_TYPE_PALETTE;
    }
    else if (image.format() == QImage::Format_Grayscale8
             || image.format() == QImage::Format_Grayscale16)
        color_type = PNG_COLOR_TYPE_GRAY;
    else if (image.hasAlphaChannel())
        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
    else
        color_type = PNG_COLOR_TYPE_RGB;

    int bpc = 0;
    switch (image.format()) {
    case QImage::Format_Mono:
    case QImage::Format_MonoLSB:
        bpc = 1;
        break;
    case QImage::Format_RGBX64:
    case QImage::Format_RGBA64:
    case QImage::Format_RGBA64_Premultiplied:
    case QImage::Format_Grayscale16:
        bpc = 16;
        break;
    default:
        bpc = 8;
        break;
    }

    png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(),
                 bpc, // per channel
                 color_type, 0, 0, 0);       // sets #channels

#ifdef PNG_iCCP_SUPPORTED
    if (image.colorSpace().isValid()) {
        QColorSpace cs = image.colorSpace();
        // Support the old gamma making it override transferfunction.
        if (gamma != 0.0 && !qFuzzyCompare(cs.gamma(), 1.0f / gamma))
            cs = cs.withTransferFunction(QColorSpace::TransferFunction::Gamma, 1.0f / gamma);
        QByteArray iccProfileName = QColorSpacePrivate::get(cs)->description.toLatin1();
        if (iccProfileName.isEmpty())
            iccProfileName = QByteArrayLiteral("Custom");
        QByteArray iccProfile = cs.iccProfile();
        png_set_iCCP(png_ptr, info_ptr,
             #if PNG_LIBPNG_VER < 10500
                     iccProfileName.data(), PNG_COMPRESSION_TYPE_BASE, iccProfile.data(),
             #else
                     iccProfileName.constData(), PNG_COMPRESSION_TYPE_BASE,
                     (png_const_bytep)iccProfile.constData(),
             #endif
                     iccProfile.length());
    } else
#endif
    if (gamma != 0.0) {
        png_set_gAMA(png_ptr, info_ptr, 1.0/gamma);
    }

    if (image.format() == QImage::Format_MonoLSB)
       png_set_packswap(png_ptr);

    if (color_type == PNG_COLOR_TYPE_PALETTE) {
        // Paletted
        int num_palette = qMin(256, image.colorCount());
        png_color palette[256];
        png_byte trans[256];
        int num_trans = 0;
        for (int i=0; i<num_palette; i++) {
            QRgb rgba=image.color(i);
            palette[i].red = qRed(rgba);
            palette[i].green = qGreen(rgba);
            palette[i].blue = qBlue(rgba);
            trans[i] = qAlpha(rgba);
            if (trans[i] < 255) {
                num_trans = i+1;
            }
        }
        png_set_PLTE(png_ptr, info_ptr, palette, num_palette);

        if (num_trans) {
            png_set_tRNS(png_ptr, info_ptr, trans, num_trans, nullptr);
        }
    }

    // Swap ARGB to RGBA (normal PNG format) before saving on
    // BigEndian machines
    if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
        switch (image.format()) {
        case QImage::Format_RGBX8888:
        case QImage::Format_RGBA8888:
        case QImage::Format_RGBX64:
        case QImage::Format_RGBA64:
        case QImage::Format_RGBA64_Premultiplied:
            break;
        default:
            png_set_swap_alpha(png_ptr);
        }
    }

    // Qt==ARGB==Big(ARGB)==Little(BGRA). But RGB888 is RGB regardless
    if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
        switch (image.format()) {
        case QImage::Format_RGB888:
        case QImage::Format_RGBX8888:
        case QImage::Format_RGBA8888:
        case QImage::Format_RGBX64:
        case QImage::Format_RGBA64:
        case QImage::Format_RGBA64_Premultiplied:
            break;
        default:
            png_set_bgr(png_ptr);
        }
    }

    if (off_x || off_y) {
        png_set_oFFs(png_ptr, info_ptr, off_x, off_y, PNG_OFFSET_PIXEL);
    }

    if (frames_written > 0)
        png_set_sig_bytes(png_ptr, 8);

    if (image.dotsPerMeterX() > 0 || image.dotsPerMeterY() > 0) {
        png_set_pHYs(png_ptr, info_ptr,
                image.dotsPerMeterX(), image.dotsPerMeterY(),
                PNG_RESOLUTION_METER);
    }

    set_text(image, png_ptr, info_ptr, description);

    png_write_info(png_ptr, info_ptr);

    if (image.depth() != 1)
        png_set_packing(png_ptr);

    if (color_type == PNG_COLOR_TYPE_RGB) {
        switch (image.format()) {
        case QImage::Format_RGB888:
        case QImage::Format_BGR888:
            break;
        case QImage::Format_RGBX8888:
        case QImage::Format_RGBX64:
            png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
            break;
        default:
            png_set_filler(png_ptr, 0,
                QSysInfo::ByteOrder == QSysInfo::BigEndian ?
                    PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
        }
    }

    if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
        switch (image.format()) {
        case QImage::Format_RGBX64:
        case QImage::Format_RGBA64:
        case QImage::Format_RGBA64_Premultiplied:
        case QImage::Format_Grayscale16:
            png_set_swap(png_ptr);
            break;
        default:
            break;
        }
    }

    if (looping >= 0 && frames_written == 0) {
        uchar data[13] = "NETSCAPE2.0";
        //                0123456789aBC
        data[0xB] = looping%0x100;
        data[0xC] = looping/0x100;
        png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFx"), data, 13);
    }
    if (ms_delay >= 0 || disposal!=Unspecified) {
        uchar data[4];
        data[0] = disposal;
        data[1] = 0;
        data[2] = (ms_delay/10)/0x100; // hundredths
        data[3] = (ms_delay/10)%0x100;
        png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFg"), data, 4);
    }

    int height = image.height();
    int width = image.width();
    switch (image.format()) {
    case QImage::Format_Mono:
    case QImage::Format_MonoLSB:
    case QImage::Format_Indexed8:
    case QImage::Format_Grayscale8:
    case QImage::Format_Grayscale16:
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32:
    case QImage::Format_RGB888:
    case QImage::Format_BGR888:
    case QImage::Format_RGBX8888:
    case QImage::Format_RGBA8888:
    case QImage::Format_RGBX64:
    case QImage::Format_RGBA64:
        {
            png_bytep* row_pointers = new png_bytep[height];
            for (int y=0; y<height; y++)
                row_pointers[y] = const_cast<png_bytep>(image.constScanLine(y));
            png_write_image(png_ptr, row_pointers);
            delete [] row_pointers;
        }
        break;
    case QImage::Format_RGBA64_Premultiplied:
        {
            QImage row;
            png_bytep row_pointers[1];
            for (int y=0; y<height; y++) {
                row = image.copy(0, y, width, 1).convertToFormat(QImage::Format_RGBA64);
                row_pointers[0] = const_cast<png_bytep>(row.constScanLine(0));
                png_write_rows(png_ptr, row_pointers, 1);
            }
        }
        break;
    default:
        {
            QImage::Format fmt = image.hasAlphaChannel() ? QImage::Format_ARGB32 : QImage::Format_RGB32;
            QImage row;
            png_bytep row_pointers[1];
            for (int y=0; y<height; y++) {
                row = image.copy(0, y, width, 1).convertToFormat(fmt);
                row_pointers[0] = const_cast<png_bytep>(row.constScanLine(0));
                png_write_rows(png_ptr, row_pointers, 1);
            }
        }
        break;
    }

    png_write_end(png_ptr, info_ptr);
    frames_written++;

    png_destroy_write_struct(&png_ptr, &info_ptr);

    return true;
}

static bool write_png_image(const QImage &image, QIODevice *device,
                            int compression, int quality, float gamma, const QString &description)
{
    // quality is used for backward compatibility, maps to compression

    QPNGImageWriter writer(device);
    if (compression >= 0)
        compression = qMin(compression, 100);
    else if (quality >= 0)
        compression = 100 - qMin(quality, 100);

    if (compression >= 0)
        compression = (compression * 9) / 91; // map [0,100] -> [0,9]

    writer.setGamma(gamma);
    return writer.writeImage(image, compression, description);
}

QPngHandler::QPngHandler()
    : d(new QPngHandlerPrivate(this))
{
}

QPngHandler::~QPngHandler()
{
    if (d->png_ptr)
        png_destroy_read_struct(&d->png_ptr, &d->info_ptr, &d->end_info);
    delete d;
}

bool QPngHandler::canRead() const
{
    if (d->state == QPngHandlerPrivate::Ready && !canRead(device()))
        return false;

    if (d->state != QPngHandlerPrivate::Error) {
        setFormat("png");
        return true;
    }

    return false;
}

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

    return device->peek(8) == "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
}

bool QPngHandler::read(QImage *image)
{
    if (!canRead())
        return false;
    return d->readPngImage(image);
}

bool QPngHandler::write(const QImage &image)
{
    return write_png_image(image, device(), d->compression, d->quality, d->gamma, d->description);
}

bool QPngHandler::supportsOption(ImageOption option) const
{
    return option == Gamma
        || option == Description
        || option == ImageFormat
        || option == Quality
        || option == CompressionRatio
        || option == Size
        || option == ScaledSize;
}

QVariant QPngHandler::option(ImageOption option) const
{
    if (d->state == QPngHandlerPrivate::Error)
        return QVariant();
    if (d->state == QPngHandlerPrivate::Ready && !d->readPngHeader())
        return QVariant();

    if (option == Gamma)
        return d->gamma == 0.0 ? d->fileGamma : d->gamma;
    else if (option == Quality)
        return d->quality;
    else if (option == CompressionRatio)
        return d->compression;
    else if (option == Description)
        return d->description;
    else if (option == Size)
        return QSize(png_get_image_width(d->png_ptr, d->info_ptr),
                     png_get_image_height(d->png_ptr, d->info_ptr));
    else if (option == ScaledSize)
        return d->scaledSize;
    else if (option == ImageFormat)
        return d->readImageFormat();
    return QVariant();
}

void QPngHandler::setOption(ImageOption option, const QVariant &value)
{
    if (option == Gamma)
        d->gamma = value.toFloat();
    else if (option == Quality)
        d->quality = value.toInt();
    else if (option == CompressionRatio)
        d->compression = value.toInt();
    else if (option == Description)
        d->description = value.toString();
    else if (option == ScaledSize)
        d->scaledSize = value.toSize();
}

QT_END_NAMESPACE

#endif // QT_NO_IMAGEFORMAT_PNG
