Preparation for ICC based color profiles

This commit is contained in:
Jakub Melka
2019-12-25 18:42:54 +01:00
parent d951a70014
commit 70daaac841
4 changed files with 33 additions and 5 deletions

View File

@ -110,6 +110,14 @@ QColor PDFCMSGeneric::getColorFromXYZ(const PDFColor3& whitePoint, const PDFColo
return QColor(); 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) : PDFCMSManager::PDFCMSManager(QObject* parent) :
BaseClass(parent) BaseClass(parent)
{ {

View File

@ -123,6 +123,12 @@ public:
/// \param intent Rendering intent /// \param intent Rendering intent
/// \param reporter Render error reporter (used, when color transform fails) /// \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; 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<PDFCMS>; using PDFCMSPointer = QSharedPointer<PDFCMS>;
@ -138,6 +144,7 @@ public:
virtual QColor getColorFromDeviceRGB(const PDFColor& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; 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 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 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 struct PDFColorProfileIdentifier

View File

@ -23,6 +23,8 @@
#include "pdfpattern.h" #include "pdfpattern.h"
#include "pdfcms.h" #include "pdfcms.h"
#include <QCryptographicHash>
namespace pdf 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])); 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_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 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]); 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); 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 // First, try to load alternate color space, if it is present
const PDFDictionary* dictionary = stream->getDictionary(); const PDFDictionary* dictionary = stream->getDictionary();
QByteArray iccProfileData = document->getDecodedStream(stream);
PDFDocumentDataLoaderDecorator loader(document); PDFDocumentDataLoaderDecorator loader(document);
PDFColorSpacePointer alternateColorSpace; PDFColorSpacePointer alternateColorSpace;
@ -958,7 +969,7 @@ PDFColorSpacePointer PDFICCBasedColorSpace::createICCBasedColorSpace(const PDFDi
auto itEnd = std::next(itStart, rangeSize); auto itEnd = std::next(itStart, rangeSize);
loader.readNumberArrayFromDictionary(dictionary, ICCBASED_RANGE, itStart, itEnd); 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) : PDFIndexedColorSpace::PDFIndexedColorSpace(PDFColorSpacePointer baseColorSpace, QByteArray&& colors, int maxValue) :

View File

@ -510,7 +510,7 @@ private:
using Ranges = std::array<PDFColorComponent, MAX_COLOR_COMPONENTS * 2>; using Ranges = std::array<PDFColorComponent, MAX_COLOR_COMPONENTS * 2>;
public: public:
explicit PDFICCBasedColorSpace(PDFColorSpacePointer alternateColorSpace, Ranges range); explicit PDFICCBasedColorSpace(PDFColorSpacePointer alternateColorSpace, Ranges range, QByteArray iccProfileData);
virtual ~PDFICCBasedColorSpace() = default; virtual ~PDFICCBasedColorSpace() = default;
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override; virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
@ -527,6 +527,8 @@ public:
private: private:
PDFColorSpacePointer m_alternateColorSpace; PDFColorSpacePointer m_alternateColorSpace;
Ranges m_range; Ranges m_range;
QByteArray m_iccProfileData;
QByteArray m_iccProfileDataChecksum;
}; };
class PDFIndexedColorSpace : public PDFAbstractColorSpace class PDFIndexedColorSpace : public PDFAbstractColorSpace