diff --git a/PdfForQtLib/sources/pdfcms.cpp b/PdfForQtLib/sources/pdfcms.cpp index 4a57145..8ee24ea 100644 --- a/PdfForQtLib/sources/pdfcms.cpp +++ b/PdfForQtLib/sources/pdfcms.cpp @@ -110,6 +110,14 @@ QColor PDFCMSGeneric::getColorFromXYZ(const PDFColor3& whitePoint, const PDFColo return QColor(); } +QColor PDFCMSGeneric::getColorFromICC(const PDFColor& color, const QByteArray& iccID, const QByteArray& iccData) const +{ + Q_UNUSED(color); + Q_UNUSED(iccID); + Q_UNUSED(iccData); + return QColor(); +} + PDFCMSManager::PDFCMSManager(QObject* parent) : BaseClass(parent) { diff --git a/PdfForQtLib/sources/pdfcms.h b/PdfForQtLib/sources/pdfcms.h index 39578ed..04db2f1 100644 --- a/PdfForQtLib/sources/pdfcms.h +++ b/PdfForQtLib/sources/pdfcms.h @@ -123,6 +123,12 @@ public: /// \param intent Rendering intent /// \param reporter Render error reporter (used, when color transform fails) virtual QColor getColorFromXYZ(const PDFColor3& whitePoint, const PDFColor3& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const = 0; + + /// Computes color from ICC color profile + /// \param color Input color + /// \param iccID Unique ICC profile identifier + /// \param iccData Color profile data + virtual QColor getColorFromICC(const PDFColor& color, const QByteArray& iccID, const QByteArray& iccData) const = 0; }; using PDFCMSPointer = QSharedPointer; @@ -138,6 +144,7 @@ public: virtual QColor getColorFromDeviceRGB(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; virtual QColor getColorFromDeviceCMYK(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; virtual QColor getColorFromXYZ(const PDFColor3& whitePoint, const PDFColor3& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; + virtual QColor getColorFromICC(const PDFColor& color, const QByteArray& iccID, const QByteArray& iccData) const override; }; struct PDFColorProfileIdentifier diff --git a/PdfForQtLib/sources/pdfcolorspaces.cpp b/PdfForQtLib/sources/pdfcolorspaces.cpp index c1df803..b75274e 100644 --- a/PdfForQtLib/sources/pdfcolorspaces.cpp +++ b/PdfForQtLib/sources/pdfcolorspaces.cpp @@ -23,6 +23,8 @@ #include "pdfpattern.h" #include "pdfcms.h" +#include + namespace pdf { @@ -850,11 +852,13 @@ PDFColorSpacePointer PDFLabColorSpace::createLabColorSpace(const PDFDocument* do return PDFColorSpacePointer(new PDFLabColorSpace(whitePoint, blackPoint, minMax[0], minMax[1], minMax[2], minMax[3])); } -PDFICCBasedColorSpace::PDFICCBasedColorSpace(PDFColorSpacePointer alternateColorSpace, Ranges range) : +PDFICCBasedColorSpace::PDFICCBasedColorSpace(PDFColorSpacePointer alternateColorSpace, Ranges range, QByteArray iccProfileData) : m_alternateColorSpace(qMove(alternateColorSpace)), - m_range(range) + m_range(range), + m_iccProfileData(qMove(iccProfileData)) { - + // Compute checksum + m_iccProfileDataChecksum = QCryptographicHash::hash(m_iccProfileData, QCryptographicHash::Md5); } QColor PDFICCBasedColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const @@ -883,6 +887,12 @@ QColor PDFICCBasedColorSpace::getColor(const PDFColor& color, const PDFCMS* cms, clippedColor[i] = qBound(m_range[imin], clippedColor[i], m_range[imax]); } + QColor cmsColor = cms->getColorFromICC(clippedColor, m_iccProfileDataChecksum, m_iccProfileData); + if (cmsColor.isValid()) + { + return cmsColor; + } + return m_alternateColorSpace->getColor(clippedColor, cms, intent, reporter); } @@ -898,6 +908,7 @@ PDFColorSpacePointer PDFICCBasedColorSpace::createICCBasedColorSpace(const PDFDi { // First, try to load alternate color space, if it is present const PDFDictionary* dictionary = stream->getDictionary(); + QByteArray iccProfileData = document->getDecodedStream(stream); PDFDocumentDataLoaderDecorator loader(document); PDFColorSpacePointer alternateColorSpace; @@ -958,7 +969,7 @@ PDFColorSpacePointer PDFICCBasedColorSpace::createICCBasedColorSpace(const PDFDi auto itEnd = std::next(itStart, rangeSize); loader.readNumberArrayFromDictionary(dictionary, ICCBASED_RANGE, itStart, itEnd); - return PDFColorSpacePointer(new PDFICCBasedColorSpace(qMove(alternateColorSpace), ranges)); + return PDFColorSpacePointer(new PDFICCBasedColorSpace(qMove(alternateColorSpace), ranges, qMove(iccProfileData))); } PDFIndexedColorSpace::PDFIndexedColorSpace(PDFColorSpacePointer baseColorSpace, QByteArray&& colors, int maxValue) : diff --git a/PdfForQtLib/sources/pdfcolorspaces.h b/PdfForQtLib/sources/pdfcolorspaces.h index d471b95..09b453d 100644 --- a/PdfForQtLib/sources/pdfcolorspaces.h +++ b/PdfForQtLib/sources/pdfcolorspaces.h @@ -510,7 +510,7 @@ private: using Ranges = std::array; public: - explicit PDFICCBasedColorSpace(PDFColorSpacePointer alternateColorSpace, Ranges range); + explicit PDFICCBasedColorSpace(PDFColorSpacePointer alternateColorSpace, Ranges range, QByteArray iccProfileData); virtual ~PDFICCBasedColorSpace() = default; virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; @@ -527,6 +527,8 @@ public: private: PDFColorSpacePointer m_alternateColorSpace; Ranges m_range; + QByteArray m_iccProfileData; + QByteArray m_iccProfileDataChecksum; }; class PDFIndexedColorSpace : public PDFAbstractColorSpace