Home | History | Annotate | Download | only in src
      1 //<<<+++OPENSOURCE
      2 //<<<+++OPENSOURCE_MUST_BEGIN COMMENT==TRUE
      3 //
      4 //  Little Color Management System
      5 //  Copyright (c) 1998-2014 Marti Maria Saguer
      6 //
      7 // Permission is hereby granted, free of charge, to any person obtaining
      8 // a copy of this software and associated documentation files (the "Software"),
      9 // to deal in the Software without restriction, including without limitation
     10 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11 // and/or sell copies of the Software, and to permit persons to whom the Software
     12 // is furnished to do so, subject to the following conditions:
     13 //
     14 // The above copyright notice and this permission notice shall be included in
     15 // all copies or substantial portions of the Software.
     16 //
     17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
     19 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     20 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
     21 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     22 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     23 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24 //
     25 //---------------------------------------------------------------------------------
     26 //
     27 
     28 #ifndef _lcms_internal_H
     29 
     30 // Include plug-in foundation
     31 #ifndef _lcms_plugin_H
     32 #include "third_party/lcms2-2.6/include/lcms2_plugin.h"
     33 #endif
     34 
     35 // ctype is part of C99 as per 7.1.2
     36 #include <ctype.h>
     37 
     38 // assert macro is part of C99 as per 7.2
     39 #include <assert.h>
     40 
     41 // Some needed constants
     42 #ifndef M_PI
     43 #       define M_PI        3.14159265358979323846
     44 #endif
     45 
     46 #ifndef M_LOG10E
     47 #       define M_LOG10E    0.434294481903251827651
     48 #endif
     49 
     50 // BorlandC 5.5, VC2003 are broken on that
     51 #if defined(__BORLANDC__) || (_MSC_VER < 1400) // 1400 == VC++ 8.0
     52 #define sinf(x) (float)sin((float)x)
     53 #define sqrtf(x) (float)sqrt((float)x)
     54 #endif
     55 
     56 
     57 // Alignment of ICC file format uses 4 bytes (cmsUInt32Number)
     58 #define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & ~(sizeof(cmsUInt32Number)-1))
     59 
     60 // Alignment to memory pointer
     61 #define _cmsALIGNMEM(x)  (((x)+(sizeof(void *) - 1)) & ~(sizeof(void *) - 1))
     62 
     63 // Maximum encodeable values in floating point
     64 #define MAX_ENCODEABLE_XYZ  (1.0 + 32767.0/32768.0)
     65 #define MIN_ENCODEABLE_ab2  (-128.0)
     66 #define MAX_ENCODEABLE_ab2  ((65535.0/256.0) - 128.0)
     67 #define MIN_ENCODEABLE_ab4  (-128.0)
     68 #define MAX_ENCODEABLE_ab4  (127.0)
     69 
     70 // Maximum of channels for internal pipeline evaluation
     71 #define MAX_STAGE_CHANNELS  128
     72 
     73 // Unused parameter warning supression
     74 #define cmsUNUSED_PARAMETER(x) ((void)x)
     75 
     76 // The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999).
     77 // unfortunately VisualC++ does not conform that
     78 #if defined(_MSC_VER) || defined(__BORLANDC__)
     79 #   define cmsINLINE __inline
     80 #else
     81 #   define cmsINLINE static inline
     82 #endif
     83 
     84 // Other replacement functions
     85 #ifdef _MSC_VER
     86 # ifndef snprintf
     87 #       define snprintf  _snprintf
     88 # endif
     89 # ifndef vsnprintf
     90 #       define vsnprintf  _vsnprintf
     91 # endif
     92 #endif
     93 
     94 
     95 // A fast way to convert from/to 16 <-> 8 bits
     96 #define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
     97 #define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((cmsUInt32Number)(rgb) * 65281U + 8388608U) >> 24) & 0xFFU)
     98 
     99 // Code analysis is broken on asserts
    100 #ifdef _MSC_VER
    101 #    if (_MSC_VER >= 1500)
    102 #            define _cmsAssert(a)  { assert((a)); __analysis_assume((a)); }
    103 #     else
    104 #            define _cmsAssert(a)   assert((a))
    105 #     endif
    106 #else
    107 #      define _cmsAssert(a)   assert((a))
    108 #endif
    109 
    110 //---------------------------------------------------------------------------------
    111 
    112 // Determinant lower than that are assumed zero (used on matrix invert)
    113 #define MATRIX_DET_TOLERANCE    0.0001
    114 
    115 //---------------------------------------------------------------------------------
    116 
    117 // Fixed point
    118 #define FIXED_TO_INT(x)         ((x)>>16)
    119 #define FIXED_REST_TO_INT(x)    ((x)&0xFFFFU)
    120 #define ROUND_FIXED_TO_INT(x)   (((x)+0x8000)>>16)
    121 
    122 cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a)                   { return a + ((a + 0x7fff) / 0xffff); }
    123 cmsINLINE int                 _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }
    124 
    125 // -----------------------------------------------------------------------------------------------------------
    126 
    127 // Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon
    128 // note than this only works in the range ..-32767...+32767 because
    129 // mantissa is interpreted as 15.16 fixed point.
    130 // The union is to avoid pointer aliasing overoptimization.
    131 cmsINLINE int _cmsQuickFloor(cmsFloat64Number val)
    132 {
    133 #ifdef CMS_DONT_USE_FAST_FLOOR
    134     return (int) floor(val);
    135 #else
    136     const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5;  // 2^36 * 1.5, (52-16=36) uses limited precision to floor
    137     union {
    138         cmsFloat64Number val;
    139         int halves[2];
    140     } temp;
    141 
    142     temp.val = val + _lcms_double2fixmagic;
    143 
    144 #ifdef CMS_USE_BIG_ENDIAN
    145     return temp.halves[1] >> 16;
    146 #else
    147     return temp.halves[0] >> 16;
    148 #endif
    149 #endif
    150 }
    151 
    152 // Fast floor restricted to 0..65535.0
    153 cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
    154 {
    155     return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
    156 }
    157 
    158 // Floor to word, taking care of saturation
    159 cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
    160 {
    161     d += 0.5;
    162     if (d <= 0) return 0;
    163     if (d >= 65535.0) return 0xffff;
    164 
    165     return _cmsQuickFloorWord(d);
    166 }
    167 
    168 
    169 // Pthread support --------------------------------------------------------------------
    170 #ifndef CMS_NO_PTHREADS
    171 
    172 // This is the threading support. Unfortunately, it has to be platform-dependent because
    173 // windows does not support pthreads.
    174 
    175 #ifdef CMS_IS_WINDOWS_
    176 
    177 #define WIN32_LEAN_AND_MEAN 1
    178 #include <windows.h>
    179 
    180 
    181 // From: http://locklessinc.com/articles/pthreads_on_windows/
    182 // The pthreads API has an initialization macro that has no correspondence to anything in
    183 // the windows API. By investigating the internal definition of the critical section type,
    184 // one may work out how to initialize one without calling InitializeCriticalSection().
    185 // The trick here is that InitializeCriticalSection() is not allowed to fail. It tries
    186 // to allocate a critical section debug object, but if no memory is available, it sets
    187 // the pointer to a specific value. (One would expect that value to be NULL, but it is
    188 // actually (void *)-1 for some reason.) Thus we can use this special value for that
    189 // pointer, and the critical section code will work.
    190 
    191 // The other important part of the critical section type to initialize is the number
    192 // of waiters. This controls whether or not the mutex is locked. Fortunately, this
    193 // part of the critical section is unlikely to change. Apparently, many programs
    194 // already test critical sections to see if they are locked using this value, so
    195 // Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical
    196 // section, even when they changed the underlying algorithm to be more scalable.
    197 // The final parts of the critical section object are unimportant, and can be set
    198 // to zero for their defaults. This yields an initialization macro:
    199 
    200 typedef CRITICAL_SECTION _cmsMutex;
    201 
    202 #define CMS_MUTEX_INITIALIZER {(void*) -1,-1,0,0,0,0}
    203 
    204 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
    205 {
    206 	EnterCriticalSection(m);
    207 	return 0;
    208 }
    209 
    210 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
    211 {
    212 	LeaveCriticalSection(m);
    213 	return 0;
    214 }
    215 
    216 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
    217 {
    218 	InitializeCriticalSection(m);
    219 	return 0;
    220 }
    221 
    222 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
    223 {
    224 	DeleteCriticalSection(m);
    225 	return 0;
    226 }
    227 
    228 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
    229 {
    230 	EnterCriticalSection(m);
    231 	return 0;
    232 }
    233 
    234 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
    235 {
    236 	LeaveCriticalSection(m);
    237 	return 0;
    238 }
    239 
    240 #else
    241 
    242 // Rest of the wide world
    243 #include <pthread.h>
    244 
    245 #define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
    246 typedef pthread_mutex_t _cmsMutex;
    247 
    248 
    249 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
    250 {
    251 	return pthread_mutex_lock(m);
    252 }
    253 
    254 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
    255 {
    256 	return pthread_mutex_unlock(m);
    257 }
    258 
    259 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
    260 {
    261 	return pthread_mutex_init(m, NULL);
    262 }
    263 
    264 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
    265 {
    266 	return pthread_mutex_destroy(m);
    267 }
    268 
    269 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
    270 {
    271 	return pthread_mutex_lock(m);
    272 }
    273 
    274 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
    275 {
    276 	return pthread_mutex_unlock(m);
    277 }
    278 
    279 #endif
    280 #else
    281 
    282 #define CMS_MUTEX_INITIALIZER 0
    283 typedef int _cmsMutex;
    284 
    285 
    286 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
    287 {
    288 	return 0;
    289     cmsUNUSED_PARAMETER(m);
    290 }
    291 
    292 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
    293 {
    294 	return 0;
    295     cmsUNUSED_PARAMETER(m);
    296 }
    297 
    298 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
    299 {
    300 	return 0;
    301     cmsUNUSED_PARAMETER(m);
    302 }
    303 
    304 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
    305 {
    306 	return 0;
    307     cmsUNUSED_PARAMETER(m);
    308 }
    309 
    310 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
    311 {
    312 	return 0;
    313     cmsUNUSED_PARAMETER(m);
    314 }
    315 
    316 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
    317 {
    318 	return 0;
    319     cmsUNUSED_PARAMETER(m);
    320 }
    321 #endif
    322 
    323 // Plug-In registration ---------------------------------------------------------------
    324 
    325 // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.
    326 void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size);
    327 
    328 // Memory management
    329 cmsBool   _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
    330 
    331 // Interpolation
    332 cmsBool  _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
    333 
    334 // Parametric curves
    335 cmsBool  _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
    336 
    337 // Formatters management
    338 cmsBool  _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
    339 
    340 // Tag type management
    341 cmsBool  _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin);
    342 
    343 // Tag management
    344 cmsBool  _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
    345 
    346 // Intent management
    347 cmsBool  _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
    348 
    349 // Multi Process elements
    350 cmsBool  _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
    351 
    352 // Optimization
    353 cmsBool  _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
    354 
    355 // Transform
    356 cmsBool  _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
    357 
    358 // Mutex
    359 cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
    360 
    361 // ---------------------------------------------------------------------------------------------------------
    362 
    363 // Suballocators.
    364 typedef struct _cmsSubAllocator_chunk_st {
    365 
    366     cmsUInt8Number* Block;
    367     cmsUInt32Number BlockSize;
    368     cmsUInt32Number Used;
    369 
    370     struct _cmsSubAllocator_chunk_st* next;
    371 
    372 } _cmsSubAllocator_chunk;
    373 
    374 
    375 typedef struct {
    376 
    377     cmsContext ContextID;
    378     _cmsSubAllocator_chunk* h;
    379 
    380 } _cmsSubAllocator;
    381 
    382 
    383 _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
    384 void              _cmsSubAllocDestroy(_cmsSubAllocator* s);
    385 void*             _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
    386 void*             _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
    387 
    388 // ----------------------------------------------------------------------------------
    389 
    390 // The context clients.
    391 typedef enum {
    392 
    393     UserPtr,            // User-defined pointer
    394     Logger,
    395     AlarmCodesContext,
    396     AdaptationStateContext,
    397     MemPlugin,
    398     InterpPlugin,
    399     CurvesPlugin,
    400     FormattersPlugin,
    401     TagTypePlugin,
    402     TagPlugin,
    403     IntentPlugin,
    404     MPEPlugin,
    405     OptimizationPlugin,
    406     TransformPlugin,
    407     MutexPlugin,
    408 
    409     // Last in list
    410     MemoryClientMax
    411 
    412 } _cmsMemoryClient;
    413 
    414 
    415 // Container for memory management plug-in.
    416 typedef struct {
    417 
    418     _cmsMallocFnPtrType     MallocPtr;
    419     _cmsMalloZerocFnPtrType MallocZeroPtr;
    420     _cmsFreeFnPtrType       FreePtr;
    421     _cmsReallocFnPtrType    ReallocPtr;
    422     _cmsCallocFnPtrType     CallocPtr;
    423     _cmsDupFnPtrType        DupPtr;
    424 
    425 } _cmsMemPluginChunkType;
    426 
    427 // Copy memory management function pointers from plug-in to chunk, taking care of missing routines
    428 void  _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);
    429 
    430 // Internal structure for context
    431 struct _cmsContext_struct {
    432 
    433     struct _cmsContext_struct* Next;  // Points to next context in the new style
    434     _cmsSubAllocator* MemPool;        // The memory pool that stores context data
    435 
    436     void* chunks[MemoryClientMax];    // array of pointers to client chunks. Memory itself is hold in the suballocator.
    437                                       // If NULL, then it reverts to global Context0
    438 
    439     _cmsMemPluginChunkType DefaultMemoryManager;  // The allocators used for creating the context itself. Cannot be overriden
    440 };
    441 
    442 // Returns a pointer to a valid context structure, including the global one if id is zero.
    443 // Verifies the magic number.
    444 struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);
    445 
    446 // Returns the block assigned to the specific zone.
    447 void*     _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc);
    448 
    449 
    450 // Chunks of context memory by plug-in client -------------------------------------------------------
    451 
    452 // Those structures encapsulates all variables needed by the several context clients (mostly plug-ins)
    453 
    454 // Container for error logger -- not a plug-in
    455 typedef struct {
    456 
    457     cmsLogErrorHandlerFunction LogErrorHandler;  // Set to NULL for Context0 fallback
    458 
    459 } _cmsLogErrorChunkType;
    460 
    461 // The global Context0 storage for error logger
    462 extern  _cmsLogErrorChunkType  _cmsLogErrorChunk;
    463 
    464 // Allocate and init error logger container.
    465 void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
    466                             const struct _cmsContext_struct* src);
    467 
    468 // Container for alarm codes -- not a plug-in
    469 typedef struct {
    470 
    471     cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];
    472 
    473 } _cmsAlarmCodesChunkType;
    474 
    475 // The global Context0 storage for alarm codes
    476 extern  _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;
    477 
    478 // Allocate and init alarm codes container.
    479 void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
    480                             const struct _cmsContext_struct* src);
    481 
    482 // Container for adaptation state -- not a plug-in
    483 typedef struct {
    484 
    485     cmsFloat64Number  AdaptationState;
    486 
    487 } _cmsAdaptationStateChunkType;
    488 
    489 // The global Context0 storage for adaptation state
    490 extern  _cmsAdaptationStateChunkType    _cmsAdaptationStateChunk;
    491 
    492 // Allocate and init adaptation state container.
    493 void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
    494                                    const struct _cmsContext_struct* src);
    495 
    496 
    497 // The global Context0 storage for memory management
    498 extern  _cmsMemPluginChunkType _cmsMemPluginChunk;
    499 
    500 // Allocate and init memory management container.
    501 void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,
    502                              const struct _cmsContext_struct* src);
    503 
    504 // Container for interpolation plug-in
    505 typedef struct {
    506 
    507     cmsInterpFnFactory Interpolators;
    508 
    509 } _cmsInterpPluginChunkType;
    510 
    511 // The global Context0 storage for interpolation plug-in
    512 extern  _cmsInterpPluginChunkType _cmsInterpPluginChunk;
    513 
    514 // Allocate and init interpolation container.
    515 void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,
    516                                 const struct _cmsContext_struct* src);
    517 
    518 // Container for parametric curves plug-in
    519 typedef struct {
    520 
    521     struct _cmsParametricCurvesCollection_st* ParametricCurves;
    522 
    523 } _cmsCurvesPluginChunkType;
    524 
    525 // The global Context0 storage for tone curves plug-in
    526 extern  _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;
    527 
    528 // Allocate and init parametric curves container.
    529 void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
    530                                                       const struct _cmsContext_struct* src);
    531 
    532 // Container for formatters plug-in
    533 typedef struct {
    534 
    535     struct _cms_formatters_factory_list* FactoryList;
    536 
    537 } _cmsFormattersPluginChunkType;
    538 
    539 // The global Context0 storage for formatters plug-in
    540 extern  _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;
    541 
    542 // Allocate and init formatters container.
    543 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
    544                                                        const struct _cmsContext_struct* src);
    545 
    546 // This chunk type is shared by TagType plug-in and MPE Plug-in
    547 typedef struct {
    548 
    549     struct _cmsTagTypeLinkedList_st* TagTypes;
    550 
    551 } _cmsTagTypePluginChunkType;
    552 
    553 
    554 // The global Context0 storage for tag types plug-in
    555 extern  _cmsTagTypePluginChunkType      _cmsTagTypePluginChunk;
    556 
    557 
    558 // The global Context0 storage for mult process elements plug-in
    559 extern  _cmsTagTypePluginChunkType      _cmsMPETypePluginChunk;
    560 
    561 // Allocate and init Tag types container.
    562 void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
    563                                                         const struct _cmsContext_struct* src);
    564 // Allocate and init MPE container.
    565 void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
    566                                                         const struct _cmsContext_struct* src);
    567 // Container for tag plug-in
    568 typedef struct {
    569 
    570     struct _cmsTagLinkedList_st* Tag;
    571 
    572 } _cmsTagPluginChunkType;
    573 
    574 
    575 // The global Context0 storage for tag plug-in
    576 extern  _cmsTagPluginChunkType _cmsTagPluginChunk;
    577 
    578 // Allocate and init Tag container.
    579 void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
    580                                                       const struct _cmsContext_struct* src);
    581 
    582 // Container for intents plug-in
    583 typedef struct {
    584 
    585     struct _cms_intents_list* Intents;
    586 
    587 } _cmsIntentsPluginChunkType;
    588 
    589 
    590 // The global Context0 storage for intents plug-in
    591 extern  _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;
    592 
    593 // Allocate and init intents container.
    594 void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
    595                                                         const struct _cmsContext_struct* src);
    596 
    597 // Container for optimization plug-in
    598 typedef struct {
    599 
    600     struct _cmsOptimizationCollection_st* OptimizationCollection;
    601 
    602 } _cmsOptimizationPluginChunkType;
    603 
    604 
    605 // The global Context0 storage for optimizers plug-in
    606 extern  _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;
    607 
    608 // Allocate and init optimizers container.
    609 void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
    610                                          const struct _cmsContext_struct* src);
    611 
    612 // Container for transform plug-in
    613 typedef struct {
    614 
    615     struct _cmsTransformCollection_st* TransformCollection;
    616 
    617 } _cmsTransformPluginChunkType;
    618 
    619 // The global Context0 storage for full-transform replacement plug-in
    620 extern  _cmsTransformPluginChunkType _cmsTransformPluginChunk;
    621 
    622 // Allocate and init transform container.
    623 void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
    624                                         const struct _cmsContext_struct* src);
    625 
    626 // Container for mutex plug-in
    627 typedef struct {
    628 
    629     _cmsCreateMutexFnPtrType  CreateMutexPtr;
    630     _cmsDestroyMutexFnPtrType DestroyMutexPtr;
    631     _cmsLockMutexFnPtrType    LockMutexPtr;
    632     _cmsUnlockMutexFnPtrType  UnlockMutexPtr;
    633 
    634 } _cmsMutexPluginChunkType;
    635 
    636 // The global Context0 storage for mutex plug-in
    637 extern  _cmsMutexPluginChunkType _cmsMutexPluginChunk;
    638 
    639 // Allocate and init mutex container.
    640 void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
    641                                         const struct _cmsContext_struct* src);
    642 
    643 // ----------------------------------------------------------------------------------
    644 // MLU internal representation
    645 typedef struct {
    646 
    647     cmsUInt16Number Language;
    648     cmsUInt16Number Country;
    649 
    650     cmsUInt32Number StrW;       // Offset to current unicode string
    651     cmsUInt32Number Len;        // Length in bytes
    652 
    653 } _cmsMLUentry;
    654 
    655 struct _cms_MLU_struct {
    656 
    657     cmsContext ContextID;
    658 
    659     // The directory
    660     int AllocatedEntries;
    661     int UsedEntries;
    662     _cmsMLUentry* Entries;     // Array of pointers to strings allocated in MemPool
    663 
    664     // The Pool
    665     cmsUInt32Number PoolSize;  // The maximum allocated size
    666     cmsUInt32Number PoolUsed;  // The used size
    667     void*  MemPool;            // Pointer to begin of memory pool
    668 };
    669 
    670 // Named color list internal representation
    671 typedef struct {
    672 
    673     char Name[cmsMAX_PATH];
    674     cmsUInt16Number PCS[3];
    675     cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
    676 
    677 } _cmsNAMEDCOLOR;
    678 
    679 struct _cms_NAMEDCOLORLIST_struct {
    680 
    681     cmsUInt32Number nColors;
    682     cmsUInt32Number Allocated;
    683     cmsUInt32Number ColorantCount;
    684 
    685     char Prefix[33];      // Prefix and suffix are defined to be 32 characters at most
    686     char Suffix[33];
    687 
    688     _cmsNAMEDCOLOR* List;
    689 
    690     cmsContext ContextID;
    691 };
    692 
    693 
    694 // ----------------------------------------------------------------------------------
    695 
    696 // This is the internal struct holding profile details.
    697 
    698 // Maximum supported tags in a profile
    699 #define MAX_TABLE_TAG       100
    700 
    701 typedef struct _cms_iccprofile_struct {
    702 
    703     // I/O handler
    704     cmsIOHANDLER*            IOhandler;
    705 
    706     // The thread ID
    707     cmsContext               ContextID;
    708 
    709     // Creation time
    710     struct tm                Created;
    711 
    712     // Only most important items found in ICC profiles
    713     cmsUInt32Number          Version;
    714     cmsProfileClassSignature DeviceClass;
    715     cmsColorSpaceSignature   ColorSpace;
    716     cmsColorSpaceSignature   PCS;
    717     cmsUInt32Number          RenderingIntent;
    718 
    719     cmsUInt32Number          flags;
    720     cmsUInt32Number          manufacturer, model;
    721     cmsUInt64Number          attributes;
    722     cmsUInt32Number          creator;
    723 
    724     cmsProfileID             ProfileID;
    725 
    726     // Dictionary
    727     cmsUInt32Number          TagCount;
    728     cmsTagSignature          TagNames[MAX_TABLE_TAG];
    729     cmsTagSignature          TagLinked[MAX_TABLE_TAG];           // The tag to wich is linked (0=none)
    730     cmsUInt32Number          TagSizes[MAX_TABLE_TAG];            // Size on disk
    731     cmsUInt32Number          TagOffsets[MAX_TABLE_TAG];
    732     cmsBool                  TagSaveAsRaw[MAX_TABLE_TAG];        // True to write uncooked
    733     void *                   TagPtrs[MAX_TABLE_TAG];
    734     cmsTagTypeHandler*       TagTypeHandlers[MAX_TABLE_TAG];     // Same structure may be serialized on different types
    735                                                                  // depending on profile version, so we keep track of the
    736                                                                  // type handler for each tag in the list.
    737     // Special
    738     cmsBool                  IsWrite;
    739 
    740     // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin
    741     void *                   UsrMutex;
    742 
    743 } _cmsICCPROFILE;
    744 
    745 // IO helpers for profiles
    746 cmsBool              _cmsReadHeader(_cmsICCPROFILE* Icc);
    747 cmsBool              _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
    748 int                  _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
    749 
    750 // Tag types
    751 cmsTagTypeHandler*   _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
    752 cmsTagTypeSignature  _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
    753 cmsTagDescriptor*    _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
    754 
    755 // Error logging ---------------------------------------------------------------------------------------------------------
    756 
    757 void                 _cmsTagSignature2String(char String[5], cmsTagSignature sig);
    758 
    759 // Interpolation ---------------------------------------------------------------------------------------------------------
    760 
    761 cmsInterpParams*     _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
    762 cmsInterpParams*     _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
    763 void                 _cmsFreeInterpParams(cmsInterpParams* p);
    764 cmsBool              _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
    765 
    766 // Curves ----------------------------------------------------------------------------------------------------------------
    767 
    768 // This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
    769 // In the case of table-based, Eval pointer is set to NULL
    770 
    771 // The gamma function main structure
    772 struct _cms_curve_struct {
    773 
    774     cmsInterpParams*  InterpParams;  // Private optimizations for interpolation
    775 
    776     cmsUInt32Number   nSegments;     // Number of segments in the curve. Zero for a 16-bit based tables
    777     cmsCurveSegment*  Segments;      // The segments
    778     cmsInterpParams** SegInterp;     // Array of private optimizations for interpolation in table-based segments
    779 
    780     cmsParametricCurveEvaluator* Evals;  // Evaluators (one per segment)
    781 
    782     // 16 bit Table-based representation follows
    783     cmsUInt32Number    nEntries;      // Number of table elements
    784     cmsUInt16Number*   Table16;       // The table itself.
    785 };
    786 
    787 
    788 //  Pipelines & Stages ---------------------------------------------------------------------------------------------
    789 
    790 // A single stage
    791 struct _cmsStage_struct {
    792 
    793     cmsContext          ContextID;
    794 
    795     cmsStageSignature   Type;           // Identifies the stage
    796     cmsStageSignature   Implements;     // Identifies the *function* of the stage (for optimizations)
    797 
    798     cmsUInt32Number     InputChannels;  // Input channels -- for optimization purposes
    799     cmsUInt32Number     OutputChannels; // Output channels -- for optimization purposes
    800 
    801     _cmsStageEvalFn     EvalPtr;        // Points to fn that evaluates the stage (always in floating point)
    802     _cmsStageDupElemFn  DupElemPtr;     // Points to a fn that duplicates the *data* of the stage
    803     _cmsStageFreeElemFn FreePtr;        // Points to a fn that sets the *data* of the stage free
    804 
    805     // A generic pointer to whatever memory needed by the stage
    806     void*               Data;
    807 
    808     // Maintains linked list (used internally)
    809     struct _cmsStage_struct* Next;
    810 };
    811 
    812 
    813 // Special Stages (cannot be saved)
    814 cmsStage*        _cmsStageAllocLab2XYZ(cmsContext ContextID);
    815 cmsStage*        _cmsStageAllocXYZ2Lab(cmsContext ContextID);
    816 cmsStage*        _cmsStageAllocLabPrelin(cmsContext ContextID);
    817 cmsStage*        _cmsStageAllocLabV2ToV4(cmsContext ContextID);
    818 cmsStage*        _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
    819 cmsStage*        _cmsStageAllocLabV4ToV2(cmsContext ContextID);
    820 cmsStage*        _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
    821 cmsStage*        _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels);
    822 cmsStage*        _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan);
    823 cmsStage*        _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
    824 cmsStage*        _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
    825 cmsStage*        _cmsStageNormalizeToLabFloat(cmsContext ContextID);
    826 cmsStage*        _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
    827 
    828 // For curve set only
    829 cmsToneCurve**     _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
    830 
    831 
    832 // Pipeline Evaluator (in floating point)
    833 typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[],
    834                                          cmsFloat32Number Out[],
    835                                          const void* Data);
    836 
    837 struct _cmsPipeline_struct {
    838 
    839     cmsStage* Elements;                                // Points to elements chain
    840     cmsUInt32Number InputChannels, OutputChannels;
    841 
    842     // Data & evaluators
    843     void *Data;
    844 
    845    _cmsOPTeval16Fn         Eval16Fn;
    846    _cmsPipelineEvalFloatFn EvalFloatFn;
    847    _cmsFreeUserDataFn      FreeDataFn;
    848    _cmsDupUserDataFn       DupDataFn;
    849 
    850     cmsContext ContextID;            // Environment
    851 
    852     cmsBool  SaveAs8Bits;            // Implementation-specific: save as 8 bits if possible
    853 };
    854 
    855 // LUT reading & creation -------------------------------------------------------------------------------------------
    856 
    857 // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
    858 // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
    859 
    860 cmsPipeline*      _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent);
    861 cmsPipeline*      _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent);
    862 cmsPipeline*      _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent);
    863 
    864 // Special values
    865 cmsBool           _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
    866 cmsBool           _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);
    867 
    868 // Profile linker --------------------------------------------------------------------------------------------------
    869 
    870 cmsPipeline* _cmsLinkProfiles(cmsContext         ContextID,
    871                               cmsUInt32Number    nProfiles,
    872                               cmsUInt32Number    TheIntents[],
    873                               cmsHPROFILE        hProfiles[],
    874                               cmsBool            BPC[],
    875                               cmsFloat64Number   AdaptationStates[],
    876                               cmsUInt32Number    dwFlags);
    877 
    878 // Sequence --------------------------------------------------------------------------------------------------------
    879 
    880 cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile);
    881 cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq);
    882 cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
    883 
    884 
    885 // LUT optimization ------------------------------------------------------------------------------------------------
    886 
    887 cmsUInt16Number  _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples);
    888 int              _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
    889 
    890 cmsBool          _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
    891                                       cmsUInt16Number **White,
    892                                       cmsUInt16Number **Black,
    893                                       cmsUInt32Number *nOutputs);
    894 
    895 cmsBool          _cmsOptimizePipeline(cmsContext ContextID,
    896                                       cmsPipeline**    Lut,
    897                                       int              Intent,
    898                                       cmsUInt32Number* InputFormat,
    899                                       cmsUInt32Number* OutputFormat,
    900                                       cmsUInt32Number* dwFlags );
    901 
    902 
    903 // Hi level LUT building ----------------------------------------------------------------------------------------------
    904 
    905 cmsPipeline*     _cmsCreateGamutCheckPipeline(cmsContext ContextID,
    906                                               cmsHPROFILE hProfiles[],
    907                                               cmsBool  BPC[],
    908                                               cmsUInt32Number Intents[],
    909                                               cmsFloat64Number AdaptationStates[],
    910                                               cmsUInt32Number nGamutPCSposition,
    911                                               cmsHPROFILE hGamut);
    912 
    913 
    914 // Formatters ------------------------------------------------------------------------------------------------------------
    915 
    916 #define cmsFLAGS_CAN_CHANGE_FORMATTER     0x02000000   // Allow change buffer format
    917 
    918 cmsBool         _cmsFormatterIsFloat(cmsUInt32Number Type);
    919 cmsBool         _cmsFormatterIs8bit(cmsUInt32Number Type);
    920 
    921 cmsFormatter    _cmsGetFormatter(cmsContext ContextID,
    922                                  cmsUInt32Number Type,          // Specific type, i.e. TYPE_RGB_8
    923                                  cmsFormatterDirection Dir,
    924                                  cmsUInt32Number dwFlags);
    925 
    926 
    927 #ifndef CMS_NO_HALF_SUPPORT
    928 
    929 // Half float
    930 cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h);
    931 cmsUInt16Number  _cmsFloat2Half(cmsFloat32Number flt);
    932 
    933 #endif
    934 
    935 // Transform logic ------------------------------------------------------------------------------------------------------
    936 
    937 struct _cmstransform_struct;
    938 
    939 typedef struct {
    940 
    941     // 1-pixel cache (16 bits only)
    942     cmsUInt16Number CacheIn[cmsMAXCHANNELS];
    943     cmsUInt16Number CacheOut[cmsMAXCHANNELS];
    944 
    945 } _cmsCACHE;
    946 
    947 
    948 
    949 // Transformation
    950 typedef struct _cmstransform_struct {
    951 
    952     cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
    953 
    954     // Points to transform code
    955     _cmsTransformFn xform;
    956 
    957     // Formatters, cannot be embedded into LUT because cache
    958     cmsFormatter16 FromInput;
    959     cmsFormatter16 ToOutput;
    960 
    961     cmsFormatterFloat FromInputFloat;
    962     cmsFormatterFloat ToOutputFloat;
    963 
    964     // 1-pixel cache seed for zero as input (16 bits, read only)
    965     _cmsCACHE Cache;
    966 
    967     // A Pipeline holding the full (optimized) transform
    968     cmsPipeline* Lut;
    969 
    970     // A Pipeline holding the gamut check. It goes from the input space to bilevel
    971     cmsPipeline* GamutCheck;
    972 
    973     // Colorant tables
    974     cmsNAMEDCOLORLIST* InputColorant;       // Input Colorant table
    975     cmsNAMEDCOLORLIST* OutputColorant;      // Colorant table (for n chans > CMYK)
    976 
    977     // Informational only
    978     cmsColorSpaceSignature EntryColorSpace;
    979     cmsColorSpaceSignature ExitColorSpace;
    980 
    981     // White points (informative only)
    982     cmsCIEXYZ EntryWhitePoint;
    983     cmsCIEXYZ ExitWhitePoint;
    984 
    985     // Profiles used to create the transform
    986     cmsSEQ* Sequence;
    987 
    988     cmsUInt32Number  dwOriginalFlags;
    989     cmsFloat64Number AdaptationState;
    990 
    991     // The intent of this transform. That is usually the last intent in the profilechain, but may differ
    992     cmsUInt32Number RenderingIntent;
    993 
    994     // An id that uniquely identifies the running context. May be null.
    995     cmsContext ContextID;
    996 
    997     // A user-defined pointer that can be used to store data for transform plug-ins
    998     void* UserData;
    999     _cmsFreeUserDataFn FreeUserData;
   1000 
   1001 } _cmsTRANSFORM;
   1002 
   1003 // --------------------------------------------------------------------------------------------------
   1004 
   1005 cmsHTRANSFORM _cmsChain2Lab(cmsContext             ContextID,
   1006                             cmsUInt32Number        nProfiles,
   1007                             cmsUInt32Number        InputFormat,
   1008                             cmsUInt32Number        OutputFormat,
   1009                             const cmsUInt32Number  Intents[],
   1010                             const cmsHPROFILE      hProfiles[],
   1011                             const cmsBool          BPC[],
   1012                             const cmsFloat64Number AdaptationStates[],
   1013                             cmsUInt32Number        dwFlags);
   1014 
   1015 
   1016 cmsToneCurve* _cmsBuildKToneCurve(cmsContext       ContextID,
   1017                             cmsUInt32Number        nPoints,
   1018                             cmsUInt32Number        nProfiles,
   1019                             const cmsUInt32Number  Intents[],
   1020                             const cmsHPROFILE      hProfiles[],
   1021                             const cmsBool          BPC[],
   1022                             const cmsFloat64Number AdaptationStates[],
   1023                             cmsUInt32Number        dwFlags);
   1024 
   1025 cmsBool   _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
   1026 
   1027 cmsBool   _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
   1028 
   1029 
   1030 #define _lcms_internal_H
   1031 #endif
   1032 //<<<+++OPENSOURCE_MUST_END
   1033