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