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