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