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