[poppler] 4 commits - poppler/GfxState.cc poppler/GfxState.h poppler/PSOutputDev.cc poppler/PSOutputDev.h
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu May 21 09:04:23 UTC 2020
poppler/GfxState.cc | 136 +++++++++++++++++++++++++++++++++++--------------
poppler/GfxState.h | 16 +++++
poppler/PSOutputDev.cc | 77 ++++++++++++++++++++-------
poppler/PSOutputDev.h | 8 +-
4 files changed, 174 insertions(+), 63 deletions(-)
New commits:
commit cc0f7960fd9dc4cfda8dc15cb061f891e909b386
Author: Philipp Knechtges <philipp-dev at knechtges.com>
Date: Sun May 17 21:00:26 2020 +0200
only activate CSA support for the most recent lcms2 version
Add a runtime check.
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 339614b2..105ef1dc 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -224,6 +224,15 @@ unsigned int GfxColorTransform::unref() {
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)
@@ -245,6 +254,9 @@ char *GfxColorTransform::getPostScriptCSA()
psCSA[size] = 0;
return psCSA;
+#else
+ return nullptr;
+#endif
}
static cmsHPROFILE RGBProfile = nullptr;
commit 2334bea5208d0506e4eee02ed170abd7e73e2fe4
Author: Philipp Knechtges <philipp-dev at knechtges.com>
Date: Sun May 17 09:11:01 2020 +0200
make the clang/clazy/Ubuntu/Android pipelines happy
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index f5f11c13..339614b2 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -203,7 +203,7 @@ GfxColorTransform::GfxColorTransform(void *sourceProfileA, void *transformA, int
cmsIntent = cmsIntentA;
inputPixelType = inputPixelTypeA;
transformPixelType = transformPixelTypeA;
- psCSA = NULL;
+ psCSA = nullptr;
}
GfxColorTransform::~GfxColorTransform() {
@@ -229,15 +229,15 @@ char *GfxColorTransform::getPostScriptCSA()
if (psCSA)
return psCSA;
- if (sourceProfile == NULL) {
- error(errSyntaxWarning, -1, "profile is NULL");
- return NULL;
+ if (sourceProfile == nullptr) {
+ error(errSyntaxWarning, -1, "profile is nullptr");
+ return nullptr;
}
- size = cmsGetPostScriptCSA(cmsGetProfileContextID(sourceProfile), sourceProfile, cmsIntent, 0, NULL, 0);
+ size = cmsGetPostScriptCSA(cmsGetProfileContextID(sourceProfile), sourceProfile, cmsIntent, 0, nullptr, 0);
if (size == 0) {
- error(errSyntaxWarning, -1, "PostScript CSA is NULL");
- return NULL;
+ error(errSyntaxWarning, -1, "PostScript CSA is nullptr");
+ return nullptr;
}
psCSA = (char*)gmalloc(size+1);
@@ -1809,9 +1809,9 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, OutputDev *out, GfxState
error(errSyntaxError, -1, "Bad ICCBased color space");
return nullptr;
}
-#ifdef USE_CMS
const Object &obj1Ref = arr->getNF(1);
const Ref iccProfileStreamA = obj1Ref.isRef() ? obj1Ref.getRef() : Ref::INVALID();
+#ifdef USE_CMS
// check cache
if (out && iccProfileStreamA != Ref::INVALID()) {
if (auto *item = out->getIccColorSpaceCache()->lookup(iccProfileStreamA)) {
@@ -1925,7 +1925,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, OutputDev *out, GfxState
error(errSyntaxWarning, -1, "Can't create transform");
cs->lineTransform = nullptr;
} else {
- cs->lineTransform = new GfxColorTransform(NULL, transform, cmsIntent, cst, dcst);
+ cs->lineTransform = new GfxColorTransform(nullptr, transform, cmsIntent, cst, dcst);
}
}
if (cs->transform == nullptr) {
@@ -2388,7 +2388,7 @@ char *GfxICCBasedColorSpace::getPostScriptCSA()
if (transform)
return transform->getPostScriptCSA();
else
- return NULL;
+ return nullptr;
}
#endif
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 3da66e8c..e07cd2a8 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -545,7 +545,7 @@ public:
GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA,
const Ref *iccProfileStreamA);
- ~GfxICCBasedColorSpace();
+ ~GfxICCBasedColorSpace() override;
GfxColorSpace *copy() const override;
GfxColorSpaceMode getMode() const override { return csICCBased; }
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 9a920fbb..f2df0d66 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -6808,7 +6808,7 @@ void PSOutputDev::dumpColorSpaceL2(GfxState *state, GfxColorSpace *colorSpace,
break;
case csICCBased:
-#if USE_CMS
+#ifdef USE_CMS
{
GfxICCBasedColorSpace *iccBasedCS;
iccBasedCS = (GfxICCBasedColorSpace *)colorSpace;
commit 1f698b44564b0313c019557616866eae11bf2cc9
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sat May 16 22:08:32 2020 +0200
Use ICC profiles in PS output
When printing PDFs that use ICC based colors, Poppler always uses the alternate color space
in the PostScript output (usually DeviceRGB or DeviceCMYK). The attached patch will use the
ICC profile color space in the PS output. Most of the patch is modifying GfxColorTransform
and callers to store the source profile as well as the transform. The GfxICCBasedColorSpace
class has a new method, getPostScriptCSA(), which uses the LCMS function cmsGetPostScriptCSA()
to generate the CIEBased color space dictionary equivalent to the ICC profile.
Based on patch from issue #125.
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 7141c9f8..f5f11c13 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -196,16 +196,22 @@ void GfxColorTransform::doTransform(void *in, void *out, unsigned int size) {
}
// transformA should be a cmsHTRANSFORM
-GfxColorTransform::GfxColorTransform(void *transformA, int cmsIntentA, unsigned int inputPixelTypeA, unsigned int transformPixelTypeA) {
+GfxColorTransform::GfxColorTransform(void *sourceProfileA, void *transformA, int cmsIntentA, unsigned int inputPixelTypeA, unsigned int transformPixelTypeA) {
+ sourceProfile = sourceProfileA;
transform = transformA;
refCount = 1;
cmsIntent = cmsIntentA;
inputPixelType = inputPixelTypeA;
transformPixelType = transformPixelTypeA;
+ psCSA = NULL;
}
GfxColorTransform::~GfxColorTransform() {
+ if (sourceProfile)
+ cmsCloseProfile(sourceProfile);
cmsDeleteTransform(transform);
+ if (psCSA)
+ gfree(psCSA);
}
void GfxColorTransform::ref() {
@@ -216,6 +222,31 @@ unsigned int GfxColorTransform::unref() {
return --refCount;
}
+char *GfxColorTransform::getPostScriptCSA()
+{
+ int size;
+
+ if (psCSA)
+ return psCSA;
+
+ if (sourceProfile == NULL) {
+ error(errSyntaxWarning, -1, "profile is NULL");
+ return NULL;
+ }
+
+ size = cmsGetPostScriptCSA(cmsGetProfileContextID(sourceProfile), sourceProfile, cmsIntent, 0, NULL, 0);
+ if (size == 0) {
+ error(errSyntaxWarning, -1, "PostScript CSA is NULL");
+ return NULL;
+ }
+
+ psCSA = (char*)gmalloc(size+1);
+ cmsGetPostScriptCSA(cmsGetProfileContextID(sourceProfile), sourceProfile, cmsIntent, 0, psCSA, size);
+ psCSA[size] = 0;
+
+ return psCSA;
+}
+
static cmsHPROFILE RGBProfile = nullptr;
static GooString *displayProfileName = nullptr; // display profile file Name
static cmsHPROFILE displayProfile = nullptr; // display profile
@@ -248,9 +279,8 @@ void GfxColorSpace::setDisplayProfile(void *displayProfileA) {
INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
error(errSyntaxWarning, -1, "Can't create Lab transform");
} else {
- XYZ2DisplayTransform = new GfxColorTransform(transform, INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, displayPixelType);
+ XYZ2DisplayTransform = new GfxColorTransform(displayProfile, transform, INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, displayPixelType);
}
- cmsCloseProfile(XYZProfile);
}
}
@@ -525,10 +555,10 @@ int GfxColorSpace::setupColorProfiles()
CHANNELS_SH(nChannels) | BYTES_SH(1),
INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
error(errSyntaxWarning, -1, "Can't create Lab transform");
+ cmsCloseProfile(XYZProfile);
} else {
- XYZ2DisplayTransform = new GfxColorTransform(transform, INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, displayPixelType);
+ XYZ2DisplayTransform = new GfxColorTransform(XYZProfile, transform, INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, displayPixelType);
}
- cmsCloseProfile(XYZProfile);
}
return 0;
}
@@ -1789,16 +1819,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, OutputDev *out, GfxState
int transformIntent = cs->getIntent();
int cmsIntent = INTENT_RELATIVE_COLORIMETRIC;
if (state != nullptr) {
- const char *intent = state->getRenderingIntent();
- if (intent != nullptr) {
- if (strcmp(intent, "AbsoluteColorimetric") == 0) {
- cmsIntent = INTENT_ABSOLUTE_COLORIMETRIC;
- } else if (strcmp(intent, "Saturation") == 0) {
- cmsIntent = INTENT_SATURATION;
- } else if (strcmp(intent, "Perceptual") == 0) {
- cmsIntent = INTENT_PERCEPTUAL;
- }
- }
+ cmsIntent = state->getCmsRenderingIntent();
}
if (transformIntent == cmsIntent) {
return cs;
@@ -1883,16 +1904,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, OutputDev *out, GfxState
int cmsIntent = INTENT_RELATIVE_COLORIMETRIC;
if (state != nullptr) {
- const char *intent = state->getRenderingIntent();
- if (intent != nullptr) {
- if (strcmp(intent, "AbsoluteColorimetric") == 0) {
- cmsIntent = INTENT_ABSOLUTE_COLORIMETRIC;
- } else if (strcmp(intent, "Saturation") == 0) {
- cmsIntent = INTENT_SATURATION;
- } else if (strcmp(intent, "Perceptual") == 0) {
- cmsIntent = INTENT_PERCEPTUAL;
- }
- }
+ cmsIntent = state->getCmsRenderingIntent();
}
if ((transform = cmsCreateTransform(hp,
COLORSPACE_SH(cst) |CHANNELS_SH(nCompsA) | BYTES_SH(1),
@@ -1903,7 +1915,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, OutputDev *out, GfxState
error(errSyntaxWarning, -1, "Can't create transform");
cs->transform = nullptr;
} else {
- cs->transform = new GfxColorTransform(transform, cmsIntent, cst, dcst);
+ cs->transform = new GfxColorTransform(hp, transform, cmsIntent, cst, dcst);
}
if (dcst == PT_RGB || dcst == PT_CMYK) {
// create line transform only when the display is RGB type color space
@@ -1913,10 +1925,12 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, OutputDev *out, GfxState
error(errSyntaxWarning, -1, "Can't create transform");
cs->lineTransform = nullptr;
} else {
- cs->lineTransform = new GfxColorTransform(transform, cmsIntent, cst, dcst);
+ cs->lineTransform = new GfxColorTransform(NULL, transform, cmsIntent, cst, dcst);
}
}
- cmsCloseProfile(hp);
+ if (cs->transform == nullptr) {
+ cmsCloseProfile(hp);
+ }
}
// put this colorSpace into cache
if (out && iccProfileStreamA != Ref::INVALID()) {
@@ -2368,6 +2382,16 @@ void GfxICCBasedColorSpace::getDefaultRanges(double *decodeLow,
#endif
}
+#ifdef USE_CMS
+char *GfxICCBasedColorSpace::getPostScriptCSA()
+{
+ if (transform)
+ return transform->getPostScriptCSA();
+ else
+ return NULL;
+}
+#endif
+
//------------------------------------------------------------------------
// GfxIndexedColorSpace
//------------------------------------------------------------------------
@@ -6597,37 +6621,46 @@ void GfxState::setDisplayProfile(cmsHPROFILE localDisplayProfileA) {
CHANNELS_SH(nChannels) | BYTES_SH(1),
INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
error(errSyntaxWarning, -1, "Can't create Lab transform");
+ cmsCloseProfile(XYZProfile);
} else {
- XYZ2DisplayTransformRelCol = new GfxColorTransform(transform, INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, localDisplayPixelType);
+ XYZ2DisplayTransformRelCol = new GfxColorTransform(XYZProfile, transform, INTENT_RELATIVE_COLORIMETRIC, PT_XYZ, localDisplayPixelType);
}
+
+ XYZProfile = cmsCreateXYZProfile();
if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
localDisplayProfile,
COLORSPACE_SH(localDisplayPixelType) |
CHANNELS_SH(nChannels) | BYTES_SH(1),
INTENT_ABSOLUTE_COLORIMETRIC,LCMS_FLAGS)) == nullptr) {
error(errSyntaxWarning, -1, "Can't create Lab transform");
+ cmsCloseProfile(XYZProfile);
} else {
- XYZ2DisplayTransformAbsCol = new GfxColorTransform(transform, INTENT_ABSOLUTE_COLORIMETRIC, PT_XYZ, localDisplayPixelType);
+ XYZ2DisplayTransformAbsCol = new GfxColorTransform(XYZProfile, transform, INTENT_ABSOLUTE_COLORIMETRIC, PT_XYZ, localDisplayPixelType);
}
+
+ XYZProfile = cmsCreateXYZProfile();
if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
localDisplayProfile,
COLORSPACE_SH(localDisplayPixelType) |
CHANNELS_SH(nChannels) | BYTES_SH(1),
INTENT_SATURATION,LCMS_FLAGS)) == nullptr) {
error(errSyntaxWarning, -1, "Can't create Lab transform");
+ cmsCloseProfile(XYZProfile);
} else {
- XYZ2DisplayTransformSat = new GfxColorTransform(transform, INTENT_SATURATION, PT_XYZ, localDisplayPixelType);
+ XYZ2DisplayTransformSat = new GfxColorTransform(XYZProfile, transform, INTENT_SATURATION, PT_XYZ, localDisplayPixelType);
}
+
+ XYZProfile = cmsCreateXYZProfile();
if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
localDisplayProfile,
COLORSPACE_SH(localDisplayPixelType) |
CHANNELS_SH(nChannels) | BYTES_SH(1),
INTENT_PERCEPTUAL,LCMS_FLAGS)) == nullptr) {
error(errSyntaxWarning, -1, "Can't create Lab transform");
+ cmsCloseProfile(XYZProfile);
} else {
- XYZ2DisplayTransformPerc = new GfxColorTransform(transform, INTENT_PERCEPTUAL, PT_XYZ, localDisplayPixelType);
+ XYZ2DisplayTransformPerc = new GfxColorTransform(XYZProfile, transform, INTENT_PERCEPTUAL, PT_XYZ, localDisplayPixelType);
}
- cmsCloseProfile(XYZProfile);
}
}
@@ -6648,6 +6681,21 @@ GfxColorTransform *GfxState::getXYZ2DisplayTransform() {
return transform;
}
+int GfxState::getCmsRenderingIntent() {
+ const char *intent = getRenderingIntent();
+ int cmsIntent = INTENT_RELATIVE_COLORIMETRIC;
+ if (intent) {
+ if (strcmp(intent, "AbsoluteColorimetric") == 0) {
+ cmsIntent = INTENT_ABSOLUTE_COLORIMETRIC;
+ } else if (strcmp(intent, "Saturation") == 0) {
+ cmsIntent = INTENT_SATURATION;
+ } else if (strcmp(intent, "Perceptual") == 0) {
+ cmsIntent = INTENT_PERCEPTUAL;
+ }
+ }
+ return cmsIntent;
+}
+
#endif
void GfxState::setPath(GfxPath *pathA) {
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 6d445ecf..3da66e8c 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -193,7 +193,8 @@ class GfxColorTransform {
public:
void doTransform(void *in, void *out, unsigned int size);
// transformA should be a cmsHTRANSFORM
- GfxColorTransform(void *transformA, int cmsIntent, unsigned int inputPixelType, unsigned int transformPixelType);
+ GfxColorTransform(void *sourceProfileA, void *transformA, int cmsIntent,
+ unsigned int inputPixelType, unsigned int transformPixelType);
~GfxColorTransform();
GfxColorTransform(const GfxColorTransform &) = delete;
GfxColorTransform& operator=(const GfxColorTransform &) = delete;
@@ -202,13 +203,17 @@ public:
int getTransformPixelType() const { return transformPixelType; }
void ref();
unsigned int unref();
+ void *getSourceProfile() { return sourceProfile; }
+ char *getPostScriptCSA();
private:
GfxColorTransform() {}
+ void *sourceProfile;
void *transform;
unsigned int refCount;
int cmsIntent;
unsigned int inputPixelType;
unsigned int transformPixelType;
+ char *psCSA;
};
class GfxColorSpace {
@@ -569,6 +574,10 @@ public:
// ICCBased-specific access.
GfxColorSpace *getAlt() { return alt; }
+ Ref getRef() { return iccProfileStream; }
+#ifdef USE_CMS
+ char *getPostScriptCSA();
+#endif
private:
@@ -1594,6 +1603,7 @@ public:
void setDisplayProfile(void *localDisplayProfileA);
void *getDisplayProfile() { return localDisplayProfile; }
GfxColorTransform *getXYZ2DisplayTransform();
+ int getCmsRenderingIntent();
#endif
// Add to path.
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 8ad72c36..9a920fbb 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -3945,6 +3945,10 @@ void PSOutputDev::endPage() {
(*overlayCbk)(this, overlayCbkData);
}
+ for (const auto& item : iccEmitted) {
+ writePSFmt("userdict /{0:s} undef\n", item.c_str());
+ }
+ iccEmitted.clear();
if (mode == psModeForm) {
writePS("pdfEndPage\n");
@@ -3955,8 +3959,8 @@ void PSOutputDev::endPage() {
if (!manualCtrl) {
writePS("showpage\n");
}
- writePS("%%PageTrailer\n");
- writePageTrailer();
+ writePS("%%PageTrailer\n");
+ writePageTrailer();
}
}
@@ -4022,7 +4026,7 @@ void PSOutputDev::updateFillColorSpace(GfxState *state) {
case psLevel2:
case psLevel3:
if (state->getFillColorSpace()->getMode() != csPattern) {
- dumpColorSpaceL2(state->getFillColorSpace(), true, false, false);
+ dumpColorSpaceL2(state, state->getFillColorSpace(), true, false, false);
writePS(" cs\n");
}
break;
@@ -4043,7 +4047,7 @@ void PSOutputDev::updateStrokeColorSpace(GfxState *state) {
case psLevel2:
case psLevel3:
if (state->getStrokeColorSpace()->getMode() != csPattern) {
- dumpColorSpaceL2(state->getStrokeColorSpace(), true, false, false);
+ dumpColorSpaceL2(state, state->getStrokeColorSpace(), true, false, false);
writePS(" CS\n");
}
break;
@@ -4940,7 +4944,7 @@ bool PSOutputDev::patchMeshShadedFill(GfxState *state,
writePS("<<\n");
writePS(" /ShadingType 7\n");
writePS(" /ColorSpace ");
- dumpColorSpaceL2(shading->getColorSpace(), false, false, false);
+ dumpColorSpaceL2(state, shading->getColorSpace(), false, false, false);
writePS("\n");
writePS(" /DataSource [\n");
@@ -5233,12 +5237,12 @@ void PSOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
break;
case psLevel2:
case psLevel2Sep:
- doImageL2(ref, nullptr, invert, inlineImg, str, width, height, len,
+ doImageL2(state, ref, nullptr, invert, inlineImg, str, width, height, len,
nullptr, nullptr, 0, 0, false);
break;
case psLevel3:
case psLevel3Sep:
- doImageL3(ref, nullptr, invert, inlineImg, str, width, height, len,
+ doImageL3(state, ref, nullptr, invert, inlineImg, str, width, height, len,
nullptr, nullptr, 0, 0, false);
break;
}
@@ -5277,12 +5281,12 @@ void PSOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
break;
case psLevel2:
case psLevel2Sep:
- doImageL2(ref, colorMap, false, inlineImg, str,
+ doImageL2(state, ref, colorMap, false, inlineImg, str,
width, height, len, maskColors, nullptr, 0, 0, false);
break;
case psLevel3:
case psLevel3Sep:
- doImageL3(ref, colorMap, false, inlineImg, str,
+ doImageL3(state, ref, colorMap, false, inlineImg, str,
width, height, len, maskColors, nullptr, 0, 0, false);
break;
}
@@ -5312,12 +5316,12 @@ void PSOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
break;
case psLevel2:
case psLevel2Sep:
- doImageL2(ref, colorMap, false, false, str, width, height, len,
+ doImageL2(state, ref, colorMap, false, false, str, width, height, len,
nullptr, maskStr, maskWidth, maskHeight, maskInvert);
break;
case psLevel3:
case psLevel3Sep:
- doImageL3(ref, colorMap, false, false, str, width, height, len,
+ doImageL3(state, ref, colorMap, false, false, str, width, height, len,
nullptr, maskStr, maskWidth, maskHeight, maskInvert);
break;
}
@@ -5769,7 +5773,7 @@ void PSOutputDev::maskToClippingPath(Stream *maskStr, int maskWidth, int maskHei
maskStr->close();
}
-void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
+void PSOutputDev::doImageL2(GfxState* state, Object *ref, GfxImageColorMap *colorMap,
bool invert, bool inlineImg,
Stream *str, int width, int height, int len,
const int *maskColors, Stream *maskStr,
@@ -5961,7 +5965,7 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
bool isCustomColor =
(level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) &&
colorMap->getColorSpace()->getMode() == csDeviceN;
- dumpColorSpaceL2(colorMap->getColorSpace(), false, !isCustomColor, false);
+ dumpColorSpaceL2(state, colorMap->getColorSpace(), false, !isCustomColor, false);
writePS(" setcolorspace\n");
}
@@ -6249,7 +6253,7 @@ void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap,
}
//~ this doesn't currently support OPI
-void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
+void PSOutputDev::doImageL3(GfxState *state, Object *ref, GfxImageColorMap *colorMap,
bool invert, bool inlineImg,
Stream *str, int width, int height, int len,
const int *maskColors, Stream *maskStr,
@@ -6364,7 +6368,7 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
bool isCustomColor =
(level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) &&
colorMap->getColorSpace()->getMode() == csDeviceN;
- dumpColorSpaceL2(colorMap->getColorSpace(), false, !isCustomColor, false);
+ dumpColorSpaceL2(state, colorMap->getColorSpace(), false, !isCustomColor, false);
writePS(" setcolorspace\n");
}
@@ -6663,7 +6667,7 @@ void PSOutputDev::doImageL3(Object *ref, GfxImageColorMap *colorMap,
}
}
-void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace,
+void PSOutputDev::dumpColorSpaceL2(GfxState *state, GfxColorSpace *colorSpace,
bool genXform, bool updateColors,
bool map01) {
GfxCalGrayColorSpace *calGrayCS;
@@ -6804,17 +6808,48 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace,
break;
case csICCBased:
+#if USE_CMS
+ {
+ GfxICCBasedColorSpace *iccBasedCS;
+ iccBasedCS = (GfxICCBasedColorSpace *)colorSpace;
+ Ref ref = iccBasedCS->getRef();
+ int intent = state->getCmsRenderingIntent();
+ GooString *name = GooString::format("ICCBased-{0:d}-{1:d}-{2:d}", ref.num, ref.gen, intent);
+ const auto& it = iccEmitted.find(name->toStr());
+ if (it != iccEmitted.end()) {
+ writePSFmt("{0:t}", name);
+ if (genXform) {
+ writePS(" {}");
+ }
+ } else {
+ char *csa = iccBasedCS->getPostScriptCSA();
+ if (csa) {
+ writePSFmt("userdict /{0:t} {1:s} put\n", name, csa);
+ iccEmitted.emplace(name->toStr());
+ writePSFmt("{0:t}", name);
+ if (genXform) {
+ writePS(" {}");
+ }
+ } else {
+ dumpColorSpaceL2(state, ((GfxICCBasedColorSpace *)colorSpace)->getAlt(),
+ genXform, updateColors, false);
+ }
+ }
+ delete name;
+ }
+#else
// there is no transform function to the alternate color space, so
// we can use it directly
- dumpColorSpaceL2(((GfxICCBasedColorSpace *)colorSpace)->getAlt(),
+ dumpColorSpaceL2(state, ((GfxICCBasedColorSpace *)colorSpace)->getAlt(),
genXform, updateColors, false);
+#endif
break;
case csIndexed:
indexedCS = (GfxIndexedColorSpace *)colorSpace;
baseCS = indexedCS->getBase();
writePS("[/Indexed ");
- dumpColorSpaceL2(baseCS, false, false, true);
+ dumpColorSpaceL2(state, baseCS, false, false, true);
n = indexedCS->getIndexHigh();
numComps = baseCS->getNComps();
lookup = indexedCS->getLookup();
@@ -6889,7 +6924,7 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace,
writePS("[/Separation ");
writePSString(separationCS->getName()->toStr());
writePS(" ");
- dumpColorSpaceL2(separationCS->getAlt(), false, false, false);
+ dumpColorSpaceL2(state, separationCS->getAlt(), false, false, false);
writePS("\n");
cvtFunction(separationCS->getFunc());
writePS("]");
@@ -6911,7 +6946,7 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace,
writePS(" ");
}
writePS("]\n");
- dumpColorSpaceL2(deviceNCS->getAlt(), false, updateColors, false);
+ dumpColorSpaceL2(state, deviceNCS->getAlt(), false, updateColors, false);
writePS("\n");
cvtFunction(deviceNCS->getTintTransformFunc(), map01 && deviceNCS->getAlt()->getMode() == csLab);
writePS("]\n");
@@ -6920,7 +6955,7 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace,
}
} else {
// DeviceN color spaces are a Level 3 PostScript feature.
- dumpColorSpaceL2(deviceNCS->getAlt(), false, updateColors, map01);
+ dumpColorSpaceL2(state, deviceNCS->getAlt(), false, updateColors, map01);
if (genXform) {
writePS(" ");
cvtFunction(deviceNCS->getTintTransformFunc());
diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h
index 5114a1d6..8641d14e 100644
--- a/poppler/PSOutputDev.h
+++ b/poppler/PSOutputDev.h
@@ -395,17 +395,17 @@ private:
Stream *str, int width, int height, int len,
const int *maskColors, Stream *maskStr,
int maskWidth, int maskHeight, bool maskInvert);
- void doImageL2(Object *ref, GfxImageColorMap *colorMap,
+ void doImageL2(GfxState *state, Object *ref, GfxImageColorMap *colorMap,
bool invert, bool inlineImg,
Stream *str, int width, int height, int len,
const int *maskColors, Stream *maskStr,
int maskWidth, int maskHeight, bool maskInvert);
- void doImageL3(Object *ref, GfxImageColorMap *colorMap,
+ void doImageL3(GfxState *state, Object *ref, GfxImageColorMap *colorMap,
bool invert, bool inlineImg,
Stream *str, int width, int height, int len,
const int *maskColors, Stream *maskStr,
int maskWidth, int maskHeight, bool maskInvert);
- void dumpColorSpaceL2(GfxColorSpace *colorSpace,
+ void dumpColorSpaceL2(GfxState *state, GfxColorSpace *colorSpace,
bool genXform, bool updateColors,
bool map01);
bool tilingPatternFillL1(GfxState *state, Catalog *cat, Object *str,
@@ -557,6 +557,8 @@ private:
bool enableLZW; // enable LZW compression
bool enableFlate; // enable Flate compression
+ std::unordered_set<std::string> iccEmitted; // contains ICCBased CSAs that have been emitted
+
#ifdef OPI_SUPPORT
int opi13Nest; // nesting level of OPI 1.3 objects
int opi20Nest; // nesting level of OPI 2.0 objects
commit d5efac76267c7adf7636514280614efcc1ac3392
Author: Philipp Knechtges <philipp-dev at knechtges.com>
Date: Sat May 16 14:06:56 2020 +0200
Revert "GfxICCBasedColorSpace: Remove unused member variable"
This reverts commit 8c8e0a143e975b16e6c437c03dc2267e7e8ff3fc.
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 47ae1e5c..7141c9f8 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -1724,9 +1724,11 @@ void GfxLabColorSpace::getDefaultRanges(double *decodeLow, double *decodeRange,
// GfxICCBasedColorSpace
//------------------------------------------------------------------------
-GfxICCBasedColorSpace::GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA) {
+GfxICCBasedColorSpace::GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA,
+ const Ref *iccProfileStreamA) {
nComps = nCompsA;
alt = altA;
+ iccProfileStream = *iccProfileStreamA;
rangeMin[0] = rangeMin[1] = rangeMin[2] = rangeMin[3] = 0;
rangeMax[0] = rangeMax[1] = rangeMax[2] = rangeMax[3] = 1;
#ifdef USE_CMS
@@ -1751,7 +1753,7 @@ GfxColorSpace *GfxICCBasedColorSpace::copy() const {
GfxICCBasedColorSpace *cs;
int i;
- cs = new GfxICCBasedColorSpace(nComps, alt->copy());
+ cs = new GfxICCBasedColorSpace(nComps, alt->copy(), &iccProfileStream);
for (i = 0; i < 4; ++i) {
cs->rangeMin[i] = rangeMin[i];
cs->rangeMax[i] = rangeMax[i];
@@ -1846,7 +1848,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, OutputDev *out, GfxState
delete altA;
return nullptr;
}
- cs = new GfxICCBasedColorSpace(nCompsA, altA);
+ cs = new GfxICCBasedColorSpace(nCompsA, altA, &iccProfileStreamA);
obj2 = dict->lookup("Range");
if (obj2.isArray() && obj2.arrayGetLength() == 2 * nCompsA) {
for (i = 0; i < nCompsA; ++i) {
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 15c4c70f..6d445ecf 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -538,8 +538,9 @@ private:
class GfxICCBasedColorSpace: public GfxColorSpace {
public:
- GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA);
- ~GfxICCBasedColorSpace() override;
+ GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA,
+ const Ref *iccProfileStreamA);
+ ~GfxICCBasedColorSpace();
GfxColorSpace *copy() const override;
GfxColorSpaceMode getMode() const override { return csICCBased; }
@@ -575,6 +576,7 @@ private:
GfxColorSpace *alt; // alternate color space
double rangeMin[4]; // min values for each component
double rangeMax[4]; // max values for each component
+ Ref iccProfileStream; // the ICC profile
#ifdef USE_CMS
int getIntent() { return (transform != nullptr) ? transform->getIntent() : 0; }
GfxColorTransform *transform;
More information about the poppler
mailing list