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