3 // Little Color Management System
4 // Copyright (c) 1998-2010 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 & Visual Studio 2003 are broken on that
50 #if defined(__BORLANDC__) || (defined(_MSC_VER) && (_MSC_VER == 1310))
51 #define sinf(x) (float)sin((float)x)
52 #define sqrtf(x) (float)sqrt((float)x)
55 // Alignment of ICC file format uses 4 bytes (cmsUInt32Number)
56 #define _cmsSIZEOFLONGMINUS1 (sizeof(cmsUInt32Number)-1)
57 #define _cmsALIGNLONG(x) (((x)+_cmsSIZEOFLONGMINUS1) & ~(_cmsSIZEOFLONGMINUS1))
59 // Maximum encodeable values in floating point
60 #define MAX_ENCODEABLE_XYZ (1.0 + 32767.0/32768.0)
61 #define MIN_ENCODEABLE_ab2 (-128.0)
62 #define MAX_ENCODEABLE_ab2 ((65535.0/256.0) - 128.0)
63 #define MIN_ENCODEABLE_ab4 (-128.0)
64 #define MAX_ENCODEABLE_ab4 (127.0)
66 // Maximum of channels for internal pipeline evaluation
67 #define MAX_STAGE_CHANNELS 128
69 // Unused parameter warning supression
70 #define cmsUNUSED_PARAMETER(x) ((void)x)
72 // The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999).
73 // unfortunately VisualC++ does not conform that
74 #if defined(_MSC_VER) || defined(__BORLANDC__)
75 # define cmsINLINE __inline
77 # define cmsINLINE static inline
80 // Other replacement functions
83 # define snprintf _snprintf
86 # define vsnprintf _vsnprintf
90 // Pthreads. In windows we use the native WIN32 API instead
91 #ifdef CMS_DONT_USE_PTHREADS
92 typedef int LCMS_RWLOCK_T;
93 # define LCMS_CREATE_LOCK(x)
94 # define LCMS_FREE_LOCK(x)
95 # define LCMS_READ_LOCK(x)
96 # define LCMS_WRITE_LOCK(x)
97 # define LCMS_UNLOCK(x)
99 #ifdef CMS_IS_WINDOWS_
100 # ifndef WIN32_LEAN_AND_MEAN
101 # define WIN32_LEAN_AND_MEAN
103 # include <windows.h>
104 typedef CRITICAL_SECTION LCMS_RWLOCK_T;
105 # define LCMS_CREATE_LOCK(x) InitializeCriticalSection((x))
106 # define LCMS_FREE_LOCK(x) DeleteCriticalSection((x))
107 # define LCMS_READ_LOCK(x) EnterCriticalSection((x))
108 # define LCMS_WRITE_LOCK(x) EnterCriticalSection((x))
109 # define LCMS_UNLOCK(x) LeaveCriticalSection((x))
111 # include <pthread.h>
112 typedef pthread_rwlock_t LCMS_RWLOCK_T;
113 # define LCMS_CREATE_LOCK(x) pthread_rwlock_init((x), NULL)
114 # define LCMS_FREE_LOCK(x) pthread_rwlock_destroy((x))
115 # define LCMS_READ_LOCK(x) pthread_rwlock_rdlock((x))
116 # define LCMS_WRITE_LOCK(x) pthread_rwlock_wrlock((x))
117 # define LCMS_UNLOCK(x) pthread_rwlock_unlock((x))
121 // A fast way to convert from/to 16 <-> 8 bits
122 #define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
123 #define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((rgb) * 65281 + 8388608) >> 24) & 0xFF)
125 // Code analysis is broken on asserts
127 # if (_MSC_VER >= 1500)
128 # define _cmsAssert(a) { assert((a)); __analysis_assume((a)); }
130 # define _cmsAssert(a) assert((a))
133 # define _cmsAssert(a) assert((a))
136 //---------------------------------------------------------------------------------
138 // Determinant lower than that are assumed zero (used on matrix invert)
139 #define MATRIX_DET_TOLERANCE 0.0001
141 //---------------------------------------------------------------------------------
144 #define FIXED_TO_INT(x) ((x)>>16)
145 #define FIXED_REST_TO_INT(x) ((x)&0xFFFFU)
146 #define ROUND_FIXED_TO_INT(x) (((x)+0x8000)>>16)
148 cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a) { return a + ((a + 0x7fff) / 0xffff); }
149 cmsINLINE int _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }
151 // -----------------------------------------------------------------------------------------------------------
153 // Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon
154 // note than this only works in the range ..-32767...+32767 because
155 // mantissa is interpreted as 15.16 fixed point.
156 // The union is to avoid pointer aliasing overoptimization.
157 cmsINLINE int _cmsQuickFloor(cmsFloat64Number val)
159 #ifdef CMS_DONT_USE_FAST_FLOOR
160 return (int) floor(val);
162 const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5; // 2^36 * 1.5, (52-16=36) uses limited precision to floor
164 cmsFloat64Number val;
168 temp.val = val + _lcms_double2fixmagic;
170 #ifdef CMS_USE_BIG_ENDIAN
171 return temp.halves[1] >> 16;
173 return temp.halves[0] >> 16;
178 // Fast floor restricted to 0..65535.0
179 cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
181 return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
184 // Floor to word, taking care of saturation
185 cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
188 if (d <= 0) return 0;
189 if (d >= 65535.0) return 0xffff;
191 return _cmsQuickFloorWord(d);
194 // Plug-In registering ---------------------------------------------------------------
196 // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.
197 void* _cmsPluginMalloc(cmsUInt32Number size);
200 cmsBool _cmsRegisterMemHandlerPlugin(cmsPluginBase* Plugin);
203 cmsBool _cmsRegisterInterpPlugin(cmsPluginBase* Plugin);
206 cmsBool _cmsRegisterParametricCurvesPlugin(cmsPluginBase* Plugin);
208 // Formatters management
209 cmsBool _cmsRegisterFormattersPlugin(cmsPluginBase* Plugin);
211 // Tag type management
212 cmsBool _cmsRegisterTagTypePlugin(cmsPluginBase* Plugin);
215 cmsBool _cmsRegisterTagPlugin(cmsPluginBase* Plugin);
218 cmsBool _cmsRegisterRenderingIntentPlugin(cmsPluginBase* Plugin);
220 // Multi Process elements
221 cmsBool _cmsRegisterMultiProcessElementPlugin(cmsPluginBase* Plugin);
224 cmsBool _cmsRegisterOptimizationPlugin(cmsPluginBase* Plugin);
227 // ---------------------------------------------------------------------------------------------------------
229 // Suballocators. Those are blocks of memory that is freed at the end on whole block.
230 typedef struct _cmsSubAllocator_chunk_st {
232 cmsUInt8Number* Block;
233 cmsUInt32Number BlockSize;
234 cmsUInt32Number Used;
236 struct _cmsSubAllocator_chunk_st* next;
238 } _cmsSubAllocator_chunk;
243 cmsContext ContextID;
244 _cmsSubAllocator_chunk* h;
249 _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
250 void _cmsSubAllocDestroy(_cmsSubAllocator* s);
251 void* _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
253 // ----------------------------------------------------------------------------------
255 // MLU internal representation
258 cmsUInt16Number Language;
259 cmsUInt16Number Country;
261 cmsUInt32Number StrW; // Offset to current unicode string
262 cmsUInt32Number Len; // Lenght in bytes
266 struct _cms_MLU_struct {
268 cmsContext ContextID;
271 int AllocatedEntries;
273 _cmsMLUentry* Entries; // Array of pointers to strings allocated in MemPool
276 cmsUInt32Number PoolSize; // The maximum allocated size
277 cmsUInt32Number PoolUsed; // The used size
278 void* MemPool; // Pointer to begin of memory pool
281 // Named color list internal representation
284 char Name[cmsMAX_PATH];
285 cmsUInt16Number PCS[3];
286 cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
290 struct _cms_NAMEDCOLORLIST_struct {
292 cmsUInt32Number nColors;
293 cmsUInt32Number Allocated;
294 cmsUInt32Number ColorantCount;
296 char Prefix[33]; // Prefix and suffix are defined to be 32 characters at most
299 _cmsNAMEDCOLOR* List;
301 cmsContext ContextID;
305 // ----------------------------------------------------------------------------------
307 // This is the internal struct holding profile details.
309 // Maximum supported tags in a profile
310 #define MAX_TABLE_TAG 100
312 typedef struct _cms_iccprofile_struct {
315 cmsIOHANDLER* IOhandler;
318 cmsContext ContextID;
323 // Only most important items found in ICC profiles
324 cmsUInt32Number Version;
325 cmsProfileClassSignature DeviceClass;
326 cmsColorSpaceSignature ColorSpace;
327 cmsColorSpaceSignature PCS;
328 cmsUInt32Number RenderingIntent;
329 cmsUInt32Number flags;
330 cmsUInt32Number manufacturer, model;
331 cmsUInt64Number attributes;
333 cmsProfileID ProfileID;
336 cmsUInt32Number TagCount;
337 cmsTagSignature TagNames[MAX_TABLE_TAG];
338 cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to wich is linked (0=none)
339 cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk
340 cmsUInt32Number TagOffsets[MAX_TABLE_TAG];
341 cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked
342 void * TagPtrs[MAX_TABLE_TAG];
343 cmsTagTypeHandler* TagTypeHandlers[MAX_TABLE_TAG]; // Same structure may be serialized on different types
344 // depending on profile version, so we keep track of the // type handler for each tag in the list.
350 // IO helpers for profiles
351 cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc);
352 cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
353 int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
356 cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsTagTypeSignature sig);
357 cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
358 cmsTagDescriptor* _cmsGetTagDescriptor(cmsTagSignature sig);
360 // Error logging ---------------------------------------------------------------------------------------------------------
362 void _cmsTagSignature2String(char String[5], cmsTagSignature sig);
364 // Interpolation ---------------------------------------------------------------------------------------------------------
366 cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
367 cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
368 void _cmsFreeInterpParams(cmsInterpParams* p);
369 cmsBool _cmsSetInterpolationRoutine(cmsInterpParams* p);
371 // Curves ----------------------------------------------------------------------------------------------------------------
373 // This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
374 // In the case of table-based, Eval pointer is set to NULL
376 // The gamma function main structure
377 struct _cms_curve_struct {
379 cmsInterpParams* InterpParams; // Private optimizations for interpolation
381 cmsUInt32Number nSegments; // Number of segments in the curve. Zero for a 16-bit based tables
382 cmsCurveSegment* Segments; // The segments
383 cmsInterpParams** SegInterp; // Array of private optimizations for interpolation in table-based segments
385 cmsParametricCurveEvaluator* Evals; // Evaluators (one per segment)
387 // 16 bit Table-based representation follows
388 cmsUInt32Number nEntries; // Number of table elements
389 cmsUInt16Number* Table16; // The table itself.
393 // Pipelines & Stages ---------------------------------------------------------------------------------------------
396 struct _cmsStage_struct {
398 cmsContext ContextID;
400 cmsStageSignature Type; // Identifies the stage
401 cmsStageSignature Implements; // Identifies the *function* of the stage (for optimizations)
403 cmsUInt32Number InputChannels; // Input channels -- for optimization purposes
404 cmsUInt32Number OutputChannels; // Output channels -- for optimization purposes
406 _cmsStageEvalFn EvalPtr; // Points to fn that evaluates the stage (always in floating point)
407 _cmsStageDupElemFn DupElemPtr; // Points to a fn that duplicates the *data* of the stage
408 _cmsStageFreeElemFn FreePtr; // Points to a fn that sets the *data* of the stage free
410 // A generic pointer to whatever memory needed by the stage
413 // Maintains linked list (used internally)
414 struct _cmsStage_struct* Next;
417 // Data kept in "Element" member of cmsStage
421 cmsUInt32Number nCurves;
422 cmsToneCurve** TheCurves;
424 } _cmsStageToneCurvesData;
428 cmsFloat64Number* Double; // floating point for the matrix
429 cmsFloat64Number* Offset; // The offset
431 } _cmsStageMatrixData;
436 union { // Can have only one of both representations at same time
437 cmsUInt16Number* T; // Points to the table 16 bits table
438 cmsFloat32Number* TFloat; // Points to the cmsFloat32Number table
442 cmsInterpParams* Params;
443 cmsUInt32Number nEntries;
444 cmsBool HasFloatValues;
449 // Special Stages (cannot be saved)
450 cmsStage* _cmsStageAllocLab2XYZ(cmsContext ContextID);
451 cmsStage* _cmsStageAllocXYZ2Lab(cmsContext ContextID);
452 cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID);
453 cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID);
454 cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
455 cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID);
456 cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList);
457 cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels);
458 cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan);
460 // For curve set only
461 cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
464 // Pipeline Evaluator (in floating point)
465 typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[],
466 cmsFloat32Number Out[],
469 struct _cmsPipeline_struct {
471 cmsStage* Elements; // Points to elements chain
472 cmsUInt32Number InputChannels, OutputChannels;
477 _cmsOPTeval16Fn Eval16Fn;
478 _cmsPipelineEvalFloatFn EvalFloatFn;
479 _cmsOPTfreeDataFn FreeDataFn;
480 _cmsOPTdupDataFn DupDataFn;
482 cmsContext ContextID; // Environment
484 cmsBool SaveAs8Bits; // Implemntation-specific: save as 8 bits if possible
487 // LUT reading & creation -------------------------------------------------------------------------------------------
489 // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
490 // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
492 cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent);
493 cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent);
494 cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent);
497 cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
498 cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);
500 // Profile linker --------------------------------------------------------------------------------------------------
502 cmsPipeline* _cmsLinkProfiles(cmsContext ContextID,
503 cmsUInt32Number nProfiles,
504 cmsUInt32Number TheIntents[],
505 cmsHPROFILE hProfiles[],
507 cmsFloat64Number AdaptationStates[],
508 cmsUInt32Number dwFlags);
510 // Sequence --------------------------------------------------------------------------------------------------------
512 cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile);
513 cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq);
514 cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
517 // LUT optimization ------------------------------------------------------------------------------------------------
519 cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples);
520 int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
522 cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
523 cmsUInt16Number **White,
524 cmsUInt16Number **Black,
525 cmsUInt32Number *nOutputs);
527 cmsBool _cmsOptimizePipeline(cmsPipeline** Lut,
529 cmsUInt32Number* InputFormat,
530 cmsUInt32Number* OutputFormat,
531 cmsUInt32Number* dwFlags );
534 // Hi level LUT building ----------------------------------------------------------------------------------------------
536 cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
537 cmsHPROFILE hProfiles[],
539 cmsUInt32Number Intents[],
540 cmsFloat64Number AdaptationStates[],
541 cmsUInt32Number nGamutPCSposition,
545 // Formatters ------------------------------------------------------------------------------------------------------------
547 #define cmsFLAGS_CAN_CHANGE_FORMATTER 0x02000000 // Allow change buffer format
549 cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type);
550 cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type);
552 cmsFormatter _cmsGetFormatter(cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
553 cmsFormatterDirection Dir,
554 cmsUInt32Number dwFlags);
557 // Transform logic ------------------------------------------------------------------------------------------------------
559 struct _cmstransform_struct;
562 typedef void (* _cmsTransformFn)(struct _cmstransform_struct *Transform,
563 const void* InputBuffer,
564 void* OutputBuffer, cmsUInt32Number Size);
568 cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
569 cmsUInt32Number StrideIn, StrideOut; // Planar support
574 typedef struct _cmstransform_struct {
576 cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
578 // Points to transform code
579 _cmsTransformFn xform;
581 // Formatters, cannot be embedded into LUT because cache
582 cmsFormatter16 FromInput;
583 cmsFormatter16 ToOutput;
585 cmsFormatterFloat FromInputFloat;
586 cmsFormatterFloat ToOutputFloat;
588 // 1-pixel cache (16 bits only)
589 cmsUInt16Number CacheIn[cmsMAXCHANNELS];
590 cmsUInt16Number CacheOut[cmsMAXCHANNELS];
592 // Semaphor for cache
593 LCMS_RWLOCK_T rwlock;
595 // A MPE LUT holding the full (optimized) transform
598 // A MPE LUT holding the gamut check. It goes from the input space to bilevel
599 cmsPipeline* GamutCheck;
602 cmsNAMEDCOLORLIST* InputColorant; // Input Colorant table
603 cmsNAMEDCOLORLIST* OutputColorant; // Colorant table (for n chans > CMYK)
605 // Informational only
606 cmsColorSpaceSignature EntryColorSpace;
607 cmsColorSpaceSignature ExitColorSpace;
609 // Profiles used to create the transform
612 cmsUInt32Number dwOriginalFlags;
613 cmsFloat64Number AdaptationState;
615 // The intent of this transform. That is usually the last intent in the profilechain, but may differ
616 cmsUInt32Number RenderingIntent;
618 // An id that uniquely identifies the running context. May be null.
619 cmsContext ContextID;
623 // --------------------------------------------------------------------------------------------------
625 cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
626 cmsUInt32Number nProfiles,
627 cmsUInt32Number InputFormat,
628 cmsUInt32Number OutputFormat,
629 const cmsUInt32Number Intents[],
630 const cmsHPROFILE hProfiles[],
632 const cmsFloat64Number AdaptationStates[],
633 cmsUInt32Number dwFlags);
636 cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID,
637 cmsUInt32Number nPoints,
638 cmsUInt32Number nProfiles,
639 const cmsUInt32Number Intents[],
640 const cmsHPROFILE hProfiles[],
642 const cmsFloat64Number AdaptationStates[],
643 cmsUInt32Number dwFlags);
645 cmsBool _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
647 cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
650 #define _lcms_internal_H