[prev in list] [next in list] [prev in thread] [next in thread]
List: freedesktop-poppler
Subject: [poppler] 4 commits - poppler/Gfx.cc poppler/GfxState.cc poppler/GfxState.h poppler/OutputDev.h popp
From: GitLab Mirror <gitlab-mirror () kemper ! freedesktop ! org>
Date: 2020-06-02 22:08:13
Message-ID: 20200602220813.B977C7610B () kemper ! freedesktop ! org
[Download RAW message or body]
poppler/Gfx.cc | 1
poppler/GfxState.cc | 255 +++++++++++---------------------------------
poppler/GfxState.h | 18 +--
poppler/OutputDev.h | 26 ++--
poppler/Page.cc | 27 ++--
qt5/src/CMakeLists.txt | 3
qt5/src/poppler-document.cc | 23 ++-
qt5/src/poppler-page.cc | 8 +
qt5/src/poppler-private.h | 4
utils/pdftocairo.cc | 4
10 files changed, 134 insertions(+), 235 deletions(-)
New commits:
commit 7257d33a3a938d5621aab0ed53b09c7ce797a646
Author: Philipp Knechtges <philipp-dev@knechtges.com>
Date: Fri May 22 18:23:09 2020 +0200
add a dummy GfxState to Page::loadThumb for proper color space handling
As far as I can tell this was the only remaining spot in the code where
GfxColorSpace::parse was called without a properly initialized GfxState.
diff --git a/poppler/Page.cc b/poppler/Page.cc
index 670768ab..2ac178d7 100644
--- a/poppler/Page.cc
+++ b/poppler/Page.cc
@@ -643,7 +643,6 @@ bool Page::loadThumb(unsigned char **data_out,
Object obj1;
Dict *dict;
GfxColorSpace *colorSpace;
- bool success = false;
Stream *str;
GfxImageColorMap *colorMap;
@@ -658,17 +657,17 @@ bool Page::loadThumb(unsigned char **data_out,
str = fetched_thumb.getStream();
if (!dict->lookupInt("Width", "W", &width))
- goto fail1;
+ return false;
if (!dict->lookupInt("Height", "H", &height))
- goto fail1;
+ return false;
if (!dict->lookupInt("BitsPerComponent", "BPC", &bits))
- goto fail1;
+ return false;
/* Check for invalid dimensions and integer overflow. */
if (width <= 0 || height <= 0)
- goto fail1;
+ return false;
if (width > INT_MAX / 3 / height)
- goto fail1;
+ return false;
pixbufdatasize = width * height * 3;
/* Get color space */
@@ -676,10 +675,14 @@ bool Page::loadThumb(unsigned char **data_out,
if (obj1.isNull ()) {
obj1 = dict->lookup ("CS");
}
- colorSpace = GfxColorSpace::parse(nullptr, &obj1, nullptr, nullptr);
+ // Just initialize some dummy GfxState for GfxColorSpace::parse.
+ // This will set a sRGB profile for ICC-based colorspaces.
+ auto pdfrectangle = std::make_shared<PDFRectangle>();
+ auto state = std::make_shared<GfxState>(72.0,72.0,pdfrectangle.get(), 0, false);
+ colorSpace = GfxColorSpace::parse(nullptr, &obj1, nullptr, state.get());
if (!colorSpace) {
fprintf (stderr, "Error: Cannot parse color space\n");
- goto fail1;
+ return false;
}
obj1 = dict->lookup("Decode");
@@ -690,7 +693,7 @@ bool Page::loadThumb(unsigned char **data_out,
if (!colorMap->isOk()) {
fprintf (stderr, "Error: invalid colormap\n");
delete colorMap;
- goto fail1;
+ return false;
}
if (data_out) {
@@ -718,8 +721,6 @@ bool Page::loadThumb(unsigned char **data_out,
delete imgstr;
}
- success = true;
-
if (width_out)
*width_out = width;
if (height_out)
@@ -728,8 +729,8 @@ bool Page::loadThumb(unsigned char **data_out,
*rowstride_out = width * 3;
delete colorMap;
- fail1:
- return success;
+
+ return true;
}
void Page::makeBox(double hDPI, double vDPI, int rotate,
commit b2141b8921525141560b8e4ef5a351f505d7cf5b
Author: Philipp Knechtges <philipp-dev@knechtges.com>
Date: Fri May 22 18:17:16 2020 +0200
cleanup displayprofile initialization
There were a bunch of global variables that were used to initilize the first \
version of the display profiles. This code was removed, and all the static \
initilization was moved from GfxColorSpace to GfxState. Furthermore, for most \
"users" the setting of the display profile was moved from the static \
GfxColorSpace::setDisplayProfile function to the OutputDev class. The latter is now \
invoked early in the initilization of Gfx to set the initial state in the GfxState \
instance.
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 2a5b295c..37a8996a 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -548,6 +548,7 @@ Gfx::Gfx(PDFDoc *docA, OutputDev *outA, int pageNum, Dict \
*resDict, // initialize
out = outA;
state = new GfxState(hDPI, vDPI, box, rotate, out->upsideDown());
+ out->initGfxState(state);
stackHeight = 1;
pushStateGuard();
fontChanged = false;
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 51922565..e8091681 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -189,9 +189,6 @@ static const std::map<unsigned int, unsigned int>::size_type \
CMSCACHE_LIMIT = 20 #include <lcms2.h>
#define LCMS_FLAGS cmsFLAGS_NOOPTIMIZE | cmsFLAGS_BLACKPOINTCOMPENSATION
-#define COLOR_PROFILE_DIR "/ColorProfiles/"
-#define GLOBAL_COLOR_PROFILE_DIR POPPLER_DATADIR COLOR_PROFILE_DIR
-
static void lcmsprofiledeleter(void* profile)
{
cmsCloseProfile(profile);
@@ -221,59 +218,9 @@ GfxColorTransform::~GfxColorTransform() {
cmsDeleteTransform(transform);
}
-static GfxLCMSProfilePtr RGBProfile = nullptr;
-static GooString *displayProfileName = nullptr; // display profile file Name
-static GfxLCMSProfilePtr displayProfile = nullptr; // display profile
-static unsigned int displayPixelType = 0;
-static std::shared_ptr<GfxColorTransform> XYZ2DisplayTransform = nullptr;
-
// convert color space signature to cmsColor type
static unsigned int getCMSColorSpaceType(cmsColorSpaceSignature cs);
static unsigned int getCMSNChannels(cmsColorSpaceSignature cs);
-static GfxLCMSProfilePtr loadColorProfile(const char *fileName);
-
-void GfxColorSpace::setDisplayProfile(const GfxLCMSProfilePtr& displayProfileA) {
- if (displayProfile) {
- error(errInternal, -1, "The display color profile can only be set once before \
any rendering is done.");
- return;
- }
- displayProfile = displayProfileA;
- if (displayProfile) {
- cmsHTRANSFORM transform;
- unsigned int nChannels;
-
- displayPixelType = getCMSColorSpaceType(cmsGetColorSpace(displayProfile.get()));
- nChannels = getCMSNChannels(cmsGetColorSpace(displayProfile.get()));
- // create transform from XYZ
- auto XYZProfile = make_GfxLCMSProfilePtr(cmsCreateXYZProfile());
- if ((transform = cmsCreateTransform(XYZProfile.get(), TYPE_XYZ_DBL,
- displayProfile.get(),
- COLORSPACE_SH(displayPixelType) |
- CHANNELS_SH(nChannels) | BYTES_SH(1),
- INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
- error(errSyntaxWarning, -1, "Can't create Lab transform");
- } else {
- XYZ2DisplayTransform = std::make_shared<GfxColorTransform>(transform, \
INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, displayPixelType);
- }
- }
-}
-
-void GfxColorSpace::setDisplayProfileName(GooString *name) {
- if (displayProfile != nullptr) {
- error(errInternal, -1, "The display color profile can only be set before any \
rendering is done.");
- return;
- }
- delete displayProfileName;
- displayProfileName = name->copy();
-}
-
-GfxLCMSProfilePtr GfxColorSpace::getRGBProfile() {
- return RGBProfile;
-}
-
-GfxLCMSProfilePtr GfxColorSpace::getDisplayProfile() {
- return displayProfile;
-}
#endif
@@ -459,83 +406,12 @@ const char *GfxColorSpace::getColorSpaceModeName(int idx) {
}
#ifdef USE_CMS
-GfxLCMSProfilePtr loadColorProfile(const char *fileName)
-{
- cmsHPROFILE hp = nullptr;
- FILE *fp;
-
- if (fileName[0] == '/') {
- // full path
- // check if open the file
- if ((fp = openFile(fileName,"r")) != nullptr) {
- fclose(fp);
- hp = cmsOpenProfileFromFile(fileName,"r");
- }
- return make_GfxLCMSProfilePtr(hp);
- }
- // try to load from global directory
- GooString *path = new GooString(GLOBAL_COLOR_PROFILE_DIR);
- path->append(fileName);
- // check if open the file
- if ((fp = openFile(path->c_str(),"r")) != nullptr) {
- fclose(fp);
- hp = cmsOpenProfileFromFile(path->c_str(),"r");
- }
- delete path;
- return make_GfxLCMSProfilePtr(hp);
-}
static void CMSError(cmsContext /*contextId*/, cmsUInt32Number /*ecode*/, const char \
*text) {
error(errSyntaxWarning, -1, "{0:s}", text);
}
-int GfxColorSpace::setupColorProfiles()
-{
- static bool initialized = false;
- cmsHTRANSFORM transform;
- unsigned int nChannels;
-
- // do only once
- if (initialized) return 0;
- initialized = true;
-
- // set error handlor
- cmsSetLogErrorHandler(CMSError);
-
- if (!displayProfile) {
- // load display profile if it was not already loaded.
- if (displayProfileName == nullptr) {
- displayProfile = loadColorProfile("display.icc");
- } else if (displayProfileName->getLength() > 0) {
- displayProfile = loadColorProfile(displayProfileName->c_str());
- }
- }
- // load RGB profile
- RGBProfile = loadColorProfile("RGB.icc");
- if (!RGBProfile) {
- /* use built in sRGB profile */
- RGBProfile = make_GfxLCMSProfilePtr(cmsCreate_sRGBProfile());
- }
- // create transforms
- if (displayProfile) {
- displayPixelType = getCMSColorSpaceType(cmsGetColorSpace(displayProfile.get()));
- nChannels = getCMSNChannels(cmsGetColorSpace(displayProfile.get()));
- // create transform from XYZ
- auto XYZProfile = make_GfxLCMSProfilePtr(cmsCreateXYZProfile());
- if ((transform = cmsCreateTransform(XYZProfile.get(), TYPE_XYZ_DBL,
- displayProfile.get(),
- COLORSPACE_SH(displayPixelType) |
- CHANNELS_SH(nChannels) | BYTES_SH(1),
- INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
- error(errSyntaxWarning, -1, "Can't create Lab transform");
- } else {
- XYZ2DisplayTransform = std::make_shared<GfxColorTransform>(transform, \
INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, displayPixelType);
- }
- }
- return 0;
-}
-
unsigned int getCMSColorSpaceType(cmsColorSpaceSignature cs)
{
switch (cs) {
@@ -815,7 +691,7 @@ GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr, GfxState \
*state) { xyzrgb[2][1] * cs->whiteY +
xyzrgb[2][2] * cs->whiteZ);
#ifdef USE_CMS
- cs->transform = (state != nullptr) ? state->getXYZ2DisplayTransform() : \
XYZ2DisplayTransform; + cs->transform = (state != nullptr) ? \
state->getXYZ2DisplayTransform() : nullptr; #endif
return cs;
}
@@ -1175,7 +1051,7 @@ GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr, GfxState \
*state) { xyzrgb[2][2] * cs->whiteZ);
#ifdef USE_CMS
- cs->transform = (state != nullptr) ? state->getXYZ2DisplayTransform() : \
XYZ2DisplayTransform; + cs->transform = (state != nullptr) ? \
state->getXYZ2DisplayTransform() : nullptr; #endif
return cs;
}
@@ -1521,7 +1397,7 @@ GfxColorSpace *GfxLabColorSpace::parse(Array *arr, GfxState \
*state) { xyzrgb[2][2] * cs->whiteZ);
#ifdef USE_CMS
- cs->transform = (state != nullptr) ? state->getXYZ2DisplayTransform() : \
XYZ2DisplayTransform; + cs->transform = (state != nullptr) ? \
state->getXYZ2DisplayTransform() : nullptr; #endif
return cs;
}
@@ -1838,12 +1714,9 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, \
OutputDev *out, GfxState if (!hp) {
error(errSyntaxWarning, -1, "read ICCBased color space profile error");
} else {
- auto dhp = (state != nullptr && state->getDisplayProfile() != nullptr) ? \
state->getDisplayProfile() : displayProfile; + auto dhp = (state != nullptr && \
state->getDisplayProfile() != nullptr) ? state->getDisplayProfile() : nullptr; if \
(!dhp) {
- if (unlikely(!RGBProfile)) {
- GfxColorSpace::setupColorProfiles();
- }
- dhp = RGBProfile;
+ dhp = GfxState::sRGBProfile;
}
unsigned int cst = getCMSColorSpaceType(cmsGetColorSpace(hp.get()));
unsigned int dNChannels = getCMSNChannels(cmsGetColorSpace(dhp.get()));
@@ -6461,12 +6334,22 @@ GfxState::GfxState(double hDPIA, double vDPIA, const \
PDFRectangle *pageBox,
saved = nullptr;
#ifdef USE_CMS
- GfxColorSpace::setupColorProfiles();
XYZ2DisplayTransformRelCol = nullptr;
XYZ2DisplayTransformAbsCol = nullptr;
XYZ2DisplayTransformSat = nullptr;
XYZ2DisplayTransformPerc = nullptr;
localDisplayProfile = nullptr;
+
+ if (!sRGBProfile) {
+ // This is probably the one of the first invocations of lcms2, so we set the \
error handler + cmsSetLogErrorHandler(CMSError);
+
+ sRGBProfile = make_GfxLCMSProfilePtr(cmsCreate_sRGBProfile());
+ }
+
+ if (!XYZProfile) {
+ XYZProfile = make_GfxLCMSProfilePtr(cmsCreateXYZProfile());
+ }
#endif
}
@@ -6600,6 +6483,10 @@ GfxState::GfxState(const GfxState *state, bool copyPath) {
}
#ifdef USE_CMS
+
+GfxLCMSProfilePtr GfxState::sRGBProfile = nullptr;
+GfxLCMSProfilePtr GfxState::XYZProfile = nullptr;
+
void GfxState::setDisplayProfile(const GfxLCMSProfilePtr& localDisplayProfileA) {
localDisplayProfile = localDisplayProfileA;
if (localDisplayProfile) {
@@ -6610,7 +6497,6 @@ void GfxState::setDisplayProfile(const GfxLCMSProfilePtr& \
localDisplayProfileA)
localDisplayPixelType = \
getCMSColorSpaceType(cmsGetColorSpace(localDisplayProfile.get()));
nChannels = getCMSNChannels(cmsGetColorSpace(localDisplayProfile.get()));
// create transform from XYZ
- auto XYZProfile = make_GfxLCMSProfilePtr(cmsCreateXYZProfile());
if ((transform = cmsCreateTransform(XYZProfile.get(), TYPE_XYZ_DBL,
localDisplayProfile.get(),
COLORSPACE_SH(localDisplayPixelType) |
@@ -6662,9 +6548,6 @@ std::shared_ptr<GfxColorTransform> \
GfxState::getXYZ2DisplayTransform() { } else if (strcmp(renderingIntent, \
"Perceptual") == 0) { transform = XYZ2DisplayTransformPerc;
}
- if (!transform) {
- transform = XYZ2DisplayTransform;
- }
return transform;
}
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index be5bb7df..c30c1a99 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -283,13 +283,6 @@ public:
// Return the name of the <idx>th color space mode.
static const char *getColorSpaceModeName(int idx);
-#ifdef USE_CMS
- static int setupColorProfiles();
- static void setDisplayProfile(const GfxLCMSProfilePtr& displayProfileA);
- static void setDisplayProfileName(GooString *name);
- static GfxLCMSProfilePtr getRGBProfile();
- static GfxLCMSProfilePtr getDisplayProfile();
-#endif
protected:
unsigned int overprintMask;
@@ -1608,6 +1601,7 @@ public:
GfxLCMSProfilePtr getDisplayProfile() { return localDisplayProfile; }
std::shared_ptr<GfxColorTransform> getXYZ2DisplayTransform();
int getCmsRenderingIntent();
+ static GfxLCMSProfilePtr sRGBProfile;
#endif
// Add to path.
@@ -1709,6 +1703,7 @@ private:
std::shared_ptr<GfxColorTransform> XYZ2DisplayTransformAbsCol;
std::shared_ptr<GfxColorTransform> XYZ2DisplayTransformSat;
std::shared_ptr<GfxColorTransform> XYZ2DisplayTransformPerc;
+ static GfxLCMSProfilePtr XYZProfile;
#endif
};
diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h
index 9dc052ae..609fa8d5 100644
--- a/poppler/OutputDev.h
+++ b/poppler/OutputDev.h
@@ -40,6 +40,7 @@
#include "Object.h"
#include "PopplerCache.h"
#include "ProfileData.h"
+#include "GfxState.h"
#include <memory>
#include <unordered_map>
#include <string>
@@ -47,21 +48,7 @@
class Annot;
class Dict;
class GooString;
-class GfxState;
class Gfx;
-struct GfxColor;
-class GfxColorSpace;
-#ifdef USE_CMS
-class GfxICCBasedColorSpace;
-#endif
-class GfxImageColorMap;
-class GfxFunctionShading;
-class GfxAxialShading;
-class GfxGouraudTriangleShading;
-class GfxPatchMeshShading;
-class GfxRadialShading;
-class GfxGouraudTriangleShading;
-class GfxPatchMeshShading;
class Stream;
class Links;
class AnnotLink;
@@ -150,6 +137,13 @@ public:
// Dump page contents to display.
virtual void dump() {}
+ virtual void initGfxState (GfxState* state)
+ {
+#ifdef USE_CMS
+ state->setDisplayProfile(displayprofile);
+#endif
+ }
+
//----- coordinate conversion
// Convert between device and user coordinates.
@@ -370,6 +364,8 @@ public:
#endif
#ifdef USE_CMS
+ void setDisplayProfile(const GfxLCMSProfilePtr& profile) { displayprofile = \
profile; } +
PopplerCache<Ref, GfxICCBasedColorSpace> *getIccColorSpaceCache() { return \
&iccColorSpaceCache; } #endif
@@ -380,6 +376,8 @@ private:
std::unique_ptr<std::unordered_map<std::string, ProfileData>> profileHash;
#ifdef USE_CMS
+ GfxLCMSProfilePtr displayprofile;
+
PopplerCache<Ref, GfxICCBasedColorSpace> iccColorSpaceCache;
#endif
};
diff --git a/qt5/src/CMakeLists.txt b/qt5/src/CMakeLists.txt
index e75b5730..bbcd612d 100644
--- a/qt5/src/CMakeLists.txt
+++ b/qt5/src/CMakeLists.txt
@@ -52,6 +52,9 @@ endif()
if (ENABLE_NSS3)
target_include_directories(poppler-qt5 SYSTEM PRIVATE ${NSS3_INCLUDE_DIRS})
endif()
+if(USE_CMS)
+ target_link_libraries(poppler-qt5 poppler ${LCMS2_LIBRARIES})
+endif()
install(TARGETS poppler-qt5 RUNTIME DESTINATION bin LIBRARY DESTINATION \
${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES
diff --git a/qt5/src/poppler-document.cc b/qt5/src/poppler-document.cc
index a40d4bac..cc6f01ad 100644
--- a/qt5/src/poppler-document.cc
+++ b/qt5/src/poppler-document.cc
@@ -649,7 +649,16 @@ namespace Poppler {
void Document::setColorDisplayProfile(void* outputProfileA)
{
#if defined(USE_CMS)
- GfxColorSpace::setDisplayProfile(make_GfxLCMSProfilePtr(outputProfileA));
+ if (m_doc->m_sRGBProfile && m_doc->m_sRGBProfile.get() == outputProfileA) {
+ // Catch the special case that the user passes the sRGB profile
+ m_doc->m_displayProfile = m_doc->m_sRGBProfile;
+ return;
+ }
+ if (m_doc->m_displayProfile && m_doc->m_displayProfile.get() == \
outputProfileA) { + // Catch the special case that the user passes the \
display profile + return;
+ }
+ m_doc->m_displayProfile = make_GfxLCMSProfilePtr(outputProfileA);
#else
Q_UNUSED(outputProfileA);
#endif
@@ -658,9 +667,8 @@ namespace Poppler {
void Document::setColorDisplayProfileName(const QString &name)
{
#if defined(USE_CMS)
- GooString *profileName = QStringToGooString( name );
- GfxColorSpace::setDisplayProfileName(profileName);
- delete profileName;
+ void* rawprofile = \
cmsOpenProfileFromFile(name.toLocal8Bit().constData(),"r"); + \
m_doc->m_displayProfile = make_GfxLCMSProfilePtr(rawprofile); #else
Q_UNUSED(name);
#endif
@@ -669,7 +677,10 @@ namespace Poppler {
void* Document::colorRgbProfile() const
{
#if defined(USE_CMS)
- return GfxColorSpace::getRGBProfile().get();
+ if (!m_doc->m_sRGBProfile) {
+ m_doc->m_sRGBProfile = make_GfxLCMSProfilePtr(cmsCreate_sRGBProfile());
+ }
+ return m_doc->m_sRGBProfile.get();
#else
return nullptr;
#endif
@@ -678,7 +689,7 @@ namespace Poppler {
void* Document::colorDisplayProfile() const
{
#if defined(USE_CMS)
- return GfxColorSpace::getDisplayProfile().get();
+ return m_doc->m_displayProfile.get();
#else
return nullptr;
#endif
diff --git a/qt5/src/poppler-page.cc b/qt5/src/poppler-page.cc
index dab4bc43..e06e88bf 100644
--- a/qt5/src/poppler-page.cc
+++ b/qt5/src/poppler-page.cc
@@ -592,6 +592,10 @@ QImage Page::renderToImage(double xres, double yres, int xPos, \
int yPos, int w,
splash_output.setFreeTypeHinting(m_page->parentDoc->m_hints & \
Document::TextHinting ? true : false,
m_page->parentDoc->m_hints & \
Document::TextSlightHinting ? true : false);
+#ifdef USE_CMS
+ splash_output.setDisplayProfile(m_page->parentDoc->m_displayProfile);
+#endif
+
splash_output.startDoc(m_page->parentDoc->doc);
const bool hideAnnotations = m_page->parentDoc->m_hints & \
Document::HideAnnotations; @@ -624,6 +628,10 @@ QImage Page::renderToImage(double \
xres, double yres, int xPos, int yPos, int w,
arthur_output.setHintingPreference(QFontHintingFromPopplerHinting(m_page->parentDoc->m_hints));
+#ifdef USE_CMS
+ arthur_output.setDisplayProfile(m_page->parentDoc->m_displayProfile);
+#endif
+
arthur_output.setCallbacks(partialUpdateCallback, \
shouldDoPartialUpdateCallback, shouldAbortRenderCallback, payload);
renderToArthur(&arthur_output, &painter, m_page, xres, yres, xPos, yPos, w, h, \
rotate, DontSaveAndRestore); painter.end();
diff --git a/qt5/src/poppler-private.h b/qt5/src/poppler-private.h
index 1ccea2b9..899b4850 100644
--- a/qt5/src/poppler-private.h
+++ b/qt5/src/poppler-private.h
@@ -178,6 +178,10 @@ namespace Poppler {
QPointer<OptContentModel> m_optContentModel;
QColor paperColor;
int m_hints;
+#ifdef USE_CMS
+ GfxLCMSProfilePtr m_sRGBProfile;
+ GfxLCMSProfilePtr m_displayProfile;
+#endif
};
class FontInfoData
diff --git a/utils/pdftocairo.cc b/utils/pdftocairo.cc
index 4f51d427..a6d9384f 100644
--- a/utils/pdftocairo.cc
+++ b/utils/pdftocairo.cc
@@ -1137,7 +1137,6 @@ int main(int argc, char *argv[]) {
} else {
profile = make_GfxLCMSProfilePtr(cmsCreate_sRGBProfile());
}
- GfxColorSpace::setDisplayProfile(profile);
#endif
doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW);
@@ -1212,6 +1211,9 @@ int main(int argc, char *argv[]) {
cairoOut = new CairoOutputDev();
+#ifdef USE_CMS
+ cairoOut->setDisplayProfile(profile);
+#endif
cairoOut->startDoc(doc);
if (sz != 0)
crop_w = crop_h = sz;
commit 7dc4f0b56057aa4facc7ba559998d6dac5042792
Author: Philipp Knechtges <philipp-dev@knechtges.com>
Date: Fri May 22 11:47:54 2020 +0200
remove sourceProfile variable from GfxColorTransform
The sourceProfile variable was initially introduced in commit \
1f698b44564b0313c019557616866eae11bf2cc9 for the Postscript CSA generation code. \
With the last commit this code has been moved to GfxICCBasedColorSpace anyway, so \
there is no use anymore for storing the profile in GfxColorTransform.
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 2fb78c1c..51922565 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -210,8 +210,7 @@ void GfxColorTransform::doTransform(void *in, void *out, unsigned \
int size) { }
// transformA should be a cmsHTRANSFORM
-GfxColorTransform::GfxColorTransform(const GfxLCMSProfilePtr& sourceProfileA, void \
*transformA, int cmsIntentA, unsigned int inputPixelTypeA, unsigned int \
transformPixelTypeA) {
- sourceProfile = sourceProfileA;
+GfxColorTransform::GfxColorTransform(void *transformA, int cmsIntentA, unsigned int \
inputPixelTypeA, unsigned int transformPixelTypeA) { transform = transformA;
cmsIntent = cmsIntentA;
inputPixelType = inputPixelTypeA;
@@ -254,7 +253,7 @@ void GfxColorSpace::setDisplayProfile(const GfxLCMSProfilePtr& \
displayProfileA) INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
error(errSyntaxWarning, -1, "Can't create Lab transform");
} else {
- XYZ2DisplayTransform = std::make_shared<GfxColorTransform>(displayProfile, \
transform, INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, displayPixelType); + \
XYZ2DisplayTransform = std::make_shared<GfxColorTransform>(transform, \
INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, displayPixelType); }
}
}
@@ -531,7 +530,7 @@ int GfxColorSpace::setupColorProfiles()
INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
error(errSyntaxWarning, -1, "Can't create Lab transform");
} else {
- XYZ2DisplayTransform = std::make_shared<GfxColorTransform>(XYZProfile, \
transform, INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, displayPixelType); + \
XYZ2DisplayTransform = std::make_shared<GfxColorTransform>(transform, \
INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, displayPixelType); }
}
return 0;
@@ -1864,7 +1863,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, \
OutputDev *out, GfxState error(errSyntaxWarning, -1, "Can't create transform");
cs->transform = nullptr;
} else {
- cs->transform = std::make_shared<GfxColorTransform>(hp, transform, cmsIntent, \
cst, dcst); + cs->transform = std::make_shared<GfxColorTransform>(transform, \
cmsIntent, cst, dcst); }
if (dcst == PT_RGB || dcst == PT_CMYK) {
// create line transform only when the display is RGB type color space
@@ -1874,7 +1873,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, \
OutputDev *out, GfxState error(errSyntaxWarning, -1, "Can't create transform");
cs->lineTransform = nullptr;
} else {
- cs->lineTransform = std::make_shared<GfxColorTransform>(hp, transform, cmsIntent, \
cst, dcst); + cs->lineTransform = std::make_shared<GfxColorTransform>(transform, \
cmsIntent, cst, dcst); }
}
}
@@ -6619,7 +6618,7 @@ void GfxState::setDisplayProfile(const GfxLCMSProfilePtr& \
localDisplayProfileA) INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
error(errSyntaxWarning, -1, "Can't create Lab transform");
} else {
- XYZ2DisplayTransformRelCol = std::make_shared<GfxColorTransform>(XYZProfile, \
transform, INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, localDisplayPixelType); + \
XYZ2DisplayTransformRelCol = std::make_shared<GfxColorTransform>(transform, \
INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, localDisplayPixelType); }
if ((transform = cmsCreateTransform(XYZProfile.get(), TYPE_XYZ_DBL,
@@ -6629,7 +6628,7 @@ void GfxState::setDisplayProfile(const GfxLCMSProfilePtr& \
localDisplayProfileA) INTENT_ABSOLUTE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
error(errSyntaxWarning, -1, "Can't create Lab transform");
} else {
- XYZ2DisplayTransformAbsCol = std::make_shared<GfxColorTransform>(XYZProfile, \
transform, INTENT_ABSOLUTE_COLORIMETRIC, PT_XYZ, localDisplayPixelType); + \
XYZ2DisplayTransformAbsCol = std::make_shared<GfxColorTransform>(transform, \
INTENT_ABSOLUTE_COLORIMETRIC, PT_XYZ, localDisplayPixelType); }
if ((transform = cmsCreateTransform(XYZProfile.get(), TYPE_XYZ_DBL,
@@ -6639,7 +6638,7 @@ void GfxState::setDisplayProfile(const GfxLCMSProfilePtr& \
localDisplayProfileA) INTENT_SATURATION,LCMS_FLAGS)) == nullptr) {
error(errSyntaxWarning, -1, "Can't create Lab transform");
} else {
- XYZ2DisplayTransformSat = std::make_shared<GfxColorTransform>(XYZProfile, \
transform, INTENT_SATURATION, PT_XYZ, localDisplayPixelType); + \
XYZ2DisplayTransformSat = std::make_shared<GfxColorTransform>(transform, \
INTENT_SATURATION, PT_XYZ, localDisplayPixelType); }
if ((transform = cmsCreateTransform(XYZProfile.get(), TYPE_XYZ_DBL,
@@ -6649,7 +6648,7 @@ void GfxState::setDisplayProfile(const GfxLCMSProfilePtr& \
localDisplayProfileA) INTENT_PERCEPTUAL,LCMS_FLAGS)) == nullptr) {
error(errSyntaxWarning, -1, "Can't create Lab transform");
} else {
- XYZ2DisplayTransformPerc = std::make_shared<GfxColorTransform>(XYZProfile, \
transform, INTENT_PERCEPTUAL, PT_XYZ, localDisplayPixelType); + \
XYZ2DisplayTransformPerc = std::make_shared<GfxColorTransform>(transform, \
INTENT_PERCEPTUAL, PT_XYZ, localDisplayPixelType); }
}
}
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index f79c6bc7..be5bb7df 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -204,7 +204,7 @@ class GfxColorTransform {
public:
void doTransform(void *in, void *out, unsigned int size);
// transformA should be a cmsHTRANSFORM
- GfxColorTransform(const GfxLCMSProfilePtr& sourceProfileA, void *transformA, int \
cmsIntent, + GfxColorTransform(void *transformA, int cmsIntent,
unsigned int inputPixelType, unsigned int transformPixelType);
~GfxColorTransform();
GfxColorTransform(const GfxColorTransform &) = delete;
@@ -212,10 +212,8 @@ public:
int getIntent() const { return cmsIntent; }
int getInputPixelType() const { return inputPixelType; }
int getTransformPixelType() const { return transformPixelType; }
- GfxLCMSProfilePtr getSourceProfile() { return sourceProfile; }
private:
GfxColorTransform() {}
- GfxLCMSProfilePtr sourceProfile;
void *transform;
int cmsIntent;
unsigned int inputPixelType;
commit 344f3e655cb0018421350c1a9916381d686025b6
Author: Philipp Knechtges <philipp-dev@knechtges.com>
Date: Fri May 22 11:39:28 2020 +0200
move Postscript CSA generation from GfxColorTransform to GfxICCBasedColorSpace
With proper ref counting for profiles in place, we can now let \
GfxICCBasedColorSpace directly generate the CSA rather than going through \
GfxColorTransform, which in the pre-ref-counting era had the sole ownership on the \
profiles.
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index fb8cb37a..2fb78c1c 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -216,51 +216,10 @@ GfxColorTransform::GfxColorTransform(const GfxLCMSProfilePtr& \
sourceProfileA, vo cmsIntent = cmsIntentA;
inputPixelType = inputPixelTypeA;
transformPixelType = transformPixelTypeA;
- psCSA = nullptr;
}
GfxColorTransform::~GfxColorTransform() {
cmsDeleteTransform(transform);
- if (psCSA)
- gfree(psCSA);
-}
-
-char *GfxColorTransform::getPostScriptCSA()
-{
-#if LCMS_VERSION>=2070
- // The runtime version check of lcms2 is only available from release 2.7 upwards.
- // The generation of the CSA code only works reliably for version 2.10 and \
upwards.
- // Cf. the explanation in the corresponding lcms2 merge request [1], and the \
original mail thread [2].
- // [1] https://github.com/mm2/Little-CMS/pull/214
- // [2] https://sourceforge.net/p/lcms/mailman/message/33182987/
- if (cmsGetEncodedCMMversion() < 2100)
- return nullptr;
-
- int size;
-
- if (psCSA)
- return psCSA;
-
- if (!sourceProfile) {
- error(errSyntaxWarning, -1, "profile is nullptr");
- return nullptr;
- }
-
- void *rawprofile = sourceProfile.get();
- size = cmsGetPostScriptCSA(cmsGetProfileContextID(rawprofile), rawprofile, \
cmsIntent, 0, nullptr, 0);
- if (size == 0) {
- error(errSyntaxWarning, -1, "PostScript CSA is nullptr");
- return nullptr;
- }
-
- psCSA = (char*)gmalloc(size+1);
- cmsGetPostScriptCSA(cmsGetProfileContextID(rawprofile), rawprofile, cmsIntent, 0, \
psCSA, size);
- psCSA[size] = 0;
-
- return psCSA;
-#else
- return nullptr;
-#endif
}
static GfxLCMSProfilePtr RGBProfile = nullptr;
@@ -1758,11 +1717,16 @@ GfxICCBasedColorSpace::GfxICCBasedColorSpace(int nCompsA, \
GfxColorSpace *altA, #ifdef USE_CMS
transform = nullptr;
lineTransform = nullptr;
+ psCSA = nullptr;
#endif
}
GfxICCBasedColorSpace::~GfxICCBasedColorSpace() {
delete alt;
+#ifdef USE_CMS
+ if (psCSA)
+ gfree(psCSA);
+#endif
}
GfxColorSpace *GfxICCBasedColorSpace::copy() const {
@@ -1870,6 +1834,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, \
OutputDev *out, GfxState
profBuf = iccStream->toUnsignedChars(&length, 65536, 65536);
auto hp = make_GfxLCMSProfilePtr(cmsOpenProfileFromMem(profBuf,length));
+ cs->profile = hp;
gfree(profBuf);
if (!hp) {
error(errSyntaxWarning, -1, "read ICCBased color space profile error");
@@ -2366,10 +2331,40 @@ void GfxICCBasedColorSpace::getDefaultRanges(double \
*decodeLow, #ifdef USE_CMS
char *GfxICCBasedColorSpace::getPostScriptCSA()
{
- if (transform)
- return transform->getPostScriptCSA();
- else
+#if LCMS_VERSION>=2070
+ // The runtime version check of lcms2 is only available from release 2.7 upwards.
+ // The generation of the CSA code only works reliably for version 2.10 and \
upwards. + // Cf. the explanation in the corresponding lcms2 merge request [1], and \
the original mail thread [2]. + // [1] https://github.com/mm2/Little-CMS/pull/214
+ // [2] https://sourceforge.net/p/lcms/mailman/message/33182987/
+ if (cmsGetEncodedCMMversion() < 2100)
return nullptr;
+
+ int size;
+
+ if (psCSA)
+ return psCSA;
+
+ if (!profile) {
+ error(errSyntaxWarning, -1, "profile is nullptr");
+ return nullptr;
+ }
+
+ void *rawprofile = profile.get();
+ size = cmsGetPostScriptCSA(cmsGetProfileContextID(rawprofile), rawprofile, \
getIntent(), 0, nullptr, 0); + if (size == 0) {
+ error(errSyntaxWarning, -1, "PostScript CSA is nullptr");
+ return nullptr;
+ }
+
+ psCSA = (char*)gmalloc(size+1);
+ cmsGetPostScriptCSA(cmsGetProfileContextID(rawprofile), rawprofile, getIntent(), \
0, psCSA, size); + psCSA[size] = 0;
+
+ return psCSA;
+#else
+ return nullptr;
+#endif
}
#endif
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 1a673b20..f79c6bc7 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -213,7 +213,6 @@ public:
int getInputPixelType() const { return inputPixelType; }
int getTransformPixelType() const { return transformPixelType; }
GfxLCMSProfilePtr getSourceProfile() { return sourceProfile; }
- char *getPostScriptCSA();
private:
GfxColorTransform() {}
GfxLCMSProfilePtr sourceProfile;
@@ -221,7 +220,6 @@ private:
int cmsIntent;
unsigned int inputPixelType;
unsigned int transformPixelType;
- char *psCSA;
};
class GfxColorSpace {
@@ -582,6 +580,7 @@ public:
Ref getRef() { return iccProfileStream; }
#ifdef USE_CMS
char *getPostScriptCSA();
+ GfxLCMSProfilePtr getProfile() { return profile; }
#endif
private:
@@ -592,6 +591,8 @@ private:
double rangeMax[4]; // max values for each component
Ref iccProfileStream; // the ICC profile
#ifdef USE_CMS
+ GfxLCMSProfilePtr profile;
+ char* psCSA;
int getIntent() { return (transform != nullptr) ? transform->getIntent() : 0; }
std::shared_ptr<GfxColorTransform> transform;
std::shared_ptr<GfxColorTransform> lineTransform; // color transform for line
_______________________________________________
poppler mailing list
poppler@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/poppler
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic