From 73a4f420075169379e651b792a3d529faa875e81 Mon Sep 17 00:00:00 2001
From: Adrian Johnson <ajohnson@redneon.com>
Date: Tue, 9 Mar 2010 22:33:23 +1030
Subject: [PATCH] Get PS color space from LCMS for ICC color spaces

Use cmsGetPostScriptCSA() to get the PostScipt color space
for ICC based colors.
---
 poppler/GfxState.cc    |   35 +++++++++++++++++++++++++++++------
 poppler/GfxState.h     |    7 ++++++-
 poppler/PSOutputDev.cc |   17 +++++++++++++++++
 3 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index 12e14d6..aaa73b1 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -137,12 +137,15 @@ void GfxColorTransform::doTransform(void *in, void *out, unsigned int size) {
 }
 
 // transformA should be a cmsHTRANSFORM
-GfxColorTransform::GfxColorTransform(void *transformA) {
+GfxColorTransform::GfxColorTransform(void *sourceProfileA, void *transformA) {
+  sourceProfile = sourceProfileA;
   transform = transformA;
   refCount = 1;
 }
 
 GfxColorTransform::~GfxColorTransform() {
+  if (sourceProfile)
+    cmsCloseProfile(sourceProfile);
   cmsDeleteTransform(transform);
 }
 
@@ -346,10 +349,10 @@ int GfxColorSpace::setupColorProfiles()
 	     CHANNELS_SH(nChannels) | BYTES_SH(1),
 	  INTENT_RELATIVE_COLORIMETRIC,0)) == 0) {
       error(-1, "Can't create Lab transform");
+      cmsCloseProfile(XYZProfile);
     } else {
-      XYZ2DisplayTransform = new GfxColorTransform(transform);
+      XYZ2DisplayTransform = new GfxColorTransform(XYZProfile, transform);
     }
-    cmsCloseProfile(XYZProfile);
   }
   return 0;
 }
@@ -1516,7 +1519,7 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, Gfx *gfx) {
       error(-1, "Can't create transform");
       cs->transform = NULL;
     } else {
-      cs->transform = new GfxColorTransform(transform);
+      cs->transform = new GfxColorTransform(hp, transform);
     }
     if (dcst == PT_RGB) {
        // create line transform only when the display is RGB type color space 
@@ -1526,10 +1529,9 @@ GfxColorSpace *GfxICCBasedColorSpace::parse(Array *arr, Gfx *gfx) {
 	error(-1, "Can't create transform");
 	cs->lineTransform = NULL;
       } else {
-	cs->lineTransform = new GfxColorTransform(transform);
+	cs->lineTransform = new GfxColorTransform(NULL, transform);
       }
     }
-    cmsCloseProfile(hp);
   }
   obj1.free();
   // put this colorSpace into cache
@@ -1684,6 +1686,27 @@ void GfxICCBasedColorSpace::getDefaultRanges(double *decodeLow,
 #endif
 }
 
+#ifdef USE_CMS
+char *GfxICCBasedColorSpace::getPostScriptCSA()
+{
+  cmsHPROFILE profile = transform->getSourceProfile();
+
+  if (profile == NULL) {
+    error(-1, "profile is NULL");
+    return NULL;
+  }
+
+  int size = cmsGetPostScriptCSA(profile, INTENT_RELATIVE_COLORIMETRIC, NULL, 0);
+  if (size == 0)
+    return NULL;
+
+  char *buf = new char[size+1];
+  cmsGetPostScriptCSA(profile, INTENT_RELATIVE_COLORIMETRIC, buf, size);
+  buf[size] = 0;
+  return buf;
+}
+#endif
+
 //------------------------------------------------------------------------
 // GfxIndexedColorSpace
 //------------------------------------------------------------------------
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 7dccfd5..a505c8e 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -160,12 +160,14 @@ class GfxColorTransform {
 public:
   void doTransform(void *in, void *out, unsigned int size);
   // transformA should be a cmsHTRANSFORM
-  GfxColorTransform(void *transformA);
+  GfxColorTransform(void *sourceProfileA, void *transformA);
   ~GfxColorTransform();
   void ref();
   unsigned int unref();
+  void *getSourceProfile() { return sourceProfile; }
 private:
   GfxColorTransform() {}
+  void *sourceProfile;
   void *transform;
   unsigned int refCount;
 };
@@ -463,6 +465,9 @@ public:
 
   // ICCBased-specific access.
   GfxColorSpace *getAlt() { return alt; }
+#ifdef USE_CMS
+  char *getPostScriptCSA();
+#endif
 
 private:
 
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index 179a494..0f3a239 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -5581,6 +5581,7 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace,
   GfxCalGrayColorSpace *calGrayCS;
   GfxCalRGBColorSpace *calRGBCS;
   GfxLabColorSpace *labCS;
+  GfxICCBasedColorSpace *iccBasedCS;
   GfxIndexedColorSpace *indexedCS;
   GfxSeparationColorSpace *separationCS;
   GfxDeviceNColorSpace *deviceNCS;
@@ -5594,6 +5595,7 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace,
   int n, numComps, numAltComps;
   int byte;
   int i, j, k;
+  char *csa;
 
   switch (colorSpace->getMode()) {
 
@@ -5717,10 +5719,25 @@ void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace,
     break;
 
   case csICCBased:
+#if USE_CMS
+    iccBasedCS = (GfxICCBasedColorSpace *)colorSpace;
+    csa = iccBasedCS->getPostScriptCSA();
+    if (csa) {
+      writePSFmt("{0:s}\n", csa);
+      if (genXform) {
+        writePS(" {}");
+      }
+      delete [] csa;
+    } else {
+      dumpColorSpaceL2(((GfxICCBasedColorSpace *)colorSpace)->getAlt(),
+                       genXform, updateColors, gFalse);
+    }
+#else
     // there is no transform function to the alternate color space, so
     // we can use it directly
     dumpColorSpaceL2(((GfxICCBasedColorSpace *)colorSpace)->getAlt(),
 		     genXform, updateColors, gFalse);
+#endif
     break;
 
   case csIndexed:
-- 
1.6.3.3

