summaryrefslogtreecommitdiffstats
path: root/src/gui/image/qpnghandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/image/qpnghandler.cpp')
-rw-r--r--src/gui/image/qpnghandler.cpp56
1 files changed, 45 insertions, 11 deletions
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 864a944fcb..16d6c25b8b 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -53,7 +53,6 @@
#include <qcolorspace.h>
#include <private/qcolorspace_p.h>
-#include <private/qicc_p.h>
#include <png.h>
#include <pngconf.h>
@@ -607,9 +606,13 @@ bool QPngHandlerPrivate::readPngHeader()
#endif
png_uint_32 profLen;
png_get_iCCP(png_ptr, info_ptr, &name, &compressionType, &profileData, &profLen);
- if (!QIcc::fromIccProfile(QByteArray::fromRawData((const char *)profileData, profLen), &colorSpace)) {
+ colorSpace = QColorSpace::fromIccProfile(QByteArray::fromRawData((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;
}
}
@@ -628,11 +631,25 @@ bool QPngHandlerPrivate::readPngHeader()
png_get_gAMA(png_ptr, info_ptr, &file_gamma);
fileGamma = file_gamma;
if (fileGamma > 0.0f && colorSpaceState <= GammaChrm) {
- QColorSpacePrivate *csPrivate = colorSpace.d_func();
- csPrivate->gamut = QColorSpace::Gamut::SRgb;
- csPrivate->transferFunction = QColorSpace::TransferFunction::Gamma;
- csPrivate->gamma = fileGamma;
- csPrivate->initialize();
+ 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;
}
}
@@ -663,10 +680,7 @@ bool QPngHandlerPrivate::readPngImage(QImage *outImage)
// This configuration forces gamma correction and
// thus changes the output colorspace
png_set_gamma(png_ptr, 1.0f / gamma, fileGamma);
- QColorSpacePrivate *csPrivate = colorSpace.d_func();
- csPrivate->transferFunction = QColorSpace::TransferFunction::Gamma;
- csPrivate->gamma = gamma;
- csPrivate->initialize();
+ colorSpace = colorSpace.withTransferFunction(QColorSpace::TransferFunction::Gamma, 1.0f / gamma);
colorSpaceState = GammaChrm;
}
@@ -962,6 +976,26 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i
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);
}