mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-02-11 09:10:36 +01:00
Rework of color spaces, some bugfixing of color spaces
This commit is contained in:
parent
b29791b890
commit
a2dc4e16a8
@ -81,6 +81,7 @@ SOURCES += \
|
|||||||
sources/pdfsnapper.cpp \
|
sources/pdfsnapper.cpp \
|
||||||
sources/pdfstructuretree.cpp \
|
sources/pdfstructuretree.cpp \
|
||||||
sources/pdftextlayout.cpp \
|
sources/pdftextlayout.cpp \
|
||||||
|
sources/pdftransparencyrenderer.cpp \
|
||||||
sources/pdfutils.cpp \
|
sources/pdfutils.cpp \
|
||||||
sources/pdfwidgettool.cpp \
|
sources/pdfwidgettool.cpp \
|
||||||
sources/pdfwidgetutils.cpp \
|
sources/pdfwidgetutils.cpp \
|
||||||
@ -150,6 +151,7 @@ HEADERS += \
|
|||||||
sources/pdfsnapper.h \
|
sources/pdfsnapper.h \
|
||||||
sources/pdfstructuretree.h \
|
sources/pdfstructuretree.h \
|
||||||
sources/pdftextlayout.h \
|
sources/pdftextlayout.h \
|
||||||
|
sources/pdftransparencyrenderer.h \
|
||||||
sources/pdfwidgettool.h \
|
sources/pdfwidgettool.h \
|
||||||
sources/pdfwidgetutils.h \
|
sources/pdfwidgetutils.h \
|
||||||
sources/pdfxreftable.h \
|
sources/pdfxreftable.h \
|
||||||
|
@ -48,6 +48,7 @@ public:
|
|||||||
virtual bool fillRGBBufferFromDeviceCMYK(const std::vector<float>& colors, RenderingIntent intent, unsigned char* outputBuffer, PDFRenderErrorReporter* reporter) const override;
|
virtual bool fillRGBBufferFromDeviceCMYK(const std::vector<float>& colors, RenderingIntent intent, unsigned char* outputBuffer, PDFRenderErrorReporter* reporter) const override;
|
||||||
virtual bool fillRGBBufferFromXYZ(const PDFColor3& whitePoint, const std::vector<float>& colors, RenderingIntent intent, unsigned char* outputBuffer, PDFRenderErrorReporter* reporter) const override;
|
virtual bool fillRGBBufferFromXYZ(const PDFColor3& whitePoint, const std::vector<float>& colors, RenderingIntent intent, unsigned char* outputBuffer, PDFRenderErrorReporter* reporter) const override;
|
||||||
virtual bool fillRGBBufferFromICC(const std::vector<float>& colors, RenderingIntent renderingIntent, unsigned char* outputBuffer, const QByteArray& iccID, const QByteArray& iccData, PDFRenderErrorReporter* reporter) const override;
|
virtual bool fillRGBBufferFromICC(const std::vector<float>& colors, RenderingIntent renderingIntent, unsigned char* outputBuffer, const QByteArray& iccID, const QByteArray& iccData, PDFRenderErrorReporter* reporter) const override;
|
||||||
|
virtual bool transformColorSpace(const ColorSpaceTransformParams& params) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
@ -279,6 +280,11 @@ bool PDFLittleCMS::fillRGBBufferFromICC(const std::vector<float>& colors, Render
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PDFLittleCMS::transformColorSpace(const PDFCMS::ColorSpaceTransformParams& params) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
PDFLittleCMS::PDFLittleCMS(const PDFCMSManager* manager, const PDFCMSSettings& settings) :
|
PDFLittleCMS::PDFLittleCMS(const PDFCMSManager* manager, const PDFCMSSettings& settings) :
|
||||||
m_manager(manager),
|
m_manager(manager),
|
||||||
m_settings(settings),
|
m_settings(settings),
|
||||||
@ -410,6 +416,7 @@ QColor PDFLittleCMS::getColorFromDeviceCMYK(const PDFColor& color, RenderingInte
|
|||||||
|
|
||||||
QColor PDFLittleCMS::getColorFromXYZ(const PDFColor3& whitePoint, const PDFColor3& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const
|
QColor PDFLittleCMS::getColorFromXYZ(const PDFColor3& whitePoint, const PDFColor3& color, RenderingIntent intent, PDFRenderErrorReporter* reporter) const
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(whitePoint);
|
||||||
cmsHTRANSFORM transform = getTransform(XYZ, getEffectiveRenderingIntent(intent), false);
|
cmsHTRANSFORM transform = getTransform(XYZ, getEffectiveRenderingIntent(intent), false);
|
||||||
|
|
||||||
if (!transform)
|
if (!transform)
|
||||||
@ -422,8 +429,10 @@ QColor PDFLittleCMS::getColorFromXYZ(const PDFColor3& whitePoint, const PDFColor
|
|||||||
{
|
{
|
||||||
Q_ASSERT(cmsGetTransformOutputFormat(transform) == TYPE_RGB_FLT);
|
Q_ASSERT(cmsGetTransformOutputFormat(transform) == TYPE_RGB_FLT);
|
||||||
|
|
||||||
|
// Jakub Melka: It seems, that Adobe Acrobat Reader doesn't do the gamut remapping (whitepoint remapping).
|
||||||
|
// so, we don't do that too.
|
||||||
const cmsCIEXYZ* d50WhitePoint = cmsD50_XYZ();
|
const cmsCIEXYZ* d50WhitePoint = cmsD50_XYZ();
|
||||||
std::array<float, 3> xyzInputColor = { color[0] / whitePoint[0] * float(d50WhitePoint->X), color[1] / whitePoint[1] * float(d50WhitePoint->Y), color[2] / whitePoint[2] * float(d50WhitePoint->Z) };
|
std::array<float, 3> xyzInputColor = { color[0] * float(d50WhitePoint->X), color[1] * float(d50WhitePoint->Y), color[2] * float(d50WhitePoint->Z)};
|
||||||
std::array<float, 3> rgbOutputColor = { };
|
std::array<float, 3> rgbOutputColor = { };
|
||||||
cmsDoTransform(transform, xyzInputColor.data(), rgbOutputColor.data(), 1);
|
cmsDoTransform(transform, xyzInputColor.data(), rgbOutputColor.data(), 1);
|
||||||
return getColorFromOutputColor(rgbOutputColor);
|
return getColorFromOutputColor(rgbOutputColor);
|
||||||
@ -933,6 +942,11 @@ bool PDFCMSGeneric::fillRGBBufferFromICC(const std::vector<float>& colors, Rende
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PDFCMSGeneric::transformColorSpace(const PDFCMS::ColorSpaceTransformParams& params) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
PDFCMSManager::PDFCMSManager(QObject* parent) :
|
PDFCMSManager::PDFCMSManager(QObject* parent) :
|
||||||
BaseClass(parent),
|
BaseClass(parent),
|
||||||
m_mutex(QMutex::Recursive)
|
m_mutex(QMutex::Recursive)
|
||||||
@ -1242,4 +1256,10 @@ PDFColorProfileIdentifier PDFColorProfileIdentifier::createFile(Type type, QStri
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFColor3 PDFCMS::getDefaultXYZWhitepoint()
|
||||||
|
{
|
||||||
|
const cmsCIEXYZ* whitePoint = cmsD50_XYZ();
|
||||||
|
return PDFColor3{ PDFColorComponent(whitePoint->X), PDFColorComponent(whitePoint->Y), PDFColorComponent(whitePoint->Z) };
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -127,14 +127,21 @@ public:
|
|||||||
/// \param Three color channel value (X,Y,Z channel)
|
/// \param Three color channel value (X,Y,Z channel)
|
||||||
/// \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
|
/// Computes color from ICC color profile
|
||||||
/// \param color Input color
|
/// \param color Input color
|
||||||
/// \param iccID Unique ICC profile identifier
|
/// \param iccID Unique ICC profile identifier
|
||||||
/// \param iccData Color profile data
|
/// \param iccData Color profile data
|
||||||
/// \param reporter Render error reporter (used, when color transform fails)
|
/// \param reporter Render error reporter (used, when color transform fails)
|
||||||
virtual QColor getColorFromICC(const PDFColor& color, RenderingIntent renderingIntent, const QByteArray& iccID, const QByteArray& iccData, PDFRenderErrorReporter* reporter) const = 0;
|
virtual QColor getColorFromICC(const PDFColor& color,
|
||||||
|
RenderingIntent renderingIntent,
|
||||||
|
const QByteArray& iccID,
|
||||||
|
const QByteArray& iccData,
|
||||||
|
PDFRenderErrorReporter* reporter) const = 0;
|
||||||
|
|
||||||
/// Fills colors in Device Gray color space to the RGB buffer. If error occurs, then false is returned.
|
/// Fills colors in Device Gray color space to the RGB buffer. If error occurs, then false is returned.
|
||||||
/// Caller then should handle this - try to convert color as accurate as possible.
|
/// Caller then should handle this - try to convert color as accurate as possible.
|
||||||
@ -142,7 +149,10 @@ public:
|
|||||||
/// \param intent Rendering intent
|
/// \param intent Rendering intent
|
||||||
/// \param outputBuffer Output buffer in format RGB_888 (8-bit RGB values)
|
/// \param outputBuffer Output buffer in format RGB_888 (8-bit RGB values)
|
||||||
/// \param reporter Render error reporter (used, when color transform fails)
|
/// \param reporter Render error reporter (used, when color transform fails)
|
||||||
virtual bool fillRGBBufferFromDeviceGray(const std::vector<float>& colors, RenderingIntent intent, unsigned char* outputBuffer, PDFRenderErrorReporter* reporter) const = 0;
|
virtual bool fillRGBBufferFromDeviceGray(const std::vector<float>& colors,
|
||||||
|
RenderingIntent intent,
|
||||||
|
unsigned char* outputBuffer,
|
||||||
|
PDFRenderErrorReporter* reporter) const = 0;
|
||||||
|
|
||||||
/// Fills colors in Device RGB color space to RGB buffer. If error occurs, then false is returned.
|
/// Fills colors in Device RGB color space to RGB buffer. If error occurs, then false is returned.
|
||||||
/// Caller then should handle this - try to convert color as accurate as possible.
|
/// Caller then should handle this - try to convert color as accurate as possible.
|
||||||
@ -150,7 +160,10 @@ public:
|
|||||||
/// \param intent Rendering intent
|
/// \param intent Rendering intent
|
||||||
/// \param outputBuffer Output buffer in format RGB_888 (8-bit RGB values)
|
/// \param outputBuffer Output buffer in format RGB_888 (8-bit RGB values)
|
||||||
/// \param reporter Render error reporter (used, when color transform fails)
|
/// \param reporter Render error reporter (used, when color transform fails)
|
||||||
virtual bool fillRGBBufferFromDeviceRGB(const std::vector<float>& colors, RenderingIntent intent, unsigned char* outputBuffer, PDFRenderErrorReporter* reporter) const = 0;
|
virtual bool fillRGBBufferFromDeviceRGB(const std::vector<float>& colors,
|
||||||
|
RenderingIntent intent,
|
||||||
|
unsigned char* outputBuffer,
|
||||||
|
PDFRenderErrorReporter* reporter) const = 0;
|
||||||
|
|
||||||
/// Fills colors in Device CMYK color space to the RGB buffer. If error occurs, then false is returned.
|
/// Fills colors in Device CMYK color space to the RGB buffer. If error occurs, then false is returned.
|
||||||
/// Caller then should handle this - try to convert color as accurate as possible.
|
/// Caller then should handle this - try to convert color as accurate as possible.
|
||||||
@ -158,7 +171,10 @@ public:
|
|||||||
/// \param intent Rendering intent
|
/// \param intent Rendering intent
|
||||||
/// \param outputBuffer Output buffer in format RGB_888 (8-bit RGB values)
|
/// \param outputBuffer Output buffer in format RGB_888 (8-bit RGB values)
|
||||||
/// \param reporter Render error reporter (used, when color transform fails)
|
/// \param reporter Render error reporter (used, when color transform fails)
|
||||||
virtual bool fillRGBBufferFromDeviceCMYK(const std::vector<float>& colors, RenderingIntent intent, unsigned char* outputBuffer, PDFRenderErrorReporter* reporter) const = 0;
|
virtual bool fillRGBBufferFromDeviceCMYK(const std::vector<float>& colors,
|
||||||
|
RenderingIntent intent,
|
||||||
|
unsigned char* outputBuffer,
|
||||||
|
PDFRenderErrorReporter* reporter) const = 0;
|
||||||
|
|
||||||
/// Fills colors in XYZ color space to the RGB buffer. If error occurs, then false is returned.
|
/// Fills colors in XYZ color space to the RGB buffer. If error occurs, then false is returned.
|
||||||
/// Caller then should handle this - try to convert color as accurate as possible.
|
/// Caller then should handle this - try to convert color as accurate as possible.
|
||||||
@ -166,14 +182,51 @@ public:
|
|||||||
/// \param Three color channel value (X,Y,Z channel)
|
/// \param Three color channel value (X,Y,Z channel)
|
||||||
/// \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 bool fillRGBBufferFromXYZ(const PDFColor3& whitePoint, const std::vector<float>& colors, RenderingIntent intent, unsigned char* outputBuffer, PDFRenderErrorReporter* reporter) const = 0;
|
virtual bool fillRGBBufferFromXYZ(const PDFColor3& whitePoint,
|
||||||
|
const std::vector<float>& colors,
|
||||||
|
RenderingIntent intent,
|
||||||
|
unsigned char* outputBuffer,
|
||||||
|
PDFRenderErrorReporter* reporter) const = 0;
|
||||||
|
|
||||||
/// Fills RGB buffer from ICC color profile colors
|
/// Fills RGB buffer from ICC color profile colors
|
||||||
/// \param colors Input colors
|
/// \param colors Input colors
|
||||||
/// \param iccID Unique ICC profile identifier
|
/// \param iccID Unique ICC profile identifier
|
||||||
/// \param iccData Color profile data
|
/// \param iccData Color profile data
|
||||||
/// \param reporter Render error reporter (used, when color transform fails)
|
/// \param reporter Render error reporter (used, when color transform fails)
|
||||||
virtual bool fillRGBBufferFromICC(const std::vector<float>& colors, RenderingIntent renderingIntent, unsigned char* outputBuffer, const QByteArray& iccID, const QByteArray& iccData, PDFRenderErrorReporter* reporter) const = 0;
|
virtual bool fillRGBBufferFromICC(const std::vector<float>& colors,
|
||||||
|
RenderingIntent renderingIntent,
|
||||||
|
unsigned char* outputBuffer,
|
||||||
|
const QByteArray& iccID,
|
||||||
|
const QByteArray& iccData,
|
||||||
|
PDFRenderErrorReporter* reporter) const = 0;
|
||||||
|
|
||||||
|
enum ColorSpaceType
|
||||||
|
{
|
||||||
|
Invalid,
|
||||||
|
DeviceGray,
|
||||||
|
DeviceRGB,
|
||||||
|
DeviceCMYK,
|
||||||
|
XYZ,
|
||||||
|
ICC
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ColorSpaceTransformParams
|
||||||
|
{
|
||||||
|
ColorSpaceType sourceType = ColorSpaceType::Invalid;
|
||||||
|
ColorSpaceType targetType = ColorSpaceType::Invalid;
|
||||||
|
|
||||||
|
QByteArray sourceIccId;
|
||||||
|
QByteArray targetIccId;
|
||||||
|
|
||||||
|
QByteArray sourceIccData;
|
||||||
|
QByteArray targetIccData;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Transforms color between two color spaces.
|
||||||
|
virtual bool transformColorSpace(const ColorSpaceTransformParams& params) const = 0;
|
||||||
|
|
||||||
|
/// Get D50 white point for XYZ color space
|
||||||
|
static PDFColor3 getDefaultXYZWhitepoint();
|
||||||
};
|
};
|
||||||
|
|
||||||
using PDFCMSPointer = QSharedPointer<PDFCMS>;
|
using PDFCMSPointer = QSharedPointer<PDFCMS>;
|
||||||
@ -195,6 +248,7 @@ public:
|
|||||||
virtual bool fillRGBBufferFromDeviceCMYK(const std::vector<float>& colors, RenderingIntent intent, unsigned char* outputBuffer, PDFRenderErrorReporter* reporter) const override;
|
virtual bool fillRGBBufferFromDeviceCMYK(const std::vector<float>& colors, RenderingIntent intent, unsigned char* outputBuffer, PDFRenderErrorReporter* reporter) const override;
|
||||||
virtual bool fillRGBBufferFromXYZ(const PDFColor3& whitePoint, const std::vector<float>& colors, RenderingIntent intent, unsigned char* outputBuffer, PDFRenderErrorReporter* reporter) const override;
|
virtual bool fillRGBBufferFromXYZ(const PDFColor3& whitePoint, const std::vector<float>& colors, RenderingIntent intent, unsigned char* outputBuffer, PDFRenderErrorReporter* reporter) const override;
|
||||||
virtual bool fillRGBBufferFromICC(const std::vector<float>& colors, RenderingIntent renderingIntent, unsigned char* outputBuffer, const QByteArray& iccID, const QByteArray& iccData, PDFRenderErrorReporter* reporter) const override;
|
virtual bool fillRGBBufferFromICC(const std::vector<float>& colors, RenderingIntent renderingIntent, unsigned char* outputBuffer, const QByteArray& iccID, const QByteArray& iccData, PDFRenderErrorReporter* reporter) const override;
|
||||||
|
virtual bool transformColorSpace(const ColorSpaceTransformParams& params) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PDFColorProfileIdentifier
|
struct PDFColorProfileIdentifier
|
||||||
|
@ -31,6 +31,43 @@
|
|||||||
namespace pdf
|
namespace pdf
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static PDFColorComponent getDeterminant(const PDFColorComponentMatrix_3x3& matrix)
|
||||||
|
{
|
||||||
|
const PDFColorComponent a_11 = matrix.getValue(0, 0);
|
||||||
|
const PDFColorComponent a_12 = matrix.getValue(0, 1);
|
||||||
|
const PDFColorComponent a_13 = matrix.getValue(0, 2);
|
||||||
|
const PDFColorComponent a_21 = matrix.getValue(1, 0);
|
||||||
|
const PDFColorComponent a_22 = matrix.getValue(1, 1);
|
||||||
|
const PDFColorComponent a_23 = matrix.getValue(1, 2);
|
||||||
|
const PDFColorComponent a_31 = matrix.getValue(2, 0);
|
||||||
|
const PDFColorComponent a_32 = matrix.getValue(2, 1);
|
||||||
|
const PDFColorComponent a_33 = matrix.getValue(2, 2);
|
||||||
|
|
||||||
|
return -a_13* a_22 * a_31 + a_12 * a_23 * a_31 + a_13 * a_21 * a_32 - a_11 * a_23 * a_32 - a_12 * a_21 * a_33 + a_11 * a_22 * a_33;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFColorComponentMatrix_3x3 getInverseMatrix(const PDFColorComponentMatrix_3x3& matrix)
|
||||||
|
{
|
||||||
|
const PDFColorComponent a_11 = matrix.getValue(0, 0);
|
||||||
|
const PDFColorComponent a_12 = matrix.getValue(0, 1);
|
||||||
|
const PDFColorComponent a_13 = matrix.getValue(0, 2);
|
||||||
|
const PDFColorComponent a_21 = matrix.getValue(1, 0);
|
||||||
|
const PDFColorComponent a_22 = matrix.getValue(1, 1);
|
||||||
|
const PDFColorComponent a_23 = matrix.getValue(1, 2);
|
||||||
|
const PDFColorComponent a_31 = matrix.getValue(2, 0);
|
||||||
|
const PDFColorComponent a_32 = matrix.getValue(2, 1);
|
||||||
|
const PDFColorComponent a_33 = matrix.getValue(2, 2);
|
||||||
|
|
||||||
|
const PDFColorComponent determinant = -a_13* a_22 * a_31 + a_12 * a_23 * a_31 + a_13 * a_21 * a_32 - a_11 * a_23 * a_32 - a_12 * a_21 * a_33 + a_11 * a_22 * a_33;
|
||||||
|
const PDFColorComponent coefficient = !qIsNull(determinant) ? 1.0 / determinant : 0.0;
|
||||||
|
|
||||||
|
PDFColorComponentMatrix_3x3 inversedMatrix { a_22 * a_33 - a_23 * a_32, a_13 * a_32 - a_12 * a_33, a_12 * a_23 - a_13 * a_22,
|
||||||
|
a_23 * a_31 - a_21 * a_33, a_11 * a_33 - a_13 * a_31, a_13 * a_21 - a_11 * a_23,
|
||||||
|
a_21 * a_32 - a_22 * a_31, a_12 * a_31 - a_11 * a_32, a_11 * a_22 - a_12 * a_21 };
|
||||||
|
inversedMatrix.multiplyByFactor(coefficient);
|
||||||
|
return inversedMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
QColor PDFDeviceGrayColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const
|
QColor PDFDeviceGrayColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const
|
||||||
{
|
{
|
||||||
return getColor(PDFColor(0.0f), cms, intent, reporter, true);
|
return getColor(PDFColor(0.0f), cms, intent, reporter, true);
|
||||||
@ -149,6 +186,23 @@ void PDFDeviceCMYKColorSpace::fillRGBBuffer(const std::vector<float>& colors, un
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PDFAbstractColorSpace::isBlendColorSpace() const
|
||||||
|
{
|
||||||
|
switch (getColorSpace())
|
||||||
|
{
|
||||||
|
case pdf::PDFAbstractColorSpace::ColorSpace::DeviceGray:
|
||||||
|
case pdf::PDFAbstractColorSpace::ColorSpace::DeviceRGB:
|
||||||
|
case pdf::PDFAbstractColorSpace::ColorSpace::DeviceCMYK:
|
||||||
|
case pdf::PDFAbstractColorSpace::ColorSpace::CalGray:
|
||||||
|
case pdf::PDFAbstractColorSpace::ColorSpace::CalRGB:
|
||||||
|
case pdf::PDFAbstractColorSpace::ColorSpace::ICCBased:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData,
|
QImage PDFAbstractColorSpace::getImage(const PDFImageData& imageData,
|
||||||
const PDFImageData& softMask,
|
const PDFImageData& softMask,
|
||||||
const PDFCMS* cms,
|
const PDFCMS* cms,
|
||||||
@ -582,6 +636,227 @@ PDFColor PDFAbstractColorSpace::mixColors(const PDFColor& color1, const PDFColor
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PDFAbstractColorSpace::transform(const PDFAbstractColorSpace* source,
|
||||||
|
const PDFAbstractColorSpace* target,
|
||||||
|
const PDFCMS* cms,
|
||||||
|
RenderingIntent intent,
|
||||||
|
const PDFColorBuffer input,
|
||||||
|
PDFColorBuffer output,
|
||||||
|
PDFRenderErrorReporter* reporter)
|
||||||
|
{
|
||||||
|
Q_ASSERT(source);
|
||||||
|
Q_ASSERT(target);
|
||||||
|
Q_ASSERT(cms);
|
||||||
|
Q_ASSERT(target->isBlendColorSpace());
|
||||||
|
Q_ASSERT(input.size() % source->getColorComponentCount() == 0);
|
||||||
|
|
||||||
|
if (source->equals(target))
|
||||||
|
{
|
||||||
|
// Just copy input buffer to output buffer
|
||||||
|
Q_ASSERT(input.size() == output.size());
|
||||||
|
std::copy(input.begin(), input.end(), output.begin());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We will use following algorithm to transform colors:
|
||||||
|
// 1. Determine source color space type for cms,
|
||||||
|
// and adjust colors to this color space type
|
||||||
|
// 2. Prepare work output buffer of target size (can have
|
||||||
|
// different size than real output buffer)
|
||||||
|
// 3. Transform colors using CMS
|
||||||
|
// 4. Transform output color buffer to target color buffer
|
||||||
|
|
||||||
|
PDFCMS::ColorSpaceTransformParams params;
|
||||||
|
std::vector<PDFColorComponent> transformedInputColorsVector;
|
||||||
|
PDFColorBuffer transformedInput = input;
|
||||||
|
|
||||||
|
switch (source->getColorSpace())
|
||||||
|
{
|
||||||
|
case ColorSpace::DeviceGray:
|
||||||
|
params.sourceType = PDFCMS::ColorSpaceType::DeviceGray;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ColorSpace::DeviceRGB:
|
||||||
|
params.sourceType = PDFCMS::ColorSpaceType::DeviceRGB;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ColorSpace::DeviceCMYK:
|
||||||
|
params.sourceType = PDFCMS::ColorSpaceType::DeviceCMYK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ColorSpace::CalGray:
|
||||||
|
{
|
||||||
|
params.sourceType = PDFCMS::ColorSpaceType::XYZ;
|
||||||
|
|
||||||
|
// Transform gray to XYZ
|
||||||
|
const PDFCalGrayColorSpace* calGrayColorSpace = static_cast<const PDFCalGrayColorSpace*>(source);
|
||||||
|
const PDFColorComponent gamma = calGrayColorSpace->getGamma();
|
||||||
|
|
||||||
|
transformedInputColorsVector.resize(input.size() * 3, 0.0f);
|
||||||
|
auto it = transformedInputColorsVector.begin();
|
||||||
|
for (PDFColorComponent gray : input)
|
||||||
|
{
|
||||||
|
const PDFColorComponent A = clip01(gray);
|
||||||
|
const PDFColorComponent xyzColor = std::powf(A, gamma);
|
||||||
|
*it++ = xyzColor;
|
||||||
|
*it++ = xyzColor;
|
||||||
|
*it++ = xyzColor;
|
||||||
|
}
|
||||||
|
Q_ASSERT(it == transformedInputColorsVector.end());
|
||||||
|
|
||||||
|
transformedInput = PDFColorBuffer(transformedInputColorsVector.data(), transformedInputColorsVector.size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ColorSpace::CalRGB:
|
||||||
|
{
|
||||||
|
params.sourceType = PDFCMS::ColorSpaceType::XYZ;
|
||||||
|
|
||||||
|
const PDFCalRGBColorSpace* calRGBColorSpace = static_cast<const PDFCalRGBColorSpace*>(source);
|
||||||
|
const PDFColor3 gamma = calRGBColorSpace->getGamma();
|
||||||
|
const PDFColorComponentMatrix_3x3 matrix = calRGBColorSpace->getMatrix();
|
||||||
|
|
||||||
|
transformedInputColorsVector.resize(input.size(), 0.0f);
|
||||||
|
auto it = transformedInputColorsVector.begin();
|
||||||
|
|
||||||
|
for (auto sourceIt = input.cbegin(); sourceIt != input.cend(); sourceIt = std::next(sourceIt, 3))
|
||||||
|
{
|
||||||
|
const PDFColor3 ABC = { };
|
||||||
|
ABC[0] = *sourceIt;
|
||||||
|
ABC[1] = *std::next(sourceIt, 1);
|
||||||
|
ABC[2] = *std::next(sourceIt, 2);
|
||||||
|
ABC = colorPowerByFactors(ABC, gamma);
|
||||||
|
|
||||||
|
const PDFColor3 XYZ = matrix * ABC;
|
||||||
|
*it++ = XYZ[0];
|
||||||
|
*it++ = XYZ[1];
|
||||||
|
*it++ = XYZ[2];
|
||||||
|
}
|
||||||
|
Q_ASSERT(it == transformedInputColorsVector.end());
|
||||||
|
|
||||||
|
transformedInput = PDFColorBuffer(transformedInputColorsVector.data(), transformedInputColorsVector.size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ColorSpace::Lab:
|
||||||
|
{
|
||||||
|
params.sourceType = PDFCMS::ColorSpaceType::XYZ;
|
||||||
|
|
||||||
|
const PDFLabColorSpace* labColorSpace = static_cast<const PDFLabColorSpace*>(source);
|
||||||
|
const PDFColor aMin = labColorSpace->getAMin();
|
||||||
|
const PDFColor aMax = labColorSpace->getAMax();
|
||||||
|
const PDFColor bMin = labColorSpace->getBMin();
|
||||||
|
const PDFColor bMax = labColorSpace->getBMax();
|
||||||
|
|
||||||
|
transformedInputColorsVector.resize(input.size(), 0.0f);
|
||||||
|
auto it = transformedInputColorsVector.begin();
|
||||||
|
|
||||||
|
for (auto sourceIt = input.cbegin(); sourceIt != input.cend(); sourceIt = std::next(sourceIt, 3))
|
||||||
|
{
|
||||||
|
PDFColorComponent LStar = qBound(0.0, interpolate(*sourceIt, 0.0, 1.0, 0.0, 100.0), 100.0);
|
||||||
|
PDFColorComponent aStar = qBound<PDFColorComponent>(aMin, interpolate(*std::next(sourceIt, 1), 0.0, 1.0, aMin, aMax), aMax);
|
||||||
|
PDFColorComponent bStar = qBound<PDFColorComponent>(bMin, interpolate(*std::next(sourceIt, 2), 0.0, 1.0, bMin, bMax), bMax);
|
||||||
|
|
||||||
|
const PDFColorComponent param1 = (LStar + 16.0f) / 116.0f;
|
||||||
|
const PDFColorComponent param2 = aStar / 500.0f;
|
||||||
|
const PDFColorComponent param3 = bStar / 200.0f;
|
||||||
|
|
||||||
|
const PDFColorComponent L = param1 + param2;
|
||||||
|
const PDFColorComponent M = param1;
|
||||||
|
const PDFColorComponent N = param1 - param3;
|
||||||
|
|
||||||
|
auto g = [](PDFColorComponent x) -> PDFColorComponent
|
||||||
|
{
|
||||||
|
if (x >= 6.0f / 29.0f)
|
||||||
|
{
|
||||||
|
return x * x * x;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (108.0f / 841.0f) * (x - 4.0f / 29.0f);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const PDFColorComponent gL = g(L);
|
||||||
|
const PDFColorComponent gM = g(M);
|
||||||
|
const PDFColorComponent gN = g(N);
|
||||||
|
|
||||||
|
*it++ = gL;
|
||||||
|
*it++ = gM;
|
||||||
|
*it++ = gN;
|
||||||
|
}
|
||||||
|
Q_ASSERT(it == transformedInputColorsVector.end());
|
||||||
|
|
||||||
|
transformedInput = PDFColorBuffer(transformedInputColorsVector.data(), transformedInputColorsVector.size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ColorSpace::ICCBased:
|
||||||
|
{
|
||||||
|
const PDFICCBasedColorSpace* iccBasedColorSpace = static_cast<const PDFICCBasedColorSpace*>(source);
|
||||||
|
|
||||||
|
params.sourceType = PDFCMS::ColorSpaceType::ICC;
|
||||||
|
params.sourceIccId = iccBasedColorSpace->getIccProfileDataChecksum();
|
||||||
|
params.sourceIccData = iccBasedColorSpace->getIccProfileData();
|
||||||
|
|
||||||
|
size_t colorComponentCount = iccBasedColorSpace->getColorComponentCount();
|
||||||
|
const PDFICCBasedColorSpace::Ranges& ranges = iccBasedColorSpace->getRange();
|
||||||
|
|
||||||
|
transformedInputColorsVector.resize(input.size(), 0.0f);
|
||||||
|
auto outputIt = transformedInputColorsVector.begin();
|
||||||
|
for (auto inputIt = input.cbegin(); inputIt != input.cend();)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < colorComponentCount; ++i)
|
||||||
|
{
|
||||||
|
const size_t imin = 2 * i + 0;
|
||||||
|
const size_t imax = 2 * i + 1;
|
||||||
|
*outputIt++ = qBound(ranges[imin], *inputIt++, ranges[imax]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transformedInput = PDFColorBuffer(transformedInputColorsVector.data(), transformedInputColorsVector.size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ColorSpace::Indexed:
|
||||||
|
{
|
||||||
|
const PDFIndexedColorSpace* indexedColorSpace = static_cast<const PDFIndexedColorSpace*>(source);
|
||||||
|
|
||||||
|
PDFColorSpacePointer baseColorSpace = indexedColorSpace->getBaseColorSpace();
|
||||||
|
std::vector<PDFColorComponent> transformedToBaseColorSpaceInput = indexedColorSpace->transformColorsToBaseColorSpace(input);
|
||||||
|
PDFColorBuffer transformedInputBuffer(transformedToBaseColorSpaceInput.data(), transformedToBaseColorSpaceInput.size());
|
||||||
|
return transform(baseColorSpace.data(), target, cms, intent, transformedInputBuffer, output, reporter);
|
||||||
|
}
|
||||||
|
|
||||||
|
case ColorSpace::Separation:
|
||||||
|
{
|
||||||
|
const PDFSeparationColorSpace* separationColorSpace = static_cast<const PDFSeparationColorSpace*>(source);
|
||||||
|
|
||||||
|
PDFColorSpacePointer alternateColorSpace = separationColorSpace->getAlternateColorSpace();
|
||||||
|
std::vector<PDFColorComponent> transformedToBaseColorSpaceInput = separationColorSpace->transformColorsToBaseColorSpace(input);
|
||||||
|
PDFColorBuffer transformedInputBuffer(transformedToBaseColorSpaceInput.data(), transformedToBaseColorSpaceInput.size());
|
||||||
|
return transform(alternateColorSpace.data(), target, cms, intent, transformedInputBuffer, output, reporter);
|
||||||
|
}
|
||||||
|
|
||||||
|
case ColorSpace::DeviceN:
|
||||||
|
{
|
||||||
|
const PDFDeviceNColorSpace* separationColorSpace = static_cast<const PDFDeviceNColorSpace*>(source);
|
||||||
|
|
||||||
|
PDFColorSpacePointer alternateColorSpace = separationColorSpace->getAlternateColorSpace();
|
||||||
|
std::vector<PDFColorComponent> transformedToBaseColorSpaceInput = separationColorSpace->transformColorsToBaseColorSpace(input);
|
||||||
|
PDFColorBuffer transformedInputBuffer(transformedToBaseColorSpaceInput.data(), transformedToBaseColorSpaceInput.size());
|
||||||
|
return transform(alternateColorSpace.data(), target, cms, intent, transformedInputBuffer, output, reporter);
|
||||||
|
}
|
||||||
|
|
||||||
|
case ColorSpace::Pattern:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Q_ASSERT(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PDFColorSpacePointer PDFAbstractColorSpace::createColorSpaceImpl(const PDFDictionary* colorSpaceDictionary,
|
PDFColorSpacePointer PDFAbstractColorSpace::createColorSpaceImpl(const PDFDictionary* colorSpaceDictionary,
|
||||||
const PDFDocument* document,
|
const PDFDocument* document,
|
||||||
const PDFObject& colorSpace,
|
const PDFObject& colorSpace,
|
||||||
@ -762,7 +1037,6 @@ PDFColor3 PDFAbstractColorSpace::convertXYZtoRGB(const PDFColor3& xyzColor)
|
|||||||
return matrixXYZtoRGB * xyzColor;
|
return matrixXYZtoRGB * xyzColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QColor PDFXYZColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const
|
QColor PDFXYZColorSpace::getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const
|
||||||
{
|
{
|
||||||
PDFColor color;
|
PDFColor color;
|
||||||
@ -926,9 +1200,26 @@ PDFColorSpacePointer PDFCalRGBColorSpace::createCalRGBColorSpace(const PDFDocume
|
|||||||
loader.readNumberArrayFromDictionary(dictionary, CAL_GAMMA, gamma.begin(), gamma.end());
|
loader.readNumberArrayFromDictionary(dictionary, CAL_GAMMA, gamma.begin(), gamma.end());
|
||||||
loader.readNumberArrayFromDictionary(dictionary, CAL_MATRIX, matrix.begin(), matrix.end());
|
loader.readNumberArrayFromDictionary(dictionary, CAL_MATRIX, matrix.begin(), matrix.end());
|
||||||
|
|
||||||
|
matrix.transpose();
|
||||||
|
|
||||||
return PDFColorSpacePointer(new PDFCalRGBColorSpace(whitePoint, blackPoint, gamma, matrix));
|
return PDFColorSpacePointer(new PDFCalRGBColorSpace(whitePoint, blackPoint, gamma, matrix));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFColor3 PDFCalRGBColorSpace::getBlackPoint() const
|
||||||
|
{
|
||||||
|
return m_blackPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFColor3 PDFCalRGBColorSpace::getGamma() const
|
||||||
|
{
|
||||||
|
return m_gamma;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PDFColorComponentMatrix_3x3& PDFCalRGBColorSpace::getMatrix() const
|
||||||
|
{
|
||||||
|
return m_matrix;
|
||||||
|
}
|
||||||
|
|
||||||
PDFLabColorSpace::PDFLabColorSpace(PDFColor3 whitePoint,
|
PDFLabColorSpace::PDFLabColorSpace(PDFColor3 whitePoint,
|
||||||
PDFColor3 blackPoint,
|
PDFColor3 blackPoint,
|
||||||
PDFColorComponent aMin,
|
PDFColorComponent aMin,
|
||||||
@ -1071,6 +1362,31 @@ 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]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFColorComponent PDFLabColorSpace::getAMin() const
|
||||||
|
{
|
||||||
|
return m_aMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFColorComponent PDFLabColorSpace::getAMax() const
|
||||||
|
{
|
||||||
|
return m_aMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFColorComponent PDFLabColorSpace::getBMin() const
|
||||||
|
{
|
||||||
|
return m_bMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFColorComponent PDFLabColorSpace::getBMax() const
|
||||||
|
{
|
||||||
|
return m_bMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFColor3 PDFLabColorSpace::getBlackPoint() const
|
||||||
|
{
|
||||||
|
return m_blackPoint;
|
||||||
|
}
|
||||||
|
|
||||||
PDFICCBasedColorSpace::PDFICCBasedColorSpace(PDFColorSpacePointer alternateColorSpace, Ranges range, QByteArray iccProfileData, PDFObjectReference metadata) :
|
PDFICCBasedColorSpace::PDFICCBasedColorSpace(PDFColorSpacePointer alternateColorSpace, Ranges range, QByteArray iccProfileData, PDFObjectReference metadata) :
|
||||||
m_alternateColorSpace(qMove(alternateColorSpace)),
|
m_alternateColorSpace(qMove(alternateColorSpace)),
|
||||||
m_range(range),
|
m_range(range),
|
||||||
@ -1213,6 +1529,21 @@ PDFColorSpacePointer PDFICCBasedColorSpace::createICCBasedColorSpace(const PDFDi
|
|||||||
return PDFColorSpacePointer(new PDFICCBasedColorSpace(qMove(alternateColorSpace), ranges, qMove(iccProfileData), loader.readReferenceFromDictionary(dictionary, "Metadata")));
|
return PDFColorSpacePointer(new PDFICCBasedColorSpace(qMove(alternateColorSpace), ranges, qMove(iccProfileData), loader.readReferenceFromDictionary(dictionary, "Metadata")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PDFICCBasedColorSpace::Ranges& PDFICCBasedColorSpace::getRange() const
|
||||||
|
{
|
||||||
|
return m_range;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray& PDFICCBasedColorSpace::getIccProfileData() const
|
||||||
|
{
|
||||||
|
return m_iccProfileData;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray& PDFICCBasedColorSpace::getIccProfileDataChecksum() const
|
||||||
|
{
|
||||||
|
return m_iccProfileDataChecksum;
|
||||||
|
}
|
||||||
|
|
||||||
PDFIndexedColorSpace::PDFIndexedColorSpace(PDFColorSpacePointer baseColorSpace, QByteArray&& colors, int maxValue) :
|
PDFIndexedColorSpace::PDFIndexedColorSpace(PDFColorSpacePointer baseColorSpace, QByteArray&& colors, int maxValue) :
|
||||||
m_baseColorSpace(qMove(baseColorSpace)),
|
m_baseColorSpace(qMove(baseColorSpace)),
|
||||||
m_colors(qMove(colors)),
|
m_colors(qMove(colors)),
|
||||||
@ -1409,6 +1740,39 @@ PDFColorSpacePointer PDFIndexedColorSpace::createIndexedColorSpace(const PDFDict
|
|||||||
return PDFColorSpacePointer(new PDFIndexedColorSpace(qMove(baseColorSpace), qMove(colors), maxValue));
|
return PDFColorSpacePointer(new PDFIndexedColorSpace(qMove(baseColorSpace), qMove(colors), maxValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFColorSpacePointer PDFIndexedColorSpace::getBaseColorSpace() const
|
||||||
|
{
|
||||||
|
return m_baseColorSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<PDFColorComponent> PDFIndexedColorSpace::transformColorsToBaseColorSpace(const PDFColorBuffer buffer) const
|
||||||
|
{
|
||||||
|
const std::size_t colorComponentCount = m_baseColorSpace->getColorComponentCount();
|
||||||
|
std::vector<PDFColorComponent> result(buffer.size() * colorComponentCount, 0.0f);
|
||||||
|
|
||||||
|
auto outputIt = result.begin();
|
||||||
|
for (PDFColorComponent input : buffer)
|
||||||
|
{
|
||||||
|
const int colorIndex = qBound(MIN_VALUE, static_cast<int>(input), m_maxValue);
|
||||||
|
const int byteOffset = colorIndex * colorComponentCount;
|
||||||
|
|
||||||
|
// We must point into the array. Check first and last component.
|
||||||
|
Q_ASSERT(byteOffset + colorComponentCount - 1 < m_colors.size());
|
||||||
|
|
||||||
|
const char* bytePointer = m_colors.constData() + byteOffset;
|
||||||
|
|
||||||
|
for (int i = 0; i < colorComponentCount; ++i)
|
||||||
|
{
|
||||||
|
const unsigned char value = *bytePointer++;
|
||||||
|
const PDFColorComponent component = static_cast<PDFColorComponent>(value) / 255.0f;
|
||||||
|
*outputIt++ = component;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Q_ASSERT(outputIt == result.cend());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
PDFSeparationColorSpace::PDFSeparationColorSpace(QByteArray&& colorName, PDFColorSpacePointer alternateColorSpace, PDFFunctionPtr tintTransform) :
|
PDFSeparationColorSpace::PDFSeparationColorSpace(QByteArray&& colorName, PDFColorSpacePointer alternateColorSpace, PDFFunctionPtr tintTransform) :
|
||||||
m_colorName(qMove(colorName)),
|
m_colorName(qMove(colorName)),
|
||||||
m_alternateColorSpace(qMove(alternateColorSpace)),
|
m_alternateColorSpace(qMove(alternateColorSpace)),
|
||||||
@ -1472,6 +1836,38 @@ size_t PDFSeparationColorSpace::getColorComponentCount() const
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<PDFColorComponent> PDFSeparationColorSpace::transformColorsToBaseColorSpace(const PDFColorBuffer buffer) const
|
||||||
|
{
|
||||||
|
const std::size_t colorComponentCount = m_alternateColorSpace->getColorComponentCount();
|
||||||
|
std::vector<PDFColorComponent> result(buffer.size() * colorComponentCount, 0.0f);
|
||||||
|
|
||||||
|
std::vector<double> outputColor;
|
||||||
|
outputColor.resize(colorComponentCount, 0.0);
|
||||||
|
|
||||||
|
auto outputIt = result.begin();
|
||||||
|
for (PDFColorComponent input : buffer)
|
||||||
|
{
|
||||||
|
// Input value
|
||||||
|
double tint = input;
|
||||||
|
|
||||||
|
if (m_isAll)
|
||||||
|
{
|
||||||
|
const double inversedTint = qBound(0.0, 1.0 - tint, 1.0);
|
||||||
|
std::fill(outputIt, outputIt + colorComponentCount, inversedTint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_tintTransform->apply(&tint, &tint + 1, outputColor.data(), outputColor.data() + outputColor.size());
|
||||||
|
std::copy(outputColor.cbegin(), outputColor.cend(), outputIt);
|
||||||
|
}
|
||||||
|
|
||||||
|
outputIt = std::next(outputIt, colorComponentCount);
|
||||||
|
}
|
||||||
|
Q_ASSERT(outputIt == result.cend());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
PDFColorSpacePointer PDFSeparationColorSpace::createSeparationColorSpace(const PDFDictionary* colorSpaceDictionary,
|
PDFColorSpacePointer PDFSeparationColorSpace::createSeparationColorSpace(const PDFDictionary* colorSpaceDictionary,
|
||||||
const PDFDocument* document,
|
const PDFDocument* document,
|
||||||
const PDFArray* array,
|
const PDFArray* array,
|
||||||
@ -1504,6 +1900,16 @@ PDFColorSpacePointer PDFSeparationColorSpace::createSeparationColorSpace(const P
|
|||||||
return PDFColorSpacePointer(new PDFSeparationColorSpace(qMove(colorName), qMove(alternateColorSpace), qMove(tintTransform)));
|
return PDFColorSpacePointer(new PDFSeparationColorSpace(qMove(colorName), qMove(alternateColorSpace), qMove(tintTransform)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFColorSpacePointer PDFSeparationColorSpace::getAlternateColorSpace() const
|
||||||
|
{
|
||||||
|
return m_alternateColorSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray& PDFSeparationColorSpace::getColorName() const
|
||||||
|
{
|
||||||
|
return m_colorName;
|
||||||
|
}
|
||||||
|
|
||||||
const unsigned char* PDFImageData::getRow(unsigned int rowIndex) const
|
const unsigned char* PDFImageData::getRow(unsigned int rowIndex) const
|
||||||
{
|
{
|
||||||
const unsigned char* data = reinterpret_cast<const unsigned char*>(m_data.constData());
|
const unsigned char* data = reinterpret_cast<const unsigned char*>(m_data.constData());
|
||||||
@ -1612,6 +2018,34 @@ size_t PDFDeviceNColorSpace::getColorComponentCount() const
|
|||||||
return m_colorants.size();
|
return m_colorants.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<PDFColorComponent> PDFDeviceNColorSpace::transformColorsToBaseColorSpace(const PDFColorBuffer buffer) const
|
||||||
|
{
|
||||||
|
std::vector<PDFColorComponent> result;
|
||||||
|
|
||||||
|
const std::size_t colorantCount = getColorComponentCount();
|
||||||
|
if (colorantCount > 0)
|
||||||
|
{
|
||||||
|
const std::size_t inputColorCount = buffer.size() / colorantCount;
|
||||||
|
const std::size_t alternateColorSpaceComponentCount = m_alternateColorSpace->getColorComponentCount();
|
||||||
|
result.resize(inputColorCount * alternateColorSpaceComponentCount, 0.0f);
|
||||||
|
|
||||||
|
std::vector<double> inputColor(colorantCount, 0.0);
|
||||||
|
std::vector<double> outputColor(alternateColorSpaceComponentCount, 0.0);
|
||||||
|
|
||||||
|
auto outputIt = result.begin();
|
||||||
|
for (auto it = buffer.begin(); it != buffer.end(); it = std::next(it, colorantCount))
|
||||||
|
{
|
||||||
|
std::copy(it, it + colorantCount, inputColor.begin());
|
||||||
|
m_tintTransform->apply(inputColor.data(), inputColor.data() + inputColor.size(), outputColor.data(), outputColor.data() + outputColor.size());
|
||||||
|
std::copy(outputColor.cbegin(), outputColor.cend(), outputIt);
|
||||||
|
outputIt = std::next(outputIt, alternateColorSpaceComponentCount);
|
||||||
|
}
|
||||||
|
Q_ASSERT(outputIt == result.cend());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
PDFColorSpacePointer PDFDeviceNColorSpace::createDeviceNColorSpace(const PDFDictionary* colorSpaceDictionary,
|
PDFColorSpacePointer PDFDeviceNColorSpace::createDeviceNColorSpace(const PDFDictionary* colorSpaceDictionary,
|
||||||
const PDFDocument* document,
|
const PDFDocument* document,
|
||||||
const PDFArray* array,
|
const PDFArray* array,
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "pdfflatarray.h"
|
#include "pdfflatarray.h"
|
||||||
#include "pdffunction.h"
|
#include "pdffunction.h"
|
||||||
|
#include "pdfutils.h"
|
||||||
|
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
@ -43,6 +44,7 @@ class PDFRenderErrorReporter;
|
|||||||
using PDFColorComponent = float;
|
using PDFColorComponent = float;
|
||||||
using PDFColor = PDFFlatArray<PDFColorComponent, 4>;
|
using PDFColor = PDFFlatArray<PDFColorComponent, 4>;
|
||||||
using PDFColorSpacePointer = QSharedPointer<PDFAbstractColorSpace>;
|
using PDFColorSpacePointer = QSharedPointer<PDFAbstractColorSpace>;
|
||||||
|
using PDFColorBuffer = PDFBuffer<PDFColorComponent>;
|
||||||
|
|
||||||
static constexpr const int COLOR_SPACE_MAX_LEVEL_OF_RECURSION = 12;
|
static constexpr const int COLOR_SPACE_MAX_LEVEL_OF_RECURSION = 12;
|
||||||
|
|
||||||
@ -209,6 +211,34 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline PDFColorComponent getValue(size_t row, size_t column) const
|
||||||
|
{
|
||||||
|
return m_values[row * Cols + column];
|
||||||
|
}
|
||||||
|
|
||||||
|
void transpose()
|
||||||
|
{
|
||||||
|
Q_ASSERT(Rows == Cols);
|
||||||
|
|
||||||
|
for (size_t row = 0; row < Rows; ++row)
|
||||||
|
{
|
||||||
|
for (size_t column = row; column < Cols; ++column)
|
||||||
|
{
|
||||||
|
const size_t index1 = row * Cols + column;
|
||||||
|
const size_t index2 = column * Cols + row;
|
||||||
|
std::swap(m_values[index1], m_values[index2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void multiplyByFactor(PDFColorComponent factor)
|
||||||
|
{
|
||||||
|
for (auto it = begin(); it != end(); ++it)
|
||||||
|
{
|
||||||
|
*it *= factor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline typename std::array<PDFColorComponent, Rows * Cols>::iterator begin() { return m_values.begin(); }
|
inline typename std::array<PDFColorComponent, Rows * Cols>::iterator begin() { return m_values.begin(); }
|
||||||
inline typename std::array<PDFColorComponent, Rows * Cols>::iterator end() { return m_values.end(); }
|
inline typename std::array<PDFColorComponent, Rows * Cols>::iterator end() { return m_values.end(); }
|
||||||
|
|
||||||
@ -226,6 +256,27 @@ public:
|
|||||||
explicit PDFAbstractColorSpace() = default;
|
explicit PDFAbstractColorSpace() = default;
|
||||||
virtual ~PDFAbstractColorSpace() = default;
|
virtual ~PDFAbstractColorSpace() = default;
|
||||||
|
|
||||||
|
enum class ColorSpace
|
||||||
|
{
|
||||||
|
DeviceGray,
|
||||||
|
DeviceRGB,
|
||||||
|
DeviceCMYK,
|
||||||
|
CalGray,
|
||||||
|
CalRGB,
|
||||||
|
Lab,
|
||||||
|
ICCBased,
|
||||||
|
Indexed,
|
||||||
|
Separation,
|
||||||
|
DeviceN,
|
||||||
|
Pattern
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns color space identification
|
||||||
|
virtual ColorSpace getColorSpace() const = 0;
|
||||||
|
|
||||||
|
/// Returns true, if this color space can be used for blending
|
||||||
|
bool isBlendColorSpace() const;
|
||||||
|
|
||||||
/// Returns default color for the color space
|
/// Returns default color for the color space
|
||||||
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const = 0;
|
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const = 0;
|
||||||
|
|
||||||
@ -320,6 +371,23 @@ public:
|
|||||||
/// \param ratio Mixing ratio
|
/// \param ratio Mixing ratio
|
||||||
static PDFColor mixColors(const PDFColor& color1, const PDFColor& color2, PDFReal ratio);
|
static PDFColor mixColors(const PDFColor& color1, const PDFColor& color2, PDFReal ratio);
|
||||||
|
|
||||||
|
/// Transforms color from source color space to target color space. Target color space
|
||||||
|
/// must be blend color space.
|
||||||
|
/// \param source Source color space
|
||||||
|
/// \param target Target color space (must be blend color space)
|
||||||
|
/// \param cms Color management system
|
||||||
|
/// \param intent Rendering intent
|
||||||
|
/// \param input Input color buffer
|
||||||
|
/// \param output Output color buffer, must match size of input color buffer
|
||||||
|
/// \param reporter Error reporter
|
||||||
|
static bool transform(const PDFAbstractColorSpace* source,
|
||||||
|
const PDFAbstractColorSpace* target,
|
||||||
|
const PDFCMS* cms,
|
||||||
|
RenderingIntent intent,
|
||||||
|
const PDFColorBuffer input,
|
||||||
|
PDFColorBuffer output,
|
||||||
|
PDFRenderErrorReporter* reporter);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Clips the color component to range [0, 1]
|
/// Clips the color component to range [0, 1]
|
||||||
static constexpr PDFColorComponent clip01(PDFColorComponent component) { return qBound<PDFColorComponent>(0.0, component, 1.0); }
|
static constexpr PDFColorComponent clip01(PDFColorComponent component) { return qBound<PDFColorComponent>(0.0, component, 1.0); }
|
||||||
@ -426,6 +494,7 @@ public:
|
|||||||
explicit PDFDeviceGrayColorSpace() = default;
|
explicit PDFDeviceGrayColorSpace() = default;
|
||||||
virtual ~PDFDeviceGrayColorSpace() = default;
|
virtual ~PDFDeviceGrayColorSpace() = default;
|
||||||
|
|
||||||
|
virtual ColorSpace getColorSpace() const override { return ColorSpace::DeviceGray; }
|
||||||
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||||
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
||||||
virtual size_t getColorComponentCount() const override;
|
virtual size_t getColorComponentCount() const override;
|
||||||
@ -438,6 +507,7 @@ public:
|
|||||||
explicit PDFDeviceRGBColorSpace() = default;
|
explicit PDFDeviceRGBColorSpace() = default;
|
||||||
virtual ~PDFDeviceRGBColorSpace() = default;
|
virtual ~PDFDeviceRGBColorSpace() = default;
|
||||||
|
|
||||||
|
virtual ColorSpace getColorSpace() const override { return ColorSpace::DeviceRGB; }
|
||||||
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||||
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
||||||
virtual size_t getColorComponentCount() const override;
|
virtual size_t getColorComponentCount() const override;
|
||||||
@ -450,6 +520,7 @@ public:
|
|||||||
explicit PDFDeviceCMYKColorSpace() = default;
|
explicit PDFDeviceCMYKColorSpace() = default;
|
||||||
virtual ~PDFDeviceCMYKColorSpace() = default;
|
virtual ~PDFDeviceCMYKColorSpace() = default;
|
||||||
|
|
||||||
|
virtual ColorSpace getColorSpace() const override { return ColorSpace::DeviceCMYK; }
|
||||||
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||||
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
||||||
virtual size_t getColorComponentCount() const override;
|
virtual size_t getColorComponentCount() const override;
|
||||||
@ -461,6 +532,8 @@ class PDFXYZColorSpace : public PDFAbstractColorSpace
|
|||||||
public:
|
public:
|
||||||
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||||
|
|
||||||
|
const PDFColor3& getWhitePoint() const { return m_whitePoint; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit PDFXYZColorSpace(PDFColor3 whitePoint);
|
explicit PDFXYZColorSpace(PDFColor3 whitePoint);
|
||||||
virtual ~PDFXYZColorSpace() = default;
|
virtual ~PDFXYZColorSpace() = default;
|
||||||
@ -480,10 +553,14 @@ public:
|
|||||||
explicit PDFCalGrayColorSpace(PDFColor3 whitePoint, PDFColor3 blackPoint, PDFColorComponent gamma);
|
explicit PDFCalGrayColorSpace(PDFColor3 whitePoint, PDFColor3 blackPoint, PDFColorComponent gamma);
|
||||||
virtual ~PDFCalGrayColorSpace() = default;
|
virtual ~PDFCalGrayColorSpace() = default;
|
||||||
|
|
||||||
|
virtual ColorSpace getColorSpace() const override { return ColorSpace::CalGray; }
|
||||||
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
||||||
virtual size_t getColorComponentCount() const override;
|
virtual size_t getColorComponentCount() const override;
|
||||||
virtual void fillRGBBuffer(const std::vector<float>& colors,unsigned char* outputBuffer, RenderingIntent intent, const PDFCMS* cms, PDFRenderErrorReporter* reporter) const override;
|
virtual void fillRGBBuffer(const std::vector<float>& colors,unsigned char* outputBuffer, RenderingIntent intent, const PDFCMS* cms, PDFRenderErrorReporter* reporter) const override;
|
||||||
|
|
||||||
|
PDFColorComponent getGamma() const { return m_gamma; }
|
||||||
|
PDFColor3 getBlackPoint() const { m_blackPoint; }
|
||||||
|
|
||||||
/// Creates CalGray color space from provided values.
|
/// Creates CalGray color space from provided values.
|
||||||
/// \param document Document
|
/// \param document Document
|
||||||
/// \param dictionary Dictionary
|
/// \param dictionary Dictionary
|
||||||
@ -500,6 +577,7 @@ public:
|
|||||||
explicit PDFCalRGBColorSpace(PDFColor3 whitePoint, PDFColor3 blackPoint, PDFColor3 gamma, PDFColorComponentMatrix_3x3 matrix);
|
explicit PDFCalRGBColorSpace(PDFColor3 whitePoint, PDFColor3 blackPoint, PDFColor3 gamma, PDFColorComponentMatrix_3x3 matrix);
|
||||||
virtual ~PDFCalRGBColorSpace() = default;
|
virtual ~PDFCalRGBColorSpace() = default;
|
||||||
|
|
||||||
|
virtual ColorSpace getColorSpace() const override { return ColorSpace::CalRGB; }
|
||||||
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
||||||
virtual size_t getColorComponentCount() const override;
|
virtual size_t getColorComponentCount() const override;
|
||||||
virtual void fillRGBBuffer(const std::vector<float>& colors,unsigned char* outputBuffer, RenderingIntent intent, const PDFCMS* cms, PDFRenderErrorReporter* reporter) const override;
|
virtual void fillRGBBuffer(const std::vector<float>& colors,unsigned char* outputBuffer, RenderingIntent intent, const PDFCMS* cms, PDFRenderErrorReporter* reporter) const override;
|
||||||
@ -509,6 +587,10 @@ public:
|
|||||||
/// \param dictionary Dictionary
|
/// \param dictionary Dictionary
|
||||||
static PDFColorSpacePointer createCalRGBColorSpace(const PDFDocument* document, const PDFDictionary* dictionary);
|
static PDFColorSpacePointer createCalRGBColorSpace(const PDFDocument* document, const PDFDictionary* dictionary);
|
||||||
|
|
||||||
|
PDFColor3 getBlackPoint() const;
|
||||||
|
PDFColor3 getGamma() const;
|
||||||
|
const PDFColorComponentMatrix_3x3& getMatrix() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PDFColor3 m_blackPoint;
|
PDFColor3 m_blackPoint;
|
||||||
PDFColor3 m_gamma;
|
PDFColor3 m_gamma;
|
||||||
@ -521,6 +603,7 @@ public:
|
|||||||
explicit PDFLabColorSpace(PDFColor3 whitePoint, PDFColor3 blackPoint, PDFColorComponent aMin, PDFColorComponent aMax, PDFColorComponent bMin, PDFColorComponent bMax);
|
explicit PDFLabColorSpace(PDFColor3 whitePoint, PDFColor3 blackPoint, PDFColorComponent aMin, PDFColorComponent aMax, PDFColorComponent bMin, PDFColorComponent bMax);
|
||||||
virtual ~PDFLabColorSpace() = default;
|
virtual ~PDFLabColorSpace() = default;
|
||||||
|
|
||||||
|
virtual ColorSpace getColorSpace() const override { return ColorSpace::Lab; }
|
||||||
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
||||||
virtual size_t getColorComponentCount() const override;
|
virtual size_t getColorComponentCount() const override;
|
||||||
virtual void fillRGBBuffer(const std::vector<float>& colors,unsigned char* outputBuffer, RenderingIntent intent, const PDFCMS* cms, PDFRenderErrorReporter* reporter) const override;
|
virtual void fillRGBBuffer(const std::vector<float>& colors,unsigned char* outputBuffer, RenderingIntent intent, const PDFCMS* cms, PDFRenderErrorReporter* reporter) const override;
|
||||||
@ -530,6 +613,13 @@ public:
|
|||||||
/// \param dictionary Dictionary
|
/// \param dictionary Dictionary
|
||||||
static PDFColorSpacePointer createLabColorSpace(const PDFDocument* document, const PDFDictionary* dictionary);
|
static PDFColorSpacePointer createLabColorSpace(const PDFDocument* document, const PDFDictionary* dictionary);
|
||||||
|
|
||||||
|
PDFColorComponent getAMin() const;
|
||||||
|
PDFColorComponent getAMax() const;
|
||||||
|
PDFColorComponent getBMin() const;
|
||||||
|
PDFColorComponent getBMax() const;
|
||||||
|
|
||||||
|
PDFColor3 getBlackPoint() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PDFColor3 m_blackPoint;
|
PDFColor3 m_blackPoint;
|
||||||
PDFColorComponent m_aMin;
|
PDFColorComponent m_aMin;
|
||||||
@ -547,6 +637,7 @@ public:
|
|||||||
explicit PDFICCBasedColorSpace(PDFColorSpacePointer alternateColorSpace, Ranges range, QByteArray iccProfileData, PDFObjectReference metadata);
|
explicit PDFICCBasedColorSpace(PDFColorSpacePointer alternateColorSpace, Ranges range, QByteArray iccProfileData, PDFObjectReference metadata);
|
||||||
virtual ~PDFICCBasedColorSpace() = default;
|
virtual ~PDFICCBasedColorSpace() = default;
|
||||||
|
|
||||||
|
virtual ColorSpace getColorSpace() const override { return ColorSpace::ICCBased; }
|
||||||
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||||
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
||||||
virtual size_t getColorComponentCount() const override;
|
virtual size_t getColorComponentCount() const override;
|
||||||
@ -566,6 +657,10 @@ public:
|
|||||||
int recursion,
|
int recursion,
|
||||||
std::set<QByteArray>& usedNames);
|
std::set<QByteArray>& usedNames);
|
||||||
|
|
||||||
|
const Ranges& getRange() const;
|
||||||
|
const QByteArray& getIccProfileData() const;
|
||||||
|
const QByteArray& getIccProfileDataChecksum() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PDFColorSpacePointer m_alternateColorSpace;
|
PDFColorSpacePointer m_alternateColorSpace;
|
||||||
Ranges m_range;
|
Ranges m_range;
|
||||||
@ -580,6 +675,7 @@ public:
|
|||||||
explicit PDFIndexedColorSpace(PDFColorSpacePointer baseColorSpace, QByteArray&& colors, int maxValue);
|
explicit PDFIndexedColorSpace(PDFColorSpacePointer baseColorSpace, QByteArray&& colors, int maxValue);
|
||||||
virtual ~PDFIndexedColorSpace() = default;
|
virtual ~PDFIndexedColorSpace() = default;
|
||||||
|
|
||||||
|
virtual ColorSpace getColorSpace() const override { return ColorSpace::Indexed; }
|
||||||
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||||
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
||||||
virtual size_t getColorComponentCount() const override;
|
virtual size_t getColorComponentCount() const override;
|
||||||
@ -601,6 +697,9 @@ public:
|
|||||||
int recursion,
|
int recursion,
|
||||||
std::set<QByteArray>& usedNames);
|
std::set<QByteArray>& usedNames);
|
||||||
|
|
||||||
|
PDFColorSpacePointer getBaseColorSpace() const;
|
||||||
|
std::vector<PDFColorComponent> transformColorsToBaseColorSpace(const PDFColorBuffer buffer) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr const int MIN_VALUE = 0;
|
static constexpr const int MIN_VALUE = 0;
|
||||||
static constexpr const int MAX_VALUE = 255;
|
static constexpr const int MAX_VALUE = 255;
|
||||||
@ -616,6 +715,7 @@ public:
|
|||||||
explicit PDFSeparationColorSpace(QByteArray&& colorName, PDFColorSpacePointer alternateColorSpace, PDFFunctionPtr tintTransform);
|
explicit PDFSeparationColorSpace(QByteArray&& colorName, PDFColorSpacePointer alternateColorSpace, PDFFunctionPtr tintTransform);
|
||||||
virtual ~PDFSeparationColorSpace() = default;
|
virtual ~PDFSeparationColorSpace() = default;
|
||||||
|
|
||||||
|
virtual ColorSpace getColorSpace() const override { return ColorSpace::Separation; }
|
||||||
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||||
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
||||||
virtual size_t getColorComponentCount() const override;
|
virtual size_t getColorComponentCount() const override;
|
||||||
@ -623,6 +723,8 @@ public:
|
|||||||
bool isNone() const { return m_isNone; }
|
bool isNone() const { return m_isNone; }
|
||||||
bool isAll() const { return m_isAll; }
|
bool isAll() const { return m_isAll; }
|
||||||
|
|
||||||
|
std::vector<PDFColorComponent> transformColorsToBaseColorSpace(const PDFColorBuffer buffer) const;
|
||||||
|
|
||||||
/// Creates separation color space from provided values.
|
/// Creates separation color space from provided values.
|
||||||
/// \param colorSpaceDictionary Color space dictionary
|
/// \param colorSpaceDictionary Color space dictionary
|
||||||
/// \param document Document
|
/// \param document Document
|
||||||
@ -635,6 +737,9 @@ public:
|
|||||||
int recursion,
|
int recursion,
|
||||||
std::set<QByteArray>& usedNames);
|
std::set<QByteArray>& usedNames);
|
||||||
|
|
||||||
|
PDFColorSpacePointer getAlternateColorSpace() const;
|
||||||
|
const QByteArray& getColorName() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QByteArray m_colorName;
|
QByteArray m_colorName;
|
||||||
PDFColorSpacePointer m_alternateColorSpace;
|
PDFColorSpacePointer m_alternateColorSpace;
|
||||||
@ -672,6 +777,7 @@ public:
|
|||||||
std::vector<QByteArray> processColorSpaceComponents);
|
std::vector<QByteArray> processColorSpaceComponents);
|
||||||
virtual ~PDFDeviceNColorSpace() = default;
|
virtual ~PDFDeviceNColorSpace() = default;
|
||||||
|
|
||||||
|
virtual ColorSpace getColorSpace() const override { return ColorSpace::DeviceN; }
|
||||||
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||||
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
||||||
virtual size_t getColorComponentCount() const override;
|
virtual size_t getColorComponentCount() const override;
|
||||||
@ -687,6 +793,8 @@ public:
|
|||||||
const std::vector<QByteArray>& getProcessColorSpaceComponents() const { return m_processColorSpaceComponents; }
|
const std::vector<QByteArray>& getProcessColorSpaceComponents() const { return m_processColorSpaceComponents; }
|
||||||
bool isNone() const { return m_isNone; }
|
bool isNone() const { return m_isNone; }
|
||||||
|
|
||||||
|
std::vector<PDFColorComponent> transformColorsToBaseColorSpace(const PDFColorBuffer buffer) const;
|
||||||
|
|
||||||
/// Creates DeviceN color space from provided values.
|
/// Creates DeviceN color space from provided values.
|
||||||
/// \param colorSpaceDictionary Color space dictionary
|
/// \param colorSpaceDictionary Color space dictionary
|
||||||
/// \param document Document
|
/// \param document Document
|
||||||
@ -723,6 +831,7 @@ public:
|
|||||||
|
|
||||||
virtual ~PDFPatternColorSpace() override = default;
|
virtual ~PDFPatternColorSpace() override = default;
|
||||||
|
|
||||||
|
virtual ColorSpace getColorSpace() const override { return ColorSpace::Pattern; }
|
||||||
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
virtual QColor getDefaultColor(const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter) const override;
|
||||||
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
virtual QColor getColor(const PDFColor& color, const PDFCMS* cms, RenderingIntent intent, PDFRenderErrorReporter* reporter, bool isRange01) const override;
|
||||||
virtual size_t getColorComponentCount() const override;
|
virtual size_t getColorComponentCount() const override;
|
||||||
|
29
Pdf4QtLib/sources/pdftransparencyrenderer.cpp
Normal file
29
Pdf4QtLib/sources/pdftransparencyrenderer.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright (C) 2020 Jakub Melka
|
||||||
|
//
|
||||||
|
// This file is part of Pdf4Qt.
|
||||||
|
//
|
||||||
|
// Pdf4Qt is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Pdf4Qt is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with Pdf4Qt. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "pdftransparencyrenderer.h"
|
||||||
|
|
||||||
|
namespace pdf
|
||||||
|
{
|
||||||
|
|
||||||
|
PDFTransparencyRenderer::PDFTransparencyRenderer()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace pdf
|
32
Pdf4QtLib/sources/pdftransparencyrenderer.h
Normal file
32
Pdf4QtLib/sources/pdftransparencyrenderer.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (C) 2020 Jakub Melka
|
||||||
|
//
|
||||||
|
// This file is part of Pdf4Qt.
|
||||||
|
//
|
||||||
|
// Pdf4Qt is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Pdf4Qt is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with Pdf4Qt. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef PDFTRANSPARENCYRENDERER_H
|
||||||
|
#define PDFTRANSPARENCYRENDERER_H
|
||||||
|
|
||||||
|
namespace pdf
|
||||||
|
{
|
||||||
|
|
||||||
|
class PDFTransparencyRenderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PDFTransparencyRenderer();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace pdf
|
||||||
|
|
||||||
|
#endif // PDFTRANSPARENCYRENDERER_H
|
@ -500,6 +500,46 @@ static inline bool isFuzzyComparedPointsSame(const QPointF& p1, const QPointF& p
|
|||||||
return squaredDistance < squaredTolerance;
|
return squaredDistance < squaredTolerance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// View on the array
|
||||||
|
template<typename T>
|
||||||
|
class PDFBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
using value_ptr = value_type*;
|
||||||
|
using const_value_type = const value_type;
|
||||||
|
using const_value_ptr = const_value_type*;
|
||||||
|
|
||||||
|
explicit inline PDFBuffer() :
|
||||||
|
m_begin(nullptr),
|
||||||
|
m_end(nullptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit inline PDFBuffer(value_ptr value, size_t size) :
|
||||||
|
m_begin(value),
|
||||||
|
m_end(value + size)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline value_ptr begin() { return m_begin; }
|
||||||
|
inline value_ptr end() { return m_end; }
|
||||||
|
|
||||||
|
inline const_value_ptr begin() const { return m_begin; }
|
||||||
|
inline const_value_ptr end() const { return m_end; }
|
||||||
|
|
||||||
|
inline const_value_ptr cbegin() const { return m_begin; }
|
||||||
|
inline const_value_ptr cend() const { return m_end; }
|
||||||
|
|
||||||
|
size_t size() const { return m_end - m_begin; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
value_ptr m_begin;
|
||||||
|
value_ptr m_end;
|
||||||
|
};
|
||||||
|
|
||||||
/// Storage for result of some operation. Stores, if operation was successful, or not and
|
/// Storage for result of some operation. Stores, if operation was successful, or not and
|
||||||
/// also error message, why operation has failed. Can be converted explicitly to bool.
|
/// also error message, why operation has failed. Can be converted explicitly to bool.
|
||||||
class PDFOperationResult
|
class PDFOperationResult
|
||||||
|
Loading…
x
Reference in New Issue
Block a user