[poppler] 5 commits - poppler/Gfx.cc poppler/GfxState.cc poppler/GfxState.h poppler/OutputDev.h poppler/PSOutputDev.cc utils/CMakeLists.txt utils/pdftoppm.1 utils/pdftoppm.cc utils/pdftops.1 utils/pdftops.cc utils/sanitychecks.cc utils/sanitychecks.h
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Sat Dec 26 23:46:21 UTC 2020
poppler/Gfx.cc | 12 ++--
poppler/GfxState.cc | 123 ++++++++++++++++++++++++++++++-------------------
poppler/GfxState.h | 36 ++++++++++++++
poppler/OutputDev.h | 34 +++++++++++++
poppler/PSOutputDev.cc | 11 +++-
utils/CMakeLists.txt | 2
utils/pdftoppm.1 | 12 ++++
utils/pdftoppm.cc | 47 ++++++++++++++++--
utils/pdftops.1 | 12 ++++
utils/pdftops.cc | 50 +++++++++++++++++--
utils/sanitychecks.cc | 52 ++++++++++++++++++++
utils/sanitychecks.h | 30 +++++++++++
12 files changed, 358 insertions(+), 63 deletions(-)
New commits:
commit 94fea737473dd513438b7fb89347c6f1273e61b3
Author: Philipp Knechtges <philipp-dev at knechtges.com>
Date: Wed Dec 2 01:04:47 2020 +0100
pdftoppm/pdftops: move shared ICC profile checks to their own file
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
index a5951795..32fbcb48 100644
--- a/utils/CMakeLists.txt
+++ b/utils/CMakeLists.txt
@@ -11,6 +11,7 @@ if (ENABLE_SPLASH)
# pdftoppm
set(pdftoppm_SOURCES ${common_srcs}
pdftoppm.cc
+ sanitychecks.cc
)
add_executable(pdftoppm ${pdftoppm_SOURCES})
target_link_libraries(pdftoppm ${common_libs})
@@ -111,6 +112,7 @@ endif ()
# pdftops
set(pdftops_SOURCES ${common_srcs}
pdftops.cc
+ sanitychecks.cc
)
add_executable(pdftops ${pdftops_SOURCES})
target_link_libraries(pdftops ${common_libs})
diff --git a/utils/pdftoppm.cc b/utils/pdftoppm.cc
index 344c83ec..57bf8614 100644
--- a/utils/pdftoppm.cc
+++ b/utils/pdftoppm.cc
@@ -61,6 +61,7 @@
#include "SplashOutputDev.h"
#include "Win32Console.h"
#include "numberofcharacters.h"
+#include "sanitychecks.h"
// Uncomment to build pdftoppm with pthreads
// You may also have to change the buildsystem to
@@ -546,6 +547,9 @@ int main(int argc, char *argv[])
goto err1;
}
profilecolorspace = cmsGetColorSpace(displayprofile.get());
+ // Note: In contrast to pdftops we do not fail if a non-matching ICC profile is supplied.
+ // Doing so would be pretentious, since SplashOutputDev by default assumes sRGB, even for
+ // the CMYK and Mono cases.
if (jpegcmyk || overprint) {
if (profilecolorspace != cmsSigCmykData) {
fprintf(stderr, "Warning: Supplied ICC profile \"%s\" is not a CMYK profile.\n", displayprofilename.c_str());
@@ -562,52 +566,19 @@ int main(int argc, char *argv[])
}
if (!defaultgrayprofilename.toStr().empty()) {
defaultgrayprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultgrayprofilename.c_str(), "r"));
- if (!defaultgrayprofile) {
- fprintf(stderr, "Could not open the ICC profile \"%s\".\n", defaultgrayprofilename.c_str());
- goto err1;
- }
- if (!cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_INPUT)
- && !cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_SATURATION, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {
- fprintf(stderr, "ICC profile \"%s\" is not an input profile.\n", defaultgrayprofilename.c_str());
- goto err1;
- }
- profilecolorspace = cmsGetColorSpace(defaultgrayprofile.get());
- if (profilecolorspace != cmsSigGrayData) {
- fprintf(stderr, "Supplied ICC profile \"%s\" is not a monochrome profile.\n", defaultgrayprofilename.c_str());
+ if (!checkICCProfile(defaultgrayprofile, defaultgrayprofilename.c_str(), LCMS_USED_AS_INPUT, cmsSigGrayData)) {
goto err1;
}
}
if (!defaultrgbprofilename.toStr().empty()) {
defaultrgbprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultrgbprofilename.c_str(), "r"));
- if (!defaultrgbprofile) {
- fprintf(stderr, "Could not open the ICC profile \"%s\".\n", defaultrgbprofilename.c_str());
- goto err1;
- }
- if (!cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_INPUT)
- && !cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_SATURATION, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {
- fprintf(stderr, "ICC profile \"%s\" is not an input profile.\n", defaultrgbprofilename.c_str());
- goto err1;
- }
- profilecolorspace = cmsGetColorSpace(defaultrgbprofile.get());
- if (profilecolorspace != cmsSigRgbData) {
- fprintf(stderr, "Supplied ICC profile \"%s\" is not a RGB profile.\n", defaultrgbprofilename.c_str());
+ if (!checkICCProfile(defaultrgbprofile, defaultrgbprofilename.c_str(), LCMS_USED_AS_INPUT, cmsSigRgbData)) {
goto err1;
}
}
if (!defaultcmykprofilename.toStr().empty()) {
defaultcmykprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultcmykprofilename.c_str(), "r"));
- if (!defaultcmykprofile) {
- fprintf(stderr, "Could not open the ICC profile \"%s\".\n", defaultcmykprofilename.c_str());
- goto err1;
- }
- if (!cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_INPUT)
- && !cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_SATURATION, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {
- fprintf(stderr, "ICC profile \"%s\" is not an input profile.\n", defaultcmykprofilename.c_str());
- goto err1;
- }
- profilecolorspace = cmsGetColorSpace(defaultcmykprofile.get());
- if (profilecolorspace != cmsSigCmykData) {
- fprintf(stderr, "Supplied ICC profile \"%s\" is not a CMYK profile.\n", defaultcmykprofilename.c_str());
+ if (!checkICCProfile(defaultcmykprofile, defaultcmykprofilename.c_str(), LCMS_USED_AS_INPUT, cmsSigCmykData)) {
goto err1;
}
}
diff --git a/utils/pdftops.cc b/utils/pdftops.cc
index e380726a..597a7937 100644
--- a/utils/pdftops.cc
+++ b/utils/pdftops.cc
@@ -55,6 +55,7 @@
#include "PSOutputDev.h"
#include "Error.h"
#include "Win32Console.h"
+#include "sanitychecks.h"
#ifdef USE_CMS
# include <lcms2.h>
@@ -359,52 +360,19 @@ int main(int argc, char *argv[])
#ifdef USE_CMS
if (!defaultgrayprofilename.toStr().empty()) {
defaultgrayprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultgrayprofilename.c_str(), "r"));
- if (!defaultgrayprofile) {
- fprintf(stderr, "Could not open the ICC profile \"%s\".\n", defaultgrayprofilename.c_str());
- goto err05;
- }
- if (!cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_INPUT)
- && !cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_SATURATION, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {
- fprintf(stderr, "ICC profile \"%s\" is not an input profile.\n", defaultgrayprofilename.c_str());
- goto err05;
- }
- profilecolorspace = cmsGetColorSpace(defaultgrayprofile.get());
- if (profilecolorspace != cmsSigGrayData) {
- fprintf(stderr, "Supplied ICC profile \"%s\" is not a monochrome profile.\n", defaultgrayprofilename.c_str());
+ if (!checkICCProfile(defaultgrayprofile, defaultgrayprofilename.c_str(), LCMS_USED_AS_INPUT, cmsSigGrayData)) {
goto err05;
}
}
if (!defaultrgbprofilename.toStr().empty()) {
defaultrgbprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultrgbprofilename.c_str(), "r"));
- if (!defaultrgbprofile) {
- fprintf(stderr, "Could not open the ICC profile \"%s\".\n", defaultrgbprofilename.c_str());
- goto err05;
- }
- if (!cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_INPUT)
- && !cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_SATURATION, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {
- fprintf(stderr, "ICC profile \"%s\" is not an input profile.\n", defaultrgbprofilename.c_str());
- goto err05;
- }
- profilecolorspace = cmsGetColorSpace(defaultrgbprofile.get());
- if (profilecolorspace != cmsSigRgbData) {
- fprintf(stderr, "Supplied ICC profile \"%s\" is not a RGB profile.\n", defaultrgbprofilename.c_str());
+ if (!checkICCProfile(defaultrgbprofile, defaultrgbprofilename.c_str(), LCMS_USED_AS_INPUT, cmsSigRgbData)) {
goto err05;
}
}
if (!defaultcmykprofilename.toStr().empty()) {
defaultcmykprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultcmykprofilename.c_str(), "r"));
- if (!defaultcmykprofile) {
- fprintf(stderr, "Could not open the ICC profile \"%s\".\n", defaultcmykprofilename.c_str());
- goto err05;
- }
- if (!cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_INPUT)
- && !cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_SATURATION, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {
- fprintf(stderr, "ICC profile \"%s\" is not an input profile.\n", defaultcmykprofilename.c_str());
- goto err05;
- }
- profilecolorspace = cmsGetColorSpace(defaultcmykprofile.get());
- if (profilecolorspace != cmsSigCmykData) {
- fprintf(stderr, "Supplied ICC profile \"%s\" is not a CMYK profile.\n", defaultcmykprofilename.c_str());
+ if (!checkICCProfile(defaultcmykprofile, defaultcmykprofilename.c_str(), LCMS_USED_AS_INPUT, cmsSigCmykData)) {
goto err05;
}
}
diff --git a/utils/sanitychecks.cc b/utils/sanitychecks.cc
new file mode 100644
index 00000000..1bcdeb72
--- /dev/null
+++ b/utils/sanitychecks.cc
@@ -0,0 +1,52 @@
+//========================================================================
+//
+// sanitychecks.cc
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright (C) 2020 Philipp Knechtges <philipp-dev at knechtges.com>
+//
+// To see a description of the changes please see the Changelog file that
+// came with your tarball or type make ChangeLog if you are building from git
+//
+//========================================================================
+
+#include <cstdio>
+#include <cstddef>
+#include <cstring>
+#include <cstdlib>
+#include <cctype>
+#include "sanitychecks.h"
+
+#ifdef USE_CMS
+bool checkICCProfile(const GfxLCMSProfilePtr &profile, const char *filename, cmsUInt32Number UsedDirection, cmsColorSpaceSignature expectedColorSpace)
+{
+ if (!profile) {
+ fprintf(stderr, "Could not open the ICC profile \"%s\".\n", filename);
+ return false;
+ }
+ if (!cmsIsIntentSupported(profile.get(), INTENT_RELATIVE_COLORIMETRIC, UsedDirection) && !cmsIsIntentSupported(profile.get(), INTENT_ABSOLUTE_COLORIMETRIC, UsedDirection)
+ && !cmsIsIntentSupported(profile.get(), INTENT_SATURATION, UsedDirection) && !cmsIsIntentSupported(profile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_OUTPUT)) {
+ if (UsedDirection == LCMS_USED_AS_OUTPUT) {
+ fprintf(stderr, "ICC profile \"%s\" is not an output profile.\n", filename);
+ } else if (UsedDirection == LCMS_USED_AS_INPUT) {
+ fprintf(stderr, "ICC profile \"%s\" is not an input profile.\n", filename);
+ } else {
+ fprintf(stderr, "ICC profile \"%s\" is not suitable.\n", filename);
+ }
+ return false;
+ }
+ auto profilecolorspace = cmsGetColorSpace(profile.get());
+ if (profilecolorspace != expectedColorSpace) {
+ if (expectedColorSpace == cmsSigCmykData) {
+ fprintf(stderr, "Supplied ICC profile \"%s\" is not a CMYK profile.\n", filename);
+ } else if (expectedColorSpace == cmsSigGrayData) {
+ fprintf(stderr, "Supplied ICC profile \"%s\" is not a monochrome profile.\n", filename);
+ } else if (expectedColorSpace == cmsSigRgbData) {
+ fprintf(stderr, "Supplied ICC profile \"%s\" is not a RGB profile.\n", filename);
+ }
+ return false;
+ }
+ return true;
+}
+#endif
diff --git a/utils/sanitychecks.h b/utils/sanitychecks.h
new file mode 100644
index 00000000..d1af2374
--- /dev/null
+++ b/utils/sanitychecks.h
@@ -0,0 +1,30 @@
+//========================================================================
+//
+// sanitychecks.h
+//
+// This file is licensed under the GPLv2 or later
+//
+// Copyright (C) 2020 Philipp Knechtges <philipp-dev at knechtges.com>
+//
+// To see a description of the changes please see the Changelog file that
+// came with your tarball or type make ChangeLog if you are building from git
+//
+//========================================================================
+
+#ifndef SANITYCHECKS_H
+#define SANITYCHECKS_H
+
+#include "config.h"
+
+#ifdef USE_CMS
+# include <lcms2.h>
+# include "GfxState.h"
+
+/*
+ * Check the supplied ICC profile for different criteria
+ */
+bool checkICCProfile(const GfxLCMSProfilePtr &profile, const char *filename, cmsUInt32Number UsedDirection, cmsColorSpaceSignature expectedColorSpace);
+
+#endif
+
+#endif
commit 3ea4508575167ec67583d3ed13efa100b8985b92
Author: Philipp Knechtges <philipp-dev at knechtges.com>
Date: Wed Sep 30 21:40:39 2020 +0200
pdftops: add options to set DeviceGray/DeviceRGB/DeviceCMYK to the CLI
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index e7c0a31b..1b0bb66c 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -3211,6 +3211,9 @@ bool PSOutputDev::checkPageSlice(Page *page, double /*hDPI*/, double /*vDPI*/, i
splashOut->setVectorAntialias(rasterAntialias);
# ifdef USE_CMS
splashOut->setDisplayProfile(getDisplayProfile());
+ splashOut->setDefaultGrayProfile(getDefaultGrayProfile());
+ splashOut->setDefaultRGBProfile(getDefaultRGBProfile());
+ splashOut->setDefaultCMYKProfile(getDefaultCMYKProfile());
# endif
splashOut->startDoc(doc);
diff --git a/utils/pdftops.1 b/utils/pdftops.1
index 00e19856..0ab17cbb 100644
--- a/utils/pdftops.1
+++ b/utils/pdftops.1
@@ -150,6 +150,18 @@ is given then \-processcolorformat is inferred from the specified ICC profile.
.BI \-processcolorprofile " filename"
Sets the ICC profile that is assumed during rasterization and transparency reduction.
.TP
+.BI \-defaultgrayprofile " defaultgrayprofilefile"
+If poppler is compiled with colour management support, this option sets the DefaultGray color space
+to the ICC profile stored in defaultgrayprofilefile.
+.TP
+.BI \-defaultrgbprofile " defaultrgbprofilefile"
+If poppler is compiled with colour management support, this option sets the DefaultRGB color space
+to the ICC profile stored in defaultrgbprofilefile.
+.TP
+.BI \-defaultcmykprofile " defaultcmykprofilefile"
+If poppler is compiled with colour management support, this option sets the DefaultCMYK color space
+to the ICC profile stored in defaultcmykprofilefile.
+.TP
.B \-optimizecolorspace
By default, bitmap images in the PDF pass through to the output PostScript
in their original color space, which produces predictable results.
diff --git a/utils/pdftops.cc b/utils/pdftops.cc
index 5b844444..e380726a 100644
--- a/utils/pdftops.cc
+++ b/utils/pdftops.cc
@@ -131,6 +131,14 @@ static GooString processcolorprofilename;
static GfxLCMSProfilePtr processcolorprofile;
# endif
#endif
+#ifdef USE_CMS
+static GooString defaultgrayprofilename;
+static GfxLCMSProfilePtr defaultgrayprofile;
+static GooString defaultrgbprofilename;
+static GfxLCMSProfilePtr defaultrgbprofile;
+static GooString defaultcmykprofilename;
+static GfxLCMSProfilePtr defaultcmykprofile;
+#endif
static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to print" },
{ "-l", argInt, &lastPage, 0, "last page to print" },
@@ -160,6 +168,11 @@ static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to
# ifdef USE_CMS
{ "-processcolorprofile", argGooString, &processcolorprofilename, 0, "ICC color profile to use as the process color profile during rasterization and transparency reduction" },
# endif
+#endif
+#ifdef USE_CMS
+ { "-defaultgrayprofile", argGooString, &defaultgrayprofilename, 0, "ICC color profile to use as the DefaultGray color space" },
+ { "-defaultrgbprofile", argGooString, &defaultrgbprofilename, 0, "ICC color profile to use as the DefaultRGB color space" },
+ { "-defaultcmykprofile", argGooString, &defaultcmykprofilename, 0, "ICC color profile to use as the DefaultCMYK color space" },
#endif
{ "-optimizecolorspace", argFlag, &optimizeColorSpace, 0, "convert gray RGB images to gray color space" },
{ "-passlevel1customcolor", argFlag, &passLevel1CustomColor, 0, "pass custom color in level1sep" },
@@ -197,7 +210,7 @@ int main(int argc, char *argv[])
bool rasterAntialias = false;
std::vector<int> pages;
#ifdef USE_CMS
- cmsColorSpaceSignature displayprofilecolorspace;
+ cmsColorSpaceSignature profilecolorspace;
#endif
Win32Console win32Console(&argc, &argv);
@@ -303,8 +316,8 @@ int main(int argc, char *argv[])
fprintf(stderr, "Error: ICC profile \"%s\" is not an output profile.\n", processcolorprofilename.c_str());
goto err05;
}
- displayprofilecolorspace = cmsGetColorSpace(processcolorprofile.get());
- if (displayprofilecolorspace == cmsSigCmykData) {
+ profilecolorspace = cmsGetColorSpace(processcolorprofile.get());
+ if (profilecolorspace == cmsSigCmykData) {
if (!processcolorformatspecified) {
processcolorformat = splashModeCMYK8;
processcolorformatspecified = true;
@@ -312,7 +325,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "Error: Supplied ICC profile \"%s\" is a CMYK profile, but process color format is not CMYK8.\n", processcolorprofilename.c_str());
goto err05;
}
- } else if (displayprofilecolorspace == cmsSigGrayData) {
+ } else if (profilecolorspace == cmsSigGrayData) {
if (!processcolorformatspecified) {
processcolorformat = splashModeMono8;
processcolorformatspecified = true;
@@ -320,7 +333,7 @@ int main(int argc, char *argv[])
fprintf(stderr, "Error: Supplied ICC profile \"%s\" is a monochrome profile, but process color format is not monochrome.\n", processcolorprofilename.c_str());
goto err05;
}
- } else if (displayprofilecolorspace == cmsSigRgbData) {
+ } else if (profilecolorspace == cmsSigRgbData) {
if (!processcolorformatspecified) {
processcolorformat = splashModeRGB8;
processcolorformatspecified = true;
@@ -343,6 +356,60 @@ int main(int argc, char *argv[])
}
#endif
+#ifdef USE_CMS
+ if (!defaultgrayprofilename.toStr().empty()) {
+ defaultgrayprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultgrayprofilename.c_str(), "r"));
+ if (!defaultgrayprofile) {
+ fprintf(stderr, "Could not open the ICC profile \"%s\".\n", defaultgrayprofilename.c_str());
+ goto err05;
+ }
+ if (!cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_INPUT)
+ && !cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_SATURATION, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {
+ fprintf(stderr, "ICC profile \"%s\" is not an input profile.\n", defaultgrayprofilename.c_str());
+ goto err05;
+ }
+ profilecolorspace = cmsGetColorSpace(defaultgrayprofile.get());
+ if (profilecolorspace != cmsSigGrayData) {
+ fprintf(stderr, "Supplied ICC profile \"%s\" is not a monochrome profile.\n", defaultgrayprofilename.c_str());
+ goto err05;
+ }
+ }
+ if (!defaultrgbprofilename.toStr().empty()) {
+ defaultrgbprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultrgbprofilename.c_str(), "r"));
+ if (!defaultrgbprofile) {
+ fprintf(stderr, "Could not open the ICC profile \"%s\".\n", defaultrgbprofilename.c_str());
+ goto err05;
+ }
+ if (!cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_INPUT)
+ && !cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_SATURATION, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {
+ fprintf(stderr, "ICC profile \"%s\" is not an input profile.\n", defaultrgbprofilename.c_str());
+ goto err05;
+ }
+ profilecolorspace = cmsGetColorSpace(defaultrgbprofile.get());
+ if (profilecolorspace != cmsSigRgbData) {
+ fprintf(stderr, "Supplied ICC profile \"%s\" is not a RGB profile.\n", defaultrgbprofilename.c_str());
+ goto err05;
+ }
+ }
+ if (!defaultcmykprofilename.toStr().empty()) {
+ defaultcmykprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultcmykprofilename.c_str(), "r"));
+ if (!defaultcmykprofile) {
+ fprintf(stderr, "Could not open the ICC profile \"%s\".\n", defaultcmykprofilename.c_str());
+ goto err05;
+ }
+ if (!cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_INPUT)
+ && !cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_SATURATION, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {
+ fprintf(stderr, "ICC profile \"%s\" is not an input profile.\n", defaultcmykprofilename.c_str());
+ goto err05;
+ }
+ profilecolorspace = cmsGetColorSpace(defaultcmykprofile.get());
+ if (profilecolorspace != cmsSigCmykData) {
+ fprintf(stderr, "Supplied ICC profile \"%s\" is not a CMYK profile.\n", defaultcmykprofilename.c_str());
+ goto err05;
+ }
+ }
+#endif
+
// open PDF file
if (ownerPassword[0] != '\001') {
ownerPW = new GooString(ownerPassword);
@@ -455,6 +522,11 @@ int main(int argc, char *argv[])
# ifdef USE_CMS
psOut->setDisplayProfile(processcolorprofile);
# endif
+#endif
+#ifdef USE_CMS
+ psOut->setDefaultGrayProfile(defaultgrayprofile);
+ psOut->setDefaultRGBProfile(defaultrgbprofile);
+ psOut->setDefaultCMYKProfile(defaultcmykprofile);
#endif
psOut->setEmbedType1(!noEmbedT1Fonts);
psOut->setEmbedTrueType(!noEmbedTTFonts);
commit 66eab5dab46d84b11d3eaa3ee107cb370061e39e
Author: Philipp Knechtges <philipp-dev at knechtges.com>
Date: Wed Sep 30 21:39:19 2020 +0200
PSOutputDev: allow ICCBased color spaces with invalid Ref to be embedded
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 4eeaf7b3..e7c0a31b 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -6592,8 +6592,14 @@ void PSOutputDev::dumpColorSpaceL2(GfxState *state, GfxColorSpace *colorSpace, b
GfxICCBasedColorSpace *iccBasedCS;
iccBasedCS = (GfxICCBasedColorSpace *)colorSpace;
Ref ref = iccBasedCS->getRef();
+ const bool validref = ref != Ref::INVALID();
int intent = state->getCmsRenderingIntent();
- GooString *name = GooString::format("ICCBased-{0:d}-{1:d}-{2:d}", ref.num, ref.gen, intent);
+ GooString *name;
+ if (validref) {
+ name = GooString::format("ICCBased-{0:d}-{1:d}-{2:d}", ref.num, ref.gen, intent);
+ } else {
+ name = GooString::format("ICCBased-hashed-{0:ullX}-{1:d}", std::hash<GfxLCMSProfilePtr> {}(iccBasedCS->getProfile()), intent);
+ }
const auto &it = iccEmitted.find(name->toStr());
if (it != iccEmitted.end()) {
writePSFmt("{0:t}", name);
commit 0d6a3dd991efff3126a1cb9b4de21a2c6db6fb45
Author: Philipp Knechtges <philipp-dev at knechtges.com>
Date: Wed Sep 30 15:47:06 2020 +0200
pdftoppm: add options to set DeviceGray/DeviceRGB/DeviceCMYK to the CLI
diff --git a/utils/pdftoppm.1 b/utils/pdftoppm.1
index 08c3a284..2cd52b19 100644
--- a/utils/pdftoppm.1
+++ b/utils/pdftoppm.1
@@ -98,6 +98,18 @@ Generate a grayscale PGM file (instead of a color PPM file).
If poppler is compiled with colour management support, this option sets the display profile
to the ICC profile stored in displayprofilefile.
.TP
+.BI \-defaultgrayprofile " defaultgrayprofilefile"
+If poppler is compiled with colour management support, this option sets the DefaultGray color space
+to the ICC profile stored in defaultgrayprofilefile.
+.TP
+.BI \-defaultrgbprofile " defaultrgbprofilefile"
+If poppler is compiled with colour management support, this option sets the DefaultRGB color space
+to the ICC profile stored in defaultrgbprofilefile.
+.TP
+.BI \-defaultcmykprofile " defaultcmykprofilefile"
+If poppler is compiled with colour management support, this option sets the DefaultCMYK color space
+to the ICC profile stored in defaultcmykprofilefile.
+.TP
.B \-png
Generates a PNG file instead a PPM file.
.TP
diff --git a/utils/pdftoppm.cc b/utils/pdftoppm.cc
index 4e3f1e67..344c83ec 100644
--- a/utils/pdftoppm.cc
+++ b/utils/pdftoppm.cc
@@ -102,6 +102,12 @@ static bool gray = false;
#ifdef USE_CMS
static GooString displayprofilename;
static GfxLCMSProfilePtr displayprofile;
+static GooString defaultgrayprofilename;
+static GfxLCMSProfilePtr defaultgrayprofile;
+static GooString defaultrgbprofilename;
+static GfxLCMSProfilePtr defaultrgbprofile;
+static GooString defaultcmykprofilename;
+static GfxLCMSProfilePtr defaultcmykprofile;
#endif
static char sep[2] = "-";
static bool forceNum = false;
@@ -158,6 +164,9 @@ static const ArgDesc argDesc[] = { { "-f", argInt, &firstPage, 0, "first page to
{ "-gray", argFlag, &gray, 0, "generate a grayscale PGM file" },
#ifdef USE_CMS
{ "-displayprofile", argGooString, &displayprofilename, 0, "ICC color profile to use as the display profile" },
+ { "-defaultgrayprofile", argGooString, &defaultgrayprofilename, 0, "ICC color profile to use as the DefaultGray color space" },
+ { "-defaultrgbprofile", argGooString, &defaultrgbprofilename, 0, "ICC color profile to use as the DefaultRGB color space" },
+ { "-defaultcmykprofile", argGooString, &defaultcmykprofilename, 0, "ICC color profile to use as the DefaultCMYK color space" },
#endif
{ "-sep", argString, sep, sizeof(sep), "single character separator between name and page number, default - " },
{ "-forcenum", argFlag, &forceNum, 0, "force page number even if there is only one page " },
@@ -353,6 +362,9 @@ static void processPageJobs()
splashOut->setEnableFreeType(enableFreeType);
# ifdef USE_CMS
splashOut->setDisplayProfile(displayprofile);
+ splashOut->setDefaultGrayProfile(defaultgrayprofile);
+ splashOut->setDefaultRGBProfile(defaultrgbprofile);
+ splashOut->setDefaultCMYKProfile(defaultcmykprofile);
# endif
splashOut->startDoc(pageJob.doc);
@@ -383,7 +395,7 @@ int main(int argc, char *argv[])
int pg, pg_num_len;
double pg_w, pg_h;
#ifdef USE_CMS
- cmsColorSpaceSignature displayprofilecolorspace;
+ cmsColorSpaceSignature profilecolorspace;
#endif
Win32Console win32Console(&argc, &argv);
@@ -533,21 +545,72 @@ int main(int argc, char *argv[])
fprintf(stderr, "ICC profile \"%s\" is not an output profile.\n", displayprofilename.c_str());
goto err1;
}
- displayprofilecolorspace = cmsGetColorSpace(displayprofile.get());
+ profilecolorspace = cmsGetColorSpace(displayprofile.get());
if (jpegcmyk || overprint) {
- if (displayprofilecolorspace != cmsSigCmykData) {
+ if (profilecolorspace != cmsSigCmykData) {
fprintf(stderr, "Warning: Supplied ICC profile \"%s\" is not a CMYK profile.\n", displayprofilename.c_str());
}
} else if (mono || gray) {
- if (displayprofilecolorspace != cmsSigGrayData) {
+ if (profilecolorspace != cmsSigGrayData) {
fprintf(stderr, "Warning: Supplied ICC profile \"%s\" is not a monochrome profile.\n", displayprofilename.c_str());
}
} else {
- if (displayprofilecolorspace != cmsSigRgbData) {
+ if (profilecolorspace != cmsSigRgbData) {
fprintf(stderr, "Warning: Supplied ICC profile \"%s\" is not a RGB profile.\n", displayprofilename.c_str());
}
}
}
+ if (!defaultgrayprofilename.toStr().empty()) {
+ defaultgrayprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultgrayprofilename.c_str(), "r"));
+ if (!defaultgrayprofile) {
+ fprintf(stderr, "Could not open the ICC profile \"%s\".\n", defaultgrayprofilename.c_str());
+ goto err1;
+ }
+ if (!cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_INPUT)
+ && !cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_SATURATION, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultgrayprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {
+ fprintf(stderr, "ICC profile \"%s\" is not an input profile.\n", defaultgrayprofilename.c_str());
+ goto err1;
+ }
+ profilecolorspace = cmsGetColorSpace(defaultgrayprofile.get());
+ if (profilecolorspace != cmsSigGrayData) {
+ fprintf(stderr, "Supplied ICC profile \"%s\" is not a monochrome profile.\n", defaultgrayprofilename.c_str());
+ goto err1;
+ }
+ }
+ if (!defaultrgbprofilename.toStr().empty()) {
+ defaultrgbprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultrgbprofilename.c_str(), "r"));
+ if (!defaultrgbprofile) {
+ fprintf(stderr, "Could not open the ICC profile \"%s\".\n", defaultrgbprofilename.c_str());
+ goto err1;
+ }
+ if (!cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_INPUT)
+ && !cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_SATURATION, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultrgbprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {
+ fprintf(stderr, "ICC profile \"%s\" is not an input profile.\n", defaultrgbprofilename.c_str());
+ goto err1;
+ }
+ profilecolorspace = cmsGetColorSpace(defaultrgbprofile.get());
+ if (profilecolorspace != cmsSigRgbData) {
+ fprintf(stderr, "Supplied ICC profile \"%s\" is not a RGB profile.\n", defaultrgbprofilename.c_str());
+ goto err1;
+ }
+ }
+ if (!defaultcmykprofilename.toStr().empty()) {
+ defaultcmykprofile = make_GfxLCMSProfilePtr(cmsOpenProfileFromFile(defaultcmykprofilename.c_str(), "r"));
+ if (!defaultcmykprofile) {
+ fprintf(stderr, "Could not open the ICC profile \"%s\".\n", defaultcmykprofilename.c_str());
+ goto err1;
+ }
+ if (!cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_ABSOLUTE_COLORIMETRIC, LCMS_USED_AS_INPUT)
+ && !cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_SATURATION, LCMS_USED_AS_INPUT) && !cmsIsIntentSupported(defaultcmykprofile.get(), INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {
+ fprintf(stderr, "ICC profile \"%s\" is not an input profile.\n", defaultcmykprofilename.c_str());
+ goto err1;
+ }
+ profilecolorspace = cmsGetColorSpace(defaultcmykprofile.get());
+ if (profilecolorspace != cmsSigCmykData) {
+ fprintf(stderr, "Supplied ICC profile \"%s\" is not a CMYK profile.\n", defaultcmykprofilename.c_str());
+ goto err1;
+ }
+ }
#endif
#ifndef UTILS_USE_PTHREADS
@@ -559,6 +622,9 @@ int main(int argc, char *argv[])
splashOut->setEnableFreeType(enableFreeType);
# ifdef USE_CMS
splashOut->setDisplayProfile(displayprofile);
+ splashOut->setDefaultGrayProfile(defaultgrayprofile);
+ splashOut->setDefaultRGBProfile(defaultrgbprofile);
+ splashOut->setDefaultCMYKProfile(defaultcmykprofile);
# endif
splashOut->startDoc(doc);
commit 1feeda46eb7c02092855c8d609cd493d9cfee18a
Author: Philipp Knechtges <philipp-dev at knechtges.com>
Date: Wed Sep 30 13:56:43 2020 +0200
Introduce options to set fallback DefaultGray/DefaultRGB/DefaultCMYK color spaces to ICC profiles
This will allow for a fully color-managed workflow in cases where the pdf does not specify default
color spaces.
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 746703ab..78adcf79 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -1315,7 +1315,7 @@ void Gfx::opSetFillGray(Object args[], int numArgs)
colorSpace = GfxColorSpace::parse(res, &obj, out, state);
}
if (colorSpace == nullptr) {
- colorSpace = new GfxDeviceGrayColorSpace();
+ colorSpace = state->copyDefaultGrayColorSpace();
}
state->setFillColorSpace(colorSpace);
out->updateFillColorSpace(state);
@@ -1335,7 +1335,7 @@ void Gfx::opSetStrokeGray(Object args[], int numArgs)
colorSpace = GfxColorSpace::parse(res, &obj, out, state);
}
if (colorSpace == nullptr) {
- colorSpace = new GfxDeviceGrayColorSpace();
+ colorSpace = state->copyDefaultGrayColorSpace();
}
state->setStrokeColorSpace(colorSpace);
out->updateStrokeColorSpace(state);
@@ -1355,7 +1355,7 @@ void Gfx::opSetFillCMYKColor(Object args[], int numArgs)
colorSpace = GfxColorSpace::parse(res, &obj, out, state);
}
if (colorSpace == nullptr) {
- colorSpace = new GfxDeviceCMYKColorSpace();
+ colorSpace = state->copyDefaultCMYKColorSpace();
}
state->setFillPattern(nullptr);
state->setFillColorSpace(colorSpace);
@@ -1379,7 +1379,7 @@ void Gfx::opSetStrokeCMYKColor(Object args[], int numArgs)
colorSpace = GfxColorSpace::parse(res, &obj, out, state);
}
if (colorSpace == nullptr) {
- colorSpace = new GfxDeviceCMYKColorSpace();
+ colorSpace = state->copyDefaultCMYKColorSpace();
}
state->setStrokeColorSpace(colorSpace);
out->updateStrokeColorSpace(state);
@@ -1402,7 +1402,7 @@ void Gfx::opSetFillRGBColor(Object args[], int numArgs)
colorSpace = GfxColorSpace::parse(res, &obj, out, state);
}
if (colorSpace == nullptr) {
- colorSpace = new GfxDeviceRGBColorSpace();
+ colorSpace = state->copyDefaultRGBColorSpace();
}
state->setFillColorSpace(colorSpace);
out->updateFillColorSpace(state);
@@ -1425,7 +1425,7 @@ void Gfx::opSetStrokeRGBColor(Object args[], int numArgs)
colorSpace = GfxColorSpace::parse(res, &obj, out, state);
}
if (colorSpace == nullptr) {
- colorSpace = new GfxDeviceRGBColorSpace();
+ colorSpace = state->copyDefaultRGBColorSpace();
}
state->setStrokeColorSpace(colorSpace);
out->updateStrokeColorSpace(state);
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index da040dd0..cffa7c43 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -234,34 +234,34 @@ GfxColorSpace *GfxColorSpace::parse(GfxResources *res, Object *csObj, OutputDev
if (res != nullptr) {
Object objCS = res->lookupColorSpace("DefaultGray");
if (objCS.isNull()) {
- cs = new GfxDeviceGrayColorSpace();
+ cs = state->copyDefaultGrayColorSpace();
} else {
cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
}
} else {
- cs = new GfxDeviceGrayColorSpace();
+ cs = state->copyDefaultGrayColorSpace();
}
} else if (csObj->isName("DeviceRGB") || csObj->isName("RGB")) {
if (res != nullptr) {
Object objCS = res->lookupColorSpace("DefaultRGB");
if (objCS.isNull()) {
- cs = new GfxDeviceRGBColorSpace();
+ cs = state->copyDefaultRGBColorSpace();
} else {
cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
}
} else {
- cs = new GfxDeviceRGBColorSpace();
+ cs = state->copyDefaultRGBColorSpace();
}
} else if (csObj->isName("DeviceCMYK") || csObj->isName("CMYK")) {
if (res != nullptr) {
Object objCS = res->lookupColorSpace("DefaultCMYK");
if (objCS.isNull()) {
- cs = new GfxDeviceCMYKColorSpace();
+ cs = state->copyDefaultCMYKColorSpace();
} else {
cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
}
} else {
- cs = new GfxDeviceCMYKColorSpace();
+ cs = state->copyDefaultCMYKColorSpace();
}
} else if (csObj->isName("Pattern")) {
cs = new GfxPatternColorSpace(nullptr);
@@ -274,34 +274,34 @@ GfxColorSpace *GfxColorSpace::parse(GfxResources *res, Object *csObj, OutputDev
if (res != nullptr) {
Object objCS = res->lookupColorSpace("DefaultGray");
if (objCS.isNull()) {
- cs = new GfxDeviceGrayColorSpace();
+ cs = state->copyDefaultGrayColorSpace();
} else {
cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
}
} else {
- cs = new GfxDeviceGrayColorSpace();
+ cs = state->copyDefaultGrayColorSpace();
}
} else if (obj1.isName("DeviceRGB") || obj1.isName("RGB")) {
if (res != nullptr) {
Object objCS = res->lookupColorSpace("DefaultRGB");
if (objCS.isNull()) {
- cs = new GfxDeviceRGBColorSpace();
+ cs = state->copyDefaultRGBColorSpace();
} else {
cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
}
} else {
- cs = new GfxDeviceRGBColorSpace();
+ cs = state->copyDefaultRGBColorSpace();
}
} else if (obj1.isName("DeviceCMYK") || obj1.isName("CMYK")) {
if (res != nullptr) {
Object objCS = res->lookupColorSpace("DefaultCMYK");
if (objCS.isNull()) {
- cs = new GfxDeviceCMYKColorSpace();
+ cs = state->copyDefaultCMYKColorSpace();
} else {
cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
}
} else {
- cs = new GfxDeviceCMYKColorSpace();
+ cs = state->copyDefaultCMYKColorSpace();
}
} else if (obj1.isName("CalGray")) {
cs = GfxCalGrayColorSpace::parse(csObj->getArray(), state);
@@ -328,34 +328,34 @@ GfxColorSpace *GfxColorSpace::parse(GfxResources *res, Object *csObj, OutputDev
if (res != nullptr) {
Object objCS = res->lookupColorSpace("DefaultGray");
if (objCS.isNull()) {
- cs = new GfxDeviceGrayColorSpace();
+ cs = state->copyDefaultGrayColorSpace();
} else {
cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
}
} else {
- cs = new GfxDeviceGrayColorSpace();
+ cs = state->copyDefaultGrayColorSpace();
}
} else if (obj1.isName("DeviceRGB")) {
if (res != nullptr) {
Object objCS = res->lookupColorSpace("DefaultRGB");
if (objCS.isNull()) {
- cs = new GfxDeviceRGBColorSpace();
+ cs = state->copyDefaultRGBColorSpace();
} else {
cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
}
} else {
- cs = new GfxDeviceRGBColorSpace();
+ cs = state->copyDefaultRGBColorSpace();
}
} else if (obj1.isName("DeviceCMYK")) {
if (res != nullptr) {
Object objCS = res->lookupColorSpace("DefaultCMYK");
if (objCS.isNull()) {
- cs = new GfxDeviceCMYKColorSpace();
+ cs = state->copyDefaultCMYKColorSpace();
} else {
cs = GfxColorSpace::parse(nullptr, &objCS, out, state);
}
} else {
- cs = new GfxDeviceCMYKColorSpace();
+ cs = state->copyDefaultCMYKColorSpace();
}
} else {
error(errSyntaxWarning, -1, "Bad color space dict'");
@@ -1724,34 +1724,7 @@ 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() : nullptr;
- if (!dhp) {
- dhp = GfxState::sRGBProfile;
- }
- unsigned int cst = getCMSColorSpaceType(cmsGetColorSpace(hp.get()));
- unsigned int dNChannels = getCMSNChannels(cmsGetColorSpace(dhp.get()));
- unsigned int dcst = getCMSColorSpaceType(cmsGetColorSpace(dhp.get()));
- cmsHTRANSFORM transform;
-
- int cmsIntent = INTENT_RELATIVE_COLORIMETRIC;
- if (state != nullptr) {
- cmsIntent = state->getCmsRenderingIntent();
- }
- if ((transform = cmsCreateTransform(hp.get(), COLORSPACE_SH(cst) | CHANNELS_SH(nCompsA) | BYTES_SH(1), dhp.get(), COLORSPACE_SH(dcst) | CHANNELS_SH(dNChannels) | BYTES_SH(1), cmsIntent, LCMS_FLAGS)) == nullptr) {
- error(errSyntaxWarning, -1, "Can't create transform");
- cs->transform = nullptr;
- } else {
- 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
- if ((transform = cmsCreateTransform(hp.get(), CHANNELS_SH(nCompsA) | BYTES_SH(1), dhp.get(), (dcst == PT_RGB) ? TYPE_RGB_8 : TYPE_CMYK_8, cmsIntent, LCMS_FLAGS)) == nullptr) {
- error(errSyntaxWarning, -1, "Can't create transform");
- cs->lineTransform = nullptr;
- } else {
- cs->lineTransform = std::make_shared<GfxColorTransform>(transform, cmsIntent, cst, dcst);
- }
- }
+ cs->buildTransforms(state);
}
// put this colorSpace into cache
if (out && iccProfileStreamA != Ref::INVALID()) {
@@ -1761,6 +1734,40 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, OutputDev *out, GfxState
return cs;
}
+#ifdef USE_CMS
+void GfxICCBasedColorSpace::buildTransforms(GfxState *state)
+{
+ auto dhp = (state != nullptr && state->getDisplayProfile() != nullptr) ? state->getDisplayProfile() : nullptr;
+ if (!dhp) {
+ dhp = GfxState::sRGBProfile;
+ }
+ unsigned int cst = getCMSColorSpaceType(cmsGetColorSpace(profile.get()));
+ unsigned int dNChannels = getCMSNChannels(cmsGetColorSpace(dhp.get()));
+ unsigned int dcst = getCMSColorSpaceType(cmsGetColorSpace(dhp.get()));
+ cmsHTRANSFORM transformA;
+
+ int cmsIntent = INTENT_RELATIVE_COLORIMETRIC;
+ if (state != nullptr) {
+ cmsIntent = state->getCmsRenderingIntent();
+ }
+ if ((transformA = cmsCreateTransform(profile.get(), COLORSPACE_SH(cst) | CHANNELS_SH(nComps) | BYTES_SH(1), dhp.get(), COLORSPACE_SH(dcst) | CHANNELS_SH(dNChannels) | BYTES_SH(1), cmsIntent, LCMS_FLAGS)) == nullptr) {
+ error(errSyntaxWarning, -1, "Can't create transform");
+ transform = nullptr;
+ } else {
+ transform = std::make_shared<GfxColorTransform>(transformA, cmsIntent, cst, dcst);
+ }
+ if (dcst == PT_RGB || dcst == PT_CMYK) {
+ // create line transform only when the display is RGB type color space
+ if ((transformA = cmsCreateTransform(profile.get(), CHANNELS_SH(nComps) | BYTES_SH(1), dhp.get(), (dcst == PT_RGB) ? TYPE_RGB_8 : TYPE_CMYK_8, cmsIntent, LCMS_FLAGS)) == nullptr) {
+ error(errSyntaxWarning, -1, "Can't create transform");
+ lineTransform = nullptr;
+ } else {
+ lineTransform = std::make_shared<GfxColorTransform>(transformA, cmsIntent, cst, dcst);
+ }
+ }
+}
+#endif
+
void GfxICCBasedColorSpace::getGray(const GfxColor *color, GfxGray *gray) const
{
#ifdef USE_CMS
@@ -6280,6 +6287,10 @@ GfxState::GfxState(double hDPIA, double vDPIA, const PDFRectangle *pageBox, int
renderingIntent[0] = 0;
saved = nullptr;
+
+ defaultGrayColorSpace = nullptr;
+ defaultRGBColorSpace = nullptr;
+ defaultCMYKColorSpace = nullptr;
#ifdef USE_CMS
XYZ2DisplayTransformRelCol = nullptr;
XYZ2DisplayTransformAbsCol = nullptr;
@@ -6329,6 +6340,10 @@ GfxState::~GfxState()
if (font) {
font->decRefCnt();
}
+
+ delete defaultGrayColorSpace;
+ delete defaultRGBColorSpace;
+ delete defaultCMYKColorSpace;
}
// Used for copy();
@@ -6429,6 +6444,22 @@ GfxState::GfxState(const GfxState *state, bool copyPath)
XYZ2DisplayTransformSat = state->XYZ2DisplayTransformSat;
XYZ2DisplayTransformPerc = state->XYZ2DisplayTransformPerc;
#endif
+
+ if (state->defaultGrayColorSpace) {
+ defaultGrayColorSpace = state->defaultGrayColorSpace->copy();
+ } else {
+ defaultGrayColorSpace = nullptr;
+ }
+ if (state->defaultRGBColorSpace) {
+ defaultRGBColorSpace = state->defaultRGBColorSpace->copy();
+ } else {
+ defaultRGBColorSpace = nullptr;
+ }
+ if (state->defaultCMYKColorSpace) {
+ defaultCMYKColorSpace = state->defaultCMYKColorSpace->copy();
+ } else {
+ defaultCMYKColorSpace = nullptr;
+ }
}
#ifdef USE_CMS
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 0eb4a9c3..f607dade 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -585,6 +585,8 @@ public:
Ref getRef() { return iccProfileStream; }
#ifdef USE_CMS
char *getPostScriptCSA();
+ void buildTransforms(GfxState *state);
+ void setProfile(GfxLCMSProfilePtr &profileA) { profile = profileA; }
GfxLCMSProfilePtr getProfile() { return profile; }
#endif
@@ -1599,6 +1601,36 @@ public:
static GfxLCMSProfilePtr sRGBProfile;
#endif
+ void setDefaultGrayColorSpace(GfxColorSpace *cs) { defaultGrayColorSpace = cs; }
+
+ void setDefaultRGBColorSpace(GfxColorSpace *cs) { defaultRGBColorSpace = cs; }
+
+ void setDefaultCMYKColorSpace(GfxColorSpace *cs) { defaultCMYKColorSpace = cs; }
+
+ GfxColorSpace *copyDefaultGrayColorSpace()
+ {
+ if (defaultGrayColorSpace) {
+ return defaultGrayColorSpace->copy();
+ }
+ return new GfxDeviceGrayColorSpace();
+ }
+
+ GfxColorSpace *copyDefaultRGBColorSpace()
+ {
+ if (defaultRGBColorSpace) {
+ return defaultRGBColorSpace->copy();
+ }
+ return new GfxDeviceRGBColorSpace();
+ }
+
+ GfxColorSpace *copyDefaultCMYKColorSpace()
+ {
+ if (defaultCMYKColorSpace) {
+ return defaultCMYKColorSpace->copy();
+ }
+ return new GfxDeviceCMYKColorSpace();
+ }
+
// Add to path.
void moveTo(double x, double y) { path->moveTo(curX = x, curY = y); }
void lineTo(double x, double y) { path->lineTo(curX = x, curY = y); }
@@ -1708,6 +1740,10 @@ private:
std::shared_ptr<GfxColorTransform> XYZ2DisplayTransformPerc;
static GfxLCMSProfilePtr XYZProfile;
#endif
+
+ GfxColorSpace *defaultGrayColorSpace;
+ GfxColorSpace *defaultRGBColorSpace;
+ GfxColorSpace *defaultCMYKColorSpace;
};
#endif
diff --git a/poppler/OutputDev.h b/poppler/OutputDev.h
index d2a8e3c8..1802894b 100644
--- a/poppler/OutputDev.h
+++ b/poppler/OutputDev.h
@@ -138,6 +138,31 @@ public:
{
#ifdef USE_CMS
state->setDisplayProfile(displayprofile);
+
+ auto invalidref = Ref::INVALID();
+ if (defaultGrayProfile) {
+ auto cs = new GfxICCBasedColorSpace(1, new GfxDeviceGrayColorSpace(), &invalidref);
+
+ cs->setProfile(defaultGrayProfile);
+ cs->buildTransforms(state); // needs to happen after state->setDisplayProfile has been called
+ state->setDefaultGrayColorSpace(cs);
+ }
+
+ if (defaultRGBProfile) {
+ auto cs = new GfxICCBasedColorSpace(3, new GfxDeviceRGBColorSpace(), &invalidref);
+
+ cs->setProfile(defaultRGBProfile);
+ cs->buildTransforms(state); // needs to happen after state->setDisplayProfile has been called
+ state->setDefaultRGBColorSpace(cs);
+ }
+
+ if (defaultCMYKProfile) {
+ auto cs = new GfxICCBasedColorSpace(4, new GfxDeviceCMYKColorSpace(), &invalidref);
+
+ cs->setProfile(defaultCMYKProfile);
+ cs->buildTransforms(state); // needs to happen after state->setDisplayProfile has been called
+ state->setDefaultCMYKColorSpace(cs);
+ }
#endif
}
@@ -324,6 +349,12 @@ public:
#ifdef USE_CMS
void setDisplayProfile(const GfxLCMSProfilePtr &profile) { displayprofile = profile; }
GfxLCMSProfilePtr getDisplayProfile() const { return displayprofile; }
+ void setDefaultGrayProfile(const GfxLCMSProfilePtr &profile) { defaultGrayProfile = profile; }
+ GfxLCMSProfilePtr getDefaultGrayProfile() const { return defaultGrayProfile; }
+ void setDefaultRGBProfile(const GfxLCMSProfilePtr &profile) { defaultRGBProfile = profile; }
+ GfxLCMSProfilePtr getDefaultRGBProfile() const { return defaultRGBProfile; }
+ void setDefaultCMYKProfile(const GfxLCMSProfilePtr &profile) { defaultCMYKProfile = profile; }
+ GfxLCMSProfilePtr getDefaultCMYKProfile() const { return defaultCMYKProfile; }
PopplerCache<Ref, GfxICCBasedColorSpace> *getIccColorSpaceCache() { return &iccColorSpaceCache; }
#endif
@@ -335,6 +366,9 @@ private:
#ifdef USE_CMS
GfxLCMSProfilePtr displayprofile;
+ GfxLCMSProfilePtr defaultGrayProfile;
+ GfxLCMSProfilePtr defaultRGBProfile;
+ GfxLCMSProfilePtr defaultCMYKProfile;
PopplerCache<Ref, GfxICCBasedColorSpace> iccColorSpaceCache;
#endif
More information about the poppler
mailing list