/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

// This file is available under and governed by the GNU General Public
// License version 2 only, as published by the Free Software Foundation.
// However, the following notice accompanied the original version of this
// file:
//
//
//  Little cms
//  Copyright (C) 1998-2006 Marti Maria
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// 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>

// 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

/*
    Implementation
    --------------

  PostScript does use XYZ as its internal PCS. But since PostScript
  interpolation tables are limited to 8 bits, I use Lab as a way to
  improve the accuracy, favoring perceptual results. So, for the creation
  of each CRD, CSA the profiles are converted to Lab via a device
  link between  profile -> Lab or Lab -> profile. The PS code necessary to
  convert Lab <-> XYZ is also included.



  Color Space Arrays (CSA)
  ==================================================================================

  In order to obtain precission, 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.

  Monochrome
  -----------

  This is implemented as /CIEBasedA CSA. The prelinearization curve is
  placed into /DecodeA section, and matrix equals to D50. Since here is
  no interpolation tables, I do the conversion directly to XYZ

  NOTE: CLUT-based monochrome profiles are NOT supported. So, cmsFLAGS_MATRIXINPUT
  flag is forced on such profiles.

    [ /CIEBasedA
      <<
            /DecodeA { transfer function } bind
            /MatrixA [D50]
            /RangeLMN [ 0.0 D50X 0.0 D50Y 0.0 D50Z ]
            /WhitePoint [D50]
            /BlackPoint [BP]
            /RenderingIntent (intent)
      >>
    ]

   On simpler profiles, the PCS is already XYZ, so no conversion is required.


   Matrix-shaper based
   -------------------

   This is implemented both with /CIEBasedABC or /CIEBasedDEF on dependig
   of profile implementation. Since here is no interpolation tables, I do
   the conversion directly to XYZ



    [ /CIEBasedABC
            <<
                /DecodeABC [ {transfer1} {transfer2} {transfer3} ]
                /MatrixABC [Matrix]
                /RangeLMN [ 0.0 D50X 0.0 D50Y 0.0 D50Z ]
                /DecodeLMN [ { / 2} dup dup ]
                /WhitePoint [D50]
                /BlackPoint [BP]
                /RenderingIntent (intent)
            >>
    ]


    CLUT based
    ----------

     Lab is used in such cases.

    [ /CIEBasedDEF
            <<
            /DecodeDEF [ <prelinearization> ]
            /Table [ p p p [<...>]]
            /RangeABC [ 0 1 0 1 0 1]
            /DecodeABC[ <postlinearization> ]
            /MatrixABC [ 1 1 1 1 0 0 0 0 -1]
            /WhitePoint [D50]
            /BlackPoint [BP]
            /RenderingIntent (intent)
    ]


  Color Rendering Dictionaries (CRD)
  ==================================
  These are always implemented as CLUT, and always are using Lab. Since CRD are expected to
  be used as resources, the code adds the definition as well.

  <<
    /ColorRenderingType 1
    /WhitePoint [ D50 ]
    /BlackPoint [BP]
    /MatrixPQR [ Bradford ]
    /RangePQR [-0.125 1.375 -0.125 1.375 -0.125 1.375 ]
    /TransformPQR [
    {4 index 3 get div 2 index 3 get mul exch pop exch pop exch pop exch pop } bind
    {4 index 4 get div 2 index 4 get mul exch pop exch pop exch pop exch pop } bind
    {4 index 5 get div 2 index 5 get mul exch pop exch pop exch pop exch pop } bind
    ]
    /MatrixABC <...>
    /EncodeABC <...>
    /RangeABC  <.. used for  XYZ -> Lab>
    /EncodeLMN
    /RenderTable [ p p p [<...>]]

    /RenderingIntent (Perceptual)
  >>
  /Current exch /ColorRendering defineresource pop


  The following stages are used to convert from XYZ to Lab
  --------------------------------------------------------

  Input is given at LMN stage on X, Y, Z

  Encode LMN gives us f(X/Xn), f(Y/Yn), f(Z/Zn)

  /EncodeLMN [

    { 0.964200  div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind
    { 1.000000  div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind
    { 0.824900  div dup 0.008856 le {7.787 mul 16 116 div add}{1 3 div exp} ifelse } bind

    ]


  MatrixABC is used to compute f(Y/Yn), f(X/Xn) - f(Y/Yn), f(Y/Yn) - f(Z/Zn)

  | 0  1  0|
  | 1 -1  0|
  | 0  1 -1|

  /MatrixABC [ 0 1 0 1 -1 1 0 0 -1 ]

 EncodeABC finally gives Lab values.

  /EncodeABC [
    { 116 mul  16 sub 100 div  } bind
    { 500 mul 128 add 255 div  } bind
    { 200 mul 128 add 255 div  } bind
    ]

  The following stages are used to convert Lab to XYZ
  ----------------------------------------------------

    /RangeABC [ 0 1 0 1 0 1]
    /DecodeABC [ { 100 mul 16 add 116 div } bind
                 { 255 mul 128 sub 500 div } bind
                 { 255 mul 128 sub 200 div } bind
               ]

    /MatrixABC [ 1 1 1 1 0 0 0 0 -1]
    /DecodeLMN [
                {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.964200 mul} bind
                {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse } bind
                {dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse 0.824900 mul} bind
                ]


*/

/*

 PostScript algorithms discussion.
 =========================================================================================================

  1D interpolation algorithm


  1D interpolation (float)
  ------------------------

    val2 = Domain * Value;

    cell0 = (int) floor(val2);
    cell1 = (int) ceil(val2);

    rest = val2 - cell0;

    y0 = LutTable[cell0] ;
    y1 = LutTable[cell1] ;

    y = y0 + (y1 - y0) * rest;



  PostScript code                   Stack
  ================================================

  {                                 % v
    <check 0..1.0>
    [array]                         % v tab
    dup                             % v tab tab
    length 1 sub                    % v tab dom

    3 -1 roll                       % tab dom v

    mul                             % tab val2
    dup                             % tab val2 val2
    dup                             % tab val2 val2 val2
    floor cvi                       % tab val2 val2 cell0
    exch                            % tab val2 cell0 val2
    ceiling cvi                     % tab val2 cell0 cell1

    3 index                         % tab val2 cell0 cell1 tab
    exch                            % tab val2 cell0 tab cell1
    get                             % tab val2 cell0 y1

    4 -1 roll                       % val2 cell0 y1 tab
    3 -1 roll                       % val2 y1 tab cell0
    get                             % val2 y1 y0

    dup                             % val2 y1 y0 y0
    3 1 roll                        % val2 y0 y1 y0

    sub                             % val2 y0 (y1-y0)
    3 -1 roll                       % y0 (y1-y0) val2
    dup                             % y0 (y1-y0) val2 val2
    floor cvi                       % y0 (y1-y0) val2 floor(val2)
    sub                             % y0 (y1-y0) rest
    mul                             % y0 t1
    add                             % y
    65535 div                       % result

  } bind


*/

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 {
                LPBYTE Block;
                LPBYTE Ptr;
                DWORD  dwMax;
                DWORD  dwUsed;
                int    MaxCols;
                int    Col;
                int    HasError;

            } MEMSTREAM, FAR* LPMEMSTREAM;


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;


// Creates a ready to use memory stream
static
LPMEMSTREAM CreateMemStream(LPBYTE Buffer, DWORD dwMax, int MaxCols)
{
    LPMEMSTREAM m = (LPMEMSTREAM) malloc(sizeof(MEMSTREAM));

    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;
}



// Convert to byte
static
BYTE Word2Byte(WORD w)
{
    return (BYTE) floor((double) 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)
{

    if (m -> dwUsed + 1 > m -> dwMax) {
        m -> HasError = 1;
    }

    if (!m ->HasError && m ->Block) {
        *m ->Ptr++ = b;
    }

    m -> dwUsed++;
}

// Write a cooked byte
static
void WriteByte(LPMEMSTREAM m, BYTE 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;
        }

}

// Does write a formatted string
static
void Writef(LPMEMSTREAM m, const char *frm, ...)
{
        va_list args;
        LPBYTE pt;
        BYTE Buffer[2048];

        va_start(args, frm);

        vsprintf((char*) Buffer, frm, args);

        for (pt = Buffer; *pt; pt++)  {

            WriteRawByte(m, *pt);
        }

        va_end(args);
}



// ----------------------------------------------------------------- PostScript generation


// Removes offending Carriage returns
static
char* RemoveCR(const char* txt)
{
    static char Buffer[2048];
    char* pt;

    strncpy(Buffer, txt, 2047);
    Buffer[2047] = 0;
    for (pt = Buffer; *pt; pt++)
            if (*pt == '\n' || *pt == '\r') *pt = ' ';

    return Buffer;

}

static
void EmitHeader(LPMEMSTREAM m, const char* Title, cmsHPROFILE hProfile)
{

    time_t timer;

    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");

}


// Emits White & Black point. White point is always D50, Black point is the device
// Black point adapted to D50.

static
void EmitWhiteBlackD50(LPMEMSTREAM m, LPcmsCIEXYZ BlackPoint)
{

    Writef(m, "/BlackPoint [%f %f %f]\n", BlackPoint -> X,
                                          BlackPoint -> Y,
                                          BlackPoint -> Z);

    Writef(m, "/WhitePoint [%f %f %f]\n", cmsD50_XYZ()->X,
                                          cmsD50_XYZ()->Y,
                                          cmsD50_XYZ()->Z);
}


static
void EmitRangeCheck(LPMEMSTREAM m)
{
    Writef(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)
{
    const char *intent;

    switch (RenderingIntent) {

        case INTENT_PERCEPTUAL:            intent = "Perceptual"; break;
        case INTENT_RELATIVE_COLORIMETRIC: intent = "RelativeColorimetric"; break;
        case INTENT_ABSOLUTE_COLORIMETRIC: intent = "AbsoluteColorimetric"; break;
        case INTENT_SATURATION:            intent = "Saturation"; break;

        default: intent = "Undefined"; break;
    }

    Writef(m, "/RenderingIntent (%s)\n", intent );
}

//
//  Convert L* to Y
//
//      Y = Yn*[ (L* + 16) / 116] ^ 3   if (L*) >= 6 / 29
//        = Yn*( L* / 116) / 7.787      if (L*) < 6 / 29
//

/*
static
void EmitL2Y(LPMEMSTREAM m)
{
    Writef(m,
            "{ "
                "100 mul 16 add 116 div "               // (L * 100 + 16) / 116
                 "dup 6 29 div ge "                     // >= 6 / 29 ?
                 "{ dup dup mul mul } "                 // yes, ^3 and done
                 "{ 4 29 div sub 108 841 div mul } "    // no, slope limiting
            "ifelse } bind ");
}
*/


// Lab -> XYZ, see the discussion above

static
void EmitLab2XYZ(LPMEMSTREAM 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.0 0.9642 0.0 1.0000 0.0 0.8249 ]\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");
}



// Outputs a table of words. It does use 16 bits

static
void Emit1Gamma(LPMEMSTREAM m, LPWORD Table, int nEntries)
{
    int i;
    double gamma;


    if (nEntries <= 0) return;  // Empty table

    // Suppress whole if identity
    if (cmsIsLinear(Table, nEntries)) return;

    // Check if is really an exponential. If so, emit "exp"
     gamma = cmsEstimateGammaEx(Table, nEntries, 0.001);
     if (gamma > 0) {
            Writef(m, "{ %g exp } bind ", gamma);
            return;
     }

    Writef(m, "{ ");

    // Bounds check
    EmitRangeCheck(m);

    // Emit intepolation code

    // PostScript code                      Stack
    // ===============                      ========================
                                            // v
    Writef(m, " [");

    // TODO: Check for endianess!!!

    for (i=0; i < nEntries; i++) {
            Writef(m, "%d ", Table[i]);
    }

    Writef(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

    Writef(m, " } bind ");
}


// Compare gamma table

static
BOOL GammaTableEquals(LPWORD g1, LPWORD g2, int nEntries)
{
    return memcmp(g1, g2, nEntries* sizeof(WORD)) == 0;
}


// Does write a set of gamma curves

static
void EmitNGamma(LPMEMSTREAM m, int n, LPWORD g[], int nEntries)
{
    int i;

    for( i=0; i < n; i++ )
    {
        if (i > 0 && GammaTableEquals(g[i-1], g[i], nEntries)) {

            Writef(m, "dup ");
        }
        else {
            Emit1Gamma(m, g[i], nEntries);
        }
    }

}


// Check whatever a profile has CLUT tables (only on input)

static
BOOL 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);
}



// Following code dumps a LUT onto memory stream


// This is the sampler. Intended to work in SAMPLER_INSPECT mode,
// 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
//
//  Returning a value other than 0 does terminate the sampling process
//
//  Each row contains LUT 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)
{
    LPSAMPLERCARGO sc = (LPSAMPLERCARGO) Cargo;
    unsigned int i;


    if (sc -> FixWhite) {

        if (In[0] == 0xFFFF) {  // Only in L* = 100

            if ((In[1] >= 0x8000 && In[1] <= 0x87FF) ||
                (In[2] >= 0x8000 && In[2] <= 0x87FF)) {

                WORD* Black;
                WORD* White;
                int nOutputs;

                if (!_cmsEndPointsBySpace(sc ->ColorSpace, &White, &Black, &nOutputs))
                        return 0;

                for (i=0; i < (unsigned int) nOutputs; i++)
                        Out[i] = White[i];
            }


        }
    }


    // Hadle the parenthesis on rows

    if (In[0] != sc ->FirstComponent) {

            if (sc ->FirstComponent != -1) {

                    Writef(sc ->m, sc ->PostMin);
                    sc ->SecondComponent = -1;
                    Writef(sc ->m, sc ->PostMaj);
            }

            // Begin block
            sc->m->Col = 0;

            Writef(sc ->m, sc ->PreMaj);
            sc ->FirstComponent = In[0];
    }


      if (In[1] != sc ->SecondComponent) {

            if (sc ->SecondComponent != -1) {

                    Writef(sc ->m, sc ->PostMin);
            }

            Writef(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++) {

        WORD wWordOut = Out[i];

        if (sc ->bps == 8) {

            // Value as byte
            BYTE wByteOut;

            // If is input, convert from Lab2 to Lab4 (just divide by 256)

            if (sc ->lIsInput) {


                wByteOut = L2Byte(wWordOut);
            }
            else
                wByteOut = Word2Byte(wWordOut);

            WriteByte(sc -> m, wByteOut);
        }
        else {

            // Value as word
            WriteByte(sc -> m, (BYTE) (wWordOut & 0xFF));
            WriteByte(sc -> m, (BYTE) ((wWordOut >> 8) & 0xFF));
        }
     }

    return 1;
}

// Writes a LUT 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)
{
    unsigned int i;
    SAMPLERCARGO sc;

    sc.FirstComponent = -1;
    sc.SecondComponent = -1;
    sc.Lut = Lut;
    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, "[");

    for (i=0; i < Lut ->InputChan; i++)
            Writef(m, " %d ", Lut ->cLutPoints);

    Writef(m, " [\n");



    cmsSample3DGrid(Lut, OutputValueSampler, (LPVOID) &sc, SAMPLER_INSPECT);


    Writef(m, PostMin);
    Writef(m, PostMaj);
    Writef(m, "] ");



}


// Dumps CIEBasedA Color Space Array

static
int EmitCIEBasedA(LPMEMSTREAM m, LPWORD Tab, int nEntries, LPcmsCIEXYZ BlackPoint)
{

        Writef(m, "[ /CIEBasedA\n");
        Writef(m, "  <<\n");

        Writef(m, "/DecodeA ");

        Emit1Gamma(m,Tab, nEntries);

        Writef(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");

        EmitWhiteBlackD50(m, BlackPoint);
        EmitIntent(m, INTENT_PERCEPTUAL);

        Writef(m, ">>\n");
        Writef(m, "]\n");

        return 1;
}


// Dumps CIEBasedABC Color Space Array

static
int EmitCIEBasedABC(LPMEMSTREAM m, LPWORD L[], int nEntries, LPWMAT3 Matrix, LPcmsCIEXYZ BlackPoint)
{
    int i;

        Writef(m, "[ /CIEBasedABC\n");
        Writef(m, "<<\n");
        Writef(m, "/DecodeABC [ ");

        EmitNGamma(m, 3, L, nEntries);

        Writef(m, "]\n");

        Writef(m, "/MatrixABC [ " );

        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]));
        }


        Writef(m, "]\n");

        Writef(m, "/RangeLMN [ 0.0 0.9642 0.0 1.0000 0.0 0.8249 ]\n");

        EmitWhiteBlackD50(m, BlackPoint);
        EmitIntent(m, INTENT_PERCEPTUAL);

        Writef(m, ">>\n");
        Writef(m, "]\n");


        return 1;
}


static
int EmitCIEBasedDEF(LPMEMSTREAM m, LPLUT Lut, int Intent, LPcmsCIEXYZ BlackPoint)
{
    const char* PreMaj;
    const char* PostMaj;
    const char* PreMin, *PostMin;

    switch (Lut ->InputChan) {
    case 3:

            Writef(m, "[ /CIEBasedDEF\n");
            PreMaj ="<";
            PostMaj= ">\n";
            PreMin = PostMin = "";
            break;
    case 4:
            Writef(m, "[ /CIEBasedDEFG\n");
            PreMaj = "[";
            PostMaj = "]\n";
            PreMin = "<";
            PostMin = ">\n";
            break;
    default:
            return 0;

    }

    Writef(m, "<<\n");

    if (Lut ->wFlags & LUT_HASTL1) {

        Writef(m, "/DecodeDEF [ ");
        EmitNGamma(m, Lut ->InputChan, Lut ->L1, Lut ->CLut16params.nSamples);
        Writef(m, "]\n");
    }



    if (Lut ->wFlags & LUT_HAS3DGRID) {

            Writef(m, "/Table ");
            WriteCLUT(m, Lut, 8, PreMaj, PostMaj, PreMin, PostMin, TRUE, FALSE, (icColorSpaceSignature) 0);
            Writef(m, "]\n");
    }

    EmitLab2XYZ(m);
    EmitWhiteBlackD50(m, BlackPoint);
    EmitIntent(m, Intent);

    Writef(m, "   >>\n");
    Writef(m, "]\n");


    return 1;
}

// Generates a curve from a gray profile

static
LPGAMMATABLE ExtractGray2Y(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);
    int i;

    for (i=0; i < 256; i++) {

      BYTE Gray = (BYTE) i;
      cmsCIEXYZ XYZ;

        cmsDoTransform(xform, &Gray, &XYZ, 1);

        Out ->GammaTable[i] =_cmsClampWord((int) floor(XYZ.Y * 65535.0 + 0.5));
    }

    cmsDeleteTransform(xform);
    cmsCloseProfile(hXYZ);
    return Out;
}



// Because PostScrip 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)
{
    cmsHPROFILE hLab;
    cmsHTRANSFORM xform;
    icColorSpaceSignature ColorSpace;
    int nChannels;
    DWORD InputFormat;
    int rc;
    cmsHPROFILE Profiles[2];
    cmsCIEXYZ BlackPointAdaptedToD50;

    // 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);
        }


    }
    else {

        // This is a normal profile
        xform = cmsCreateTransform(hProfile, InputFormat, hLab,
                            TYPE_Lab_DBL, Intent, 0);
    }



    if (xform == NULL) {

            cmsSignalError(LCMS_ERRC_ABORTED, "Cannot create transform Profile -> Lab");
            return 0;
    }

    // Only 1, 3 and 4 channels are allowed

    switch (nChannels) {

    case 1: {
            LPGAMMATABLE Gray2Y = ExtractGray2Y(hProfile, Intent);
            EmitCIEBasedA(m, Gray2Y->GammaTable, Gray2Y ->nEntries, &BlackPointAdaptedToD50);
            cmsFreeGamma(Gray2Y);
            }
            break;

    case 3:
    case 4: {
            LPLUT DeviceLink;
            _LPcmsTRANSFORM v = (_LPcmsTRANSFORM) xform;

            if (v ->DeviceLink)
                rc = EmitCIEBasedDEF(m, v->DeviceLink, Intent, &BlackPointAdaptedToD50);
            else {
                DeviceLink = _cmsPrecalculateDeviceLink(xform, 0);
                rc = EmitCIEBasedDEF(m, DeviceLink, Intent, &BlackPointAdaptedToD50);
                cmsFreeLUT(DeviceLink);
            }
            }
            break;

    default:

            cmsSignalError(LCMS_ERRC_ABORTED, "Only 3, 4 channels supported for CSA. This profile has %d channels.", nChannels);
            return 0;
    }


    cmsDeleteTransform(xform);
    cmsCloseProfile(hLab);
    return 1;
}



// Does create CSA based on matrix-shaper. Allowed types are gray and RGB based

static
int WriteInputMatrixShaper(LPMEMSTREAM m, cmsHPROFILE hProfile)
{
    icColorSpaceSignature ColorSpace;
    LPMATSHAPER MatShaper;
    int rc;
    cmsCIEXYZ BlackPointAdaptedToD50;


    ColorSpace = cmsGetColorSpace(hProfile);
    MatShaper  = cmsBuildInputMatrixShaper(hProfile);

    cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, INTENT_RELATIVE_COLORIMETRIC, LCMS_BPFLAGS_D50_ADAPTED);

    if (MatShaper == NULL) {

                cmsSignalError(LCMS_ERRC_ABORTED, "This profile is not suitable for input");
                return 0;
    }

    if (ColorSpace == icSigGrayData) {

            rc = EmitCIEBasedA(m, MatShaper ->L[0],
                                  MatShaper ->p16.nSamples,
                                  &BlackPointAdaptedToD50);

    }
    else
        if (ColorSpace == icSigRgbData) {


            rc = EmitCIEBasedABC(m, MatShaper->L,
                                        MatShaper ->p16.nSamples,
                                        &MatShaper ->Matrix,
                                        &BlackPointAdaptedToD50);
        }
        else  {

            cmsSignalError(LCMS_ERRC_ABORTED, "Profile is not suitable for CSA. Unsupported colorspace.");
            return 0;
        }

    cmsFreeMatShaper(MatShaper);
    return rc;
}



// Creates a PostScript color list from a named profile data.
// This is a HP extension, and it works in Lab instead of XYZ

static
int WriteNamedColorCSA(LPMEMSTREAM m, cmsHPROFILE hNamedColor, int Intent)
{
    cmsHTRANSFORM xform;
    cmsHPROFILE   hLab;
    int i, nColors;
    char ColorName[32];


    hLab  = cmsCreateLabProfile(NULL);
    xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX,
                        hLab, TYPE_Lab_DBL, Intent, cmsFLAGS_NOTPRECALC);
    if (xform == 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");

    nColors   = cmsNamedColorCount(xform);


    for (i=0; i < nColors; i++) {

        WORD In[1];
        cmsCIELab Lab;

        In[0] = (WORD) i;

        if (!cmsNamedColorInfo(xform, i, ColorName, NULL, NULL))
                continue;

        cmsDoTransform(xform, In, &Lab, 1);
        Writef(m, "  (%s) [ %.3f %.3f %.3f ]\n", ColorName, Lab.L, Lab.a, Lab.b);
    }



    Writef(m, ">>\n");

    cmsDeleteTransform(xform);
    cmsCloseProfile(hLab);
    return 1;
}


// Does create a Color Space Array on XYZ colorspace for PostScript usage

DWORD LCMSEXPORT cmsGetPostScriptCSA(cmsHPROFILE hProfile,
                              int Intent,
                              LPVOID Buffer, DWORD dwBufferLen)
{

    LPMEMSTREAM mem;
    DWORD dwBytesUsed;

    // Set up the serialization engine
    mem = CreateMemStream((LPBYTE) Buffer, dwBufferLen, MAXPSCOLS);
    if (!mem) return 0;


    // Is a named color profile?
    if (cmsGetDeviceClass(hProfile) == icSigNamedColorClass) {

        if (!WriteNamedColorCSA(mem, hProfile, Intent)) {

                    free((void*) mem);
                    return 0;
        }
    }
    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) {

            cmsSignalError(LCMS_ERRC_ABORTED, "Invalid output color space");
            free((void*) mem);
            return 0;
    }

    // Is there any CLUT?
    if (IsLUTbased(hProfile, Intent)) {

        // Yes, so handle as LUT-based
        if (!WriteInputLUT(mem, hProfile, Intent)) {

                    free((void*) mem);
                    return 0;
        }
    }
    else {

        // No, try Matrix-shaper (this only works on XYZ)

        if (!WriteInputMatrixShaper(mem, hProfile)) {

                    free((void*) mem);  // Something went wrong
                    return 0;
        }
    }
    }


    // Done, keep memory usage
    dwBytesUsed = mem ->dwUsed;

    // Get rid of memory stream
    free((void*) mem);

    // Finally, return used byte count
    return dwBytesUsed;
}

// ------------------------------------------------------ Color Rendering Dictionary (CRD)



/*

  Black point compensation plus chromatic adaptation:

  Step 1 - Chromatic adaptation
  =============================

          WPout
    X = ------- PQR
          Wpin

  Step 2 - Black point compensation
  =================================

          (WPout - BPout)*X - WPout*(BPin - BPout)
    out = ---------------------------------------
                        WPout - BPin


  Algorithm discussion
  ====================

  TransformPQR(WPin, BPin, WPout, BPout, PQR)

  Wpin,etc= { Xws Yws Zws Pws Qws Rws }


  Algorithm             Stack 0...n
  ===========================================================
                        PQR BPout WPout BPin WPin
  4 index 3 get         WPin PQR BPout WPout BPin WPin
  div                   (PQR/WPin) BPout WPout BPin WPin
  2 index 3 get         WPout (PQR/WPin) BPout WPout BPin WPin
  mult                  WPout*(PQR/WPin) BPout WPout BPin WPin

  2 index 3 get         WPout WPout*(PQR/WPin) BPout WPout BPin WPin
  2 index 3 get         BPout WPout WPout*(PQR/WPin) BPout WPout BPin WPin
  sub                   (WPout-BPout) WPout*(PQR/WPin) BPout WPout BPin WPin
  mult                  (WPout-BPout)* WPout*(PQR/WPin) BPout WPout BPin WPin

  2 index 3 get         WPout (BPout-WPout)* WPout*(PQR/WPin) BPout WPout BPin WPin
  4 index 3 get         BPin WPout (BPout-WPout)* WPout*(PQR/WPin) BPout WPout BPin WPin
  3 index 3 get         BPout BPin WPout (BPout-WPout)* WPout*(PQR/WPin) BPout WPout BPin WPin

  sub                   (BPin-BPout) WPout (BPout-WPout)* WPout*(PQR/WPin) BPout WPout BPin WPin
  mult                  (BPin-BPout)*WPout (BPout-WPout)* WPout*(PQR/WPin) BPout WPout BPin WPin
  sub                   (BPout-WPout)* WPout*(PQR/WPin)-(BPin-BPout)*WPout BPout WPout BPin WPin

  3 index 3 get         BPin (BPout-WPout)* WPout*(PQR/WPin)-(BPin-BPout)*WPout BPout WPout BPin WPin
  3 index 3 get         WPout BPin (BPout-WPout)* WPout*(PQR/WPin)-(BPin-BPout)*WPout BPout WPout BPin WPin
  exch
  sub                   (WPout-BPin) (BPout-WPout)* WPout*(PQR/WPin)-(BPin-BPout)*WPout BPout WPout BPin WPin
  div

  exch pop
  exch pop
  exch pop
  exch pop

*/


static
void EmitPQRStage(LPMEMSTREAM m, int DoBPC, int lIsAbsolute)
{


        Writef(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");


        if (lIsAbsolute) {

            // For absolute colorimetric intent, do nothing

            Writef(m, "%% Absolute colorimetric -- no transformation\n"
                      "/TransformPQR [\n"
                      "{exch pop exch pop exch pop exch pop} bind dup dup]\n");
            return;
        }


        // No BPC

        if (!DoBPC) {

            Writef(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"
                      "{exch pop exch 5 get mul exch pop exch 5 get div} bind\n]\n");
        } else {

            // BPC

            Writef(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 "
                    "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 "
                    "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 "
                    "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 "
                    "exch pop exch pop exch pop exch pop } bind\n]\n");

        }


}


static
void EmitXYZ2Lab(LPMEMSTREAM m)
{
    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");



    Writef(m, "{ 116 mul  16 sub 100 div  } bind\n");
    Writef(m, "{ 500 mul 128 add 255 div  } bind\n");
    Writef(m, "{ 200 mul 128 add 255 div  } bind\n");


    /*
    Writef(m, "{ 116 mul  16 sub 256 mul 25700 div  } bind\n");
    Writef(m, "{ 500 mul 128 add 256 mul 65535 div  } bind\n");
    Writef(m, "{ 200 mul 128 add 256 mul 65535 div  } bind\n");
    */

    Writef(m, "]\n");


}

// Due to impedance mismatch between XYZ and almost all RGB and CMYK spaces
// I choose to dump LUTS in Lab instead of XYZ. There is still a lot of wasted
// space on 3D CLUT, but since space seems not to be a problem here, 33 points
// would give a reasonable accurancy. Note also that CRD tables must operate in
// 8 bits.

static
int WriteOutputLUT(LPMEMSTREAM m, cmsHPROFILE hProfile, int Intent, DWORD dwFlags)
{
    cmsHPROFILE hLab;
    cmsHTRANSFORM xform;
    icColorSpaceSignature ColorSpace;
    int i, nChannels;
    DWORD OutputFormat;
    _LPcmsTRANSFORM v;
    LPLUT DeviceLink;
    cmsHPROFILE Profiles[3];
    cmsCIEXYZ BlackPointAdaptedToD50;
    BOOL lFreeDeviceLink = FALSE;
    BOOL lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);


    // Trick our v4 profile as it were v2. This prevents the ajusting done
    // in perceptual & saturation. We only neew v4 encoding!

    hLab         = cmsCreateLab4Profile(NULL);
    cmsSetProfileICCversion(hLab, 0);

    ColorSpace  =  cmsGetColorSpace(hProfile);
    nChannels   = _cmsChannelsOf(ColorSpace);
    OutputFormat = CHANNELS_SH(nChannels) | BYTES_SH(2);

    // Is a devicelink profile?
    if (cmsGetDeviceClass(hProfile) == icSigLinkClass) {

        // if devicelink input already in Lab

        if (ColorSpace == icSigLabData) {

              // adjust input to Lab to out v4

            Profiles[0] = hLab;
            Profiles[1] = hProfile;

            xform = cmsCreateMultiprofileTransform(Profiles, 2, TYPE_Lab_DBL,
                                                        OutputFormat, Intent, 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, Intent, cmsFLAGS_NOPRELINEARIZATION);
    }

    if (xform == NULL) {

            cmsSignalError(LCMS_ERRC_ABORTED, "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, 0);
        lFreeDeviceLink = TRUE;
    }

    Writef(m, "<<\n");
    Writef(m, "/ColorRenderingType 1\n");


    cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, Intent, LCMS_BPFLAGS_D50_ADAPTED);

    // Emit headers, etc.
    EmitWhiteBlackD50(m, &BlackPointAdaptedToD50);
    EmitPQRStage(m, 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,
    // zero is slightly moved towards right, so assure next node (in L=100 slice) is mapped to
    // zero. This would sacrifice a bit of highlights, but failure to do so would cause
    // scum dot. Ouch.

    Writef(m, "/RenderTable ");

    WriteCLUT(m, DeviceLink, 8, "<", ">\n", "", "", FALSE,
                (Intent != INTENT_ABSOLUTE_COLORIMETRIC), ColorSpace);

    Writef(m, " %d {} bind ", nChannels);

    for (i=1; i < nChannels; i++)
            Writef(m, "dup ");

    Writef(m, "]\n");


    EmitIntent(m, Intent);

    Writef(m, ">>\n");

    if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {

        Writef(m, "/Current exch /ColorRendering defineresource pop\n");
    }

    if (lFreeDeviceLink) cmsFreeLUT(DeviceLink);
    cmsDeleteTransform(xform);
    cmsCloseProfile(hLab);

    return 1;
}


// Builds a ASCII string containing colorant list in 0..1.0 range
static
void BuildColorantList(char *Colorant, int nColorant, WORD Out[])
{
    char Buff[32];
    int j;

    Colorant[0] = 0;
    for (j=0; j < nColorant; j++) {

                sprintf(Buff, "%.3f", Out[j] / 65535.0);
                strcat(Colorant, Buff);
                if (j < nColorant -1)
                        strcat(Colorant, " ");

        }
}


// Creates a PostScript color list from a named profile data.
// This is a HP extension.

static
int WriteNamedColorCRD(LPMEMSTREAM m, cmsHPROFILE hNamedColor, int Intent, DWORD dwFlags)
{
    cmsHTRANSFORM xform;
    int i, nColors, nColorant;
    DWORD OutputFormat;
    char ColorName[32];
    char Colorant[128];

    nColorant = _cmsChannelsOf(cmsGetColorSpace(hNamedColor));
    OutputFormat = CHANNELS_SH(nColorant) | BYTES_SH(2);

    xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX,
                        NULL, OutputFormat, Intent, cmsFLAGS_NOTPRECALC);
    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");

    nColors   = cmsNamedColorCount(xform);


    for (i=0; i < nColors; i++) {

        WORD In[1];
        WORD Out[MAXCHANNELS];

        In[0] = (WORD) i;

        if (!cmsNamedColorInfo(xform, i, ColorName, NULL, NULL))
                continue;

        cmsDoTransform(xform, In, Out, 1);
        BuildColorantList(Colorant, nColorant, Out);
        Writef(m, "  (%s) [ %s ]\n", ColorName, Colorant);
    }

    Writef(m, "   >>");

    if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {

    Writef(m, " /Current exch /HPSpotTable defineresource pop\n");
    }

    cmsDeleteTransform(xform);
    return 1;
}



// This one does create a Color Rendering Dictionary.
// 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)
{

    LPMEMSTREAM mem;
    DWORD dwBytesUsed;

    // Set up the serialization artifact
    mem = CreateMemStream((LPBYTE) Buffer, dwBufferLen, MAXPSCOLS);
    if (!mem) return 0;


    if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {

    EmitHeader(mem, "Color Rendering Dictionary (CRD)", hProfile);
    }


    // Is a named color profile?
    if (cmsGetDeviceClass(hProfile) == icSigNamedColorClass) {

        if (!WriteNamedColorCRD(mem, hProfile, Intent, dwFlags)) {

                    free((void*) mem);
                    return 0;
        }
    }
    else {

    // CRD are always implemented as LUT.


    if (!WriteOutputLUT(mem, hProfile, Intent, dwFlags)) {
        free((void*) mem);
        return 0;
    }
    }

    if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {

    Writef(mem, "%%%%EndResource\n");
    Writef(mem, "\n%% CRD End\n");
    }

    // Done, keep memory usage
    dwBytesUsed = mem ->dwUsed;

    // Get rid of memory stream
    free((void*) mem);

    // Finally, return used byte count
    return dwBytesUsed;
}


// For compatibility with previous versions

DWORD LCMSEXPORT cmsGetPostScriptCRD(cmsHPROFILE hProfile,
                              int Intent,
                              LPVOID Buffer, DWORD dwBufferLen)
{
    return cmsGetPostScriptCRDEx(hProfile, Intent, 0, Buffer, dwBufferLen);
}
