[poppler] OutputIntents in PDF (was Re: poppler/Gfx.cc poppler/Gfx.h poppler/GfxState.cc poppler/GfxState.h poppler/Page.cc)
Leonard Rosenthol
lrosenth at adobe.com
Wed Oct 2 15:00:36 PDT 2013
Remember that you ONLY do this for files that comply with one of the
subset standards (PDF/X, PDF/A, etc.). An OutputIntent containe in a
"regular" PDF is to be ignored!
Leonard
On 10/2/13 5:36 PM, "Albert Astals Cid" <aacid at kemper.freedesktop.org>
wrote:
> poppler/Gfx.cc | 114 ++++++++++---
> poppler/Gfx.h | 8
> poppler/GfxState.cc | 429
>+++++++++++++++++++++++++++++++++++++++++-----------
> poppler/GfxState.h | 72 ++++++--
> poppler/Page.cc | 2
> 5 files changed, 490 insertions(+), 135 deletions(-)
>
>New commits:
>commit bd49b3c0c6f2adccc5bda561edbaf9f00ed2917a
>Author: Thomas Freitag <Thomas.Freitag at alfa.de>
>Date: Wed Oct 2 23:32:09 2013 +0200
>
> Use icc profile in OutputIntents
>
> Bug #34053
>
>diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
>index f2971d6..90bf41e 100644
>--- a/poppler/Gfx.cc
>+++ b/poppler/Gfx.cc
>@@ -460,7 +460,7 @@ void GfxResources::lookupColorSpace(const char *name,
>Object *obj) {
> obj->initNull();
> }
>
>-GfxPattern *GfxResources::lookupPattern(char *name, OutputDev *out) {
>+GfxPattern *GfxResources::lookupPattern(char *name, OutputDev *out,
>GfxState *state) {
> GfxResources *resPtr;
> GfxPattern *pattern;
> Object obj;
>@@ -468,7 +468,7 @@ GfxPattern *GfxResources::lookupPattern(char *name,
>OutputDev *out) {
> for (resPtr = this; resPtr; resPtr = resPtr->next) {
> if (resPtr->patternDict.isDict()) {
> if (!resPtr->patternDict.dictLookup(name, &obj)->isNull()) {
>- pattern = GfxPattern::parse(&obj, out);
>+ pattern = GfxPattern::parse(&obj, out, state);
> obj.free();
> return pattern;
> }
>@@ -479,7 +479,7 @@ GfxPattern *GfxResources::lookupPattern(char *name,
>OutputDev *out) {
> return NULL;
> }
>
>-GfxShading *GfxResources::lookupShading(char *name, OutputDev *out) {
>+GfxShading *GfxResources::lookupShading(char *name, OutputDev *out,
>GfxState *state) {
> GfxResources *resPtr;
> GfxShading *shading;
> Object obj;
>@@ -487,7 +487,7 @@ GfxShading *GfxResources::lookupShading(char *name,
>OutputDev *out) {
> for (resPtr = this; resPtr; resPtr = resPtr->next) {
> if (resPtr->shadingDict.isDict()) {
> if (!resPtr->shadingDict.dictLookup(name, &obj)->isNull()) {
>- shading = GfxShading::parse(&obj, out);
>+ shading = GfxShading::parse(&obj, out, state);
> obj.free();
> return shading;
> }
>@@ -584,6 +584,9 @@ Gfx::Gfx(PDFDoc *docA, OutputDev *outA, int pageNum,
>Dict *resDict,
> out->clip(state);
> state->clearPath();
> }
>+#ifdef USE_CMS
>+ initDisplayProfile();
>+#endif
> }
>
> Gfx::Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict,
>@@ -633,8 +636,55 @@ Gfx::Gfx(PDFDoc *docA, OutputDev *outA, Dict
>*resDict,
> out->clip(state);
> state->clearPath();
> }
>+#ifdef USE_CMS
>+ initDisplayProfile();
>+#endif
> }
>
>+#ifdef USE_CMS
>+
>+#ifdef USE_LCMS1
>+#include <lcms.h>
>+#else
>+#include <lcms2.h>
>+#define LCMS_FLAGS cmsFLAGS_NOOPTIMIZE
>+#endif
>+
>+void Gfx::initDisplayProfile() {
>+ Object catDict;
>+ xref->getCatalog(&catDict);
>+ if (catDict.isDict()) {
>+ Object outputIntents;
>+ catDict.dictLookup("OutputIntents", &outputIntents);
>+ if (outputIntents.isArray() && outputIntents.arrayGetLength() == 1)
>{
>+ Object firstElement;
>+ outputIntents.arrayGet(0, &firstElement);
>+ if (firstElement.isDict()) {
>+ Object profile;
>+ firstElement.dictLookup("DestOutputProfile", &profile);
>+ if (profile.isStream()) {
>+ Stream *iccStream = profile.getStream();
>+ int length = 0;
>+ Guchar *profBuf = iccStream->toUnsignedChars(&length,
>65536, 65536);
>+ cmsHPROFILE hp = cmsOpenProfileFromMem(profBuf,length);
>+ if (hp == 0) {
>+ error(errSyntaxWarning, -1, "read ICCBased color space
>profile error");
>+ } else {
>+ state->setDisplayProfile(hp);
>+ }
>+ gfree(profBuf);
>+ }
>+ profile.free();
>+ }
>+ firstElement.free();
>+ }
>+ outputIntents.free();
>+ }
>+ catDict.free();
>+}
>+
>+#endif
>+
> Gfx::~Gfx() {
> while (stateGuards.size()) {
> popStateGuard();
>@@ -1183,7 +1233,7 @@ void Gfx::opSetExtGState(Object args[], int
>numArgs) {
> blendingColorSpace = NULL;
> isolated = knockout = gFalse;
> if (!obj4.dictLookup("CS", &obj5)->isNull()) {
>- blendingColorSpace = GfxColorSpace::parse(&obj5, out);
>+ blendingColorSpace = GfxColorSpace::parse(&obj5, out, state);
> }
> obj5.free();
> if (obj4.dictLookup("I", &obj5)->isBool()) {
>@@ -1371,6 +1421,7 @@ void Gfx::doSoftMask(Object *str, GBool alpha,
> }
>
> void Gfx::opSetRenderingIntent(Object args[], int numArgs) {
>+ state->setRenderingIntent(args[0].getName());
> }
>
>
>//------------------------------------------------------------------------
>@@ -1385,7 +1436,7 @@ void Gfx::opSetFillGray(Object args[], int numArgs)
>{
> state->setFillPattern(NULL);
> res->lookupColorSpace("DefaultGray", &obj);
> if (!obj.isNull()) {
>- colorSpace = GfxColorSpace::parse(&obj, out);
>+ colorSpace = GfxColorSpace::parse(&obj, out, state);
> }
> if (colorSpace == NULL) {
> colorSpace = new GfxDeviceGrayColorSpace();
>@@ -1406,7 +1457,7 @@ void Gfx::opSetStrokeGray(Object args[], int
>numArgs) {
> state->setStrokePattern(NULL);
> res->lookupColorSpace("DefaultGray", &obj);
> if (!obj.isNull()) {
>- colorSpace = GfxColorSpace::parse(&obj, out);
>+ colorSpace = GfxColorSpace::parse(&obj, out, state);
> }
> if (colorSpace == NULL) {
> colorSpace = new GfxDeviceGrayColorSpace();
>@@ -1427,7 +1478,7 @@ void Gfx::opSetFillCMYKColor(Object args[], int
>numArgs) {
>
> res->lookupColorSpace("DefaultCMYK", &obj);
> if (!obj.isNull()) {
>- colorSpace = GfxColorSpace::parse(&obj, out);
>+ colorSpace = GfxColorSpace::parse(&obj, out, state);
> }
> if (colorSpace == NULL) {
> colorSpace = new GfxDeviceCMYKColorSpace();
>@@ -1452,7 +1503,7 @@ void Gfx::opSetStrokeCMYKColor(Object args[], int
>numArgs) {
> state->setStrokePattern(NULL);
> res->lookupColorSpace("DefaultCMYK", &obj);
> if (!obj.isNull()) {
>- colorSpace = GfxColorSpace::parse(&obj, out);
>+ colorSpace = GfxColorSpace::parse(&obj, out, state);
> }
> if (colorSpace == NULL) {
> colorSpace = new GfxDeviceCMYKColorSpace();
>@@ -1476,7 +1527,7 @@ void Gfx::opSetFillRGBColor(Object args[], int
>numArgs) {
> state->setFillPattern(NULL);
> res->lookupColorSpace("DefaultRGB", &obj);
> if (!obj.isNull()) {
>- colorSpace = GfxColorSpace::parse(&obj, out);
>+ colorSpace = GfxColorSpace::parse(&obj, out, state);
> }
> if (colorSpace == NULL) {
> colorSpace = new GfxDeviceRGBColorSpace();
>@@ -1500,7 +1551,7 @@ void Gfx::opSetStrokeRGBColor(Object args[], int
>numArgs) {
> state->setStrokePattern(NULL);
> res->lookupColorSpace("DefaultRGB", &obj);
> if (!obj.isNull()) {
>- colorSpace = GfxColorSpace::parse(&obj, out);
>+ colorSpace = GfxColorSpace::parse(&obj, out, state);
> }
> if (colorSpace == NULL) {
> colorSpace = new GfxDeviceRGBColorSpace();
>@@ -1522,9 +1573,9 @@ void Gfx::opSetFillColorSpace(Object args[], int
>numArgs) {
>
> res->lookupColorSpace(args[0].getName(), &obj);
> if (obj.isNull()) {
>- colorSpace = GfxColorSpace::parse(&args[0], out);
>+ colorSpace = GfxColorSpace::parse(&args[0], out, state);
> } else {
>- colorSpace = GfxColorSpace::parse(&obj, out);
>+ colorSpace = GfxColorSpace::parse(&obj, out, state);
> }
> obj.free();
> if (colorSpace) {
>@@ -1547,9 +1598,9 @@ void Gfx::opSetStrokeColorSpace(Object args[], int
>numArgs) {
> state->setStrokePattern(NULL);
> res->lookupColorSpace(args[0].getName(), &obj);
> if (obj.isNull()) {
>- colorSpace = GfxColorSpace::parse(&args[0], out);
>+ colorSpace = GfxColorSpace::parse(&args[0], out, state);
> } else {
>- colorSpace = GfxColorSpace::parse(&obj, out);
>+ colorSpace = GfxColorSpace::parse(&obj, out, state);
> }
> obj.free();
> if (colorSpace) {
>@@ -1620,7 +1671,7 @@ void Gfx::opSetFillColorN(Object args[], int
>numArgs) {
> }
> if (numArgs > 0) {
> if (args[numArgs-1].isName() &&
>- (pattern = res->lookupPattern(args[numArgs-1].getName(), out))) {
>+ (pattern = res->lookupPattern(args[numArgs-1].getName(), out,
>state))) {
> state->setFillPattern(pattern);
> }
> }
>@@ -1672,7 +1723,7 @@ void Gfx::opSetStrokeColorN(Object args[], int
>numArgs) {
> return;
> }
> if (args[numArgs-1].isName() &&
>- (pattern = res->lookupPattern(args[numArgs-1].getName(), out))) {
>+ (pattern = res->lookupPattern(args[numArgs-1].getName(), out, state))) {
> state->setStrokePattern(pattern);
> }
>
>@@ -2382,7 +2433,7 @@ void Gfx::opShFill(Object args[], int numArgs) {
> return;
> }
>
>- if (!(shading = res->lookupShading(args[0].getName(), out))) {
>+ if (!(shading = res->lookupShading(args[0].getName(), out, state))) {
> return;
> }
>
>@@ -4339,14 +4390,29 @@ void Gfx::doImage(Object *ref, Stream *str, GBool
>inlineImg) {
> }
> }
> if (!obj1.isNull()) {
>- colorSpace = GfxColorSpace::parse(&obj1, out);
>+ Object objIntent;
>+ char *tempIntent = NULL;
>+ dict->lookup("Intent", &objIntent);
>+ if (objIntent.isName()) {
>+ tempIntent = state->getRenderingIntent();
>+ if (tempIntent != NULL) {
>+ tempIntent = strdup(tempIntent);
>+ }
>+ state->setRenderingIntent(objIntent.getName());
>+ }
>+ colorSpace = GfxColorSpace::parse(&obj1, out, state);
>+ if (objIntent.isName()) {
>+ state->setRenderingIntent(tempIntent);
>+ free(tempIntent);
>+ }
>+ objIntent.free();
> } else if (csMode == streamCSDeviceGray) {
> Object objCS;
> res->lookupColorSpace("DefaultGray", &objCS);
> if (objCS.isNull()) {
> colorSpace = new GfxDeviceGrayColorSpace();
> } else {
>- colorSpace = GfxColorSpace::parse(&objCS, out);
>+ colorSpace = GfxColorSpace::parse(&objCS, out, state);
> }
> objCS.free();
> } else if (csMode == streamCSDeviceRGB) {
>@@ -4355,7 +4421,7 @@ void Gfx::doImage(Object *ref, Stream *str, GBool
>inlineImg) {
> if (objCS.isNull()) {
> colorSpace = new GfxDeviceRGBColorSpace();
> } else {
>- colorSpace = GfxColorSpace::parse(&objCS, out);
>+ colorSpace = GfxColorSpace::parse(&objCS, out, state);
> }
> objCS.free();
> } else if (csMode == streamCSDeviceCMYK) {
>@@ -4364,7 +4430,7 @@ void Gfx::doImage(Object *ref, Stream *str, GBool
>inlineImg) {
> if (objCS.isNull()) {
> colorSpace = new GfxDeviceCMYKColorSpace();
> } else {
>- colorSpace = GfxColorSpace::parse(&objCS, out);
>+ colorSpace = GfxColorSpace::parse(&objCS, out, state);
> }
> objCS.free();
> } else {
>@@ -4459,7 +4525,7 @@ void Gfx::doImage(Object *ref, Stream *str, GBool
>inlineImg) {
> obj2.free();
> }
> }
>- maskColorSpace = GfxColorSpace::parse(&obj1, out);
>+ maskColorSpace = GfxColorSpace::parse(&obj1, out, state);
> obj1.free();
> if (!maskColorSpace || maskColorSpace->getMode() != csDeviceGray) {
> goto err1;
>@@ -4755,7 +4821,7 @@ void Gfx::doForm(Object *str) {
> if (dict->lookup("Group", &obj1)->isDict()) {
> if (obj1.dictLookup("S", &obj2)->isName("Transparency")) {
> if (!obj1.dictLookup("CS", &obj3)->isNull()) {
>- blendingColorSpace = GfxColorSpace::parse(&obj3, out);
>+ blendingColorSpace = GfxColorSpace::parse(&obj3, out, state);
> }
> obj3.free();
> if (obj1.dictLookup("I", &obj3)->isBool()) {
>diff --git a/poppler/Gfx.h b/poppler/Gfx.h
>index aba3b7e..a82f9f4 100644
>--- a/poppler/Gfx.h
>+++ b/poppler/Gfx.h
>@@ -117,8 +117,8 @@ public:
> GBool lookupXObjectNF(char *name, Object *obj);
> GBool lookupMarkedContentNF(char *name, Object *obj);
> void lookupColorSpace(const char *name, Object *obj);
>- GfxPattern *lookupPattern(char *name, OutputDev *out);
>- GfxShading *lookupShading(char *name, OutputDev *out);
>+ GfxPattern *lookupPattern(char *name, OutputDev *out, GfxState *state);
>+ GfxShading *lookupShading(char *name, OutputDev *out, GfxState *state);
> GBool lookupGState(char *name, Object *obj);
> GBool lookupGStateNF(char *name, Object *obj);
>
>@@ -156,7 +156,9 @@ public:
> PDFRectangle *box, PDFRectangle *cropBox,
> GBool (*abortCheckCbkA)(void *data) = NULL,
> void *abortCheckCbkDataA = NULL, XRef *xrefA = NULL);
>-
>+#ifdef USE_CMS
>+ void initDisplayProfile();
>+#endif
> ~Gfx();
>
> XRef *getXRef() { return xref; }
>diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
>index 11540ad..8a53ee4 100644
>--- a/poppler/GfxState.cc
>+++ b/poppler/GfxState.cc
>@@ -201,9 +201,11 @@ void GfxColorTransform::doTransform(void *in, void
>*out, unsigned int size) {
> }
>
> // transformA should be a cmsHTRANSFORM
>-GfxColorTransform::GfxColorTransform(void *transformA) {
>+GfxColorTransform::GfxColorTransform(void *transformA, int cmsIntentA,
>unsigned int transformPixelTypeA) {
> transform = transformA;
> refCount = 1;
>+ cmsIntent = cmsIntentA;
>+ transformPixelType = transformPixelTypeA;
> }
>
> GfxColorTransform::~GfxColorTransform() {
>@@ -231,6 +233,25 @@ static cmsHPROFILE loadColorProfile(const char
>*fileName);
>
> void GfxColorSpace::setDisplayProfile(void *displayProfileA) {
> displayProfile = displayProfileA;
>+ if (displayProfile != NULL) {
>+ cmsHTRANSFORM transform;
>+ unsigned int nChannels;
>+
>+ displayPixelType =
>getCMSColorSpaceType(cmsGetColorSpace(displayProfile));
>+ nChannels = getCMSNChannels(cmsGetColorSpace(displayProfile));
>+ // create transform from XYZ
>+ cmsHPROFILE XYZProfile = cmsCreateXYZProfile();
>+ if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
>+ displayProfile,
>+ COLORSPACE_SH(displayPixelType) |
>+ CHANNELS_SH(nChannels) | BYTES_SH(1),
>+ INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == 0) {
>+ error(errSyntaxWarning, -1, "Can't create Lab transform");
>+ } else {
>+ XYZ2DisplayTransform = new GfxColorTransform(transform,
>INTENT_RELATIVE_COLORIMETRIC, displayPixelType);
>+ }
>+ cmsCloseProfile(XYZProfile);
>+ }
> }
>
> void GfxColorSpace::setDisplayProfileName(GooString *name) {
>@@ -259,7 +280,7 @@ GfxColorSpace::GfxColorSpace() {
> GfxColorSpace::~GfxColorSpace() {
> }
>
>-GfxColorSpace *GfxColorSpace::parse(Object *csObj, OutputDev *out, int
>recursion) {
>+GfxColorSpace *GfxColorSpace::parse(Object *csObj, OutputDev *out,
>GfxState *state, int recursion) {
> GfxColorSpace *cs;
> Object obj1;
>
>@@ -290,21 +311,21 @@ GfxColorSpace *GfxColorSpace::parse(Object *csObj,
>OutputDev *out, int recursion
> } else if (obj1.isName("DeviceCMYK") || obj1.isName("CMYK")) {
> cs = new GfxDeviceCMYKColorSpace();
> } else if (obj1.isName("CalGray")) {
>- cs = GfxCalGrayColorSpace::parse(csObj->getArray());
>+ cs = GfxCalGrayColorSpace::parse(csObj->getArray(), state);
> } else if (obj1.isName("CalRGB")) {
>- cs = GfxCalRGBColorSpace::parse(csObj->getArray());
>+ cs = GfxCalRGBColorSpace::parse(csObj->getArray(), state);
> } else if (obj1.isName("Lab")) {
>- cs = GfxLabColorSpace::parse(csObj->getArray());
>+ cs = GfxLabColorSpace::parse(csObj->getArray(), state);
> } else if (obj1.isName("ICCBased")) {
>- cs = GfxICCBasedColorSpace::parse(csObj->getArray(), out,
>recursion);
>+ cs = GfxICCBasedColorSpace::parse(csObj->getArray(), out, state,
>recursion);
> } else if (obj1.isName("Indexed") || obj1.isName("I")) {
>- cs = GfxIndexedColorSpace::parse(csObj->getArray(), out,
>recursion);
>+ cs = GfxIndexedColorSpace::parse(csObj->getArray(), out, state,
>recursion);
> } else if (obj1.isName("Separation")) {
>- cs = GfxSeparationColorSpace::parse(csObj->getArray(), out,
>recursion);
>+ cs = GfxSeparationColorSpace::parse(csObj->getArray(), out, state,
>recursion);
> } else if (obj1.isName("DeviceN")) {
>- cs = GfxDeviceNColorSpace::parse(csObj->getArray(), out,
>recursion);
>+ cs = GfxDeviceNColorSpace::parse(csObj->getArray(), out, state,
>recursion);
> } else if (obj1.isName("Pattern")) {
>- cs = GfxPatternColorSpace::parse(csObj->getArray(), out,
>recursion);
>+ cs = GfxPatternColorSpace::parse(csObj->getArray(), out, state,
>recursion);
> } else {
> error(errSyntaxWarning, -1, "Bad color space");
> }
>@@ -423,13 +444,13 @@ int GfxColorSpace::setupColorProfiles()
> // create transform from XYZ
> cmsHPROFILE XYZProfile = cmsCreateXYZProfile();
> if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
>- displayProfile,
>+ displayProfile,
> COLORSPACE_SH(displayPixelType) |
> CHANNELS_SH(nChannels) | BYTES_SH(1),
> INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == 0) {
> error(errSyntaxWarning, -1, "Can't create Lab transform");
> } else {
>- XYZ2DisplayTransform = new GfxColorTransform(transform);
>+ XYZ2DisplayTransform = new GfxColorTransform(transform,
>INTENT_RELATIVE_COLORIMETRIC, displayPixelType);
> }
> cmsCloseProfile(XYZProfile);
> }
>@@ -651,6 +672,11 @@ GfxCalGrayColorSpace::GfxCalGrayColorSpace() {
> }
>
> GfxCalGrayColorSpace::~GfxCalGrayColorSpace() {
>+#ifdef USE_CMS
>+ if (transform != NULL) {
>+ if (transform->unref() == 0) delete transform;
>+ }
>+#endif
> }
>
> GfxColorSpace *GfxCalGrayColorSpace::copy() {
>@@ -664,6 +690,10 @@ GfxColorSpace *GfxCalGrayColorSpace::copy() {
> cs->blackY = blackY;
> cs->blackZ = blackZ;
> cs->gamma = gamma;
>+#ifdef USE_CMS
>+ cs->transform = transform;
>+ if (transform != NULL) transform->ref();
>+#endif
> return cs;
> }
>
>@@ -675,7 +705,7 @@ static const double xyzrgb[3][3] = {
> { 0.055643, -0.204026, 1.057229 }
> };
>
>-GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr) {
>+GfxColorSpace *GfxCalGrayColorSpace::parse(Array *arr, GfxState *state) {
> GfxCalGrayColorSpace *cs;
> Object obj1, obj2, obj3;
>
>@@ -733,7 +763,10 @@ GfxColorSpace *GfxCalGrayColorSpace::parse(Array
>*arr) {
> cs->kb = 1 / (xyzrgb[2][0] * cs->whiteX +
> xyzrgb[2][1] * cs->whiteY +
> xyzrgb[2][2] * cs->whiteZ);
>-
>+#ifdef USE_CMS
>+ cs->transform = (state != NULL) ? state->getXYZ2DisplayTransform() :
>XYZ2DisplayTransform;
>+ if (cs->transform != NULL) cs->transform->ref();
>+#endif
> return cs;
> }
>
>@@ -752,7 +785,7 @@ void GfxCalGrayColorSpace::getGray(GfxColor *color,
>GfxGray *gray) {
> GfxRGB rgb;
>
> #ifdef USE_CMS
>- if (XYZ2DisplayTransform != NULL && displayPixelType == PT_GRAY) {
>+ if (transform != NULL && transform->getTransformPixelType() ==
>PT_GRAY) {
> Guchar out[gfxColorMaxComps];
> double in[gfxColorMaxComps];
> double X, Y, Z;
>@@ -761,7 +794,7 @@ void GfxCalGrayColorSpace::getGray(GfxColor *color,
>GfxGray *gray) {
> in[0] = clip01(X);
> in[1] = clip01(Y);
> in[2] = clip01(Z);
>- XYZ2DisplayTransform->doTransform(in,out,1);
>+ transform->doTransform(in,out,1);
> *gray = byteToCol(out[0]);
> return;
> }
>@@ -778,14 +811,14 @@ void GfxCalGrayColorSpace::getRGB(GfxColor *color,
>GfxRGB *rgb) {
>
> getXYZ(color,&X,&Y,&Z);
> #ifdef USE_CMS
>- if (XYZ2DisplayTransform != NULL && displayPixelType == PT_RGB) {
>+ if (transform != NULL && transform->getTransformPixelType() == PT_RGB)
>{
> Guchar out[gfxColorMaxComps];
> double in[gfxColorMaxComps];
>
> in[0] = clip01(X);
> in[1] = clip01(Y);
> in[2] = clip01(Z);
>- XYZ2DisplayTransform->doTransform(in,out,1);
>+ transform->doTransform(in,out,1);
> rgb->r = byteToCol(out[0]);
> rgb->g = byteToCol(out[1]);
> rgb->b = byteToCol(out[2]);
>@@ -809,7 +842,7 @@ void GfxCalGrayColorSpace::getCMYK(GfxColor *color,
>GfxCMYK *cmyk) {
> GfxColorComp c, m, y, k;
>
> #ifdef USE_CMS
>- if (XYZ2DisplayTransform != NULL && displayPixelType == PT_CMYK) {
>+ if (transform != NULL && transform->getTransformPixelType() ==
>PT_CMYK) {
> double in[gfxColorMaxComps];
> Guchar out[gfxColorMaxComps];
> double X, Y, Z;
>@@ -819,7 +852,7 @@ void GfxCalGrayColorSpace::getCMYK(GfxColor *color,
>GfxCMYK *cmyk) {
> in[1] = clip01(Y);
> in[2] = clip01(Z);
>
>- XYZ2DisplayTransform->doTransform(in,out,1);
>+ transform->doTransform(in,out,1);
> cmyk->c = byteToCol(out[0]);
> cmyk->m = byteToCol(out[1]);
> cmyk->y = byteToCol(out[2]);
>@@ -1017,6 +1050,11 @@ GfxCalRGBColorSpace::GfxCalRGBColorSpace() {
> }
>
> GfxCalRGBColorSpace::~GfxCalRGBColorSpace() {
>+#ifdef USE_CMS
>+ if (transform != NULL) {
>+ if (transform->unref() == 0) delete transform;
>+ }
>+#endif
> }
>
> GfxColorSpace *GfxCalRGBColorSpace::copy() {
>@@ -1036,10 +1074,14 @@ GfxColorSpace *GfxCalRGBColorSpace::copy() {
> for (i = 0; i < 9; ++i) {
> cs->mat[i] = mat[i];
> }
>+#ifdef USE_CMS
>+ cs->transform = transform;
>+ if (transform != NULL) transform->ref();
>+#endif
> return cs;
> }
>
>-GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr) {
>+GfxColorSpace *GfxCalRGBColorSpace::parse(Array *arr, GfxState *state) {
> GfxCalRGBColorSpace *cs;
> Object obj1, obj2, obj3;
> int i;
>@@ -1121,6 +1163,10 @@ GfxColorSpace *GfxCalRGBColorSpace::parse(Array
>*arr) {
> xyzrgb[2][1] * cs->whiteY +
> xyzrgb[2][2] * cs->whiteZ);
>
>+#ifdef USE_CMS
>+ cs->transform = (state != NULL) ? state->getXYZ2DisplayTransform() :
>XYZ2DisplayTransform;
>+ if (cs->transform != NULL) cs->transform->ref();
>+#endif
> return cs;
> }
>
>@@ -1141,7 +1187,7 @@ void GfxCalRGBColorSpace::getGray(GfxColor *color,
>GfxGray *gray) {
> GfxRGB rgb;
>
> #ifdef USE_CMS
>- if (XYZ2DisplayTransform != NULL && displayPixelType == PT_GRAY) {
>+ if (transform != NULL && transform->getTransformPixelType() ==
>PT_GRAY) {
> Guchar out[gfxColorMaxComps];
> double in[gfxColorMaxComps];
> double X, Y, Z;
>@@ -1150,7 +1196,7 @@ void GfxCalRGBColorSpace::getGray(GfxColor *color,
>GfxGray *gray) {
> in[0] = clip01(X);
> in[1] = clip01(Y);
> in[2] = clip01(Z);
>- XYZ2DisplayTransform->doTransform(in,out,1);
>+ transform->doTransform(in,out,1);
> *gray = byteToCol(out[0]);
> return;
> }
>@@ -1167,14 +1213,14 @@ void GfxCalRGBColorSpace::getRGB(GfxColor *color,
>GfxRGB *rgb) {
>
> getXYZ(color,&X,&Y,&Z);
> #ifdef USE_CMS
>- if (XYZ2DisplayTransform != NULL && displayPixelType == PT_RGB) {
>+ if (transform != NULL && transform->getTransformPixelType() == PT_RGB)
>{
> Guchar out[gfxColorMaxComps];
> double in[gfxColorMaxComps];
>
> in[0] = clip01(X/whiteX);
> in[1] = clip01(Y/whiteY);
> in[2] = clip01(Z/whiteZ);
>- XYZ2DisplayTransform->doTransform(in,out,1);
>+ transform->doTransform(in,out,1);
> rgb->r = byteToCol(out[0]);
> rgb->g = byteToCol(out[1]);
> rgb->b = byteToCol(out[2]);
>@@ -1195,7 +1241,7 @@ void GfxCalRGBColorSpace::getCMYK(GfxColor *color,
>GfxCMYK *cmyk) {
> GfxColorComp c, m, y, k;
>
> #ifdef USE_CMS
>- if (XYZ2DisplayTransform != NULL && displayPixelType == PT_CMYK) {
>+ if (transform != NULL && transform->getTransformPixelType() ==
>PT_CMYK) {
> double in[gfxColorMaxComps];
> Guchar out[gfxColorMaxComps];
> double X, Y, Z;
>@@ -1204,7 +1250,7 @@ void GfxCalRGBColorSpace::getCMYK(GfxColor *color,
>GfxCMYK *cmyk) {
> in[0] = clip01(X);
> in[1] = clip01(Y);
> in[2] = clip01(Z);
>- XYZ2DisplayTransform->doTransform(in,out,1);
>+ transform->doTransform(in,out,1);
> cmyk->c = byteToCol(out[0]);
> cmyk->m = byteToCol(out[1]);
> cmyk->y = byteToCol(out[2]);
>@@ -1391,6 +1437,11 @@ GfxLabColorSpace::GfxLabColorSpace() {
> }
>
> GfxLabColorSpace::~GfxLabColorSpace() {
>+#ifdef USE_CMS
>+ if (transform != NULL) {
>+ if (transform->unref() == 0) delete transform;
>+ }
>+#endif
> }
>
> GfxColorSpace *GfxLabColorSpace::copy() {
>@@ -1410,10 +1461,14 @@ GfxColorSpace *GfxLabColorSpace::copy() {
> cs->kr = kr;
> cs->kg = kg;
> cs->kb = kb;
>+#ifdef USE_CMS
>+ cs->transform = transform;
>+ if (transform != NULL) transform->ref();
>+#endif
> return cs;
> }
>
>-GfxColorSpace *GfxLabColorSpace::parse(Array *arr) {
>+GfxColorSpace *GfxLabColorSpace::parse(Array *arr, GfxState *state) {
> GfxLabColorSpace *cs;
> Object obj1, obj2, obj3;
>
>@@ -1478,6 +1533,10 @@ GfxColorSpace *GfxLabColorSpace::parse(Array *arr)
>{
> xyzrgb[2][1] * cs->whiteY +
> xyzrgb[2][2] * cs->whiteZ);
>
>+#ifdef USE_CMS
>+ cs->transform = (state != NULL) ? state->getXYZ2DisplayTransform() :
>XYZ2DisplayTransform;
>+ if (cs->transform != NULL) cs->transform->ref();
>+#endif
> return cs;
> }
>
>@@ -1485,12 +1544,12 @@ void GfxLabColorSpace::getGray(GfxColor *color,
>GfxGray *gray) {
> GfxRGB rgb;
>
> #ifdef USE_CMS
>- if (XYZ2DisplayTransform != NULL && displayPixelType == PT_GRAY) {
>+ if (transform != NULL && transform->getTransformPixelType() ==
>PT_GRAY) {
> Guchar out[gfxColorMaxComps];
> double in[gfxColorMaxComps];
>
> getXYZ(color, &in[0], &in[1], &in[2]);
>- XYZ2DisplayTransform->doTransform(in,out,1);
>+ transform->doTransform(in,out,1);
> *gray = byteToCol(out[0]);
> return;
> }
>@@ -1537,18 +1596,40 @@ void GfxLabColorSpace::getRGB(GfxColor *color,
>GfxRGB *rgb) {
>
> getXYZ(color, &X, &Y, &Z);
> #ifdef USE_CMS
>- if (XYZ2DisplayTransform != NULL && displayPixelType == PT_RGB) {
>+ if (transform != NULL && transform->getTransformPixelType() == PT_RGB)
>{
> Guchar out[gfxColorMaxComps];
> double in[gfxColorMaxComps];
>
> in[0] = clip01(X);
> in[1] = clip01(Y);
> in[2] = clip01(Z);
>- XYZ2DisplayTransform->doTransform(in,out,1);
>+ transform->doTransform(in,out,1);
> rgb->r = byteToCol(out[0]);
> rgb->g = byteToCol(out[1]);
> rgb->b = byteToCol(out[2]);
> return;
>+ } else if (transform != NULL && transform->getTransformPixelType() ==
>PT_CMYK) {
>+ Guchar out[gfxColorMaxComps];
>+ double in[gfxColorMaxComps];
>+ double c, m, y, k, c1, m1, y1, k1, r, g, b;
>+
>+ in[0] = clip01(X);
>+ in[1] = clip01(Y);
>+ in[2] = clip01(Z);
>+ transform->doTransform(in,out,1);
>+ c = byteToDbl(out[0]);
>+ m = byteToDbl(out[1]);
>+ y = byteToDbl(out[2]);
>+ k = byteToDbl(out[3]);
>+ c1 = 1 - c;
>+ m1 = 1 - m;
>+ y1 = 1 - y;
>+ k1 = 1 - k;
>+ cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
>+ rgb->r = clip01(dblToCol(r));
>+ rgb->g = clip01(dblToCol(g));
>+ rgb->b = clip01(dblToCol(b));
>+ return;
> }
> #endif
> X *= whiteX;
>@@ -1568,12 +1649,12 @@ void GfxLabColorSpace::getCMYK(GfxColor *color,
>GfxCMYK *cmyk) {
> GfxColorComp c, m, y, k;
>
> #ifdef USE_CMS
>- if (XYZ2DisplayTransform != NULL && displayPixelType == PT_CMYK) {
>+ if (transform != NULL && transform->getTransformPixelType() ==
>PT_CMYK) {
> double in[gfxColorMaxComps];
> Guchar out[gfxColorMaxComps];
>
> getXYZ(color, &in[0], &in[1], &in[2]);
>- XYZ2DisplayTransform->doTransform(in,out,1);
>+ transform->doTransform(in,out,1);
> cmyk->c = byteToCol(out[0]);
> cmyk->m = byteToCol(out[1]);
> cmyk->y = byteToCol(out[2]);
>@@ -1716,7 +1797,7 @@ GfxColorSpace *GfxICCBasedColorSpace::copy() {
> return cs;
> }
>
>-GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, OutputDev *out,
>int recursion) {
>+GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, OutputDev *out,
>GfxState *state, int recursion) {
> GfxICCBasedColorSpace *cs;
> Ref iccProfileStreamA;
> int nCompsA;
>@@ -1745,7 +1826,24 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array
>*arr, OutputDev *out, int recu
> if (item != NULL)
> {
> cs = static_cast<GfxICCBasedColorSpace*>(item->cs->copy());
>- return cs;
>+ int transformIntent = cs->getIntent();
>+ int cmsIntent = INTENT_RELATIVE_COLORIMETRIC;
>+ if (state != NULL) {
>+ const char *intent = state->getRenderingIntent();
>+ if (intent != NULL) {
>+ 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;
>+ }
>+ }
>+ }
>+ if (transformIntent == cmsIntent) {
>+ return cs;
>+ }
>+ delete cs;
> }
> }
> #endif
>@@ -1771,7 +1869,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array
>*arr, OutputDev *out, int recu
> nCompsA = 4;
> }
> if (dict->lookup("Alternate", &obj2)->isNull() ||
>- !(altA = GfxColorSpace::parse(&obj2, out, recursion + 1))) {
>+ !(altA = GfxColorSpace::parse(&obj2, out, state, recursion + 1))) {
> switch (nCompsA) {
> case 1:
> altA = new GfxDeviceGrayColorSpace();
>@@ -1821,32 +1919,46 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array
>*arr, OutputDev *out, int recu
> if (hp == 0) {
> error(errSyntaxWarning, -1, "read ICCBased color space profile
>error");
> } else {
>- cmsHPROFILE dhp = displayProfile;
>+ cmsHPROFILE dhp = (state != NULL && state->getDisplayProfile() !=
>NULL) ? state->getDisplayProfile() : displayProfile;
> if (dhp == NULL) dhp = RGBProfile;
> unsigned int cst = getCMSColorSpaceType(cmsGetColorSpace(hp));
> unsigned int dNChannels = getCMSNChannels(cmsGetColorSpace(dhp));
> unsigned int dcst = getCMSColorSpaceType(cmsGetColorSpace(dhp));
> cmsHTRANSFORM transform;
>+
>+ int cmsIntent = INTENT_RELATIVE_COLORIMETRIC;
>+ if (state != NULL) {
>+ const char *intent = state->getRenderingIntent();
>+ if (intent != NULL) {
>+ 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;
>+ }
>+ }
>+ }
> if ((transform = cmsCreateTransform(hp,
> COLORSPACE_SH(cst) |CHANNELS_SH(nCompsA) | BYTES_SH(1),
> dhp,
> COLORSPACE_SH(dcst) |
> CHANNELS_SH(dNChannels) | BYTES_SH(1),
>- INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == 0) {
>+ cmsIntent, LCMS_FLAGS)) == 0) {
> error(errSyntaxWarning, -1, "Can't create transform");
> cs->transform = NULL;
> } else {
>- cs->transform = new GfxColorTransform(transform);
>+ cs->transform = new GfxColorTransform(transform, cmsIntent, dcst);
> }
>- if (dcst == PT_RGB) {
>+ if (dcst == PT_RGB || dcst == PT_CMYK) {
> // create line transform only when the display is RGB type color
>space
> if ((transform = cmsCreateTransform(hp,
> CHANNELS_SH(nCompsA) | BYTES_SH(1),dhp,
>- TYPE_RGB_8,INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == 0) {
>+ (dcst == PT_RGB) ? TYPE_RGB_8 : TYPE_CMYK_8, cmsIntent,
>LCMS_FLAGS)) == 0) {
> error(errSyntaxWarning, -1, "Can't create transform");
> cs->lineTransform = NULL;
> } else {
>- cs->lineTransform = new GfxColorTransform(transform);
>+ cs->lineTransform = new GfxColorTransform(transform, cmsIntent, dcst);
> }
> }
> cmsCloseProfile(hp);
>@@ -1864,7 +1976,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array
>*arr, OutputDev *out, int recu
>
> void GfxICCBasedColorSpace::getGray(GfxColor *color, GfxGray *gray) {
> #ifdef USE_CMS
>- if (transform != 0 && displayPixelType == PT_GRAY) {
>+ if (transform != 0 && transform->getTransformPixelType() == PT_GRAY) {
> Guchar in[gfxColorMaxComps];
> Guchar out[gfxColorMaxComps];
>
>@@ -1907,8 +2019,7 @@ void GfxICCBasedColorSpace::getGray(GfxColor
>*color, GfxGray *gray) {
>
> void GfxICCBasedColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) {
> #ifdef USE_CMS
>- if (transform != 0
>- && (displayProfile == NULL || displayPixelType == PT_RGB)) {
>+ if (transform != 0 && transform->getTransformPixelType() == PT_RGB) {
> Guchar in[gfxColorMaxComps];
> Guchar out[gfxColorMaxComps];
>
>@@ -1941,11 +2052,10 @@ void GfxICCBasedColorSpace::getRGB(GfxColor
>*color, GfxRGB *rgb) {
> unsigned int value = (out[0] << 16) + (out[1] << 8) + out[2];
> cmsCache.insert(std::pair<unsigned int, unsigned int>(key, value));
> }
>- } else if (transform != 0
>- && (displayProfile == NULL || displayPixelType == PT_CMYK)) {
>+ } else if (transform != NULL && transform->getTransformPixelType() ==
>PT_CMYK) {
> Guchar in[gfxColorMaxComps];
> Guchar out[gfxColorMaxComps];
>- double c, m, y, k, c1, m1, y1, k1, r, g, b;
>+ double c, m, y, k, c1, m1, y1, k1, r, g, b;
>
> for (int i = 0;i < nComps;i++) {
> in[i] = colToByte(color->c[i]);
>@@ -1996,7 +2106,7 @@ void GfxICCBasedColorSpace::getRGB(GfxColor *color,
>GfxRGB *rgb) {
> void GfxICCBasedColorSpace::getRGBLine(Guchar *in, unsigned int *out,
> int length) {
> #ifdef USE_CMS
>- if (lineTransform != 0) {
>+ if (lineTransform != 0 && lineTransform->getTransformPixelType() ==
>PT_RGB) {
> Guchar* tmp = (Guchar *)gmallocn(3 * length, sizeof(Guchar));
> lineTransform->doTransform(in, tmp, length);
> for (int i = 0; i < length; ++i) {
>@@ -2014,7 +2124,7 @@ void GfxICCBasedColorSpace::getRGBLine(Guchar *in,
>unsigned int *out,
>
> void GfxICCBasedColorSpace::getRGBLine(Guchar *in, Guchar *out, int
>length) {
> #ifdef USE_CMS
>- if (lineTransform != 0) {
>+ if (lineTransform != 0 && lineTransform->getTransformPixelType() ==
>PT_RGB) {
> Guchar* tmp = (Guchar *)gmallocn(3 * length, sizeof(Guchar));
> lineTransform->doTransform(in, tmp, length);
> Guchar *current = tmp;
>@@ -2024,6 +2134,26 @@ void GfxICCBasedColorSpace::getRGBLine(Guchar *in,
>Guchar *out, int length) {
> *out++ = *current++;
> }
> gfree(tmp);
>+ } else if (lineTransform != NULL &&
>lineTransform->getTransformPixelType() == PT_CMYK) {
>+ Guchar* tmp = (Guchar *)gmallocn(4 * length, sizeof(Guchar));
>+ lineTransform->doTransform(in, tmp, length);
>+ Guchar *current = tmp;
>+ double c, m, y, k, c1, m1, y1, k1, r, g, b;
>+ for (int i = 0; i < length; ++i) {
>+ c = byteToDbl(*current++);
>+ m = byteToDbl(*current++);
>+ y = byteToDbl(*current++);
>+ k = byteToDbl(*current++);
>+ c1 = 1 - c;
>+ m1 = 1 - m;
>+ y1 = 1 - y;
>+ k1 = 1 - k;
>+ cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
>+ *out++ = dblToByte(r);
>+ *out++ = dblToByte(g);
>+ *out++ = dblToByte(b);
>+ }
>+ gfree(tmp);
> } else {
> alt->getRGBLine(in, out, length);
> }
>@@ -2034,7 +2164,7 @@ void GfxICCBasedColorSpace::getRGBLine(Guchar *in,
>Guchar *out, int length) {
>
> void GfxICCBasedColorSpace::getRGBXLine(Guchar *in, Guchar *out, int
>length) {
> #ifdef USE_CMS
>- if (lineTransform != 0) {
>+ if (lineTransform != 0 && lineTransform->getTransformPixelType() ==
>PT_RGB) {
> Guchar* tmp = (Guchar *)gmallocn(3 * length, sizeof(Guchar));
> lineTransform->doTransform(in, tmp, length);
> Guchar *current = tmp;
>@@ -2055,7 +2185,7 @@ void GfxICCBasedColorSpace::getRGBXLine(Guchar *in,
>Guchar *out, int length) {
>
> void GfxICCBasedColorSpace::getCMYKLine(Guchar *in, Guchar *out, int
>length) {
> #ifdef USE_CMS
>- if (lineTransform != NULL && displayPixelType == PT_CMYK) {
>+ if (lineTransform != NULL && lineTransform->getTransformPixelType() ==
>PT_CMYK) {
> transform->doTransform(in,out,length);
> } else if (lineTransform != NULL) {
> GfxColorComp c, m, y, k;
>@@ -2089,7 +2219,7 @@ void GfxICCBasedColorSpace::getCMYKLine(Guchar *in,
>Guchar *out, int length) {
>
> void GfxICCBasedColorSpace::getDeviceNLine(Guchar *in, Guchar *out, int
>length) {
> #ifdef USE_CMS
>- if (lineTransform != NULL && displayPixelType == PT_CMYK) {
>+ if (lineTransform != NULL && lineTransform->getTransformPixelType() ==
>PT_CMYK) {
> Guchar* tmp = (Guchar *)gmallocn(4 * length, sizeof(Guchar));
> transform->doTransform(in,tmp,length);
> Guchar *p = tmp;
>@@ -2135,7 +2265,7 @@ void GfxICCBasedColorSpace::getDeviceNLine(Guchar
>*in, Guchar *out, int length)
>
> void GfxICCBasedColorSpace::getCMYK(GfxColor *color, GfxCMYK *cmyk) {
> #ifdef USE_CMS
>- if (transform != NULL && displayPixelType == PT_CMYK) {
>+ if (transform != NULL && transform->getTransformPixelType() ==
>PT_CMYK) {
> Guchar in[gfxColorMaxComps];
> Guchar out[gfxColorMaxComps];
>
>@@ -2288,7 +2418,7 @@ GfxColorSpace *GfxIndexedColorSpace::copy() {
> return cs;
> }
>
>-GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr, OutputDev *out,
>int recursion) {
>+GfxColorSpace *GfxIndexedColorSpace::parse(Array *arr, OutputDev *out,
>GfxState *state, int recursion) {
> GfxIndexedColorSpace *cs;
> GfxColorSpace *baseA;
> int indexHighA;
>@@ -2301,7 +2431,7 @@ GfxColorSpace *GfxIndexedColorSpace::parse(Array
>*arr, OutputDev *out, int recur
> goto err1;
> }
> arr->get(1, &obj1);
>- if (!(baseA = GfxColorSpace::parse(&obj1, out, recursion + 1))) {
>+ if (!(baseA = GfxColorSpace::parse(&obj1, out, state, recursion + 1)))
>{
> error(errSyntaxWarning, -1, "Bad Indexed color space (base color
>space)");
> goto err2;
> }
>@@ -2553,7 +2683,7 @@ GfxColorSpace *GfxSeparationColorSpace::copy() {
> }
>
> //~ handle the 'All' and 'None' colorants
>-GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr, OutputDev
>*out, int recursion) {
>+GfxColorSpace *GfxSeparationColorSpace::parse(Array *arr, OutputDev
>*out, GfxState *state, int recursion) {
> GfxSeparationColorSpace *cs;
> GooString *nameA;
> GfxColorSpace *altA;
>@@ -2571,7 +2701,7 @@ GfxColorSpace *GfxSeparationColorSpace::parse(Array
>*arr, OutputDev *out, int re
> nameA = new GooString(obj1.getName());
> obj1.free();
> arr->get(2, &obj1);
>- if (!(altA = GfxColorSpace::parse(&obj1, out, recursion + 1))) {
>+ if (!(altA = GfxColorSpace::parse(&obj1, out, state, recursion + 1))) {
> error(errSyntaxWarning, -1, "Bad Separation color space (alternate
>color space)");
> goto err3;
> }
>@@ -2802,7 +2932,7 @@ GfxColorSpace *GfxDeviceNColorSpace::copy() {
> }
>
> //~ handle the 'None' colorant
>-GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr, OutputDev *out,
>int recursion) {
>+GfxColorSpace *GfxDeviceNColorSpace::parse(Array *arr, OutputDev *out,
>GfxState *state, int recursion) {
> GfxDeviceNColorSpace *cs;
> int nCompsA;
> GooString *namesA[gfxColorMaxComps];
>@@ -2837,7 +2967,7 @@ GfxColorSpace *GfxDeviceNColorSpace::parse(Array
>*arr, OutputDev *out, int recur
> }
> obj1.free();
> arr->get(2, &obj1);
>- if (!(altA = GfxColorSpace::parse(&obj1, out, recursion + 1))) {
>+ if (!(altA = GfxColorSpace::parse(&obj1, out, state, recursion + 1))) {
> error(errSyntaxWarning, -1, "Bad DeviceN color space (alternate
>color space)");
> goto err3;
> }
>@@ -2860,7 +2990,7 @@ GfxColorSpace *GfxDeviceNColorSpace::parse(Array
>*arr, OutputDev *out, int recur
> Object obj3;
> colorants->getVal(i, &obj3);
> if (obj3.isArray()) {
>-
>separationList->append(GfxSeparationColorSpace::parse(obj3.getArray(),
>out, recursion));
>+
>separationList->append(GfxSeparationColorSpace::parse(obj3.getArray(),
>out, state, recursion));
> } else {
> obj3.free();
> obj2.free();
>@@ -3068,7 +3198,7 @@ GfxColorSpace *GfxPatternColorSpace::copy() {
> (GfxColorSpace *)NULL);
> }
>
>-GfxColorSpace *GfxPatternColorSpace::parse(Array *arr, OutputDev *out,
>int recursion) {
>+GfxColorSpace *GfxPatternColorSpace::parse(Array *arr, OutputDev *out,
>GfxState *state, int recursion) {
> GfxPatternColorSpace *cs;
> GfxColorSpace *underA;
> Object obj1;
>@@ -3080,7 +3210,7 @@ GfxColorSpace *GfxPatternColorSpace::parse(Array
>*arr, OutputDev *out, int recur
> underA = NULL;
> if (arr->getLength() == 2) {
> arr->get(1, &obj1);
>- if (!(underA = GfxColorSpace::parse(&obj1, out, recursion + 1))) {
>+ if (!(underA = GfxColorSpace::parse(&obj1, out, state, recursion +
>1))) {
> error(errSyntaxWarning, -1, "Bad Pattern color space (underlying
>color space)");
> obj1.free();
> return NULL;
>@@ -3125,7 +3255,7 @@ GfxPattern::GfxPattern(int typeA) {
> GfxPattern::~GfxPattern() {
> }
>
>-GfxPattern *GfxPattern::parse(Object *obj, OutputDev *out) {
>+GfxPattern *GfxPattern::parse(Object *obj, OutputDev *out, GfxState
>*state) {
> GfxPattern *pattern;
> Object obj1;
>
>@@ -3140,7 +3270,7 @@ GfxPattern *GfxPattern::parse(Object *obj,
>OutputDev *out) {
> if (obj1.isInt() && obj1.getInt() == 1) {
> pattern = GfxTilingPattern::parse(obj);
> } else if (obj1.isInt() && obj1.getInt() == 2) {
>- pattern = GfxShadingPattern::parse(obj, out);
>+ pattern = GfxShadingPattern::parse(obj, out, state);
> }
> obj1.free();
> return pattern;
>@@ -3268,7 +3398,7 @@ GfxPattern *GfxTilingPattern::copy() {
> // GfxShadingPattern
>
>//------------------------------------------------------------------------
>
>-GfxShadingPattern *GfxShadingPattern::parse(Object *patObj, OutputDev
>*out) {
>+GfxShadingPattern *GfxShadingPattern::parse(Object *patObj, OutputDev
>*out, GfxState *state) {
> Dict *dict;
> GfxShading *shadingA;
> double matrixA[6];
>@@ -3281,7 +3411,7 @@ GfxShadingPattern *GfxShadingPattern::parse(Object
>*patObj, OutputDev *out) {
> dict = patObj->getDict();
>
> dict->lookup("Shading", &obj1);
>- shadingA = GfxShading::parse(&obj1, out);
>+ shadingA = GfxShading::parse(&obj1, out, state);
> obj1.free();
> if (!shadingA) {
> return NULL;
>@@ -3354,7 +3484,7 @@ GfxShading::~GfxShading() {
> }
> }
>
>-GfxShading *GfxShading::parse(Object *obj, OutputDev *out) {
>+GfxShading *GfxShading::parse(Object *obj, OutputDev *out, GfxState
>*state) {
> GfxShading *shading;
> Dict *dict;
> int typeA;
>@@ -3378,17 +3508,17 @@ GfxShading *GfxShading::parse(Object *obj,
>OutputDev *out) {
>
> switch (typeA) {
> case 1:
>- shading = GfxFunctionShading::parse(dict, out);
>+ shading = GfxFunctionShading::parse(dict, out, state);
> break;
> case 2:
>- shading = GfxAxialShading::parse(dict, out);
>+ shading = GfxAxialShading::parse(dict, out, state);
> break;
> case 3:
>- shading = GfxRadialShading::parse(dict, out);
>+ shading = GfxRadialShading::parse(dict, out, state);
> break;
> case 4:
> if (obj->isStream()) {
>- shading = GfxGouraudTriangleShading::parse(4, dict,
>obj->getStream(), out);
>+ shading = GfxGouraudTriangleShading::parse(4, dict,
>obj->getStream(), out, state);
> } else {
> error(errSyntaxWarning, -1, "Invalid Type 4 shading object");
> goto err1;
>@@ -3396,7 +3526,7 @@ GfxShading *GfxShading::parse(Object *obj,
>OutputDev *out) {
> break;
> case 5:
> if (obj->isStream()) {
>- shading = GfxGouraudTriangleShading::parse(5, dict,
>obj->getStream(), out);
>+ shading = GfxGouraudTriangleShading::parse(5, dict,
>obj->getStream(), out, state);
> } else {
> error(errSyntaxWarning, -1, "Invalid Type 5 shading object");
> goto err1;
>@@ -3404,7 +3534,7 @@ GfxShading *GfxShading::parse(Object *obj,
>OutputDev *out) {
> break;
> case 6:
> if (obj->isStream()) {
>- shading = GfxPatchMeshShading::parse(6, dict, obj->getStream(),
>out);
>+ shading = GfxPatchMeshShading::parse(6, dict, obj->getStream(),
>out, state);
> } else {
> error(errSyntaxWarning, -1, "Invalid Type 6 shading object");
> goto err1;
>@@ -3412,7 +3542,7 @@ GfxShading *GfxShading::parse(Object *obj,
>OutputDev *out) {
> break;
> case 7:
> if (obj->isStream()) {
>- shading = GfxPatchMeshShading::parse(7, dict, obj->getStream(),
>out);
>+ shading = GfxPatchMeshShading::parse(7, dict, obj->getStream(),
>out, state);
> } else {
> error(errSyntaxWarning, -1, "Invalid Type 7 shading object");
> goto err1;
>@@ -3429,12 +3559,12 @@ GfxShading *GfxShading::parse(Object *obj,
>OutputDev *out) {
> return NULL;
> }
>
>-GBool GfxShading::init(Dict *dict, OutputDev *out) {
>+GBool GfxShading::init(Dict *dict, OutputDev *out, GfxState *state) {
> Object obj1, obj2;
> int i;
>
> dict->lookup("ColorSpace", &obj1);
>- if (!(colorSpace = GfxColorSpace::parse(&obj1, out))) {
>+ if (!(colorSpace = GfxColorSpace::parse(&obj1, out, state))) {
> error(errSyntaxWarning, -1, "Bad color space in shading dictionary");
> obj1.free();
> return gFalse;
>@@ -3541,7 +3671,7 @@ GfxFunctionShading::~GfxFunctionShading() {
> }
> }
>
>-GfxFunctionShading *GfxFunctionShading::parse(Dict *dict, OutputDev
>*out) {
>+GfxFunctionShading *GfxFunctionShading::parse(Dict *dict, OutputDev
>*out, GfxState *state) {
> GfxFunctionShading *shading;
> double x0A, y0A, x1A, y1A;
> double matrixA[6];
>@@ -3609,7 +3739,7 @@ GfxFunctionShading *GfxFunctionShading::parse(Dict
>*dict, OutputDev *out) {
>
> shading = new GfxFunctionShading(x0A, y0A, x1A, y1A, matrixA,
> funcsA, nFuncsA);
>- if (!shading->init(dict, out)) {
>+ if (!shading->init(dict, out, state)) {
> delete shading;
> return NULL;
> }
>@@ -3860,7 +3990,7 @@ GfxAxialShading::GfxAxialShading(GfxAxialShading
>*shading):
> GfxAxialShading::~GfxAxialShading() {
> }
>
>-GfxAxialShading *GfxAxialShading::parse(Dict *dict, OutputDev *out) {
>+GfxAxialShading *GfxAxialShading::parse(Dict *dict, OutputDev *out,
>GfxState *state) {
> GfxAxialShading *shading;
> double x0A, y0A, x1A, y1A;
> double t0A, t1A;
>@@ -3957,7 +4087,7 @@ GfxAxialShading *GfxAxialShading::parse(Dict *dict,
>OutputDev *out) {
>
> shading = new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A,
> funcsA, nFuncsA, extend0A, extend1A);
>- if (!shading->init(dict, out)) {
>+ if (!shading->init(dict, out, state)) {
> delete shading;
> return NULL;
> }
>@@ -4068,7 +4198,7 @@ GfxRadialShading::GfxRadialShading(GfxRadialShading
>*shading):
> GfxRadialShading::~GfxRadialShading() {
> }
>
>-GfxRadialShading *GfxRadialShading::parse(Dict *dict, OutputDev *out) {
>+GfxRadialShading *GfxRadialShading::parse(Dict *dict, OutputDev *out,
>GfxState *state) {
> GfxRadialShading *shading;
> double x0A, y0A, r0A, x1A, y1A, r1A;
> double t0A, t1A;
>@@ -4147,7 +4277,7 @@ GfxRadialShading *GfxRadialShading::parse(Dict
>*dict, OutputDev *out) {
>
> shading = new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A,
> funcsA, nFuncsA, extend0A, extend1A);
>- if (!shading->init(dict, out)) {
>+ if (!shading->init(dict, out, state)) {
> delete shading;
> return NULL;
> }
>@@ -4591,7 +4721,7 @@
>GfxGouraudTriangleShading::~GfxGouraudTriangleShading() {
> GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(int typeA,
> Dict *dict,
> Stream *str,
>- OutputDev *out) {
>+ OutputDev *out, GfxState *gfxState) {
> GfxGouraudTriangleShading *shading;
> Function *funcsA[gfxColorMaxComps];
> int nFuncsA;
>@@ -4787,7 +4917,7 @@ GfxGouraudTriangleShading
>*GfxGouraudTriangleShading::parse(int typeA,
> shading = new GfxGouraudTriangleShading(typeA, verticesA, nVerticesA,
> trianglesA, nTrianglesA,
> funcsA, nFuncsA);
>- if (!shading->init(dict, out)) {
>+ if (!shading->init(dict, out, gfxState)) {
> delete shading;
> return NULL;
> }
>@@ -4934,7 +5064,7 @@ GfxPatchMeshShading::~GfxPatchMeshShading() {
> }
>
> GfxPatchMeshShading *GfxPatchMeshShading::parse(int typeA, Dict *dict,
>- Stream *str, OutputDev *out) {
>+ Stream *str, OutputDev *out, GfxState *state) {
> GfxPatchMeshShading *shading;
> Function *funcsA[gfxColorMaxComps];
> int nFuncsA;
>@@ -5458,7 +5588,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(int
>typeA, Dict *dict,
>
> shading = new GfxPatchMeshShading(typeA, patchesA, nPatchesA,
> funcsA, nFuncsA);
>- if (!shading->init(dict, out)) {
>+ if (!shading->init(dict, out, state)) {
> delete shading;
> return NULL;
> }
>@@ -6394,9 +6524,17 @@ GfxState::GfxState(double hDPIA, double vDPIA,
>PDFRectangle *pageBox,
> clipXMax = pageWidth;
> clipYMax = pageHeight;
>
>+ renderingIntent[0] = 0;
>+
> saved = NULL;
> #ifdef USE_CMS
> GfxColorSpace::setupColorProfiles();
>+ XYZ2DisplayTransformRelCol = NULL;
>+ XYZ2DisplayTransformAbsCol = NULL;
>+ XYZ2DisplayTransformSat = NULL;
>+ XYZ2DisplayTransformPerc = NULL;
>+ localDisplayProfile = NULL;
>+ displayProfileRef = 0;
> #endif
> }
>
>@@ -6428,6 +6566,27 @@ GfxState::~GfxState() {
> if (font) {
> font->decRefCnt();
> }
>+#ifdef USE_CMS
>+ if (XYZ2DisplayTransformRelCol) {
>+ if (XYZ2DisplayTransformRelCol->unref() == 0)
>+ delete XYZ2DisplayTransformRelCol;
>+ }
>+ if (XYZ2DisplayTransformAbsCol) {
>+ if (XYZ2DisplayTransformAbsCol->unref() == 0)
>+ delete XYZ2DisplayTransformAbsCol;
>+ }
>+ if (XYZ2DisplayTransformSat) {
>+ if (XYZ2DisplayTransformSat->unref() == 0)
>+ delete XYZ2DisplayTransformSat;
>+ }
>+ if (XYZ2DisplayTransformPerc) {
>+ if (XYZ2DisplayTransformPerc->unref() == 0)
>+ delete XYZ2DisplayTransformPerc;
>+ }
>+ if (--displayProfileRef == 0 && localDisplayProfile != NULL) {
>+ cmsCloseProfile(localDisplayProfile);
>+ }
>+#endif
> }
>
> // Used for copy();
>@@ -6463,8 +6622,102 @@ GfxState::GfxState(GfxState *state, GBool
>copyPath) {
> path = state->path->copy();
> }
> saved = NULL;
>+#ifdef USE_CMS
>+ if (XYZ2DisplayTransformRelCol) {
>+ XYZ2DisplayTransformRelCol->ref();
>+ }
>+ if (XYZ2DisplayTransformAbsCol) {
>+ XYZ2DisplayTransformAbsCol->ref();
>+ }
>+ if (XYZ2DisplayTransformSat) {
>+ XYZ2DisplayTransformSat->ref();
>+ }
>+ if (XYZ2DisplayTransformPerc) {
>+ XYZ2DisplayTransformPerc->ref();
>+ }
>+ if (localDisplayProfile) {
>+ displayProfileRef++;
>+ }
>+#endif
>+}
>+
>+#ifdef USE_CMS
>+void GfxState::setDisplayProfile(cmsHPROFILE localDisplayProfileA) {
>+ if (localDisplayProfile != NULL) {
>+ cmsCloseProfile(localDisplayProfile);
>+ }
>+ localDisplayProfile = localDisplayProfileA;
>+ if (localDisplayProfileA != NULL) {
>+ cmsHTRANSFORM transform;
>+ unsigned int nChannels;
>+ unsigned int localDisplayPixelType;
>+
>+ localDisplayPixelType =
>getCMSColorSpaceType(cmsGetColorSpace(localDisplayProfile));
>+ nChannels = getCMSNChannels(cmsGetColorSpace(localDisplayProfile));
>+ displayProfileRef = 1;
>+ // create transform from XYZ
>+ cmsHPROFILE XYZProfile = cmsCreateXYZProfile();
>+ if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
>+ localDisplayProfile,
>+ COLORSPACE_SH(localDisplayPixelType) |
>+ CHANNELS_SH(nChannels) | BYTES_SH(1),
>+ INTENT_RELATIVE_COLORIMETRIC,LCMS_FLAGS)) == 0) {
>+ error(errSyntaxWarning, -1, "Can't create Lab transform");
>+ } else {
>+ XYZ2DisplayTransformRelCol = new GfxColorTransform(transform,
>INTENT_RELATIVE_COLORIMETRIC, localDisplayPixelType);
>+ }
>+ if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
>+ localDisplayProfile,
>+ COLORSPACE_SH(localDisplayPixelType) |
>+ CHANNELS_SH(nChannels) | BYTES_SH(1),
>+ INTENT_ABSOLUTE_COLORIMETRIC,LCMS_FLAGS)) == 0) {
>+ error(errSyntaxWarning, -1, "Can't create Lab transform");
>+ } else {
>+ XYZ2DisplayTransformAbsCol = new GfxColorTransform(transform,
>INTENT_ABSOLUTE_COLORIMETRIC, localDisplayPixelType);
>+ }
>+ if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
>+ localDisplayProfile,
>+ COLORSPACE_SH(localDisplayPixelType) |
>+ CHANNELS_SH(nChannels) | BYTES_SH(1),
>+ INTENT_SATURATION,LCMS_FLAGS)) == 0) {
>+ error(errSyntaxWarning, -1, "Can't create Lab transform");
>+ } else {
>+ XYZ2DisplayTransformSat = new GfxColorTransform(transform,
>INTENT_SATURATION, localDisplayPixelType);
>+ }
>+ if ((transform = cmsCreateTransform(XYZProfile, TYPE_XYZ_DBL,
>+ localDisplayProfile,
>+ COLORSPACE_SH(localDisplayPixelType) |
>+ CHANNELS_SH(nChannels) | BYTES_SH(1),
>+ INTENT_PERCEPTUAL,LCMS_FLAGS)) == 0) {
>+ error(errSyntaxWarning, -1, "Can't create Lab transform");
>+ } else {
>+ XYZ2DisplayTransformPerc = new GfxColorTransform(transform,
>INTENT_PERCEPTUAL, localDisplayPixelType);
>+ }
>+ cmsCloseProfile(XYZProfile);
>+ }
> }
>
>+GfxColorTransform *GfxState::getXYZ2DisplayTransform() {
>+ GfxColorTransform *transform;
>+
>+ transform = XYZ2DisplayTransformRelCol;
>+ if (renderingIntent != NULL) {
>+ if (strcmp(renderingIntent, "AbsoluteColorimetric") == 0) {
>+ transform = XYZ2DisplayTransformAbsCol;
>+ } else if (strcmp(renderingIntent, "Saturation") == 0) {
>+ transform = XYZ2DisplayTransformSat;
>+ } else if (strcmp(renderingIntent, "Perceptual") == 0) {
>+ transform = XYZ2DisplayTransformPerc;
>+ }
>+ }
>+ if (transform == NULL) {
>+ transform = XYZ2DisplayTransform;
>+ }
>+ return transform;
>+}
>+
>+#endif
>+
> void GfxState::setPath(GfxPath *pathA) {
> delete path;
> path = pathA;
>diff --git a/poppler/GfxState.h b/poppler/GfxState.h
>index 286008d..106b2c0 100644
>--- a/poppler/GfxState.h
>+++ b/poppler/GfxState.h
>@@ -52,6 +52,7 @@ class GfxShading;
> class PopplerCache;
> class GooList;
> class OutputDev;
>+class GfxState;
>
> class Matrix {
> public:
>@@ -181,14 +182,18 @@ class GfxColorTransform {
> public:
> void doTransform(void *in, void *out, unsigned int size);
> // transformA should be a cmsHTRANSFORM
>- GfxColorTransform(void *transformA);
>+ GfxColorTransform(void *transformA, int cmsIntent, unsigned int
>transformPixelType);
> ~GfxColorTransform();
>+ int getIntent() { return cmsIntent; }
>+ int getTransformPixelType() { return transformPixelType; }
> void ref();
> unsigned int unref();
> private:
> GfxColorTransform() {}
> void *transform;
> unsigned int refCount;
>+ int cmsIntent;
>+ unsigned int transformPixelType;
> };
>
> class GfxColorSpace {
>@@ -200,7 +205,7 @@ public:
> virtual GfxColorSpaceMode getMode() = 0;
>
> // Construct a color space. Returns NULL if unsuccessful.
>- static GfxColorSpace *parse(Object *csObj, OutputDev *out, int
>recursion = 0);
>+ static GfxColorSpace *parse(Object *csObj, OutputDev *out, GfxState
>*state, int recursion = 0);
>
> // Convert to gray, RGB, or CMYK.
> virtual void getGray(GfxColor *color, GfxGray *gray) = 0;
>@@ -313,7 +318,7 @@ public:
> virtual GfxColorSpaceMode getMode() { return csCalGray; }
>
> // Construct a CalGray color space. Returns NULL if unsuccessful.
>- static GfxColorSpace *parse(Array *arr);
>+ static GfxColorSpace *parse(Array *arr, GfxState *state);
>
> virtual void getGray(GfxColor *color, GfxGray *gray);
> virtual void getRGB(GfxColor *color, GfxRGB *rgb);
>@@ -339,6 +344,9 @@ private:
> double gamma; // gamma value
> double kr, kg, kb; // gamut mapping mulitpliers
> void getXYZ(GfxColor *color, double *pX, double *pY, double *pZ);
>+#ifdef USE_CMS
>+ GfxColorTransform *transform;
>+#endif
> };
>
>
>//------------------------------------------------------------------------
>@@ -388,7 +396,7 @@ public:
> virtual GfxColorSpaceMode getMode() { return csCalRGB; }
>
> // Construct a CalRGB color space. Returns NULL if unsuccessful.
>- static GfxColorSpace *parse(Array *arr);
>+ static GfxColorSpace *parse(Array *arr, GfxState *state);
>
> virtual void getGray(GfxColor *color, GfxGray *gray);
> virtual void getRGB(GfxColor *color, GfxRGB *rgb);
>@@ -418,6 +426,9 @@ private:
> double mat[9]; // ABC -> XYZ transform matrix
> double kr, kg, kb; // gamut mapping mulitpliers
> void getXYZ(GfxColor *color, double *pX, double *pY, double *pZ);
>+#ifdef USE_CMS
>+ GfxColorTransform *transform;
>+#endif
> };
>
>
>//------------------------------------------------------------------------
>@@ -464,7 +475,7 @@ public:
> virtual GfxColorSpaceMode getMode() { return csLab; }
>
> // Construct a Lab color space. Returns NULL if unsuccessful.
>- static GfxColorSpace *parse(Array *arr);
>+ static GfxColorSpace *parse(Array *arr, GfxState *state);
>
> virtual void getGray(GfxColor *color, GfxGray *gray);
> virtual void getRGB(GfxColor *color, GfxRGB *rgb);
>@@ -496,6 +507,9 @@ private:
> double aMin, aMax, bMin, bMax; // range for the a and b components
> double kr, kg, kb; // gamut mapping mulitpliers
> void getXYZ(GfxColor *color, double *pX, double *pY, double *pZ);
>+#ifdef USE_CMS
>+ GfxColorTransform *transform;
>+#endif
> };
>
>
>//------------------------------------------------------------------------
>@@ -512,7 +526,7 @@ public:
> virtual GfxColorSpaceMode getMode() { return csICCBased; }
>
> // Construct an ICCBased color space. Returns NULL if unsuccessful.
>- static GfxColorSpace *parse(Array *arr, OutputDev *out, int recursion);
>+ static GfxColorSpace *parse(Array *arr, OutputDev *out, GfxState
>*state, int recursion);
>
> virtual void getGray(GfxColor *color, GfxGray *gray);
> virtual void getRGB(GfxColor *color, GfxRGB *rgb);
>@@ -545,6 +559,7 @@ private:
> double rangeMax[4]; // max values for each component
> Ref iccProfileStream; // the ICC profile
> #ifdef USE_CMS
>+ int getIntent() { return (transform != NULL) ? transform->getIntent()
>: 0; }
> GfxColorTransform *transform;
> GfxColorTransform *lineTransform; // color transform for line
> std::map<unsigned int, unsigned int> cmsCache;
>@@ -563,7 +578,7 @@ public:
> virtual GfxColorSpaceMode getMode() { return csIndexed; }
>
> // Construct an Indexed color space. Returns NULL if unsuccessful.
>- static GfxColorSpace *parse(Array *arr, OutputDev *out, int recursion);
>+ static GfxColorSpace *parse(Array *arr, OutputDev *out, GfxState
>*state, int recursion);
>
> virtual void getGray(GfxColor *color, GfxGray *gray);
> virtual void getRGB(GfxColor *color, GfxRGB *rgb);
>@@ -616,7 +631,7 @@ public:
> virtual GfxColorSpaceMode getMode() { return csSeparation; }
>
> // Construct a Separation color space. Returns NULL if unsuccessful.
>- static GfxColorSpace *parse(Array *arr, OutputDev *out, int recursion);
>+ static GfxColorSpace *parse(Array *arr, OutputDev *out, GfxState
>*state, int recursion);
>
> virtual void getGray(GfxColor *color, GfxGray *gray);
> virtual void getRGB(GfxColor *color, GfxRGB *rgb);
>@@ -661,7 +676,7 @@ public:
> virtual GfxColorSpaceMode getMode() { return csDeviceN; }
>
> // Construct a DeviceN color space. Returns NULL if unsuccessful.
>- static GfxColorSpace *parse(Array *arr, OutputDev *out, int recursion);
>+ static GfxColorSpace *parse(Array *arr, OutputDev *out, GfxState
>*state, int recursion);
>
> virtual void getGray(GfxColor *color, GfxGray *gray);
> virtual void getRGB(GfxColor *color, GfxRGB *rgb);
>@@ -708,7 +723,7 @@ public:
> virtual GfxColorSpaceMode getMode() { return csPattern; }
>
> // Construct a Pattern color space. Returns NULL if unsuccessful.
>- static GfxColorSpace *parse(Array *arr, OutputDev *out, int recursion);
>+ static GfxColorSpace *parse(Array *arr, OutputDev *out, GfxState
>*state, int recursion);
>
> virtual void getGray(GfxColor *color, GfxGray *gray);
> virtual void getRGB(GfxColor *color, GfxRGB *rgb);
>@@ -737,7 +752,7 @@ public:
> GfxPattern(int typeA);
> virtual ~GfxPattern();
>
>- static GfxPattern *parse(Object *obj, OutputDev *out);
>+ static GfxPattern *parse(Object *obj, OutputDev *out, GfxState *state);
>
> virtual GfxPattern *copy() = 0;
>
>@@ -793,7 +808,7 @@ private:
> class GfxShadingPattern: public GfxPattern {
> public:
>
>- static GfxShadingPattern *parse(Object *patObj, OutputDev *out);
>+ static GfxShadingPattern *parse(Object *patObj, OutputDev *out,
>GfxState *state);
> virtual ~GfxShadingPattern();
>
> virtual GfxPattern *copy();
>@@ -820,7 +835,7 @@ public:
> GfxShading(GfxShading *shading);
> virtual ~GfxShading();
>
>- static GfxShading *parse(Object *obj, OutputDev *out);
>+ static GfxShading *parse(Object *obj, OutputDev *out, GfxState *state);
>
> virtual GfxShading *copy() = 0;
>
>@@ -834,7 +849,7 @@ public:
>
> protected:
>
>- GBool init(Dict *dict, OutputDev *out);
>+ GBool init(Dict *dict, OutputDev *out, GfxState *state);
>
> int type;
> GfxColorSpace *colorSpace;
>@@ -903,7 +918,7 @@ public:
> GfxFunctionShading(GfxFunctionShading *shading);
> virtual ~GfxFunctionShading();
>
>- static GfxFunctionShading *parse(Dict *dict, OutputDev *out);
>+ static GfxFunctionShading *parse(Dict *dict, OutputDev *out, GfxState
>*state);
>
> virtual GfxShading *copy();
>
>@@ -937,7 +952,7 @@ public:
> GfxAxialShading(GfxAxialShading *shading);
> virtual ~GfxAxialShading();
>
>- static GfxAxialShading *parse(Dict *dict, OutputDev *out);
>+ static GfxAxialShading *parse(Dict *dict, OutputDev *out, GfxState
>*state);
>
> virtual GfxShading *copy();
>
>@@ -970,7 +985,7 @@ public:
> GfxRadialShading(GfxRadialShading *shading);
> virtual ~GfxRadialShading();
>
>- static GfxRadialShading *parse(Dict *dict, OutputDev *out);
>+ static GfxRadialShading *parse(Dict *dict, OutputDev *out, GfxState
>*state);
>
> virtual GfxShading *copy();
>
>@@ -1008,7 +1023,7 @@ public:
> GfxGouraudTriangleShading(GfxGouraudTriangleShading *shading);
> virtual ~GfxGouraudTriangleShading();
>
>- static GfxGouraudTriangleShading *parse(int typeA, Dict *dict, Stream
>*str, OutputDev *out);
>+ static GfxGouraudTriangleShading *parse(int typeA, Dict *dict, Stream
>*str, OutputDev *out, GfxState *state);
>
> virtual GfxShading *copy();
>
>@@ -1094,7 +1109,7 @@ public:
> GfxPatchMeshShading(GfxPatchMeshShading *shading);
> virtual ~GfxPatchMeshShading();
>
>- static GfxPatchMeshShading *parse(int typeA, Dict *dict, Stream *str,
>OutputDev *out);
>+ static GfxPatchMeshShading *parse(int typeA, Dict *dict, Stream *str,
>OutputDev *out, GfxState *state);
>
> virtual GfxShading *copy();
>
>@@ -1439,6 +1454,7 @@ public:
> double getLeading() { return leading; }
> double getRise() { return rise; }
> int getRender() { return render; }
>+ char *getRenderingIntent() { return renderingIntent; }
> GfxPath *getPath() { return path; }
> void setPath(GfxPath *pathA);
> double getCurX() { return curX; }
>@@ -1517,6 +1533,14 @@ public:
> { rise = riseA; }
> void setRender(int renderA)
> { render = renderA; }
>+ void setRenderingIntent(const char *intent)
>+ { strncpy(renderingIntent, intent, 31); }
>+
>+#ifdef USE_CMS
>+ void setDisplayProfile(void *localDisplayProfileA);
>+ void *getDisplayProfile() { return localDisplayProfile; }
>+ GfxColorTransform *getXYZ2DisplayTransform();
>+#endif
>
> // Add to path.
> void moveTo(double x, double y)
>@@ -1605,10 +1629,20 @@ private:
>
> double clipXMin, clipYMin, // bounding box for clip region
> clipXMax, clipYMax;
>+ char renderingIntent[32];
>
> GfxState *saved; // next GfxState on stack
>
> GfxState(GfxState *state, GBool copyPath);
>+
>+#ifdef USE_CMS
>+ void *localDisplayProfile;
>+ int displayProfileRef;
>+ GfxColorTransform *XYZ2DisplayTransformRelCol;
>+ GfxColorTransform *XYZ2DisplayTransformAbsCol;
>+ GfxColorTransform *XYZ2DisplayTransformSat;
>+ GfxColorTransform *XYZ2DisplayTransformPerc;
>+#endif
> };
>
> #endif
>diff --git a/poppler/Page.cc b/poppler/Page.cc
>index 0465c6b..ecdff32 100644
>--- a/poppler/Page.cc
>+++ b/poppler/Page.cc
>@@ -672,7 +672,7 @@ GBool Page::loadThumb(unsigned char **data_out,
> obj1.free ();
> dict->lookup ("CS", &obj1);
> }
>- colorSpace = GfxColorSpace::parse(&obj1, NULL);
>+ colorSpace = GfxColorSpace::parse(&obj1, NULL, NULL);
> obj1.free();
> if (!colorSpace) {
> fprintf (stderr, "Error: Cannot parse color space\n");
>_______________________________________________
>poppler mailing list
>poppler at lists.freedesktop.org
>http://lists.freedesktop.org/mailman/listinfo/poppler
More information about the poppler
mailing list