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