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