3 // Little Color Management System
4 // Copyright (c) 1998-2011 Marti Maria Saguer
6 // Permission is hereby granted, free of charge, to any person obtaining
7 // a copy of this software and associated documentation files (the "Software"),
8 // to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 // and/or sell copies of the Software, and to permit persons to whom the Software
11 // is furnished to do so, subject to the following conditions:
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
18 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 //---------------------------------------------------------------------------------
27 #ifndef _lcms_internal_H
29 // Include plug-in foundation
30 #ifndef _lcms_plugin_H
31 # include "lcms2_plugin.h"
34 // ctype is part of C99 as per 7.1.2
37 // assert macro is part of C99 as per 7.2
40 // Some needed constants
42 # define M_PI 3.14159265358979323846
46 # define M_LOG10E 0.434294481903251827651
49 // BorlandC 5.5, VC2003 are broken on that
50 #if defined(__BORLANDC__) || (_MSC_VER < 1400) // 1400 == VC++ 8.0
51 #define sinf(x) (float)sin((float)x)
52 #define sqrtf(x) (float)sqrt((float)x)
56 // Alignment of ICC file format uses 4 bytes (cmsUInt32Number)
57 #define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & ~(sizeof(cmsUInt32Number)-1))
59 // Alignment to memory pointer
60 #define _cmsALIGNMEM(x) (((x)+(sizeof(void *) - 1)) & ~(sizeof(void *) - 1))
62 // Maximum encodeable values in floating point
63 #define MAX_ENCODEABLE_XYZ (1.0 + 32767.0/32768.0)
64 #define MIN_ENCODEABLE_ab2 (-128.0)
65 #define MAX_ENCODEABLE_ab2 ((65535.0/256.0) - 128.0)
66 #define MIN_ENCODEABLE_ab4 (-128.0)
67 #define MAX_ENCODEABLE_ab4 (127.0)
69 // Maximum of channels for internal pipeline evaluation
70 #define MAX_STAGE_CHANNELS 128
72 // Unused parameter warning supression
73 #define cmsUNUSED_PARAMETER(x) ((void)x)
75 // The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999).
76 // unfortunately VisualC++ does not conform that
77 #if defined(_MSC_VER) || defined(__BORLANDC__)
78 # define cmsINLINE __inline
80 # define cmsINLINE static inline
83 // Other replacement functions
86 # define snprintf _snprintf
89 # define vsnprintf _vsnprintf
94 // A fast way to convert from/to 16 <-> 8 bits
95 #define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
96 #define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((rgb) * 65281 + 8388608) >> 24) & 0xFF)
98 // Code analysis is broken on asserts
100 # if (_MSC_VER >= 1500)
101 # define _cmsAssert(a) { assert((a)); __analysis_assume((a)); }
103 # define _cmsAssert(a) assert((a))
106 # define _cmsAssert(a) assert((a))
109 //---------------------------------------------------------------------------------
111 // Determinant lower than that are assumed zero (used on matrix invert)
112 #define MATRIX_DET_TOLERANCE 0.0001
114 //---------------------------------------------------------------------------------
117 #define FIXED_TO_INT(x) ((x)>>16)
118 #define FIXED_REST_TO_INT(x) ((x)&0xFFFFU)
119 #define ROUND_FIXED_TO_INT(x) (((x)+0x8000)>>16)
121 cmsINLINE cmsS15Fixed16Number
_cmsToFixedDomain(int a
) { return a
+ ((a
+ 0x7fff) / 0xffff); }
122 cmsINLINE
int _cmsFromFixedDomain(cmsS15Fixed16Number a
) { return a
- ((a
+ 0x7fff) >> 16); }
124 // -----------------------------------------------------------------------------------------------------------
126 // Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon
127 // note than this only works in the range ..-32767...+32767 because
128 // mantissa is interpreted as 15.16 fixed point.
129 // The union is to avoid pointer aliasing overoptimization.
130 cmsINLINE
int _cmsQuickFloor(cmsFloat64Number val
)
132 #ifdef CMS_DONT_USE_FAST_FLOOR
133 return (int) floor(val
);
135 const cmsFloat64Number _lcms_double2fixmagic
= 68719476736.0 * 1.5; // 2^36 * 1.5, (52-16=36) uses limited precision to floor
137 cmsFloat64Number val
;
141 temp
.val
= val
+ _lcms_double2fixmagic
;
143 #ifdef CMS_USE_BIG_ENDIAN
144 return temp
.halves
[1] >> 16;
146 return temp
.halves
[0] >> 16;
151 // Fast floor restricted to 0..65535.0
152 cmsINLINE cmsUInt16Number
_cmsQuickFloorWord(cmsFloat64Number d
)
154 return (cmsUInt16Number
) _cmsQuickFloor(d
- 32767.0) + 32767U;
157 // Floor to word, taking care of saturation
158 cmsINLINE cmsUInt16Number
_cmsQuickSaturateWord(cmsFloat64Number d
)
161 if (d
<= 0) return 0;
162 if (d
>= 65535.0) return 0xffff;
164 return _cmsQuickFloorWord(d
);
167 // Plug-In registering ---------------------------------------------------------------
169 // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.
170 void* _cmsPluginMalloc(cmsContext ContextID
, cmsUInt32Number size
);
173 cmsBool
_cmsRegisterMemHandlerPlugin(cmsPluginBase
* Plugin
);
176 cmsBool
_cmsRegisterInterpPlugin(cmsPluginBase
* Plugin
);
179 cmsBool
_cmsRegisterParametricCurvesPlugin(cmsContext ContextID
, cmsPluginBase
* Plugin
);
181 // Formatters management
182 cmsBool
_cmsRegisterFormattersPlugin(cmsContext ContextID
, cmsPluginBase
* Plugin
);
184 // Tag type management
185 cmsBool
_cmsRegisterTagTypePlugin(cmsContext ContextID
, cmsPluginBase
* Plugin
);
188 cmsBool
_cmsRegisterTagPlugin(cmsContext ContextID
, cmsPluginBase
* Plugin
);
191 cmsBool
_cmsRegisterRenderingIntentPlugin(cmsContext ContextID
, cmsPluginBase
* Plugin
);
193 // Multi Process elements
194 cmsBool
_cmsRegisterMultiProcessElementPlugin(cmsContext ContextID
, cmsPluginBase
* Plugin
);
197 cmsBool
_cmsRegisterOptimizationPlugin(cmsContext ContextID
, cmsPluginBase
* Plugin
);
200 cmsBool
_cmsRegisterTransformPlugin(cmsContext ContextID
, cmsPluginBase
* Plugin
);
202 // ---------------------------------------------------------------------------------------------------------
204 // Suballocators. Those are blocks of memory that is freed at the end on whole block.
205 typedef struct _cmsSubAllocator_chunk_st
{
207 cmsUInt8Number
* Block
;
208 cmsUInt32Number BlockSize
;
209 cmsUInt32Number Used
;
211 struct _cmsSubAllocator_chunk_st
* next
;
213 } _cmsSubAllocator_chunk
;
218 cmsContext ContextID
;
219 _cmsSubAllocator_chunk
* h
;
224 _cmsSubAllocator
* _cmsCreateSubAlloc(cmsContext ContextID
, cmsUInt32Number Initial
);
225 void _cmsSubAllocDestroy(_cmsSubAllocator
* s
);
226 void* _cmsSubAlloc(_cmsSubAllocator
* s
, cmsUInt32Number size
);
228 // ----------------------------------------------------------------------------------
230 // MLU internal representation
233 cmsUInt16Number Language
;
234 cmsUInt16Number Country
;
236 cmsUInt32Number StrW
; // Offset to current unicode string
237 cmsUInt32Number Len
; // Length in bytes
241 struct _cms_MLU_struct
{
243 cmsContext ContextID
;
246 int AllocatedEntries
;
248 _cmsMLUentry
* Entries
; // Array of pointers to strings allocated in MemPool
251 cmsUInt32Number PoolSize
; // The maximum allocated size
252 cmsUInt32Number PoolUsed
; // The used size
253 void* MemPool
; // Pointer to begin of memory pool
256 // Named color list internal representation
259 char Name
[cmsMAX_PATH
];
260 cmsUInt16Number PCS
[3];
261 cmsUInt16Number DeviceColorant
[cmsMAXCHANNELS
];
265 struct _cms_NAMEDCOLORLIST_struct
{
267 cmsUInt32Number nColors
;
268 cmsUInt32Number Allocated
;
269 cmsUInt32Number ColorantCount
;
271 char Prefix
[33]; // Prefix and suffix are defined to be 32 characters at most
274 _cmsNAMEDCOLOR
* List
;
276 cmsContext ContextID
;
280 // ----------------------------------------------------------------------------------
282 // This is the internal struct holding profile details.
284 // Maximum supported tags in a profile
285 #define MAX_TABLE_TAG 100
287 typedef struct _cms_iccprofile_struct
{
290 cmsIOHANDLER
* IOhandler
;
293 cmsContext ContextID
;
298 // Only most important items found in ICC profiles
299 cmsUInt32Number Version
;
300 cmsProfileClassSignature DeviceClass
;
301 cmsColorSpaceSignature ColorSpace
;
302 cmsColorSpaceSignature PCS
;
303 cmsUInt32Number RenderingIntent
;
305 cmsUInt32Number flags
;
306 cmsUInt32Number manufacturer
, model
;
307 cmsUInt64Number attributes
;
308 cmsUInt32Number creator
;
310 cmsProfileID ProfileID
;
313 cmsUInt32Number TagCount
;
314 cmsTagSignature TagNames
[MAX_TABLE_TAG
];
315 cmsTagSignature TagLinked
[MAX_TABLE_TAG
]; // The tag to wich is linked (0=none)
316 cmsUInt32Number TagSizes
[MAX_TABLE_TAG
]; // Size on disk
317 cmsUInt32Number TagOffsets
[MAX_TABLE_TAG
];
318 cmsBool TagSaveAsRaw
[MAX_TABLE_TAG
]; // True to write uncooked
319 void * TagPtrs
[MAX_TABLE_TAG
];
320 cmsTagTypeHandler
* TagTypeHandlers
[MAX_TABLE_TAG
]; // Same structure may be serialized on different types
321 // depending on profile version, so we keep track of the // type handler for each tag in the list.
327 // IO helpers for profiles
328 cmsBool
_cmsReadHeader(_cmsICCPROFILE
* Icc
);
329 cmsBool
_cmsWriteHeader(_cmsICCPROFILE
* Icc
, cmsUInt32Number UsedSpace
);
330 int _cmsSearchTag(_cmsICCPROFILE
* Icc
, cmsTagSignature sig
, cmsBool lFollowLinks
);
333 cmsTagTypeHandler
* _cmsGetTagTypeHandler(cmsTagTypeSignature sig
);
334 cmsTagTypeSignature
_cmsGetTagTrueType(cmsHPROFILE hProfile
, cmsTagSignature sig
);
335 cmsTagDescriptor
* _cmsGetTagDescriptor(cmsTagSignature sig
);
337 // Error logging ---------------------------------------------------------------------------------------------------------
339 void _cmsTagSignature2String(char String
[5], cmsTagSignature sig
);
341 // Interpolation ---------------------------------------------------------------------------------------------------------
343 cmsInterpParams
* _cmsComputeInterpParams(cmsContext ContextID
, int nSamples
, int InputChan
, int OutputChan
, const void* Table
, cmsUInt32Number dwFlags
);
344 cmsInterpParams
* _cmsComputeInterpParamsEx(cmsContext ContextID
, const cmsUInt32Number nSamples
[], int InputChan
, int OutputChan
, const void* Table
, cmsUInt32Number dwFlags
);
345 void _cmsFreeInterpParams(cmsInterpParams
* p
);
346 cmsBool
_cmsSetInterpolationRoutine(cmsInterpParams
* p
);
348 // Curves ----------------------------------------------------------------------------------------------------------------
350 // This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
351 // In the case of table-based, Eval pointer is set to NULL
353 // The gamma function main structure
354 struct _cms_curve_struct
{
356 cmsInterpParams
* InterpParams
; // Private optimizations for interpolation
358 cmsUInt32Number nSegments
; // Number of segments in the curve. Zero for a 16-bit based tables
359 cmsCurveSegment
* Segments
; // The segments
360 cmsInterpParams
** SegInterp
; // Array of private optimizations for interpolation in table-based segments
362 cmsParametricCurveEvaluator
* Evals
; // Evaluators (one per segment)
364 // 16 bit Table-based representation follows
365 cmsUInt32Number nEntries
; // Number of table elements
366 cmsUInt16Number
* Table16
; // The table itself.
370 // Pipelines & Stages ---------------------------------------------------------------------------------------------
373 struct _cmsStage_struct
{
375 cmsContext ContextID
;
377 cmsStageSignature Type
; // Identifies the stage
378 cmsStageSignature Implements
; // Identifies the *function* of the stage (for optimizations)
380 cmsUInt32Number InputChannels
; // Input channels -- for optimization purposes
381 cmsUInt32Number OutputChannels
; // Output channels -- for optimization purposes
383 _cmsStageEvalFn EvalPtr
; // Points to fn that evaluates the stage (always in floating point)
384 _cmsStageDupElemFn DupElemPtr
; // Points to a fn that duplicates the *data* of the stage
385 _cmsStageFreeElemFn FreePtr
; // Points to a fn that sets the *data* of the stage free
387 // A generic pointer to whatever memory needed by the stage
390 // Maintains linked list (used internally)
391 struct _cmsStage_struct
* Next
;
395 // Special Stages (cannot be saved)
396 cmsStage
* _cmsStageAllocLab2XYZ(cmsContext ContextID
);
397 cmsStage
* _cmsStageAllocXYZ2Lab(cmsContext ContextID
);
398 cmsStage
* _cmsStageAllocLabPrelin(cmsContext ContextID
);
399 cmsStage
* _cmsStageAllocLabV2ToV4(cmsContext ContextID
);
400 cmsStage
* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID
);
401 cmsStage
* _cmsStageAllocLabV4ToV2(cmsContext ContextID
);
402 cmsStage
* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST
* NamedColorList
, cmsBool UsePCS
);
403 cmsStage
* _cmsStageAllocIdentityCurves(cmsContext ContextID
, int nChannels
);
404 cmsStage
* _cmsStageAllocIdentityCLut(cmsContext ContextID
, int nChan
);
405 cmsStage
* _cmsStageNormalizeFromLabFloat(cmsContext ContextID
);
406 cmsStage
* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID
);
407 cmsStage
* _cmsStageNormalizeToLabFloat(cmsContext ContextID
);
408 cmsStage
* _cmsStageNormalizeToXyzFloat(cmsContext ContextID
);
410 // For curve set only
411 cmsToneCurve
** _cmsStageGetPtrToCurveSet(const cmsStage
* mpe
);
414 // Pipeline Evaluator (in floating point)
415 typedef void (* _cmsPipelineEvalFloatFn
)(const cmsFloat32Number In
[],
416 cmsFloat32Number Out
[],
419 struct _cmsPipeline_struct
{
421 cmsStage
* Elements
; // Points to elements chain
422 cmsUInt32Number InputChannels
, OutputChannels
;
427 _cmsOPTeval16Fn Eval16Fn
;
428 _cmsPipelineEvalFloatFn EvalFloatFn
;
429 _cmsFreeUserDataFn FreeDataFn
;
430 _cmsDupUserDataFn DupDataFn
;
432 cmsContext ContextID
; // Environment
434 cmsBool SaveAs8Bits
; // Implementation-specific: save as 8 bits if possible
437 // LUT reading & creation -------------------------------------------------------------------------------------------
439 // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
440 // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
442 cmsPipeline
* _cmsReadInputLUT(cmsHPROFILE hProfile
, int Intent
);
443 cmsPipeline
* _cmsReadOutputLUT(cmsHPROFILE hProfile
, int Intent
);
444 cmsPipeline
* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile
, int Intent
);
447 cmsBool
_cmsReadMediaWhitePoint(cmsCIEXYZ
* Dest
, cmsHPROFILE hProfile
);
448 cmsBool
_cmsReadCHAD(cmsMAT3
* Dest
, cmsHPROFILE hProfile
);
450 // Profile linker --------------------------------------------------------------------------------------------------
452 cmsPipeline
* _cmsLinkProfiles(cmsContext ContextID
,
453 cmsUInt32Number nProfiles
,
454 cmsUInt32Number TheIntents
[],
455 cmsHPROFILE hProfiles
[],
457 cmsFloat64Number AdaptationStates
[],
458 cmsUInt32Number dwFlags
);
460 // Sequence --------------------------------------------------------------------------------------------------------
462 cmsSEQ
* _cmsReadProfileSequence(cmsHPROFILE hProfile
);
463 cmsBool
_cmsWriteProfileSequence(cmsHPROFILE hProfile
, const cmsSEQ
* seq
);
464 cmsSEQ
* _cmsCompileProfileSequence(cmsContext ContextID
, cmsUInt32Number nProfiles
, cmsHPROFILE hProfiles
[]);
467 // LUT optimization ------------------------------------------------------------------------------------------------
469 cmsUInt16Number
_cmsQuantizeVal(cmsFloat64Number i
, int MaxSamples
);
470 int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace
, cmsUInt32Number dwFlags
);
472 cmsBool
_cmsEndPointsBySpace(cmsColorSpaceSignature Space
,
473 cmsUInt16Number
**White
,
474 cmsUInt16Number
**Black
,
475 cmsUInt32Number
*nOutputs
);
477 cmsBool
_cmsOptimizePipeline(cmsPipeline
** Lut
,
479 cmsUInt32Number
* InputFormat
,
480 cmsUInt32Number
* OutputFormat
,
481 cmsUInt32Number
* dwFlags
);
484 // Hi level LUT building ----------------------------------------------------------------------------------------------
486 cmsPipeline
* _cmsCreateGamutCheckPipeline(cmsContext ContextID
,
487 cmsHPROFILE hProfiles
[],
489 cmsUInt32Number Intents
[],
490 cmsFloat64Number AdaptationStates
[],
491 cmsUInt32Number nGamutPCSposition
,
495 // Formatters ------------------------------------------------------------------------------------------------------------
497 #define cmsFLAGS_CAN_CHANGE_FORMATTER 0x02000000 // Allow change buffer format
499 cmsBool
_cmsFormatterIsFloat(cmsUInt32Number Type
);
500 cmsBool
_cmsFormatterIs8bit(cmsUInt32Number Type
);
502 cmsFormatter
_cmsGetFormatter(cmsUInt32Number Type
, // Specific type, i.e. TYPE_RGB_8
503 cmsFormatterDirection Dir
,
504 cmsUInt32Number dwFlags
);
507 #ifndef CMS_NO_HALF_SUPPORT
510 cmsFloat32Number
_cmsHalf2Float(cmsUInt16Number h
);
511 cmsUInt16Number
_cmsFloat2Half(cmsFloat32Number flt
);
515 // Transform logic ------------------------------------------------------------------------------------------------------
517 struct _cmstransform_struct
;
521 // 1-pixel cache (16 bits only)
522 cmsUInt16Number CacheIn
[cmsMAXCHANNELS
];
523 cmsUInt16Number CacheOut
[cmsMAXCHANNELS
];
530 typedef struct _cmstransform_struct
{
532 cmsUInt32Number InputFormat
, OutputFormat
; // Keep formats for further reference
534 // Points to transform code
535 _cmsTransformFn xform
;
537 // Formatters, cannot be embedded into LUT because cache
538 cmsFormatter16 FromInput
;
539 cmsFormatter16 ToOutput
;
541 cmsFormatterFloat FromInputFloat
;
542 cmsFormatterFloat ToOutputFloat
;
544 // 1-pixel cache seed for zero as input (16 bits, read only)
547 // A Pipeline holding the full (optimized) transform
550 // A Pipeline holding the gamut check. It goes from the input space to bilevel
551 cmsPipeline
* GamutCheck
;
554 cmsNAMEDCOLORLIST
* InputColorant
; // Input Colorant table
555 cmsNAMEDCOLORLIST
* OutputColorant
; // Colorant table (for n chans > CMYK)
557 // Informational only
558 cmsColorSpaceSignature EntryColorSpace
;
559 cmsColorSpaceSignature ExitColorSpace
;
561 // White points (informative only)
562 cmsCIEXYZ EntryWhitePoint
;
563 cmsCIEXYZ ExitWhitePoint
;
565 // Profiles used to create the transform
568 cmsUInt32Number dwOriginalFlags
;
569 cmsFloat64Number AdaptationState
;
571 // The intent of this transform. That is usually the last intent in the profilechain, but may differ
572 cmsUInt32Number RenderingIntent
;
574 // An id that uniquely identifies the running context. May be null.
575 cmsContext ContextID
;
577 // A user-defined pointer that can be used to store data for transform plug-ins
579 _cmsFreeUserDataFn FreeUserData
;
583 // --------------------------------------------------------------------------------------------------
585 cmsHTRANSFORM
_cmsChain2Lab(cmsContext ContextID
,
586 cmsUInt32Number nProfiles
,
587 cmsUInt32Number InputFormat
,
588 cmsUInt32Number OutputFormat
,
589 const cmsUInt32Number Intents
[],
590 const cmsHPROFILE hProfiles
[],
592 const cmsFloat64Number AdaptationStates
[],
593 cmsUInt32Number dwFlags
);
596 cmsToneCurve
* _cmsBuildKToneCurve(cmsContext ContextID
,
597 cmsUInt32Number nPoints
,
598 cmsUInt32Number nProfiles
,
599 const cmsUInt32Number Intents
[],
600 const cmsHPROFILE hProfiles
[],
602 const cmsFloat64Number AdaptationStates
[],
603 cmsUInt32Number dwFlags
);
605 cmsBool
_cmsAdaptationMatrix(cmsMAT3
* r
, const cmsMAT3
* ConeMatrix
, const cmsCIEXYZ
* FromIll
, const cmsCIEXYZ
* ToIll
);
607 cmsBool
_cmsBuildRGB2XYZtransferMatrix(cmsMAT3
* r
, const cmsCIExyY
* WhitePoint
, const cmsCIExyYTRIPLE
* Primaries
);
610 #define _lcms_internal_H