

                        little cms Engine

                         API Definition

                          by Marti Maria

        ---------------------------------------------------

                           Index
                           -----

        1 - Profile & Transform functions
        2 - Information functions
        3 - On-the-fly profile creation functions
          3.1 - White point
          3.2 - Gamma handling functions

        4 - Error handling
        5 - Conversion functions




1 - Profile & Transform functions
_________________________________

 These are the basic functions on making transformations. For
 simpler operation, you must open two profiles using
 cmsOpenProfileFromFile(), then create a transform with these
 opened profiles with cmsCreateTransform(). Using this transform
 you can color correct your bitmaps by cmsDoTransform(). When you
 are done you must free the transform AND the profiles by
 cmsDeleteTransform() and cmsCloseProfile().


_________________________________________________________________________________

 cmsHPROFILE cmsOpenProfileFromFile(const char *ICCProfile, const char *sAccess);
_________________________________________________________________________________

 Opens a profile returning a handle to it. The profile must be
 contained in a file on disk.

Parameters:

        ICCProfile:   File name w/ full path.
        sAccess:      Reserved for futures ampliations, must be "r"

Returns:

          NULL on error, a profile handle on success.

Example:

                void GetProductNameOf(const char *ICMProfileFile)
                {
                cmsHPROFILE hProfile

                        hProfile = cmsOpenProfileFromFile(ICMProfileFile, "r");
                        if (hProfile == NULL) printf("Error!");
                        else {
                        printf("%s\n", cmsGetProductName(hProfile));
                        cmsCloseProfile(hProfile);
                        }
                }

_________________________________________________________________________________

cmsHPROFILE cmsOpenProfileFromMem(LPVOID MemPtr, DWORD dwSize);
_________________________________________________________________________________

  Same as anterior, but profile is contained in memory. Usefull
  for embedded profiles. MemPtr must point to a buffer of at
  least dwSize bytes. This buffer must hold a full profile image.
  Memory must be contiguous.

Parameters:

       MemPtr: Points to a block of contiguous memory containing the profile
       dwSize: Profile's size measured in bytes.

Returns:

       NULL on error, a profile handle on success.


_________________________________________________________________________________

BOOL  cmsCloseProfile(cmsHPROFILE hProfile);
_________________________________________________________________________________

  Closes a profile handle and frees associated memory. Note that
  cmsDeleteTransform() does NOT close the involved profiles. You
  must close any opened profile handle on cleanup.


Parameters:
                hProfile: Handle to an open profile

Returns:
                FALSE on error, TRUE on success

Comments:

  Actually, this function only returns error condition if null
  hProfile is given, but the ability of returning error status is
  provided for futures ampliations (ie, flushing profiles to disk
  when writing profiles)


_________________________________________________________________________________

  cmsHTRANSFORM cmsCreateTransform(cmsHPROFILE Input,
                                       DWORD InputFormat,
                                       cmsHPROFILE Output,
                                       DWORD OutputFormat,
                                       int Intent,
                                       DWORD dwFlags);                             .
_________________________________________________________________________________

Creates a transform for translating bitmaps.

Parameters:

   Input, Output:    Input, Output profile handles

 Input, Output format: This value describes how values are to be
                       coded. It is formed by a combination of
                       channels, bitdepths andextra samples. See
                       below.

        for example:

                     TYPE_BGR_8  : 3 channels of 8 bits, using Windows convention
                     TYPE_RGB_8  : 3 channels of 8 bits per component
                     TYPE_RGB_16 : 3 channels of 16 bits per component
                     TYPE_RGBA_8 : 4 channels, 3 containing RGB of 8 bpc, and one channel of 8 bits holding alpha
                     ...

  Note than even some Lab and XYZ are defined, these specifiers
  has nothing to do with colorspaces, but only how data is
  encoded.


  Intent: The ICC intent to apply. If an appropiate tag for this
          intent is not found, no error is raised and the intent
          is reverted to perceptual.


              INTENT_PERCEPTUAL                                 0
              INTENT_RELATIVE_COLORIMETRIC                      1
              INTENT_SATURATION                                 2
              INTENT_ABSOLUTE_COLORIMETRIC                      3


   dwFlags: This value commands on how to handle the whole
            process. Some or none of this values can be joined
            via the or | operator.


        cmsFLAGS_MATRIXINPUT: CLUT ignored on input profile,
                              matrix-shaper used instead (for
                              speed, and debugging purposes)

        cmsFLAGS_MATRIXOUTPUT: Same as anterior, but for output
                               profile only.

        cmsFLAGS_MATRIXONLY: Both input and output are forced to
                             matrix-shaper.

        cmsFLAGS_NOTPRECALC: By default, lcms smelt luts into a
                             device-link CLUT. This speedup whole
                             transform greatly. If you don't
                             wanna this, and wish every value to
                             be translated to PCS and back to
                             output space, include this flag.

        cmsFLAGS_GAMUTCHECK: Color out of gamut are flagged to a
                             fixed color defined by the function
                             cmsSetAlarmCodes(int r, int g, int b);


        cmsFLAGS_NULLTRANFORM: Don't transform anyway, only apply
                             pack/unpack routines (usefull to
                             deactivate color correction but keep
                             formatting capabilities)

Returns:

       NULL on error, a transform handle on success.

Comments:

 This function tries to build a device link profile using the
 Input and Output profiles. This small time-consuming penalty (3
 sec. on a Pentium-100) does accelerate the bitmap transform
 process greately. You can override this behaviour if you wish,
 or if you plan to transform only a couple of pixels by using
 cmsFLAGS_NOTPRECALC on dwFlags parameter. But normally it will
 be better leave this flag alone.

 Also, in this function is where you must specify the format of
 the input and output bitmaps. The InputFormat and OutputFormat
 parameters are formed by combining several bits:

             Bit positions

                 X S EEE CCC BBB

                X: Swap endianess of 16 bps formats?
                S: Do swap? ie, BGR, KCMY
                E: Extra samples
                C: Channels (Samples per pixel)
                B: Bytes per sample



lcms.h does include several predefined specifiers, as examples:

 TYPE_RGB_8     8 bits per sample RGB
 TYPE_BGR_8     8 bits per sample BGR (Windows Bitmaps are often
                  coded in this way)
 TYPE_RGB_16    16 bits per sample RGB
 TYPE_RGBA_8    8 bits per sample RGB plus alpha channel. Alpha is
                  ignored by lcms.
 TYPE_RGBA_16   16 bits per sample RGB plus alpha.
 TYPE_XYZ_16    16 bits fixed 15.16 XYZ (used in PCS)
 TYPE_Lab_8     8 bits per sample Lab
 TYPE_Lab_16    16 bits per sample Lab
 TYPE_CMY_8     8 bits per sample CMY
 TYPE_CMY_16    16 bits per sample CMY
 TYPE_CMYK_8    8 bits per sample CMYK
 TYPE_CMYK_16   16 bits per sample CMY

You can build your own specifiers if you wish by combining the following macros with the bitwise OR operator |

 DOSWAP_SH(e)           1 or 0 depending on swap even channels
 EXTRA_SH(e)            up to 7 extra channels
 CHANNELS_SH(c)         up to 4 handled channels
 BYTES_SH(b)            1 if 16 bits per sample, 0 if 8 bits per sample
 ENDIAN16_SH(e)         1 if 16 bits samples comes swapped.


See the lcms.h for more information on how to build format specifiers.


_________________________________________________________________________________

cmsHTRANSFORM cdecl cmsCreateProofingTransform(cmsHPROFILE Input,
                        DWORD InputFormat,
                        cmsHPROFILE Output,
                        DWORD OutputFormat,
                        cmsHPROFILE Proofing,
                        int Intent,
                        int ProofingIntent,
                        DWORD dwFlags);
_________________________________________________________________________________


  Same as cmsCreateTransform(), but including soft-proofing. The
  obtained transform emulates the device described by the
  "Proofing" profile. Useful to preview final result whithout
  rendering to physical medium.

  Parameters and returns same as anterior, but with the addition of

        Proofing: a handle to proofing profile.

        ProofingIntent: Is the intent for translating emulated
                        colors. Default is

                            INTENT_ABSOLUTE_COLORIMETRIC.


  Notes: Actually this only works on profiles that does have the
  preview tag included. In futures revisions, this will work on
  any profile suporting relative colorimetric intent.


_________________________________________________________________________________

void cmsDeleteTransform(cmsHTRANSFORM hTransform);
_________________________________________________________________________________

Closes a transform handle and frees associated memory.

Parameters:
                hTransform: The transform handle to be deleted.


  Comments: This function does NOT free any profiles associated
  with the transform. Is programmer's responsability to free
  them.



_________________________________________________________________________________

void cmsDoTransform(cmsHTRANSFORM hTransform,
                                  LPVOID InputBuffer,
                                  LPVOID OutputBuffer, unsigned int Size);
_________________________________________________________________________________

  This function translates bitmaps according of transform. Format
  of buffers is described by InputFormat and OutputFormat
  parameters in function cmsCreateTransform() or
  cmsCreateProofingTransform()

Parameters:
                hTransform: A handle to a transform describing the translation.
                InputBuffer: A pointer to a input bitmap
                OutputBuffer: A pointer to a output bitmap.
                Size: the number of PIXELS to be transformed.

Comments:

  Windows, stores the bitmaps in a particular way... for speed
  purposes, does align the scanlines to doubleword boundaries, so
  a bitmap has in windows always a size multiple of 4. This is
  ok, since no matter if you waste a couple of bytes, but if you
  call cmsDoTransform() and passes it WHOLE image, lcms doesn't
  know nothing about this extra padding bytes. So, it assumes
  that you are passing a block of BGR triplets with no alignment
  at all. This result in a strange looking "lines" in obtained
  bitmap.

  The solution most evident is to convert scanline by scanline
  instead of whole image. This is as easy as to add a for() loop,
  and the time penalty is so low that is impossible to detect.



2 - Information functions
_________________________________________________________________________________

  These functions are intended for identify profiles. You can use
  these functions for build an user interface to select profiles.


_________________________________________________________________________________

const char* cmsTakeProductName(cmsHPROFILE hProfile);
_________________________________________________________________________________

  Returns a pointer to a string containing the product name. The
  string is holded in a static buffer that is overwritten in
  every call to this function.

Parameters:
            hProfile: Handle to an open profile



_________________________________________________________________________________

const char* cmsTakeProductInfo(cmsHPROFILE hProfile);
_________________________________________________________________________________

  Returns a pointer to a string containing additional info about
  hProfile. The string is holded in a static buffer overwritten
  in each call to this function.

Parameters:
            hProfile: Handle to an open profile



_________________________________________________________________________________

icColorSpaceSignature cmsGetPCS(cmsHPROFILE hProfile)
_________________________________________________________________________________

  This function returns the PCS used by the hProfile, using the
  ICC convention.

Parameters:
                hProfile: Handle to an open profile

Returns:
                The PCS  of the profile


_________________________________________________________________________________

icColorSpaceSignature cmsGetColorSpace(cmsHPROFILE hProfile)
_________________________________________________________________________________

  This function returns the Color space used by the hProfile,
  using the ICC convention.

Parameters:
                hProfile: Handle to an open profile

Returns:
                The color space of the profile


_________________________________________________________________________________

icProfileClassSignature cmsGetDeviceClass(cmsHPROFILE hProfile)
_________________________________________________________________________________

  This function returns the Device class of hProfile, using the
  ICC convention.


Parameters:
                hProfile: Handle to an open profile

Returns:
                The device class of the profile


_________________________________________________________________________________

BOOL cmsTakeMediaWhitePoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
_________________________________________________________________________________

  This function takes the white point of hProfile.

Parameters:


        Dest:     a pointer to an cmsCIEXYZ struct that will hold the
                  media white point
        hProfile: Handle to an open profile


Returns:
                FALSE on error, TRUE on success

_________________________________________________________________________________

BOOL cmsTakeMediaBlackPoint(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
_________________________________________________________________________________

This function takes the black point of hProfile if present.

Parameters:
                Dest: a pointer to an cmsCIEXYZ struct that will
                        hold the media black point.

                hProfile: Handle to an open profile

Returns:
                FALSE on error, TRUE on success

_________________________________________________________________________________

BOOL cmsTakeIluminant(LPcmsCIEXYZ Dest, cmsHPROFILE hProfile);
_________________________________________________________________________________

This function takes the value of PCS illuminant of hProfile.

Parameters:
                hProfile: Handle to an open profile
                Dest: a pointer to an cmsCIEXYZ struct that will
                      hold the illuminant white point

Returns:
                FALSE on error, TRUE on success

 Notes: ICC states that profile illuminants MUST be D50. However,
 in practish, each manufacturer uses an illuminant value that
 differs slightly of D50. lcms takes this variation in account
 and does the necessary scaling.


_________________________________________________________________________________

BOOL cmsTakeColorants(LPcmsCIEXYZTRIPLE Dest, cmsHPROFILE hProfile);
_________________________________________________________________________________

 This function takes the value of colorant matrix of hProfile if
 present.

 Notes: A lot of manufacturers includes colorants even if a CLUT
 is present. Often this colorants are private values, true
 primaries or negative values. Interpretation of these
 undocumented values is out of scope of lcms.


_________________________________________________________________________________

BOOL  cmsIsTag(cmsHPROFILE hProfile, icTagSignature sig);
_________________________________________________________________________________

 Tests if a particular tag is present in hProfile.

Parameters:
                hProfile: Handle to an open profile
                sig: a tag signature

Returns:
                FALSE if not present, TRUE if tag is found

_________________________________________________________________________________

int  cmsTakeRenderingIntent(cmsHPROFILE hProfile);
_________________________________________________________________________________

Returns the rendering intent (absolute/relative) of a profile.

Parameters:
                hProfile: Handle to an open profile

Returns:        one of the following values:

              INTENT_PERCEPTUAL                                 0
              INTENT_RELATIVE_COLORIMETRIC                      1
              INTENT_SATURATION                                 2
              INTENT_ABSOLUTE_COLORIMETRIC                      3


_________________________________________________________________________________

void  cmsSetAlarmCodes(int r, int g, int b)
_________________________________________________________________________________

  Used to establish the out-of-gamut alarm color. This color will
  replace all out-of-gamut colors if sFLAGS_GAMUTCHEK is used in
  dwFlags parameter. See cmsCreateTransform()



3 - On-the-fly profile creation functions
_________________________________________________________________________________

  These function gives the ability of create virtual profiles.
  These profiles are often used in modelling monitors, but can
  also be used as any input or output device. Once created, you
  can use the profile handle like another file-based profile.


_________________________________________________________________________________

cmsHPROFILE  cmsCreateRGBProfile(LPcmsCIExyY WhitePoint,
                                        LPcmsCIExyYTRIPLE Primaries,
                                        LPGAMMATABLE TransferFunction[3])
_________________________________________________________________________________

  Creates a virtual profile based in primaries, white point and
  transfer tables.

Parameters:

        White point: You can specify chromacity of white point,
                     or use cmsWhitePointFromTemp() to generate
                     the white point from temperature.

        Primaries:   The primaries (the TRUE primaries, not the
                     colorants) of the device.

     Gamma tables: You can directly specify tables or use the
                   gamma handling functions for obtaining these
                   tables



3.1 - White point
_________________________________________________________________________________


BOOL cmsWhitePointFromTemp(int TempK, LPcmsCIExyY WhitePoint);
_________________________________________________________________________________

  Obtains the chromacity of white point based on temperature K

Parameters:

                TempK: Temperature in K

Returns:
                FALSE on error, TRUE on success



_________________________________________________________________________________

LCMSAPI void          LCMSEXPORT cmsXYZ2xyY(LPcmsCIExyY Dest,
                                                 CONST LPcmsCIEXYZ Source);
LCMSAPI void          LCMSEXPORT cmsxyY2XYZ(LPcmsCIEXYZ Dest,
                                                 CONST LPcmsCIExyY Source);
_________________________________________________________________________________


  Converts from/to xyY cromacity space.

  Parameters:

              Dest, Source: points to vectors to convert


_________________________________________________________________________________

LCMSAPI BOOL          LCMSEXPORT cmsAdaptToIlluminant(LPcmsCIEXYZ Result,
                                                        LPcmsCIExyY SourceWhitePt,
                                                        LPcmsCIExyY Illuminant,
                                                        LPcmsCIEXYZ Value);
_________________________________________________________________________________


   Provides a model-dependent chromatic adaptation between two illuminants,
   actually it uses a Von-Kries approximation of Bradford, using the Lam-Rigg
   cone responses. It Is under consideration to be replaced for a more
   proper model like CIECAM97s in futures versions.


   Parameters:
              Result:              Points to resulting XYZ color
              SourceWhitePoint:    original white point
              Illuminant:          adapting illuminant
              Value:               the original color

   Returns:

                FALSE on error, TRUE on success

3.2 - Gamma handling functions
______________________________

  This is the struct of a gamma table (or transfer function)

  typedef struct {
              int  nEntries;
              WORD GammaTable[1];

              } GAMMATABLE, FAR* LPGAMMATABLE;

  That is, first it comes a 32 integer for entry count, followed of
  a variable number of words describing the table. The easiest way to
  generate a gamma table is to use the following function


_________________________________________________________________________________

LPGAMMATABLE cmsBuildGamma(int nEntries, double Gamma);
_________________________________________________________________________________

  Allocates an fill a table describing generic gamma.

  You must specify the number of entries your table will consist of,
  and the float value for gamma.


_________________________________________________________________________________

LPGAMMATABLE cmsAllocGamma(int nEntries);
_________________________________________________________________________________

  Allocates space for a gamma table, memory is unitialized.


_________________________________________________________________________________

void cmsFreeGamma(LPGAMMATABLE Gamma);
_________________________________________________________________________________

  Frees a gamma table


_________________________________________________________________________________

LPGAMMATABLE cmsReverseGamma(int nResultSamples, LPGAMMATABLE InGamma);
_________________________________________________________________________________

  Reverses a gamma table resampling it in a new table.

  This function reverses the gamma table if it can be done. lcms does not
  detect whatever a non-monotonic function is given, so wrong input can
  result in ugly results: not to be a problem since "normal" gamma curves
  are not collapsing inputs at same output value. The new curve will be
  resampled to nResultSamples entries.


_________________________________________________________________________________

LPGAMMATABLE cmsJoinGamma(LPGAMMATABLE InGamma, LPGAMMATABLE OutGamma);
_________________________________________________________________________________

 Obtains a table joining two tables, one as input and other as
 output. Output table is reversed and then composited with input gamma.

 This will let you to "refine" the generic gamma for monitors (2.1 or 2.2
 are usual values) to match viewing conditions of more or less background
 light. Note that this function uses TABULATED functions, so very exotic
 curves can be obtained by combining transfer functions with reversed
 gamma curves. Normally there is no need of worry about such gamma
 manipulations, but the functionality is here if you wish to use.



4 - Error handling
_________________________________________________________________________________

void cmsErrorAction(int nAction)
_________________________________________________________________________________

  Tells lcms how to react if an error is raised.

Parameters:

        nAction: can be one of these:

                LCMS_ERROR_ABORT        Aborts whole application
                LCMS_ERROR_SHOW         Displays a message, but does not abort application
                LCMS_ERROR_IGNORE       Does not show any message, however, operation is aborted.


_________________________________________________________________________________

void cmsSignalError(int ErrorCode, const char *ErrorText, ...)
_________________________________________________________________________________

  This is the default error handler. If you are using lcms as a
  static library, you can replace it by one of your own.

Parameters:

        ErrorCode: a number for coding error (with not meaning by now)
        ErrorText: a format specifier describing the error
        ...       : additional parameters needed by ErrorText, in a printf like fashion.


_________________________________________________________________________________

5 - Conversion functions
_________________________________________________________________________________

These functions can be used to convert from/to floating point to/from fixed
encoding in spaces XYZ and Lab used by profiles.


#include "lcms.h" // Here is the DOUBLE_TO_FIXED macro

// In XYZ All 3 components are encoded using 1.15 fixed point

WORD XYZ2Fix(double d)
{
       return (WORD) ((Fixed32) (DOUBLE_TO_FIXED(d) >> 1));
}


// In Lab, L is handled separately. The 0.5 is for rounding

WORD L2Fix(double L)
{
        return (WORD) (L *  652.800 + 0.5);
}

WORD ab2Fix(double ab)
{
        return (WORD) ((ab + 128.0) * 256.0 + 0.5);
}


//  To convert from Fixed 1.15 point to double

double XYZ2float(WORD v)
{
       Fixed32 fix32;

       // From 1.15 to 15.16

       fix32 = v << 1;

       // From fixed 15.16 to double

       return FIXED_TO_DOUBLE(fix32);
}

// Convert L to double

double L2float(WORD v)
{
       Fixed32 fix32;

       fix32 = (Fixed32) v;
       return (double) fix32 / 652.800;
}


// the a/b part

double ab2float(WORD v)
{
       Fixed32 fix32;


       fix32 = (Fixed32) v;
       return ((double) fix32/256.0)-128.0;
}
