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