--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Tue Sep 07 16:54:39 2010 +0400
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Thu Sep 09 16:20:55 2010 +0400
@@ -27,9 +27,10 @@
// However, the following notice accompanied the original version of this
// file:
//
+//---------------------------------------------------------------------------------
//
-// Little cms
-// Copyright (C) 1998-2007 Marti Maria
+// Little Color Management System
+// Copyright (c) 1998-2008 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -48,22 +49,14 @@
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-// Postscript level 2 operators
-
+//
+//---------------------------------------------------------------------------------
+//
-
-#include "lcms.h"
-#include <time.h>
-#include <stdarg.h>
+#include "lcms2_internal.h"
// PostScript ColorRenderingDictionary and ColorSpaceArray
-LCMSAPI DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile, int Intent, LPVOID Buffer, DWORD dwBufferLen);
-LCMSAPI DWORD LCMSEXPORT cmsGetPostScriptCRD(cmsHPROFILE hProfile, int Intent, LPVOID Buffer, DWORD dwBufferLen);
-LCMSAPI DWORD LCMSEXPORT cmsGetPostScriptCRDEx(cmsHPROFILE hProfile, int Intent, DWORD dwFlags, LPVOID Buffer, DWORD dwBufferLen);
-// -------------------------------------------------------------------- Implementation
#define MAXPSCOLS 60 // Columns on tables
@@ -83,9 +76,9 @@
Color Space Arrays (CSA)
==================================================================================
- In order to obtain precission, code chooses between three ways to implement
+ In order to obtain precision, code chooses between three ways to implement
the device -> XYZ transform. These cases identifies monochrome profiles (often
- implemented as a set of curves), matrix-shaper and LUT-based.
+ implemented as a set of curves), matrix-shaper and Pipeline-based.
Monochrome
-----------
@@ -101,7 +94,7 @@
<<
/DecodeA { transfer function } bind
/MatrixA [D50]
- /RangeLMN [ 0.0 D50X 0.0 D50Y 0.0 D50Z ]
+ /RangeLMN [ 0.0 cmsD50X 0.0 cmsD50Y 0.0 cmsD50Z ]
/WhitePoint [D50]
/BlackPoint [BP]
/RenderingIntent (intent)
@@ -115,7 +108,7 @@
-------------------
This is implemented both with /CIEBasedABC or /CIEBasedDEF on dependig
- of profile implementation. Since here is no interpolation tables, I do
+ of profile implementation. Since here there are no interpolation tables, I do
the conversion directly to XYZ
@@ -124,7 +117,7 @@
<<
/DecodeABC [ {transfer1} {transfer2} {transfer3} ]
/MatrixABC [Matrix]
- /RangeLMN [ 0.0 D50X 0.0 D50Y 0.0 D50Z ]
+ /RangeLMN [ 0.0 cmsD50X 0.0 cmsD50Y 0.0 cmsD50Z ]
/DecodeLMN [ { / 2} dup dup ]
/WhitePoint [D50]
/BlackPoint [BP]
@@ -299,153 +292,66 @@
*/
-static icTagSignature Device2PCSTab[] = {icSigAToB0Tag, // Perceptual
- icSigAToB1Tag, // Relative colorimetric
- icSigAToB2Tag, // Saturation
- icSigAToB1Tag }; // Absolute colorimetric
- // (Relative/WhitePoint)
-
-// --------------------------------------------------------------- Memory Stream
-//
// This struct holds the memory block currently being write
-//
+typedef struct {
+ _cmsStageCLutData* Pipeline;
+ cmsIOHANDLER* m;
+
+ int FirstComponent;
+ int SecondComponent;
-typedef struct {
- LPBYTE Block;
- LPBYTE Ptr;
- DWORD dwMax;
- DWORD dwUsed;
- int MaxCols;
- int Col;
- int HasError;
+ const char* PreMaj;
+ const char* PostMaj;
+ const char* PreMin;
+ const char* PostMin;
- } MEMSTREAM, FAR* LPMEMSTREAM;
+ int FixWhite; // Force mapping of pure white
+
+ cmsColorSpaceSignature ColorSpace; // ColorSpace of profile
-typedef struct {
- LPLUT Lut;
- LPMEMSTREAM m;
-
- int FirstComponent;
- int SecondComponent;
-
- int bps;
- const char* PreMaj;
- const char* PostMaj;
- const char* PreMin;
- const char* PostMin;
-
- int lIsInput; // Handle L* encoding
- int FixWhite; // Force mapping of pure white
-
- icColorSpaceSignature ColorSpace; // ColorSpace of profile
-
-
- } SAMPLERCARGO, FAR* LPSAMPLERCARGO;
+} cmsPsSamplerCargo;
-
-// Creates a ready to use memory stream
-static
-LPMEMSTREAM CreateMemStream(LPBYTE Buffer, DWORD dwMax, int MaxCols)
-{
- LPMEMSTREAM m = (LPMEMSTREAM) _cmsMalloc(sizeof(MEMSTREAM));
- if (m == NULL) return NULL;
-
- ZeroMemory(m, sizeof(MEMSTREAM));
-
- m -> Block = m -> Ptr = Buffer;
- m -> dwMax = dwMax;
- m -> dwUsed = 0;
- m -> MaxCols = MaxCols;
- m -> Col = 0;
- m -> HasError = 0;
-
- return m;
-}
-
+static int _cmsPSActualColumn = 0;
// Convert to byte
static
-BYTE Word2Byte(WORD w)
+cmsUInt8Number Word2Byte(cmsUInt16Number w)
{
- return (BYTE) floor((double) w / 257.0 + 0.5);
+ return (cmsUInt8Number) floor((cmsFloat64Number) w / 257.0 + 0.5);
}
// Convert to byte (using ICC2 notation)
-
-static
-BYTE L2Byte(WORD w)
-{
- int ww = w + 0x0080;
-
- if (ww > 0xFFFF) return 0xFF;
-
- return (BYTE) ((WORD) (ww >> 8) & 0xFF);
-}
-
-// Write a raw, uncooked byte. Check for space
+/*
static
-void WriteRawByte(LPMEMSTREAM m, BYTE b)
+cmsUInt8Number L2Byte(cmsUInt16Number w)
{
- if (m -> dwUsed + 1 > m -> dwMax) {
- m -> HasError = 1;
- }
+ int ww = w + 0x0080;
- if (!m ->HasError && m ->Block) {
- *m ->Ptr++ = b;
- }
+ if (ww > 0xFFFF) return 0xFF;
- m -> dwUsed++;
+ return (cmsUInt8Number) ((cmsUInt16Number) (ww >> 8) & 0xFF);
}
+*/
// Write a cooked byte
+
static
-void WriteByte(LPMEMSTREAM m, BYTE b)
+void WriteByte(cmsIOHANDLER* m, cmsUInt8Number b)
{
- static const BYTE Hex[] = "0123456789ABCDEF";
- BYTE c;
-
- c = Hex[(b >> 4) & 0x0f];
- WriteRawByte(m, c);
-
- c = Hex[b & 0x0f];
- WriteRawByte(m, c);
-
- m -> Col += 2;
-
- if (m -> Col > m -> MaxCols) {
-
- WriteRawByte(m, '\n');
- m -> Col = 0;
- }
-
-}
+ _cmsIOPrintf(m, "%02x", b);
+ _cmsPSActualColumn += 2;
-// Does write a formatted string. Guaranteed to be 2048 bytes at most.
-static
-void Writef(LPMEMSTREAM m, const char *frm, ...)
-{
- va_list args;
- LPBYTE pt;
- BYTE Buffer[2048];
-
- va_start(args, frm);
+ if (_cmsPSActualColumn > MAXPSCOLS) {
- vsnprintf((char*) Buffer, 2048, frm, args);
-
- for (pt = Buffer; *pt; pt++) {
-
- WriteRawByte(m, *pt);
- }
-
- va_end(args);
+ _cmsIOPrintf(m, "\n");
+ _cmsPSActualColumn = 0;
+ }
}
-
-
// ----------------------------------------------------------------- PostScript generation
@@ -466,21 +372,31 @@
}
static
-void EmitHeader(LPMEMSTREAM m, const char* Title, cmsHPROFILE hProfile)
+void EmitHeader(cmsIOHANDLER* m, const char* Title, cmsHPROFILE hProfile)
{
-
time_t timer;
+ cmsMLU *Description, *Copyright;
+ char DescASCII[256], CopyrightASCII[256];
time(&timer);
- Writef(m, "%%!PS-Adobe-3.0\n");
- Writef(m, "%%\n");
- Writef(m, "%% %s\n", Title);
- Writef(m, "%% Source: %s\n", RemoveCR(cmsTakeProductName(hProfile)));
- Writef(m, "%% Description: %s\n", RemoveCR(cmsTakeProductDesc(hProfile)));
- Writef(m, "%% Created: %s", ctime(&timer)); // ctime appends a \n!!!
- Writef(m, "%%\n");
- Writef(m, "%%%%BeginResource\n");
+ Description = (cmsMLU*) cmsReadTag(hProfile, cmsSigProfileDescriptionTag);
+ Copyright = (cmsMLU*) cmsReadTag(hProfile, cmsSigCopyrightTag);
+
+ DescASCII[0] = DescASCII[255] = 0;
+ CopyrightASCII[0] = CopyrightASCII[255] = 0;
+
+ if (Description != NULL) cmsMLUgetASCII(Description, cmsNoLanguage, cmsNoCountry, DescASCII, 255);
+ if (Copyright != NULL) cmsMLUgetASCII(Copyright, cmsNoLanguage, cmsNoCountry, CopyrightASCII, 255);
+
+ _cmsIOPrintf(m, "%%!PS-Adobe-3.0\n");
+ _cmsIOPrintf(m, "%%\n");
+ _cmsIOPrintf(m, "%% %s\n", Title);
+ _cmsIOPrintf(m, "%% Source: %s\n", RemoveCR(DescASCII));
+ _cmsIOPrintf(m, "%% %s\n", RemoveCR(CopyrightASCII));
+ _cmsIOPrintf(m, "%% Created: %s", ctime(&timer)); // ctime appends a \n!!!
+ _cmsIOPrintf(m, "%%\n");
+ _cmsIOPrintf(m, "%%%%BeginResource\n");
}
@@ -489,31 +405,31 @@
// Black point adapted to D50.
static
-void EmitWhiteBlackD50(LPMEMSTREAM m, LPcmsCIEXYZ BlackPoint)
+void EmitWhiteBlackD50(cmsIOHANDLER* m, cmsCIEXYZ* BlackPoint)
{
- Writef(m, "/BlackPoint [%f %f %f]\n", BlackPoint -> X,
+ _cmsIOPrintf(m, "/BlackPoint [%f %f %f]\n", BlackPoint -> X,
BlackPoint -> Y,
BlackPoint -> Z);
- Writef(m, "/WhitePoint [%f %f %f]\n", cmsD50_XYZ()->X,
+ _cmsIOPrintf(m, "/WhitePoint [%f %f %f]\n", cmsD50_XYZ()->X,
cmsD50_XYZ()->Y,
cmsD50_XYZ()->Z);
}
static
-void EmitRangeCheck(LPMEMSTREAM m)
+void EmitRangeCheck(cmsIOHANDLER* m)
{
- Writef(m, "dup 0.0 lt { pop 0.0 } if "
- "dup 1.0 gt { pop 1.0 } if ");
+ _cmsIOPrintf(m, "dup 0.0 lt { pop 0.0 } if "
+ "dup 1.0 gt { pop 1.0 } if ");
}
// Does write the intent
static
-void EmitIntent(LPMEMSTREAM m, int RenderingIntent)
+void EmitIntent(cmsIOHANDLER* m, int RenderingIntent)
{
const char *intent;
@@ -527,7 +443,7 @@
default: intent = "Undefined"; break;
}
- Writef(m, "/RenderingIntent (%s)\n", intent );
+ _cmsIOPrintf(m, "/RenderingIntent (%s)\n", intent );
}
//
@@ -539,9 +455,9 @@
/*
static
-void EmitL2Y(LPMEMSTREAM m)
+void EmitL2Y(cmsIOHANDLER* m)
{
- Writef(m,
+ _cmsIOPrintf(m,
"{ "
"100 mul 16 add 116 div " // (L * 100 + 16) / 116
"dup 6 29 div ge " // >= 6 / 29 ?
@@ -555,21 +471,21 @@
// Lab -> XYZ, see the discussion above
static
-void EmitLab2XYZ(LPMEMSTREAM m)
+void EmitLab2XYZ(cmsIOHANDLER* m)
{
- Writef(m, "/RangeABC [ 0 1 0 1 0 1]\n");
- Writef(m, "/DecodeABC [\n");
- Writef(m, "{100 mul 16 add 116 div } bind\n");
- Writef(m, "{255 mul 128 sub 500 div } bind\n");
- Writef(m, "{255 mul 128 sub 200 div } bind\n");
- Writef(m, "]\n");
- Writef(m, "/MatrixABC [ 1 1 1 1 0 0 0 0 -1]\n");
- Writef(m, "/RangeLMN [ -0.236 1.254 0 1 -0.635 1.640 ]\n");
- Writef(m, "/DecodeLMN [\n");
- Writef(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.964200 mul} bind\n");
- Writef(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse } bind\n");
- Writef(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.824900 mul} bind\n");
- Writef(m, "]\n");
+ _cmsIOPrintf(m, "/RangeABC [ 0 1 0 1 0 1]\n");
+ _cmsIOPrintf(m, "/DecodeABC [\n");
+ _cmsIOPrintf(m, "{100 mul 16 add 116 div } bind\n");
+ _cmsIOPrintf(m, "{255 mul 128 sub 500 div } bind\n");
+ _cmsIOPrintf(m, "{255 mul 128 sub 200 div } bind\n");
+ _cmsIOPrintf(m, "]\n");
+ _cmsIOPrintf(m, "/MatrixABC [ 1 1 1 1 0 0 0 0 -1]\n");
+ _cmsIOPrintf(m, "/RangeLMN [ -0.236 1.254 0 1 -0.635 1.640 ]\n");
+ _cmsIOPrintf(m, "/DecodeLMN [\n");
+ _cmsIOPrintf(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.964200 mul} bind\n");
+ _cmsIOPrintf(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse } bind\n");
+ _cmsIOPrintf(m, "{dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.824900 mul} bind\n");
+ _cmsIOPrintf(m, "]\n");
}
@@ -577,29 +493,25 @@
// Outputs a table of words. It does use 16 bits
static
-void Emit1Gamma(LPMEMSTREAM m, LPWORD Table, int nEntries)
+void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table)
{
- int i;
- double gamma;
+ cmsUInt32Number i;
+ cmsFloat64Number gamma;
- if (nEntries <= 0) return; // Empty table
+ if (Table ->nEntries <= 0) return; // Empty table
// Suppress whole if identity
- if (cmsIsLinear(Table, nEntries)) {
- Writef(m, "{} ");
- return;
- }
-
+ if (cmsIsToneCurveLinear(Table)) return;
// Check if is really an exponential. If so, emit "exp"
- gamma = cmsEstimateGammaEx(Table, nEntries, 0.001);
+ gamma = cmsEstimateGamma(Table, 0.001);
if (gamma > 0) {
- Writef(m, "{ %g exp } bind ", gamma);
+ _cmsIOPrintf(m, "{ %g exp } bind ", gamma);
return;
}
- Writef(m, "{ ");
+ _cmsIOPrintf(m, "{ ");
// Bounds check
EmitRangeCheck(m);
@@ -609,94 +521,74 @@
// PostScript code Stack
// =============== ========================
// v
- Writef(m, " [");
+ _cmsIOPrintf(m, " [");
- // TODO: Check for endianess!!!
-
- for (i=0; i < nEntries; i++) {
- Writef(m, "%d ", Table[i]);
+ for (i=0; i < Table->nEntries; i++) {
+ _cmsIOPrintf(m, "%d ", Table->Table16[i]);
}
- Writef(m, "] "); // v tab
+ _cmsIOPrintf(m, "] "); // v tab
- Writef(m, "dup "); // v tab tab
- Writef(m, "length 1 sub "); // v tab dom
- Writef(m, "3 -1 roll "); // tab dom v
- Writef(m, "mul "); // tab val2
- Writef(m, "dup "); // tab val2 val2
- Writef(m, "dup "); // tab val2 val2 val2
- Writef(m, "floor cvi "); // tab val2 val2 cell0
- Writef(m, "exch "); // tab val2 cell0 val2
- Writef(m, "ceiling cvi "); // tab val2 cell0 cell1
- Writef(m, "3 index "); // tab val2 cell0 cell1 tab
- Writef(m, "exch "); // tab val2 cell0 tab cell1
- Writef(m, "get "); // tab val2 cell0 y1
- Writef(m, "4 -1 roll "); // val2 cell0 y1 tab
- Writef(m, "3 -1 roll "); // val2 y1 tab cell0
- Writef(m, "get "); // val2 y1 y0
- Writef(m, "dup "); // val2 y1 y0 y0
- Writef(m, "3 1 roll "); // val2 y0 y1 y0
- Writef(m, "sub "); // val2 y0 (y1-y0)
- Writef(m, "3 -1 roll "); // y0 (y1-y0) val2
- Writef(m, "dup "); // y0 (y1-y0) val2 val2
- Writef(m, "floor cvi "); // y0 (y1-y0) val2 floor(val2)
- Writef(m, "sub "); // y0 (y1-y0) rest
- Writef(m, "mul "); // y0 t1
- Writef(m, "add "); // y
- Writef(m, "65535 div "); // result
+ _cmsIOPrintf(m, "dup "); // v tab tab
+ _cmsIOPrintf(m, "length 1 sub "); // v tab dom
+ _cmsIOPrintf(m, "3 -1 roll "); // tab dom v
+ _cmsIOPrintf(m, "mul "); // tab val2
+ _cmsIOPrintf(m, "dup "); // tab val2 val2
+ _cmsIOPrintf(m, "dup "); // tab val2 val2 val2
+ _cmsIOPrintf(m, "floor cvi "); // tab val2 val2 cell0
+ _cmsIOPrintf(m, "exch "); // tab val2 cell0 val2
+ _cmsIOPrintf(m, "ceiling cvi "); // tab val2 cell0 cell1
+ _cmsIOPrintf(m, "3 index "); // tab val2 cell0 cell1 tab
+ _cmsIOPrintf(m, "exch "); // tab val2 cell0 tab cell1
+ _cmsIOPrintf(m, "get "); // tab val2 cell0 y1
+ _cmsIOPrintf(m, "4 -1 roll "); // val2 cell0 y1 tab
+ _cmsIOPrintf(m, "3 -1 roll "); // val2 y1 tab cell0
+ _cmsIOPrintf(m, "get "); // val2 y1 y0
+ _cmsIOPrintf(m, "dup "); // val2 y1 y0 y0
+ _cmsIOPrintf(m, "3 1 roll "); // val2 y0 y1 y0
+ _cmsIOPrintf(m, "sub "); // val2 y0 (y1-y0)
+ _cmsIOPrintf(m, "3 -1 roll "); // y0 (y1-y0) val2
+ _cmsIOPrintf(m, "dup "); // y0 (y1-y0) val2 val2
+ _cmsIOPrintf(m, "floor cvi "); // y0 (y1-y0) val2 floor(val2)
+ _cmsIOPrintf(m, "sub "); // y0 (y1-y0) rest
+ _cmsIOPrintf(m, "mul "); // y0 t1
+ _cmsIOPrintf(m, "add "); // y
+ _cmsIOPrintf(m, "65535 div "); // result
- Writef(m, " } bind ");
+ _cmsIOPrintf(m, " } bind ");
}
// Compare gamma table
static
-LCMSBOOL GammaTableEquals(LPWORD g1, LPWORD g2, int nEntries)
+cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, int nEntries)
{
- return memcmp(g1, g2, nEntries* sizeof(WORD)) == 0;
+ return memcmp(g1, g2, nEntries* sizeof(cmsUInt16Number)) == 0;
}
// Does write a set of gamma curves
static
-void EmitNGamma(LPMEMSTREAM m, int n, LPWORD g[], int nEntries)
+void EmitNGamma(cmsIOHANDLER* m, int n, cmsToneCurve* g[])
{
int i;
for( i=0; i < n; i++ )
{
- if (i > 0 && GammaTableEquals(g[i-1], g[i], nEntries)) {
+ if (i > 0 && GammaTableEquals(g[i-1]->Table16, g[i]->Table16, g[i]->nEntries)) {
- Writef(m, "dup ");
+ _cmsIOPrintf(m, "dup ");
}
else {
- Emit1Gamma(m, g[i], nEntries);
+ Emit1Gamma(m, g[i]);
}
}
}
-// Check whatever a profile has CLUT tables (only on input)
-
-static
-LCMSBOOL IsLUTbased(cmsHPROFILE hProfile, int Intent)
-{
- icTagSignature Tag;
-
- // Check if adequate tag is present
- Tag = Device2PCSTab[Intent];
-
- if (cmsIsTag(hProfile, Tag)) return 1;
-
- // If not present, revert to default (perceptual)
- Tag = icSigAToB0Tag;
-
- // If no tag present, try matrix-shaper
- return cmsIsTag(hProfile, Tag);
-}
@@ -707,19 +599,19 @@
// that is, the callback will be called for each knot with
//
// In[] The grid location coordinates, normalized to 0..ffff
-// Out[] The LUT values, normalized to 0..ffff
+// Out[] The Pipeline values, normalized to 0..ffff
//
// Returning a value other than 0 does terminate the sampling process
//
-// Each row contains LUT values for all but first component. So, I
+// Each row contains Pipeline values for all but first component. So, I
// detect row changing by keeping a copy of last value of first
// component. -1 is used to mark begining of whole block.
static
-int OutputValueSampler(register WORD In[], register WORD Out[], register LPVOID Cargo)
+int OutputValueSampler(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo)
{
- LPSAMPLERCARGO sc = (LPSAMPLERCARGO) Cargo;
- unsigned int i;
+ cmsPsSamplerCargo* sc = (cmsPsSamplerCargo*) Cargo;
+ cmsUInt32Number i;
if (sc -> FixWhite) {
@@ -729,14 +621,14 @@
if ((In[1] >= 0x7800 && In[1] <= 0x8800) &&
(In[2] >= 0x7800 && In[2] <= 0x8800)) {
- WORD* Black;
- WORD* White;
- int nOutputs;
+ cmsUInt16Number* Black;
+ cmsUInt16Number* White;
+ cmsUInt32Number nOutputs;
if (!_cmsEndPointsBySpace(sc ->ColorSpace, &White, &Black, &nOutputs))
return 0;
- for (i=0; i < (unsigned int) nOutputs; i++)
+ for (i=0; i < nOutputs; i++)
Out[i] = White[i];
}
@@ -751,15 +643,15 @@
if (sc ->FirstComponent != -1) {
- Writef(sc ->m, sc ->PostMin);
+ _cmsIOPrintf(sc ->m, sc ->PostMin);
sc ->SecondComponent = -1;
- Writef(sc ->m, sc ->PostMaj);
+ _cmsIOPrintf(sc ->m, sc ->PostMaj);
}
// Begin block
- sc->m->Col = 0;
+ _cmsPSActualColumn = 0;
- Writef(sc ->m, sc ->PreMaj);
+ _cmsIOPrintf(sc ->m, sc ->PreMaj);
sc ->FirstComponent = In[0];
}
@@ -768,96 +660,66 @@
if (sc ->SecondComponent != -1) {
- Writef(sc ->m, sc ->PostMin);
+ _cmsIOPrintf(sc ->m, sc ->PostMin);
}
- Writef(sc ->m, sc ->PreMin);
+ _cmsIOPrintf(sc ->m, sc ->PreMin);
sc ->SecondComponent = In[1];
}
-
-
- // Dump table. Could be Word or byte based on
- // depending on bps member (16 bps mode is not currently
- // being used at all, but is here for future ampliations)
-
- for (i=0; i < sc -> Lut ->OutputChan; i++) {
+ // Dump table.
- WORD wWordOut = Out[i];
-
- if (sc ->bps == 8) {
+ for (i=0; i < sc -> Pipeline ->Params->nOutputs; i++) {
- // Value as byte
- BYTE wByteOut;
-
- // If is input, convert from Lab2 to Lab4 (just divide by 256)
+ cmsUInt16Number wWordOut = Out[i];
+ cmsUInt8Number wByteOut; // Value as byte
- if (sc ->lIsInput) {
-
-
- wByteOut = L2Byte(wWordOut);
- }
- else
- wByteOut = Word2Byte(wWordOut);
+ // We always deal with Lab4
- WriteByte(sc -> m, wByteOut);
- }
- else {
+ wByteOut = Word2Byte(wWordOut);
+ WriteByte(sc -> m, wByteOut);
+ }
- // Value as word
- WriteByte(sc -> m, (BYTE) (wWordOut & 0xFF));
- WriteByte(sc -> m, (BYTE) ((wWordOut >> 8) & 0xFF));
- }
- }
-
- return 1;
+ return 1;
}
-// Writes a LUT on memstream. Could be 8 or 16 bits based
+// Writes a Pipeline on memstream. Could be 8 or 16 bits based
static
-void WriteCLUT(LPMEMSTREAM m, LPLUT Lut, int bps, const char* PreMaj,
- const char* PostMaj,
- const char* PreMin,
- const char* PostMin,
- int lIsInput,
- int FixWhite,
- icColorSpaceSignature ColorSpace)
+void WriteCLUT(cmsIOHANDLER* m, cmsStage* mpe, const char* PreMaj,
+ const char* PostMaj,
+ const char* PreMin,
+ const char* PostMin,
+ int FixWhite,
+ cmsColorSpaceSignature ColorSpace)
{
- unsigned int i;
- SAMPLERCARGO sc;
+ cmsUInt32Number i;
+ cmsPsSamplerCargo sc;
sc.FirstComponent = -1;
sc.SecondComponent = -1;
- sc.Lut = Lut;
+ sc.Pipeline = (_cmsStageCLutData *) mpe ->Data;
sc.m = m;
- sc.bps = bps;
sc.PreMaj = PreMaj;
sc.PostMaj= PostMaj;
sc.PreMin = PreMin;
sc.PostMin = PostMin;
- sc.lIsInput = lIsInput;
sc.FixWhite = FixWhite;
sc.ColorSpace = ColorSpace;
- Writef(m, "[");
+ _cmsIOPrintf(m, "[");
- for (i=0; i < Lut ->InputChan; i++)
- Writef(m, " %d ", Lut ->cLutPoints);
-
- Writef(m, " [\n");
-
-
+ for (i=0; i < sc.Pipeline->Params->nInputs; i++)
+ _cmsIOPrintf(m, " %d ", sc.Pipeline->Params->nSamples[i]);
- cmsSample3DGrid(Lut, OutputValueSampler, (LPVOID) &sc, SAMPLER_INSPECT);
+ _cmsIOPrintf(m, " [\n");
+ cmsStageSampleCLut16bit(mpe, OutputValueSampler, (void*) &sc, SAMPLER_INSPECT);
- Writef(m, PostMin);
- Writef(m, PostMaj);
- Writef(m, "] ");
-
-
+ _cmsIOPrintf(m, PostMin);
+ _cmsIOPrintf(m, PostMaj);
+ _cmsIOPrintf(m, "] ");
}
@@ -865,89 +727,92 @@
// Dumps CIEBasedA Color Space Array
static
-int EmitCIEBasedA(LPMEMSTREAM m, LPWORD Tab, int nEntries, LPcmsCIEXYZ BlackPoint)
+int EmitCIEBasedA(cmsIOHANDLER* m, cmsToneCurve* Curve, cmsCIEXYZ* BlackPoint)
{
- Writef(m, "[ /CIEBasedA\n");
- Writef(m, " <<\n");
+ _cmsIOPrintf(m, "[ /CIEBasedA\n");
+ _cmsIOPrintf(m, " <<\n");
- Writef(m, "/DecodeA ");
+ _cmsIOPrintf(m, "/DecodeA ");
- Emit1Gamma(m,Tab, nEntries);
+ Emit1Gamma(m, Curve);
- Writef(m, " \n");
+ _cmsIOPrintf(m, " \n");
- Writef(m, "/MatrixA [ 0.9642 1.0000 0.8249 ]\n");
- Writef(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n");
+ _cmsIOPrintf(m, "/MatrixA [ 0.9642 1.0000 0.8249 ]\n");
+ _cmsIOPrintf(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n");
- EmitWhiteBlackD50(m, BlackPoint);
- EmitIntent(m, INTENT_PERCEPTUAL);
+ EmitWhiteBlackD50(m, BlackPoint);
+ EmitIntent(m, INTENT_PERCEPTUAL);
- Writef(m, ">>\n");
- Writef(m, "]\n");
+ _cmsIOPrintf(m, ">>\n");
+ _cmsIOPrintf(m, "]\n");
- return 1;
+ return 1;
}
// Dumps CIEBasedABC Color Space Array
static
-int EmitCIEBasedABC(LPMEMSTREAM m, LPWORD L[], int nEntries, LPWMAT3 Matrix, LPcmsCIEXYZ BlackPoint)
+int EmitCIEBasedABC(cmsIOHANDLER* m, cmsFloat64Number* Matrix, cmsToneCurve** CurveSet, cmsCIEXYZ* BlackPoint)
{
int i;
- Writef(m, "[ /CIEBasedABC\n");
- Writef(m, "<<\n");
- Writef(m, "/DecodeABC [ ");
+ _cmsIOPrintf(m, "[ /CIEBasedABC\n");
+ _cmsIOPrintf(m, "<<\n");
+ _cmsIOPrintf(m, "/DecodeABC [ ");
- EmitNGamma(m, 3, L, nEntries);
+ EmitNGamma(m, 3, CurveSet);
- Writef(m, "]\n");
+ _cmsIOPrintf(m, "]\n");
- Writef(m, "/MatrixABC [ " );
+ _cmsIOPrintf(m, "/MatrixABC [ " );
- for( i=0; i < 3; i++ ) {
+ for( i=0; i < 3; i++ ) {
- Writef(m, "%.6f %.6f %.6f ",
- FIXED_TO_DOUBLE(Matrix->v[0].n[i]),
- FIXED_TO_DOUBLE(Matrix->v[1].n[i]),
- FIXED_TO_DOUBLE(Matrix->v[2].n[i]));
- }
+ _cmsIOPrintf(m, "%.6f %.6f %.6f ", Matrix[0 + 3*i],
+ Matrix[1 + 3*i],
+ Matrix[2 + 3*i]);
+ }
- Writef(m, "]\n");
+ _cmsIOPrintf(m, "]\n");
- Writef(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n");
+ _cmsIOPrintf(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n");
- EmitWhiteBlackD50(m, BlackPoint);
- EmitIntent(m, INTENT_PERCEPTUAL);
+ EmitWhiteBlackD50(m, BlackPoint);
+ EmitIntent(m, INTENT_PERCEPTUAL);
- Writef(m, ">>\n");
- Writef(m, "]\n");
+ _cmsIOPrintf(m, ">>\n");
+ _cmsIOPrintf(m, "]\n");
- return 1;
+ return 1;
}
static
-int EmitCIEBasedDEF(LPMEMSTREAM m, LPLUT Lut, int Intent, LPcmsCIEXYZ BlackPoint)
+int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, int Intent, cmsCIEXYZ* BlackPoint)
{
const char* PreMaj;
const char* PostMaj;
const char* PreMin, *PostMin;
+ cmsStage* mpe;
- switch (Lut ->InputChan) {
+ mpe = Pipeline ->Elements;
+
+
+ switch (cmsStageInputChannels(mpe)) {
case 3:
- Writef(m, "[ /CIEBasedDEF\n");
+ _cmsIOPrintf(m, "[ /CIEBasedDEF\n");
PreMaj ="<";
PostMaj= ">\n";
PreMin = PostMin = "";
break;
case 4:
- Writef(m, "[ /CIEBasedDEFG\n");
+ _cmsIOPrintf(m, "[ /CIEBasedDEFG\n");
PreMaj = "[";
PostMaj = "]\n";
PreMin = "<";
@@ -958,30 +823,32 @@
}
- Writef(m, "<<\n");
+ _cmsIOPrintf(m, "<<\n");
- if (Lut ->wFlags & LUT_HASTL1) {
+ if (cmsStageType(mpe) == cmsSigCurveSetElemType) {
- Writef(m, "/DecodeDEF [ ");
- EmitNGamma(m, Lut ->InputChan, Lut ->L1, Lut ->CLut16params.nSamples);
- Writef(m, "]\n");
+ _cmsIOPrintf(m, "/DecodeDEF [ ");
+ EmitNGamma(m, cmsStageOutputChannels(mpe), _cmsStageGetPtrToCurveSet(mpe));
+ _cmsIOPrintf(m, "]\n");
+
+ mpe = mpe ->Next;
}
- if (Lut ->wFlags & LUT_HAS3DGRID) {
+ if (cmsStageType(mpe) == cmsSigCLutElemType) {
- Writef(m, "/Table ");
- WriteCLUT(m, Lut, 8, PreMaj, PostMaj, PreMin, PostMin, TRUE, FALSE, (icColorSpaceSignature) 0);
- Writef(m, "]\n");
+ _cmsIOPrintf(m, "/Table ");
+ WriteCLUT(m, mpe, PreMaj, PostMaj, PreMin, PostMin, FALSE, (cmsColorSpaceSignature) 0);
+ _cmsIOPrintf(m, "]\n");
}
EmitLab2XYZ(m);
EmitWhiteBlackD50(m, BlackPoint);
EmitIntent(m, Intent);
- Writef(m, " >>\n");
- Writef(m, "]\n");
+ _cmsIOPrintf(m, " >>\n");
+ _cmsIOPrintf(m, "]\n");
return 1;
@@ -990,21 +857,21 @@
// Generates a curve from a gray profile
static
-LPGAMMATABLE ExtractGray2Y(cmsHPROFILE hProfile, int Intent)
+cmsToneCurve* ExtractGray2Y(cmsContext ContextID, cmsHPROFILE hProfile, int Intent)
{
- LPGAMMATABLE Out = cmsAllocGamma(256);
- cmsHPROFILE hXYZ = cmsCreateXYZProfile();
- cmsHTRANSFORM xform = cmsCreateTransform(hProfile, TYPE_GRAY_8, hXYZ, TYPE_XYZ_DBL, Intent, cmsFLAGS_NOTPRECALC);
+ cmsToneCurve* Out = cmsBuildTabulatedToneCurve16(ContextID, 256, NULL);
+ cmsHPROFILE hXYZ = cmsCreateXYZProfile();
+ cmsHTRANSFORM xform = cmsCreateTransformTHR(ContextID, hProfile, TYPE_GRAY_8, hXYZ, TYPE_XYZ_DBL, Intent, cmsFLAGS_NOOPTIMIZE);
int i;
for (i=0; i < 256; i++) {
- BYTE Gray = (BYTE) i;
+ cmsUInt8Number Gray = (cmsUInt8Number) i;
cmsCIEXYZ XYZ;
cmsDoTransform(xform, &Gray, &XYZ, 1);
- Out ->GammaTable[i] =_cmsClampWord((int) floor(XYZ.Y * 65535.0 + 0.5));
+ Out ->Table16[i] =_cmsQuickSaturateWord(XYZ.Y * 65535.0);
}
cmsDeleteTransform(xform);
@@ -1014,17 +881,16 @@
-// Because PostScrip has only 8 bits in /Table, we should use
+// Because PostScript has only 8 bits in /Table, we should use
// a more perceptually uniform space... I do choose Lab.
static
-int WriteInputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent)
+int WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, int Intent, cmsUInt32Number dwFlags)
{
cmsHPROFILE hLab;
cmsHTRANSFORM xform;
- icColorSpaceSignature ColorSpace;
- int nChannels;
- DWORD InputFormat;
+ cmsUInt32Number nChannels;
+ cmsUInt32Number InputFormat;
int rc;
cmsHPROFILE Profiles[2];
cmsCIEXYZ BlackPointAdaptedToD50;
@@ -1032,49 +898,25 @@
// Does create a device-link based transform.
// The DeviceLink is next dumped as working CSA.
- hLab = cmsCreateLabProfile(NULL);
- ColorSpace = cmsGetColorSpace(hProfile);
- nChannels = _cmsChannelsOf(ColorSpace);
- InputFormat = CHANNELS_SH(nChannels) | BYTES_SH(2);
-
- cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, Intent,LCMS_BPFLAGS_D50_ADAPTED);
-
- // Is a devicelink profile?
- if (cmsGetDeviceClass(hProfile) == icSigLinkClass) {
-
- // if devicelink output already Lab, use it directly
-
- if (cmsGetPCS(hProfile) == icSigLabData) {
-
- xform = cmsCreateTransform(hProfile, InputFormat, NULL,
- TYPE_Lab_DBL, Intent, 0);
- }
- else {
-
- // Nope, adjust output to Lab if possible
-
- Profiles[0] = hProfile;
- Profiles[1] = hLab;
-
- xform = cmsCreateMultiprofileTransform(Profiles, 2, InputFormat,
- TYPE_Lab_DBL, Intent, 0);
- }
+ InputFormat = cmsFormatterForColorspaceOfProfile(hProfile, 2, FALSE);
+ nChannels = T_CHANNELS(InputFormat);
- }
- else {
+ cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, Intent, 0);
+
+ // Adjust output to Lab4
+ hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
- // This is a normal profile
- xform = cmsCreateTransform(hProfile, InputFormat, hLab,
- TYPE_Lab_DBL, Intent, 0);
- }
+ Profiles[0] = hProfile;
+ Profiles[1] = hLab;
-
+ xform = cmsCreateMultiprofileTransform(Profiles, 2, InputFormat, TYPE_Lab_DBL, Intent, 0);
+ cmsCloseProfile(hLab);
if (xform == NULL) {
- cmsSignalError(LCMS_ERRC_ABORTED, "Cannot create transform Profile -> Lab");
- return 0;
+ cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Cannot create transform Profile -> Lab");
+ return 0;
}
// Only 1, 3 and 4 channels are allowed
@@ -1082,86 +924,82 @@
switch (nChannels) {
case 1: {
- LPGAMMATABLE Gray2Y = ExtractGray2Y(hProfile, Intent);
- EmitCIEBasedA(m, Gray2Y->GammaTable, Gray2Y ->nEntries, &BlackPointAdaptedToD50);
- cmsFreeGamma(Gray2Y);
+ cmsToneCurve* Gray2Y = ExtractGray2Y(m ->ContextID, hProfile, Intent);
+ EmitCIEBasedA(m, Gray2Y, &BlackPointAdaptedToD50);
+ cmsFreeToneCurve(Gray2Y);
}
break;
case 3:
case 4: {
- LPLUT DeviceLink;
- _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform;
+ cmsUInt32Number OutFrm = TYPE_Lab_16;
+ cmsPipeline* DeviceLink;
+ _cmsTRANSFORM* v = (_cmsTRANSFORM*) xform;
- if (v ->DeviceLink)
- rc = EmitCIEBasedDEF(m, v->DeviceLink, Intent, &BlackPointAdaptedToD50);
- else {
- DeviceLink = _cmsPrecalculateDeviceLink(xform, 0);
- rc = EmitCIEBasedDEF(m, DeviceLink, Intent, &BlackPointAdaptedToD50);
- cmsFreeLUT(DeviceLink);
- }
+ DeviceLink = cmsPipelineDup(v ->Lut);
+ if (DeviceLink == NULL) return 0;
+
+ dwFlags |= cmsFLAGS_FORCE_CLUT;
+ _cmsOptimizePipeline(&DeviceLink, Intent, &InputFormat, &OutFrm, &dwFlags);
+
+ rc = EmitCIEBasedDEF(m, DeviceLink, Intent, &BlackPointAdaptedToD50);
+ cmsPipelineFree(DeviceLink);
}
break;
default:
- cmsSignalError(LCMS_ERRC_ABORTED, "Only 3, 4 channels supported for CSA. This profile has %d channels.", nChannels);
- return 0;
+ cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Only 3, 4 channels supported for CSA. This profile has %d channels.", nChannels);
+ return 0;
}
cmsDeleteTransform(xform);
- cmsCloseProfile(hLab);
+
return 1;
}
+static
+cmsFloat64Number* GetPtrToMatrix(const cmsStage* mpe)
+{
+ _cmsStageMatrixData* Data = (_cmsStageMatrixData*) mpe ->Data;
+
+ return Data -> Double;
+}
// Does create CSA based on matrix-shaper. Allowed types are gray and RGB based
static
-int WriteInputMatrixShaper(LPMEMSTREAM m, cmsHPROFILE hProfile)
+int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matrix, cmsStage* Shaper)
{
- icColorSpaceSignature ColorSpace;
- LPMATSHAPER MatShaper;
+ cmsColorSpaceSignature ColorSpace;
int rc;
cmsCIEXYZ BlackPointAdaptedToD50;
-
ColorSpace = cmsGetColorSpace(hProfile);
- MatShaper = cmsBuildInputMatrixShaper(hProfile);
- cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, INTENT_RELATIVE_COLORIMETRIC, LCMS_BPFLAGS_D50_ADAPTED);
-
- if (MatShaper == NULL) {
+ cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, INTENT_RELATIVE_COLORIMETRIC, 0);
- cmsSignalError(LCMS_ERRC_ABORTED, "This profile is not suitable for input");
- return 0;
- }
+ if (ColorSpace == cmsSigGrayData) {
- if (ColorSpace == icSigGrayData) {
-
- rc = EmitCIEBasedA(m, MatShaper ->L[0],
- MatShaper ->p16.nSamples,
- &BlackPointAdaptedToD50);
+ cmsToneCurve** ShaperCurve = _cmsStageGetPtrToCurveSet(Shaper);
+ rc = EmitCIEBasedA(m, ShaperCurve[0], &BlackPointAdaptedToD50);
}
else
- if (ColorSpace == icSigRgbData) {
-
+ if (ColorSpace == cmsSigRgbData) {
- rc = EmitCIEBasedABC(m, MatShaper->L,
- MatShaper ->p16.nSamples,
- &MatShaper ->Matrix,
- &BlackPointAdaptedToD50);
+ rc = EmitCIEBasedABC(m, GetPtrToMatrix(Matrix),
+ _cmsStageGetPtrToCurveSet(Shaper),
+ &BlackPointAdaptedToD50);
}
else {
- cmsSignalError(LCMS_ERRC_ABORTED, "Profile is not suitable for CSA. Unsupported colorspace.");
+ cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Profile is not suitable for CSA. Unsupported colorspace.");
return 0;
}
- cmsFreeMatShaper(MatShaper);
return rc;
}
@@ -1171,45 +1009,46 @@
// This is a HP extension, and it works in Lab instead of XYZ
static
-int WriteNamedColorCSA(LPMEMSTREAM m, cmsHPROFILE hNamedColor, int Intent)
+int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, int Intent)
{
cmsHTRANSFORM xform;
cmsHPROFILE hLab;
int i, nColors;
char ColorName[32];
-
+ cmsNAMEDCOLORLIST* NamedColorList;
- hLab = cmsCreateLabProfile(NULL);
- xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX,
- hLab, TYPE_Lab_DBL, Intent, cmsFLAGS_NOTPRECALC);
+ hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
+ xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX, hLab, TYPE_Lab_DBL, Intent, 0);
if (xform == NULL) return 0;
+ NamedColorList = cmsGetNamedColorList(xform);
+ if (NamedColorList == NULL) return 0;
- Writef(m, "<<\n");
- Writef(m, "(colorlistcomment) (%s)\n", "Named color CSA");
- Writef(m, "(Prefix) [ (Pantone ) (PANTONE ) ]\n");
- Writef(m, "(Suffix) [ ( CV) ( CVC) ( C) ]\n");
+ _cmsIOPrintf(m, "<<\n");
+ _cmsIOPrintf(m, "(colorlistcomment) (%s)\n", "Named color CSA");
+ _cmsIOPrintf(m, "(Prefix) [ (Pantone ) (PANTONE ) ]\n");
+ _cmsIOPrintf(m, "(Suffix) [ ( CV) ( CVC) ( C) ]\n");
- nColors = cmsNamedColorCount(xform);
+ nColors = cmsNamedColorCount(NamedColorList);
for (i=0; i < nColors; i++) {
- WORD In[1];
+ cmsUInt16Number In[1];
cmsCIELab Lab;
- In[0] = (WORD) i;
+ In[0] = (cmsUInt16Number) i;
- if (!cmsNamedColorInfo(xform, i, ColorName, NULL, NULL))
+ if (!cmsNamedColorInfo(NamedColorList, i, ColorName, NULL, NULL, NULL, NULL))
continue;
cmsDoTransform(xform, In, &Lab, 1);
- Writef(m, " (%s) [ %.3f %.3f %.3f ]\n", ColorName, Lab.L, Lab.a, Lab.b);
+ _cmsIOPrintf(m, " (%s) [ %.3f %.3f %.3f ]\n", ColorName, Lab.L, Lab.a, Lab.b);
}
- Writef(m, ">>\n");
+ _cmsIOPrintf(m, ">>\n");
cmsDeleteTransform(xform);
cmsCloseProfile(hLab);
@@ -1218,75 +1057,68 @@
// Does create a Color Space Array on XYZ colorspace for PostScript usage
-
-DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
- int Intent,
- LPVOID Buffer, DWORD dwBufferLen)
+static
+cmsUInt32Number GenerateCSA(cmsContext ContextID,
+ cmsHPROFILE hProfile,
+ cmsUInt32Number Intent,
+ cmsUInt32Number dwFlags,
+ cmsIOHANDLER* mem)
{
-
- LPMEMSTREAM mem;
- DWORD dwBytesUsed;
-
- // Set up the serialization engine
- mem = CreateMemStream((LPBYTE) Buffer, dwBufferLen, MAXPSCOLS);
- if (!mem) return 0;
+ cmsUInt32Number dwBytesUsed;
+ cmsPipeline* lut = NULL;
+ cmsStage* Matrix, *Shaper;
// Is a named color profile?
- if (cmsGetDeviceClass(hProfile) == icSigNamedColorClass) {
-
- if (!WriteNamedColorCSA(mem, hProfile, Intent)) {
+ if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
- _cmsFree((void*) mem);
- return 0;
- }
+ if (!WriteNamedColorCSA(mem, hProfile, Intent)) goto Error;
}
else {
- // Any profile class are allowed (including devicelink), but
- // output (PCS) colorspace must be XYZ or Lab
- icColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
-
- if (ColorSpace != icSigXYZData &&
- ColorSpace != icSigLabData) {
+ // Any profile class are allowed (including devicelink), but
+ // output (PCS) colorspace must be XYZ or Lab
+ cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile);
- cmsSignalError(LCMS_ERRC_ABORTED, "Invalid output color space");
- _cmsFree((void*) mem);
- return 0;
- }
+ if (ColorSpace != cmsSigXYZData &&
+ ColorSpace != cmsSigLabData) {
- // Is there any CLUT?
- if (IsLUTbased(hProfile, Intent)) {
+ cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "Invalid output color space");
+ goto Error;
+ }
+
- // Yes, so handle as LUT-based
- if (!WriteInputLUT(mem, hProfile, Intent)) {
+ // Read the lut with all necessary conversion stages
+ lut = _cmsReadInputLUT(hProfile, Intent);
+ if (lut == NULL) goto Error;
- _cmsFree((void*) mem);
- return 0;
- }
- }
- else {
+
+ // Tone curves + matrix can be implemented without any LUT
+ if (cmsPipelineCheckAndRetreiveStages(lut, 2, cmsSigCurveSetElemType, cmsSigMatrixElemType, &Shaper, &Matrix)) {
- // No, try Matrix-shaper (this only works on XYZ)
-
- if (!WriteInputMatrixShaper(mem, hProfile)) {
+ if (!WriteInputMatrixShaper(mem, hProfile, Matrix, Shaper)) goto Error;
- _cmsFree((void*) mem); // Something went wrong
- return 0;
}
- }
+ else {
+ // We need a LUT for the rest
+ if (!WriteInputLUT(mem, hProfile, Intent, dwFlags)) goto Error;
+ }
}
// Done, keep memory usage
- dwBytesUsed = mem ->dwUsed;
+ dwBytesUsed = mem ->UsedSpace;
- // Get rid of memory stream
- _cmsFree((void*) mem);
+ // Get rid of LUT
+ if (lut != NULL) cmsPipelineFree(lut);
// Finally, return used byte count
return dwBytesUsed;
+
+Error:
+ if (lut != NULL) cmsPipelineFree(lut);
+ return 0;
}
// ------------------------------------------------------ Color Rendering Dictionary (CRD)
@@ -1356,45 +1188,45 @@
static
-void EmitPQRStage(LPMEMSTREAM m, cmsHPROFILE hProfile, int DoBPC, int lIsAbsolute)
+void EmitPQRStage(cmsIOHANDLER* m, cmsHPROFILE hProfile, int DoBPC, int lIsAbsolute)
{
if (lIsAbsolute) {
// For absolute colorimetric intent, encode back to relative
- // and generate a relative LUT
+ // and generate a relative Pipeline
// Relative encoding is obtained across XYZpcs*(D50/WhitePoint)
cmsCIEXYZ White;
- cmsTakeMediaWhitePoint(&White, hProfile);
+ _cmsReadMediaWhitePoint(&White, hProfile);
- Writef(m,"/MatrixPQR [1 0 0 0 1 0 0 0 1 ]\n");
- Writef(m,"/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
+ _cmsIOPrintf(m,"/MatrixPQR [1 0 0 0 1 0 0 0 1 ]\n");
+ _cmsIOPrintf(m,"/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
- Writef(m, "%% Absolute colorimetric -- encode to relative to maximize LUT usage\n"
+ _cmsIOPrintf(m, "%% Absolute colorimetric -- encode to relative to maximize LUT usage\n"
"/TransformPQR [\n"
"{0.9642 mul %g div exch pop exch pop exch pop exch pop} bind\n"
"{1.0000 mul %g div exch pop exch pop exch pop exch pop} bind\n"
"{0.8249 mul %g div exch pop exch pop exch pop exch pop} bind\n]\n",
- White.X, White.Y, White.Z);
+ White.X, White.Y, White.Z);
return;
}
- Writef(m,"%% Bradford Cone Space\n"
+ _cmsIOPrintf(m,"%% Bradford Cone Space\n"
"/MatrixPQR [0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296 ] \n");
- Writef(m, "/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
+ _cmsIOPrintf(m, "/RangePQR [ -0.5 2 -0.5 2 -0.5 2 ]\n");
// No BPC
if (!DoBPC) {
- Writef(m, "%% VonKries-like transform in Bradford Cone Space\n"
+ _cmsIOPrintf(m, "%% VonKries-like transform in Bradford Cone Space\n"
"/TransformPQR [\n"
"{exch pop exch 3 get mul exch pop exch 3 get div} bind\n"
"{exch pop exch 4 get mul exch pop exch 4 get div} bind\n"
@@ -1403,22 +1235,22 @@
// BPC
- Writef(m, "%% VonKries-like transform in Bradford Cone Space plus BPC\n"
+ _cmsIOPrintf(m, "%% VonKries-like transform in Bradford Cone Space plus BPC\n"
"/TransformPQR [\n");
- Writef(m, "{4 index 3 get div 2 index 3 get mul "
+ _cmsIOPrintf(m, "{4 index 3 get div 2 index 3 get mul "
"2 index 3 get 2 index 3 get sub mul "
"2 index 3 get 4 index 3 get 3 index 3 get sub mul sub "
"3 index 3 get 3 index 3 get exch sub div "
"exch pop exch pop exch pop exch pop } bind\n");
- Writef(m, "{4 index 4 get div 2 index 4 get mul "
+ _cmsIOPrintf(m, "{4 index 4 get div 2 index 4 get mul "
"2 index 4 get 2 index 4 get sub mul "
"2 index 4 get 4 index 4 get 3 index 4 get sub mul sub "
"3 index 4 get 3 index 4 get exch sub div "
"exch pop exch pop exch pop exch pop } bind\n");
- Writef(m, "{4 index 5 get div 2 index 5 get mul "
+ _cmsIOPrintf(m, "{4 index 5 get div 2 index 5 get mul "
"2 index 5 get 2 index 5 get sub mul "
"2 index 5 get 4 index 5 get 3 index 5 get sub mul sub "
"3 index 5 get 3 index 5 get exch sub div "
@@ -1431,24 +1263,24 @@
static
-void EmitXYZ2Lab(LPMEMSTREAM m)
+void EmitXYZ2Lab(cmsIOHANDLER* m)
{
- Writef(m, "/RangeLMN [ -0.635 2.0 0 2 -0.635 2.0 ]\n");
- Writef(m, "/EncodeLMN [\n");
- Writef(m, "{ 0.964200 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
- Writef(m, "{ 1.000000 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
- Writef(m, "{ 0.824900 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
- Writef(m, "]\n");
- Writef(m, "/MatrixABC [ 0 1 0 1 -1 1 0 0 -1 ]\n");
- Writef(m, "/EncodeABC [\n");
+ _cmsIOPrintf(m, "/RangeLMN [ -0.635 2.0 0 2 -0.635 2.0 ]\n");
+ _cmsIOPrintf(m, "/EncodeLMN [\n");
+ _cmsIOPrintf(m, "{ 0.964200 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
+ _cmsIOPrintf(m, "{ 1.000000 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
+ _cmsIOPrintf(m, "{ 0.824900 div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind\n");
+ _cmsIOPrintf(m, "]\n");
+ _cmsIOPrintf(m, "/MatrixABC [ 0 1 0 1 -1 1 0 0 -1 ]\n");
+ _cmsIOPrintf(m, "/EncodeABC [\n");
- Writef(m, "{ 116 mul 16 sub 100 div } bind\n");
- Writef(m, "{ 500 mul 128 add 256 div } bind\n");
- Writef(m, "{ 200 mul 128 add 256 div } bind\n");
+ _cmsIOPrintf(m, "{ 116 mul 16 sub 100 div } bind\n");
+ _cmsIOPrintf(m, "{ 500 mul 128 add 256 div } bind\n");
+ _cmsIOPrintf(m, "{ 200 mul 128 add 256 div } bind\n");
- Writef(m, "]\n");
+ _cmsIOPrintf(m, "]\n");
}
@@ -1460,104 +1292,74 @@
// 8 bits.
static
-int WriteOutputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent, DWORD dwFlags)
+int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, int Intent, cmsUInt32Number dwFlags)
{
cmsHPROFILE hLab;
cmsHTRANSFORM xform;
- icColorSpaceSignature ColorSpace;
int i, nChannels;
- DWORD OutputFormat;
- _LPcmsTRANSFORM v;
- LPLUT DeviceLink;
+ cmsUInt32Number OutputFormat;
+ _cmsTRANSFORM* v;
+ cmsPipeline* DeviceLink;
cmsHPROFILE Profiles[3];
cmsCIEXYZ BlackPointAdaptedToD50;
- LCMSBOOL lFreeDeviceLink = FALSE;
- LCMSBOOL lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
- LCMSBOOL lFixWhite = !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP);
+ cmsBool lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
+ cmsBool lFixWhite = !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP);
+ cmsUInt32Number InFrm = TYPE_Lab_16;
int RelativeEncodingIntent;
-
+ cmsColorSpaceSignature ColorSpace;
- hLab = cmsCreateLabProfile(NULL);
+ hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
+ if (hLab == NULL) return 0;
- ColorSpace = cmsGetColorSpace(hProfile);
- nChannels = _cmsChannelsOf(ColorSpace);
- OutputFormat = CHANNELS_SH(nChannels) | BYTES_SH(2);
+ OutputFormat = cmsFormatterForColorspaceOfProfile(hProfile, 2, FALSE);
+ nChannels = T_CHANNELS(OutputFormat);
- // For absolute colorimetric, the LUT is encoded as relative
- // in order to preserve precission.
+ ColorSpace = cmsGetColorSpace(hProfile);
+
+ // For absolute colorimetric, the LUT is encoded as relative in order to preserve precision.
RelativeEncodingIntent = Intent;
if (RelativeEncodingIntent == INTENT_ABSOLUTE_COLORIMETRIC)
RelativeEncodingIntent = INTENT_RELATIVE_COLORIMETRIC;
- // Is a devicelink profile?
- if (cmsGetDeviceClass(hProfile) == icSigLinkClass) {
-
- // if devicelink input already in Lab
-
- if (ColorSpace == icSigLabData) {
-
- // adjust input to Lab to our v4
-
- Profiles[0] = hLab;
- Profiles[1] = hProfile;
+ // Use V4 Lab always
+ Profiles[0] = hLab;
+ Profiles[1] = hProfile;
- xform = cmsCreateMultiprofileTransform(Profiles, 2, TYPE_Lab_DBL,
- OutputFormat, RelativeEncodingIntent,
- dwFlags|cmsFLAGS_NOWHITEONWHITEFIXUP|cmsFLAGS_NOPRELINEARIZATION);
-
- }
- else {
- cmsSignalError(LCMS_ERRC_ABORTED, "Cannot use devicelink profile for CRD creation");
- return 0;
- }
-
-
- }
- else {
-
- // This is a normal profile
- xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hProfile,
- OutputFormat, RelativeEncodingIntent, dwFlags|cmsFLAGS_NOWHITEONWHITEFIXUP|cmsFLAGS_NOPRELINEARIZATION);
- }
+ xform = cmsCreateMultiprofileTransformTHR(m ->ContextID,
+ Profiles, 2, TYPE_Lab_DBL,
+ OutputFormat, RelativeEncodingIntent, 0);
+ cmsCloseProfile(hLab);
if (xform == NULL) {
- cmsSignalError(LCMS_ERRC_ABORTED, "Cannot create transform Lab -> Profile in CRD creation");
- return 0;
+ cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Cannot create transform Lab -> Profile in CRD creation");
+ return 0;
}
- // Get the internal precalculated devicelink
-
- v = (_LPcmsTRANSFORM) xform;
- DeviceLink = v ->DeviceLink;
-
- if (!DeviceLink) {
-
- DeviceLink = _cmsPrecalculateDeviceLink(xform, cmsFLAGS_NOPRELINEARIZATION);
- lFreeDeviceLink = TRUE;
- }
-
- Writef(m, "<<\n");
- Writef(m, "/ColorRenderingType 1\n");
+ // Get a copy of the internal devicelink
+ v = (_cmsTRANSFORM*) xform;
+ DeviceLink = cmsPipelineDup(v ->Lut);
+ if (DeviceLink == NULL) return 0;
- cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, Intent, LCMS_BPFLAGS_D50_ADAPTED);
+ // We need a CLUT
+ dwFlags |= cmsFLAGS_FORCE_CLUT;
+ _cmsOptimizePipeline(&DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags);
+
+ _cmsIOPrintf(m, "<<\n");
+ _cmsIOPrintf(m, "/ColorRenderingType 1\n");
+
+
+ cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, Intent, 0);
// Emit headers, etc.
EmitWhiteBlackD50(m, &BlackPointAdaptedToD50);
EmitPQRStage(m, hProfile, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC);
EmitXYZ2Lab(m);
- if (DeviceLink ->wFlags & LUT_HASTL1) {
-
- // Shouldn't happen
- cmsSignalError(LCMS_ERRC_ABORTED, "Internal error (prelinearization on CRD)");
- return 0;
- }
-
// FIXUP: map Lab (100, 0, 0) to perfect white, because the particular encoding for Lab
// does map a=b=0 not falling into any specific node. Since range a,b goes -128..127,
@@ -1568,31 +1370,30 @@
if (Intent == INTENT_ABSOLUTE_COLORIMETRIC)
lFixWhite = FALSE;
- Writef(m, "/RenderTable ");
+ _cmsIOPrintf(m, "/RenderTable ");
+
- WriteCLUT(m, DeviceLink, 8, "<", ">\n", "", "", FALSE,
- lFixWhite, ColorSpace);
+ WriteCLUT(m, cmsPipelineGetPtrToFirstStage(DeviceLink), "<", ">\n", "", "", lFixWhite, ColorSpace);
- Writef(m, " %d {} bind ", nChannels);
+ _cmsIOPrintf(m, " %d {} bind ", nChannels);
for (i=1; i < nChannels; i++)
- Writef(m, "dup ");
+ _cmsIOPrintf(m, "dup ");
- Writef(m, "]\n");
+ _cmsIOPrintf(m, "]\n");
EmitIntent(m, Intent);
- Writef(m, ">>\n");
+ _cmsIOPrintf(m, ">>\n");
if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {
- Writef(m, "/Current exch /ColorRendering defineresource pop\n");
+ _cmsIOPrintf(m, "/Current exch /ColorRendering defineresource pop\n");
}
- if (lFreeDeviceLink) cmsFreeLUT(DeviceLink);
+ cmsPipelineFree(DeviceLink);
cmsDeleteTransform(xform);
- cmsCloseProfile(hLab);
return 1;
}
@@ -1600,14 +1401,14 @@
// Builds a ASCII string containing colorant list in 0..1.0 range
static
-void BuildColorantList(char *Colorant, int nColorant, WORD Out[])
+void BuildColorantList(char *Colorant, int nColorant, cmsUInt16Number Out[])
{
char Buff[32];
int j;
Colorant[0] = 0;
- if (nColorant > MAXCHANNELS)
- nColorant = MAXCHANNELS;
+ if (nColorant > cmsMAXCHANNELS)
+ nColorant = cmsMAXCHANNELS;
for (j=0; j < nColorant; j++) {
@@ -1624,50 +1425,54 @@
// This is a HP extension.
static
-int WriteNamedColorCRD(LPMEMSTREAM m, cmsHPROFILE hNamedColor, int Intent, DWORD dwFlags)
+int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, int Intent, cmsUInt32Number dwFlags)
{
cmsHTRANSFORM xform;
int i, nColors, nColorant;
- DWORD OutputFormat;
+ cmsUInt32Number OutputFormat;
char ColorName[32];
char Colorant[128];
+ cmsNAMEDCOLORLIST* NamedColorList;
- nColorant = _cmsChannelsOf(cmsGetColorSpace(hNamedColor));
- OutputFormat = CHANNELS_SH(nColorant) | BYTES_SH(2);
- xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX,
- NULL, OutputFormat, Intent, cmsFLAGS_NOTPRECALC);
+ OutputFormat = cmsFormatterForColorspaceOfProfile(hNamedColor, 2, FALSE);
+ nColorant = T_CHANNELS(OutputFormat);
+
+
+ xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX, NULL, OutputFormat, Intent, dwFlags);
if (xform == NULL) return 0;
- Writef(m, "<<\n");
- Writef(m, "(colorlistcomment) (%s) \n", "Named profile");
- Writef(m, "(Prefix) [ (Pantone ) (PANTONE ) ]\n");
- Writef(m, "(Suffix) [ ( CV) ( CVC) ( C) ]\n");
+ NamedColorList = cmsGetNamedColorList(xform);
+ if (NamedColorList == NULL) return 0;
- nColors = cmsNamedColorCount(xform);
+ _cmsIOPrintf(m, "<<\n");
+ _cmsIOPrintf(m, "(colorlistcomment) (%s) \n", "Named profile");
+ _cmsIOPrintf(m, "(Prefix) [ (Pantone ) (PANTONE ) ]\n");
+ _cmsIOPrintf(m, "(Suffix) [ ( CV) ( CVC) ( C) ]\n");
+ nColors = cmsNamedColorCount(NamedColorList);
for (i=0; i < nColors; i++) {
- WORD In[1];
- WORD Out[MAXCHANNELS];
+ cmsUInt16Number In[1];
+ cmsUInt16Number Out[cmsMAXCHANNELS];
- In[0] = (WORD) i;
+ In[0] = (cmsUInt16Number) i;
- if (!cmsNamedColorInfo(xform, i, ColorName, NULL, NULL))
+ if (!cmsNamedColorInfo(NamedColorList, i, ColorName, NULL, NULL, NULL, NULL))
continue;
cmsDoTransform(xform, In, Out, 1);
BuildColorantList(Colorant, nColorant, Out);
- Writef(m, " (%s) [ %s ]\n", ColorName, Colorant);
+ _cmsIOPrintf(m, " (%s) [ %s ]\n", ColorName, Colorant);
}
- Writef(m, " >>");
+ _cmsIOPrintf(m, " >>");
if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {
- Writef(m, " /Current exch /HPSpotTable defineresource pop\n");
+ _cmsIOPrintf(m, " /Current exch /HPSpotTable defineresource pop\n");
}
cmsDeleteTransform(xform);
@@ -1680,67 +1485,129 @@
// CRD are always LUT-Based, no matter if profile is
// implemented as matrix-shaper.
-DWORD LCMSEXPORT cmsGetPostScriptCRDEx(cmsHPROFILE hProfile,
- int Intent, DWORD dwFlags,
- LPVOID Buffer, DWORD dwBufferLen)
+static
+cmsUInt32Number GenerateCRD(cmsContext ContextID,
+ cmsHPROFILE hProfile,
+ cmsUInt32Number Intent, cmsUInt32Number dwFlags,
+ cmsIOHANDLER* mem)
{
-
- LPMEMSTREAM mem;
- DWORD dwBytesUsed;
-
- // Set up the serialization artifact
- mem = CreateMemStream((LPBYTE) Buffer, dwBufferLen, MAXPSCOLS);
- if (!mem) return 0;
-
+ cmsUInt32Number dwBytesUsed;
if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {
- EmitHeader(mem, "Color Rendering Dictionary (CRD)", hProfile);
+ EmitHeader(mem, "Color Rendering Dictionary (CRD)", hProfile);
}
// Is a named color profile?
- if (cmsGetDeviceClass(hProfile) == icSigNamedColorClass) {
+ if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
if (!WriteNamedColorCRD(mem, hProfile, Intent, dwFlags)) {
-
- _cmsFree((void*) mem);
- return 0;
+ return 0;
}
}
else {
- // CRD are always implemented as LUT.
-
+ // CRD are always implemented as LUT
- if (!WriteOutputLUT(mem, hProfile, Intent, dwFlags)) {
- _cmsFree((void*) mem);
- return 0;
- }
+ if (!WriteOutputLUT(mem, hProfile, Intent, dwFlags)) {
+ return 0;
+ }
}
if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {
- Writef(mem, "%%%%EndResource\n");
- Writef(mem, "\n%% CRD End\n");
+ _cmsIOPrintf(mem, "%%%%EndResource\n");
+ _cmsIOPrintf(mem, "\n%% CRD End\n");
}
// Done, keep memory usage
- dwBytesUsed = mem ->dwUsed;
+ dwBytesUsed = mem ->UsedSpace;
+
+ // Finally, return used byte count
+ return dwBytesUsed;
+
+ cmsUNUSED_PARAMETER(ContextID);
+}
+
+
+
+
+cmsUInt32Number CMSEXPORT cmsGetPostScriptColorResource(cmsContext ContextID,
+ cmsPSResourceType Type,
+ cmsHPROFILE hProfile,
+ cmsUInt32Number Intent,
+ cmsUInt32Number dwFlags,
+ cmsIOHANDLER* io)
+{
+ cmsUInt32Number rc;
+
+
+ switch (Type) {
+
+ case cmsPS_RESOURCE_CSA:
+ rc = GenerateCSA(ContextID, hProfile, Intent, dwFlags, io);
+ break;
+ default:
+ case cmsPS_RESOURCE_CRD:
+ rc = GenerateCRD(ContextID, hProfile, Intent, dwFlags, io);
+ break;
+ }
+
+ return rc;
+}
+
+
+
+cmsUInt32Number CMSEXPORT cmsGetPostScriptCRD(cmsContext ContextID,
+ cmsHPROFILE hProfile,
+ cmsUInt32Number Intent, cmsUInt32Number dwFlags,
+ void* Buffer, cmsUInt32Number dwBufferLen)
+{
+ cmsIOHANDLER* mem;
+ cmsUInt32Number dwBytesUsed;
+
+ // Set up the serialization engine
+ if (Buffer == NULL)
+ mem = cmsOpenIOhandlerFromNULL(ContextID);
+ else
+ mem = cmsOpenIOhandlerFromMem(ContextID, Buffer, dwBufferLen, "w");
+
+ if (!mem) return 0;
+
+ dwBytesUsed = cmsGetPostScriptColorResource(ContextID, cmsPS_RESOURCE_CRD, hProfile, Intent, dwFlags, mem);
// Get rid of memory stream
- _cmsFree((void*) mem);
+ cmsCloseIOhandler(mem);
- // Finally, return used byte count
return dwBytesUsed;
}
-// For compatibility with previous versions
+
+// Does create a Color Space Array on XYZ colorspace for PostScript usage
+cmsUInt32Number CMSEXPORT cmsGetPostScriptCSA(cmsContext ContextID,
+ cmsHPROFILE hProfile,
+ cmsUInt32Number Intent,
+ cmsUInt32Number dwFlags,
+ void* Buffer,
+ cmsUInt32Number dwBufferLen)
+{
+ cmsIOHANDLER* mem;
+ cmsUInt32Number dwBytesUsed;
-DWORD LCMSEXPORT cmsGetPostScriptCRD(cmsHPROFILE hProfile,
- int Intent,
- LPVOID Buffer, DWORD dwBufferLen)
-{
- return cmsGetPostScriptCRDEx(hProfile, Intent, 0, Buffer, dwBufferLen);
+ if (Buffer == NULL)
+ mem = cmsOpenIOhandlerFromNULL(ContextID);
+ else
+ mem = cmsOpenIOhandlerFromMem(ContextID, Buffer, dwBufferLen, "w");
+
+ if (!mem) return 0;
+
+ dwBytesUsed = cmsGetPostScriptColorResource(ContextID, cmsPS_RESOURCE_CSA, hProfile, Intent, dwFlags, mem);
+
+ // Get rid of memory stream
+ cmsCloseIOhandler(mem);
+
+ return dwBytesUsed;
+
}