1 /** @file
2     File:       IccTagLut.h
3 
4     Contains:   Header for implementation of the Multi-Dimensional
5                 Lut tag classes classes
6 
7     Version:    V1
8 
9     Copyright:  � see ICC Software License
10 */
11 
12 /*
13  * The ICC Software License, Version 0.2
14  *
15  *
16  * Copyright (c) 2005 The International Color Consortium. All rights
17  * reserved.
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions
21  * are met:
22  *
23  * 1. Redistributions of source code must retain the above copyright
24  *    notice, this list of conditions and the following disclaimer.
25  *
26  * 2. Redistributions in binary form must reproduce the above copyright
27  *    notice, this list of conditions and the following disclaimer in
28  *    the documentation and/or other materials provided with the
29  *    distribution.
30  *
31  * 3. In the absence of prior written permission, the names "ICC" and "The
32  *    International Color Consortium" must not be used to imply that the
33  *    ICC organization endorses or promotes products derived from this
34  *    software.
35  *
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED.  IN NO EVENT SHALL THE INTERNATIONAL COLOR CONSORTIUM OR
41  * ITS CONTRIBUTING MEMBERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals on behalf of the The International Color Consortium.
53  *
54  *
55  * Membership in the ICC is encouraged when this software is used for
56  * commercial purposes.
57  *
58  *
59  * For more information on The International Color Consortium, please
60  * see <http://www.color.org/>.
61  *
62  *
63  */
64 
65 //////////////////////////////////////////////////////////////////////
66 // HISTORY:
67 //
68 // -Initial implementation by Max Derhak 5-15-2003
69 //
70 // -Moved LUT tags to separate file 4-30-2005
71 //
72 //////////////////////////////////////////////////////////////////////
73 
74 #if !defined(_ICCTAGLUT_H)
75 #define _ICCTAGLUT_H
76 
77 #ifdef USESAMPLEICCNAMESPACE
78 namespace sampleICC {
79 #endif
80 
81 #include "IccTagBasic.h"
82 
83 /**
84 ****************************************************************************
85 * Class: CIccCurve
86 *
87 * Purpose: The base curve class
88 *****************************************************************************
89 */
90 class ICCPROFLIB_API CIccCurve : public CIccTag
91 {
92 public:
CIccCurve()93   CIccCurve() {}
NewCopy()94   virtual CIccTag *NewCopy() const { return new CIccCurve; }
~CIccCurve()95   virtual ~CIccCurve() {}
96 
DumpLut(std::string & sDescription,const icChar * szName,icColorSpaceSignature csSig,int nIndex)97   virtual void DumpLut(std::string &sDescription, const icChar *szName,
98     icColorSpaceSignature csSig, int nIndex) {}
99 
Begin()100   virtual void Begin() {}
Apply(icFloatNumber v)101   virtual icFloatNumber Apply(icFloatNumber v) { return v; }
102 
Find(icFloatNumber v)103   icFloatNumber Find(icFloatNumber v) { return Find(v, 0, Apply(0), 1.0, Apply(1.0)); }
IsIdentity()104   virtual bool IsIdentity() {return false;}
105 
106 protected:
107   icFloatNumber Find(icFloatNumber v,
108     icFloatNumber p0, icFloatNumber v0,
109     icFloatNumber p1, icFloatNumber v1);
110 
111 };
112 typedef CIccCurve* LPIccCurve;
113 
114 typedef enum {
115   icInitNone,
116   icInitZero,
117   icInitIdentity,
118 } icTagCurveSizeInit;
119 
120 /**
121 ****************************************************************************
122 * Class: CIccTagCurve
123 *
124 * Purpose: The curveType tag
125 *****************************************************************************
126 */
127 class ICCPROFLIB_API CIccTagCurve : public CIccCurve
128 {
129 public:
130   CIccTagCurve(int nSize=0);
131   CIccTagCurve(const CIccTagCurve &ITCurve);
132   CIccTagCurve &operator=(const CIccTagCurve &CurveTag);
NewCopy()133   virtual CIccTag *NewCopy() const { return new CIccTagCurve(*this);}
134   virtual ~CIccTagCurve();
135 
GetType()136   virtual icTagTypeSignature GetType() const { return icSigCurveType; }
GetClassName()137   virtual const icChar *GetClassName() const { return "CIccTagCurve"; }
138 
139   virtual void Describe(std::string &sDescription);
140   virtual void DumpLut(std::string &sDescription, const icChar *szName,
141     icColorSpaceSignature csSig, int nIndex);
142 
143   virtual bool Read(icUInt32Number size, CIccIO *pIO);
144   virtual bool Write(CIccIO *pIO);
145 
146   icFloatNumber &operator[](icUInt32Number index) {return m_Curve[index];}
GetData(icUInt32Number index)147   icFloatNumber *GetData(icUInt32Number index) {return &m_Curve[index];}
GetSize()148   icUInt32Number GetSize() const { return m_nSize; }
149   void SetSize(icUInt32Number nSize, icTagCurveSizeInit nSizeOpt=icInitZero);
150   void SetGamma(icFloatNumber gamma);
151 
Begin()152   virtual void Begin() {m_nMaxIndex = (icUInt16Number)m_nSize - 1;}
153   virtual icFloatNumber Apply(icFloatNumber v);
154   virtual icValidateStatus Validate(icTagSignature sig, std::string &sReport, const CIccProfile* pProfile=NULL) const;
155   virtual bool IsIdentity();
156 
157 protected:
158   icFloatNumber *m_Curve;
159   icUInt32Number m_nSize;
160   icUInt16Number m_nMaxIndex;
161 };
162 
163 /**
164 ****************************************************************************
165 * Class: CIccTagParametricCurve
166 *
167 * Purpose: The parametric curve type tag
168 *****************************************************************************
169 */
170 class ICCPROFLIB_API CIccTagParametricCurve : public CIccCurve
171 {
172 public:
173   CIccTagParametricCurve();
174   CIccTagParametricCurve(const CIccTagParametricCurve &ITPC);
175   CIccTagParametricCurve &operator=(const CIccTagParametricCurve &ParamCurveTag);
NewCopy()176   virtual CIccTag *NewCopy() const { return new CIccTagParametricCurve(*this);}
177   virtual ~CIccTagParametricCurve();
178 
GetType()179   virtual icTagTypeSignature GetType() const { return icSigParametricCurveType; }
GetClassName()180   virtual const icChar *GetClassName() const { return "CIccTagParametricCurve"; }
181 
182   virtual void Describe(std::string &sDescription);
183   virtual void DumpLut(std::string &sDescription, const icChar *szName,
184     icColorSpaceSignature csSig, int nIndex);
185 
186   virtual bool Read(icUInt32Number size, CIccIO *pIO);
187   virtual bool Write(CIccIO *pIO);
188 
189 
190   bool SetFunctionType(icUInt16Number nFunctionType); //# parameters set by
GetFunctionType()191   icUInt16Number GetFunctionType() const {return m_nFunctionType; }
192 
GetNumParam()193   icUInt16Number GetNumParam() const { return m_nNumParam; }
GetParams()194   icFloatNumber *GetParams() const { return m_dParam; }
Param(int index)195   icFloatNumber Param(int index) const { return m_dParam[index]; }
196   icFloatNumber& operator[](int index) { return m_dParam[index]; }
197 
Apply(icFloatNumber v)198   virtual icFloatNumber Apply(icFloatNumber v) { return DoApply(v); }
199   virtual icValidateStatus Validate(icTagSignature sig, std::string &sReport, const CIccProfile* pProfile=NULL) const;
200   virtual bool IsIdentity();
201 
202   icUInt16Number      m_nReserved2;
203 protected:
204   icFloatNumber DoApply(icFloatNumber v) const;
205   icUInt16Number      m_nFunctionType;
206   icUInt16Number      m_nNumParam;
207   icFloatNumber *m_dParam;
208 };
209 
210 
211 /**
212 ****************************************************************************
213 * Class: CIccMatrix
214 *
215 * Purpose: The base matrix class
216 *****************************************************************************
217 */
218 class ICCPROFLIB_API CIccMatrix
219 {
220 public:
221   CIccMatrix(bool bUseConstants=true);
222   CIccMatrix(const CIccMatrix &MatrixClass);
223   CIccMatrix &operator=(const CIccMatrix &MatrixClass);
~CIccMatrix()224   virtual ~CIccMatrix() {}
225 
226   void DumpLut(std::string &sDescription, const icChar *szName);
227 
228   icFloatNumber m_e[12]; //e = element
229   bool m_bUseConstants;
230 
231   virtual void Apply(icFloatNumber *Pixel) const;
232   icValidateStatus Validate(icTagTypeSignature sig, std::string &sReport, const CIccProfile* pProfile=NULL) const;
233   virtual bool IsIdentity();
234 };
235 
236 /**
237 ****************************************************************************
238 * Interface Class: IIccCLUTExec
239 *
240 * Purpose: Interface class that is useful to populate CLUTs
241 *****************************************************************************
242 */
243 class ICCPROFLIB_API IIccCLUTExec
244 {
245 public:
~IIccCLUTExec()246   virtual ~IIccCLUTExec() {}
247 
248   virtual void PixelOp(icFloatNumber* pGridAdr, icFloatNumber* pData)=0;
249 };
250 
251 typedef icFloatNumber (*icCLUTCLIPFUNC)(icFloatNumber v);
252 
253 /**
254 ****************************************************************************
255 * Class: CIccCLUT
256 *
257 * Purpose: The base multidimensional color look-up table (CLUT) class
258 *****************************************************************************
259 */
260 class ICCPROFLIB_API CIccCLUT
261 {
262 public:
263   CIccCLUT(icUInt8Number nInputChannels, icUInt16Number nOutputChannels, icUInt8Number nPrecision=2);
264   CIccCLUT(const CIccCLUT &ICLUT);
265   CIccCLUT &operator=(const CIccCLUT &CLUTClass);
266   virtual ~CIccCLUT();
267 
268   bool Init(icUInt8Number nGridPoints);
269   bool Init(icUInt8Number *pGridPoints);
270 
271   bool ReadData(icUInt32Number size, CIccIO *pIO, icUInt8Number nPrecision);
272   bool WriteData(CIccIO *pIO, icUInt8Number nPrecision);
273 
274   bool Read(icUInt32Number size, CIccIO *pIO);
275   bool Write(CIccIO *pIO);
276 
277   void DumpLut(std::string  &sDescription, const icChar *szName,
278                icColorSpaceSignature csInput, icColorSpaceSignature csOutput,
279                bool bUseLegacy=false);
280 
281   icFloatNumber& operator[](int index) { return m_pData[index]; }
GetData(int index)282   icFloatNumber* GetData(int index) { return &m_pData[index]; }
NumPoints()283   icUInt32Number NumPoints() const { return m_nNumPoints; }
GridPoints()284   icUInt8Number GridPoints() const { return m_GridPoints[0]; }
GridPoint(int index)285   icUInt8Number GridPoint(int index) const { return m_GridPoints[index]; }
MaxGridPoint(int index)286   icUInt32Number MaxGridPoint(int index) const { return m_MaxGridPoint[index]; }
287 
GetDimSize(icUInt8Number nIndex)288   icUInt32Number GetDimSize(icUInt8Number nIndex) const { return m_DimSize[nIndex]; }
289 
GetInputDim()290   icUInt8Number GetInputDim() const { return m_nInput; }
GetOutputChannels()291   icUInt16Number GetOutputChannels() const { return m_nOutput; }
292 
GetNumOffset()293   icUInt32Number GetNumOffset() const { return m_nNodes; }
GetOffset(int index)294   icUInt32Number GetOffset(int index) const { return m_nOffset ? m_nOffset[index] : 0; }
295 
296 
297   void Begin();
298   void Interp3dTetra(icFloatNumber *destPixel, const icFloatNumber *srcPixel) const;
299   void Interp3d(icFloatNumber *destPixel, const icFloatNumber *srcPixel) const;
300   void Interp4d(icFloatNumber *destPixel, const icFloatNumber *srcPixel) const;
301   void Interp5d(icFloatNumber *destPixel, const icFloatNumber *srcPixel) const;
302   void Interp6d(icFloatNumber *destPixel, const icFloatNumber *srcPixel) const;
303   void InterpND(icFloatNumber *destPixel, const icFloatNumber *srcPixel) const;
304 
305   void Iterate(IIccCLUTExec* pExec);
306   icValidateStatus Validate(icTagTypeSignature sig, std::string &sReport, const CIccProfile* pProfile=NULL)  const;
307 
SetClipFunc(icCLUTCLIPFUNC ClipFunc)308   void SetClipFunc(icCLUTCLIPFUNC ClipFunc) { UnitClip = ClipFunc; }
309 
GetPrecision()310   icUInt8Number GetPrecision() { return m_nPrecision; }
311 
312 protected:
313   void Iterate(std::string &sDescription, icUInt8Number nIndex, icUInt32Number nPos, bool bUseLegacy=false);
314   void SubIterate(IIccCLUTExec* pExec, icUInt8Number nIndex, icUInt32Number nPos);
315 
316   icCLUTCLIPFUNC UnitClip;
317 
318   icUInt8Number m_nReserved2[3];
319 
320   icUInt8Number m_nInput;
321   icUInt16Number m_nOutput; //16 bit to support MPE CLUT elements
322   icUInt8Number m_nPrecision;
323 
324   icUInt8Number m_GridPoints[16];
325   icUInt32Number m_nNumPoints;
326 
327   icUInt32Number m_DimSize[16];
328   icFloatNumber *m_pData;
329 
330   //Iteration temporary variables
331   icUInt8Number m_GridAdr[16];
332   icFloatNumber m_fGridAdr[16];
333   icChar *m_pOutText, *m_pVal;
334   icColorSpaceSignature m_csInput, m_csOutput;
335 
336   //Tetrahedral interpolation variables
337   icUInt8Number m_MaxGridPoint[16];
338   icUInt32Number n000, n001, n010, n011, n100, n101, n110, n111, n1000, n10000, n100000;
339 
340   //ND Interpolation
341   icUInt32Number *m_nOffset;
342   // Temporary ND Interp Variables
343   icFloatNumber *m_g, *m_s, *m_df;
344   icUInt32Number* m_ig;
345   icUInt32Number m_nNodes, m_nPower[16];
346 };
347 
348 
349 /**
350 ****************************************************************************
351 * Class: CIccMBB
352 *
353 * Purpose: The Multi-dimensional Black Box (MBB) base class for lut8, lut16,
354 *  lutA2B and lutB2A tag types
355 *****************************************************************************
356 */
357 class ICCPROFLIB_API CIccMBB : public CIccTag
358 {
359   friend class ICCPROFLIB_API CIccXform3DLut;
360   friend class ICCPROFLIB_API CIccXform4DLut;
361   friend class ICCPROFLIB_API CIccXformNDLut;
362 public:
363   CIccMBB();
364   CIccMBB(const CIccMBB &IMBB);
365   CIccMBB &operator=(const CIccMBB &IMBB);
NewCopy()366   virtual CIccTag* NewCopy() const {return new CIccMBB(*this);}
367   virtual ~CIccMBB();
368 
IsMBBType()369   virtual bool IsMBBType() { return true;}
370 
GetPrecision()371   virtual icUInt8Number GetPrecision() { return 2; }
IsInputMatrix()372   virtual bool IsInputMatrix() { return m_bInputMatrix; } //Is matrix on input side of CLUT?
UseLegacyPCS()373   virtual bool UseLegacyPCS() const { return false; } //Treat Lab Encoding differently?
374 
IsInputB()375   bool IsInputB() { return IsInputMatrix(); }
SwapMBCurves()376   bool SwapMBCurves() { return m_bUseMCurvesAsBCurves; }
377 
378   void Cleanup();
379   void Init(icUInt8Number nInputChannels, icUInt8Number nOutputChannels);
380 
InputChannels()381   icUInt8Number InputChannels() const { return m_nInput; }
OutputChannels()382   icUInt8Number OutputChannels() const { return m_nOutput; }
383 
384   virtual void Describe(std::string &sDescription);
385 
386   virtual void SetColorSpaces(icColorSpaceSignature csInput, icColorSpaceSignature csOutput);
387   virtual icValidateStatus Validate(icTagSignature sig, std::string &sReport, const CIccProfile* pProfile=NULL) const;
388 
389   LPIccCurve* NewCurvesA();
390   CIccCLUT*   NewCLUT(icUInt8Number nGridPoints, icUInt8Number nPrecision=2);
391   CIccCLUT*   NewCLUT(icUInt8Number *pGridPoints, icUInt8Number nPrecision=2);
392   CIccMatrix* NewMatrix();
393   LPIccCurve* NewCurvesM();
394   LPIccCurve* NewCurvesB();
395 
GetMatrix()396   CIccMatrix *GetMatrix() const  {return m_Matrix; }
GetCLUT()397   CIccCLUT   *GetCLUT() const    {return m_CLUT;}
GetCurvesA()398   LPIccCurve *GetCurvesA() const {return m_CurvesA;}
GetCurvesB()399   LPIccCurve *GetCurvesB() const {return m_CurvesB;}
GetCurvesM()400   LPIccCurve *GetCurvesM() const {return m_CurvesM;}
401 
402   CIccCLUT *SetCLUT(CIccCLUT *clut);
403 
404 protected:
405   bool m_bInputMatrix;
406   bool m_bUseMCurvesAsBCurves;
407 
408   icUInt8Number m_nInput;
409   icUInt8Number m_nOutput;
410 
411   icColorSpaceSignature m_csInput;
412   icColorSpaceSignature m_csOutput;
413 
414   LPIccCurve *m_CurvesA;
415   CIccCLUT  *m_CLUT;
416   CIccMatrix *m_Matrix;
417   LPIccCurve *m_CurvesM;
418   LPIccCurve *m_CurvesB;
419 
420 };
421 
422 /**
423 ****************************************************************************
424 * Class: CIccTagLutAtoB
425 *
426 * Purpose: The LutA2B tag type
427 *****************************************************************************
428 */
429 class ICCPROFLIB_API CIccTagLutAtoB : public CIccMBB
430 {
431 public:
432   CIccTagLutAtoB();
433   CIccTagLutAtoB(const CIccTagLutAtoB &ITLA2B);
434   CIccTagLutAtoB &operator=(const CIccTagLutAtoB &ITLA2B);
NewCopy()435   virtual CIccTag* NewCopy() const { return new CIccTagLutAtoB(*this); }
436   virtual ~CIccTagLutAtoB();
437 
GetType()438   virtual icTagTypeSignature GetType() const { return icSigLutAtoBType; }
439 
440   bool Read(icUInt32Number size, CIccIO *pIO);
441   bool Write(CIccIO *pIO);
442   virtual icValidateStatus Validate(icTagSignature sig, std::string &sReport, const CIccProfile* pProfile=NULL) const;
443 
444 protected:
445   icUInt16Number m_nReservedWord;
446 };
447 
448 /**
449 ****************************************************************************
450 * Class: CIccTagLutBtoA
451 *
452 * Purpose: The LutB2A tag type
453 *****************************************************************************
454 */
455 class ICCPROFLIB_API CIccTagLutBtoA : public CIccTagLutAtoB
456 {
457 public:
458   CIccTagLutBtoA();
459   CIccTagLutBtoA(const CIccTagLutBtoA &ITLB2A);
460   CIccTagLutBtoA &operator=(const CIccTagLutBtoA &ITLB2A);
NewCopy()461   virtual CIccTag* NewCopy() const { return new CIccTagLutBtoA(*this); }
462 
GetType()463   virtual icTagTypeSignature GetType() const { return icSigLutBtoAType; }
464   virtual icValidateStatus Validate(icTagSignature sig, std::string &sReport, const CIccProfile* pProfile=NULL) const;
465 };
466 
467 
468 /**
469 ****************************************************************************
470 * Class: CIccTagLut8
471 *
472 * Purpose: The Lut8 tag type
473 *****************************************************************************
474 */
475 class ICCPROFLIB_API CIccTagLut8 : public CIccMBB
476 {
477 public:
478   CIccTagLut8();
479   CIccTagLut8(const CIccTagLut8 &ITL);
480   CIccTagLut8 &operator=(const CIccTagLut8 &ITL);
NewCopy()481   virtual CIccTag* NewCopy() const {return new CIccTagLut8(*this);}
482   virtual ~CIccTagLut8();
483 
GetType()484   virtual icTagTypeSignature GetType() const { return icSigLut8Type; }
GetPrecision()485   virtual icUInt8Number GetPrecision() { return 1; }
486 
487   bool Read(icUInt32Number size, CIccIO *pIO);
488   bool Write(CIccIO *pIO);
489 
490   virtual void SetColorSpaces(icColorSpaceSignature csInput, icColorSpaceSignature csOutput);
491   virtual icValidateStatus Validate(icTagSignature sig, std::string &sReport, const CIccProfile* pProfile=NULL) const;
492 
493 protected:
494   icUInt8Number m_nReservedByte;
495   icS15Fixed16Number m_XYZMatrix[9];
496 };
497 
498 /**
499 ****************************************************************************
500 * Class: CIccTagLut16
501 *
502 * Purpose: The Lut16 tag type
503 *****************************************************************************
504 */
505 class ICCPROFLIB_API CIccTagLut16 : public CIccMBB
506 {
507 public:
508   CIccTagLut16();
509   CIccTagLut16(const CIccTagLut16 &ITL);
510   CIccTagLut16 &operator=(const CIccTagLut16 &ITL);
NewCopy()511   virtual CIccTag* NewCopy() const {return new CIccTagLut16(*this);}
512   virtual ~CIccTagLut16();
513 
GetType()514   virtual icTagTypeSignature GetType() const { return icSigLut16Type; }
UseLegacyPCS()515   virtual bool UseLegacyPCS() const { return true; } //Treat Lab Encoding differently?
516 
517   bool Read(icUInt32Number size, CIccIO *pIO);
518   bool Write(CIccIO *pIO);
519 
520   virtual void SetColorSpaces(icColorSpaceSignature csInput, icColorSpaceSignature csOutput);
521   virtual icValidateStatus Validate(icTagSignature sig, std::string &sReport, const CIccProfile* pProfile=NULL) const;
522 
523 protected:
524   icUInt8Number m_nReservedByte;
525   icS15Fixed16Number m_XYZMatrix[9];
526 };
527 
528 
529 #ifdef USESAMPLEICCNAMESPACE
530 } //namespace sampleICC
531 #endif
532 
533 #endif // !defined(_ICCTAG_H)
534