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