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