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 an initialization macro: 227 228 typedef CRITICAL_SECTION _cmsMutex; 229 230 #define CMS_MUTEX_INITIALIZER {(void*) -1,-1,0,0,0,0} 231 232 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) 233 { 234 EnterCriticalSection(m); 235 return 0; 236 } 237 238 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) 239 { 240 LeaveCriticalSection(m); 241 return 0; 242 } 243 244 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) 245 { 246 InitializeCriticalSection(m); 247 return 0; 248 } 249 250 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) 251 { 252 DeleteCriticalSection(m); 253 return 0; 254 } 255 256 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) 257 { 258 EnterCriticalSection(m); 259 return 0; 260 } 261 262 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) 263 { 264 LeaveCriticalSection(m); 265 return 0; 266 } 267 268 #else 269 270 // Rest of the wide world 271 #include <pthread.h> 272 273 #define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 274 typedef pthread_mutex_t _cmsMutex; 275 276 277 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) 278 { 279 return pthread_mutex_lock(m); 280 } 281 282 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) 283 { 284 return pthread_mutex_unlock(m); 285 } 286 287 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) 288 { 289 return pthread_mutex_init(m, NULL); 290 } 291 292 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) 293 { 294 return pthread_mutex_destroy(m); 295 } 296 297 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) 298 { 299 return pthread_mutex_lock(m); 300 } 301 302 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) 303 { 304 return pthread_mutex_unlock(m); 305 } 306 307 #endif 308 #else 309 310 #define CMS_MUTEX_INITIALIZER 0 311 typedef int _cmsMutex; 312 313 314 cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) 315 { 316 return 0; 317 cmsUNUSED_PARAMETER(m); 318 } 319 320 cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) 321 { 322 return 0; 323 cmsUNUSED_PARAMETER(m); 324 } 325 326 cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) 327 { 328 return 0; 329 cmsUNUSED_PARAMETER(m); 330 } 331 332 cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) 333 { 334 return 0; 335 cmsUNUSED_PARAMETER(m); 336 } 337 338 cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) 339 { 340 return 0; 341 cmsUNUSED_PARAMETER(m); 342 } 343 344 cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) 345 { 346 return 0; 347 cmsUNUSED_PARAMETER(m); 348 } 349 #endif 350 351 // Plug-In registration --------------------------------------------------------------- 352 353 // Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once. 354 void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size); 355 356 // Memory management 357 cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 358 359 // Interpolation 360 cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 361 362 // Parametric curves 363 cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 364 365 // Formatters management 366 cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 367 368 // Tag type management 369 cmsBool _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin); 370 371 // Tag management 372 cmsBool _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 373 374 // Intent management 375 cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 376 377 // Multi Process elements 378 cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 379 380 // Optimization 381 cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 382 383 // Transform 384 cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 385 386 // Mutex 387 cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 388 389 // --------------------------------------------------------------------------------------------------------- 390 391 // Suballocators. 392 typedef struct _cmsSubAllocator_chunk_st { 393 394 cmsUInt8Number* Block; 395 cmsUInt32Number BlockSize; 396 cmsUInt32Number Used; 397 398 struct _cmsSubAllocator_chunk_st* next; 399 400 } _cmsSubAllocator_chunk; 401 402 403 typedef struct { 404 405 cmsContext ContextID; 406 _cmsSubAllocator_chunk* h; 407 408 } _cmsSubAllocator; 409 410 411 _cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial); 412 void _cmsSubAllocDestroy(_cmsSubAllocator* s); 413 void* _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size); 414 void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size); 415 416 // ---------------------------------------------------------------------------------- 417 418 // The context clients. 419 typedef enum { 420 421 UserPtr, // User-defined pointer 422 Logger, 423 AlarmCodesContext, 424 AdaptationStateContext, 425 MemPlugin, 426 InterpPlugin, 427 CurvesPlugin, 428 FormattersPlugin, 429 TagTypePlugin, 430 TagPlugin, 431 IntentPlugin, 432 MPEPlugin, 433 OptimizationPlugin, 434 TransformPlugin, 435 MutexPlugin, 436 437 // Last in list 438 MemoryClientMax 439 440 } _cmsMemoryClient; 441 442 443 // Container for memory management plug-in. 444 typedef struct { 445 446 _cmsMallocFnPtrType MallocPtr; 447 _cmsMalloZerocFnPtrType MallocZeroPtr; 448 _cmsFreeFnPtrType FreePtr; 449 _cmsReallocFnPtrType ReallocPtr; 450 _cmsCallocFnPtrType CallocPtr; 451 _cmsDupFnPtrType DupPtr; 452 453 } _cmsMemPluginChunkType; 454 455 // Copy memory management function pointers from plug-in to chunk, taking care of missing routines 456 void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr); 457 458 // Internal structure for context 459 struct _cmsContext_struct { 460 461 struct _cmsContext_struct* Next; // Points to next context in the new style 462 _cmsSubAllocator* MemPool; // The memory pool that stores context data 463 464 void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator. 465 // If NULL, then it reverts to global Context0 466 467 _cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overriden 468 }; 469 470 // Returns a pointer to a valid context structure, including the global one if id is zero. 471 // Verifies the magic number. 472 struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID); 473 474 // Returns the block assigned to the specific zone. 475 void* _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc); 476 477 478 // Chunks of context memory by plug-in client ------------------------------------------------------- 479 480 // Those structures encapsulates all variables needed by the several context clients (mostly plug-ins) 481 482 // Container for error logger -- not a plug-in 483 typedef struct { 484 485 cmsLogErrorHandlerFunction LogErrorHandler; // Set to NULL for Context0 fallback 486 487 } _cmsLogErrorChunkType; 488 489 // The global Context0 storage for error logger 490 extern _cmsLogErrorChunkType _cmsLogErrorChunk; 491 492 // Allocate and init error logger container. 493 void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx, 494 const struct _cmsContext_struct* src); 495 496 // Container for alarm codes -- not a plug-in 497 typedef struct { 498 499 cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]; 500 501 } _cmsAlarmCodesChunkType; 502 503 // The global Context0 storage for alarm codes 504 extern _cmsAlarmCodesChunkType _cmsAlarmCodesChunk; 505 506 // Allocate and init alarm codes container. 507 void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx, 508 const struct _cmsContext_struct* src); 509 510 // Container for adaptation state -- not a plug-in 511 typedef struct { 512 513 cmsFloat64Number AdaptationState; 514 515 } _cmsAdaptationStateChunkType; 516 517 // The global Context0 storage for adaptation state 518 extern _cmsAdaptationStateChunkType _cmsAdaptationStateChunk; 519 520 // Allocate and init adaptation state container. 521 void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx, 522 const struct _cmsContext_struct* src); 523 524 525 // The global Context0 storage for memory management 526 extern _cmsMemPluginChunkType _cmsMemPluginChunk; 527 528 // Allocate and init memory management container. 529 void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, 530 const struct _cmsContext_struct* src); 531 532 // Container for interpolation plug-in 533 typedef struct { 534 535 cmsInterpFnFactory Interpolators; 536 537 } _cmsInterpPluginChunkType; 538 539 // The global Context0 storage for interpolation plug-in 540 extern _cmsInterpPluginChunkType _cmsInterpPluginChunk; 541 542 // Allocate and init interpolation container. 543 void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx, 544 const struct _cmsContext_struct* src); 545 546 // Container for parametric curves plug-in 547 typedef struct { 548 549 struct _cmsParametricCurvesCollection_st* ParametricCurves; 550 551 } _cmsCurvesPluginChunkType; 552 553 // The global Context0 storage for tone curves plug-in 554 extern _cmsCurvesPluginChunkType _cmsCurvesPluginChunk; 555 556 // Allocate and init parametric curves container. 557 void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx, 558 const struct _cmsContext_struct* src); 559 560 // Container for formatters plug-in 561 typedef struct { 562 563 struct _cms_formatters_factory_list* FactoryList; 564 565 } _cmsFormattersPluginChunkType; 566 567 // The global Context0 storage for formatters plug-in 568 extern _cmsFormattersPluginChunkType _cmsFormattersPluginChunk; 569 570 // Allocate and init formatters container. 571 void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx, 572 const struct _cmsContext_struct* src); 573 574 // This chunk type is shared by TagType plug-in and MPE Plug-in 575 typedef struct { 576 577 struct _cmsTagTypeLinkedList_st* TagTypes; 578 579 } _cmsTagTypePluginChunkType; 580 581 582 // The global Context0 storage for tag types plug-in 583 extern _cmsTagTypePluginChunkType _cmsTagTypePluginChunk; 584 585 586 // The global Context0 storage for mult process elements plug-in 587 extern _cmsTagTypePluginChunkType _cmsMPETypePluginChunk; 588 589 // Allocate and init Tag types container. 590 void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx, 591 const struct _cmsContext_struct* src); 592 // Allocate and init MPE container. 593 void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx, 594 const struct _cmsContext_struct* src); 595 // Container for tag plug-in 596 typedef struct { 597 598 struct _cmsTagLinkedList_st* Tag; 599 600 } _cmsTagPluginChunkType; 601 602 603 // The global Context0 storage for tag plug-in 604 extern _cmsTagPluginChunkType _cmsTagPluginChunk; 605 606 // Allocate and init Tag container. 607 void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx, 608 const struct _cmsContext_struct* src); 609 610 // Container for intents plug-in 611 typedef struct { 612 613 struct _cms_intents_list* Intents; 614 615 } _cmsIntentsPluginChunkType; 616 617 618 // The global Context0 storage for intents plug-in 619 extern _cmsIntentsPluginChunkType _cmsIntentsPluginChunk; 620 621 // Allocate and init intents container. 622 void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx, 623 const struct _cmsContext_struct* src); 624 625 // Container for optimization plug-in 626 typedef struct { 627 628 struct _cmsOptimizationCollection_st* OptimizationCollection; 629 630 } _cmsOptimizationPluginChunkType; 631 632 633 // The global Context0 storage for optimizers plug-in 634 extern _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk; 635 636 // Allocate and init optimizers container. 637 void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx, 638 const struct _cmsContext_struct* src); 639 640 // Container for transform plug-in 641 typedef struct { 642 643 struct _cmsTransformCollection_st* TransformCollection; 644 645 } _cmsTransformPluginChunkType; 646 647 // The global Context0 storage for full-transform replacement plug-in 648 extern _cmsTransformPluginChunkType _cmsTransformPluginChunk; 649 650 // Allocate and init transform container. 651 void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx, 652 const struct _cmsContext_struct* src); 653 654 // Container for mutex plug-in 655 typedef struct { 656 657 _cmsCreateMutexFnPtrType CreateMutexPtr; 658 _cmsDestroyMutexFnPtrType DestroyMutexPtr; 659 _cmsLockMutexFnPtrType LockMutexPtr; 660 _cmsUnlockMutexFnPtrType UnlockMutexPtr; 661 662 } _cmsMutexPluginChunkType; 663 664 // The global Context0 storage for mutex plug-in 665 extern _cmsMutexPluginChunkType _cmsMutexPluginChunk; 666 667 // Allocate and init mutex container. 668 void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx, 669 const struct _cmsContext_struct* src); 670 671 // ---------------------------------------------------------------------------------- 672 // MLU internal representation 673 typedef struct { 674 675 cmsUInt16Number Language; 676 cmsUInt16Number Country; 677 678 cmsUInt32Number StrW; // Offset to current unicode string 679 cmsUInt32Number Len; // Length in bytes 680 681 } _cmsMLUentry; 682 683 struct _cms_MLU_struct { 684 685 cmsContext ContextID; 686 687 // The directory 688 int AllocatedEntries; 689 int UsedEntries; 690 _cmsMLUentry* Entries; // Array of pointers to strings allocated in MemPool 691 692 // The Pool 693 cmsUInt32Number PoolSize; // The maximum allocated size 694 cmsUInt32Number PoolUsed; // The used size 695 void* MemPool; // Pointer to begin of memory pool 696 }; 697 698 // Named color list internal representation 699 typedef struct { 700 701 char Name[cmsMAX_PATH]; 702 cmsUInt16Number PCS[3]; 703 cmsUInt16Number DeviceColorant[cmsMAXCHANNELS]; 704 705 } _cmsNAMEDCOLOR; 706 707 struct _cms_NAMEDCOLORLIST_struct { 708 709 cmsUInt32Number nColors; 710 cmsUInt32Number Allocated; 711 cmsUInt32Number ColorantCount; 712 713 char Prefix[33]; // Prefix and suffix are defined to be 32 characters at most 714 char Suffix[33]; 715 716 _cmsNAMEDCOLOR* List; 717 718 cmsContext ContextID; 719 }; 720 721 722 // ---------------------------------------------------------------------------------- 723 724 // This is the internal struct holding profile details. 725 726 // Maximum supported tags in a profile 727 #define MAX_TABLE_TAG 100 728 729 typedef struct _cms_iccprofile_struct { 730 731 // I/O handler 732 cmsIOHANDLER* IOhandler; 733 734 // The thread ID 735 cmsContext ContextID; 736 737 // Creation time 738 struct tm Created; 739 740 // Only most important items found in ICC profiles 741 cmsUInt32Number Version; 742 cmsProfileClassSignature DeviceClass; 743 cmsColorSpaceSignature ColorSpace; 744 cmsColorSpaceSignature PCS; 745 cmsUInt32Number RenderingIntent; 746 747 cmsUInt32Number flags; 748 cmsUInt32Number manufacturer, model; 749 cmsUInt64Number attributes; 750 cmsUInt32Number creator; 751 752 cmsProfileID ProfileID; 753 754 // Dictionary 755 cmsUInt32Number TagCount; 756 cmsTagSignature TagNames[MAX_TABLE_TAG]; 757 cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to wich is linked (0=none) 758 cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk 759 cmsUInt32Number TagOffsets[MAX_TABLE_TAG]; 760 cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked 761 void * TagPtrs[MAX_TABLE_TAG]; 762 cmsTagTypeHandler* TagTypeHandlers[MAX_TABLE_TAG]; // Same structure may be serialized on different types 763 // depending on profile version, so we keep track of the 764 // type handler for each tag in the list. 765 // Special 766 cmsBool IsWrite; 767 768 // Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin 769 void * UsrMutex; 770 771 } _cmsICCPROFILE; 772 773 // IO helpers for profiles 774 cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc); 775 cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace); 776 int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks); 777 778 // Tag types 779 cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig); 780 cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig); 781 cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig); 782 783 // Error logging --------------------------------------------------------------------------------------------------------- 784 785 void _cmsTagSignature2String(char String[5], cmsTagSignature sig); 786 787 // Interpolation --------------------------------------------------------------------------------------------------------- 788 789 cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags); 790 cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags); 791 void _cmsFreeInterpParams(cmsInterpParams* p); 792 cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p); 793 794 // Curves ---------------------------------------------------------------------------------------------------------------- 795 796 // This struct holds information about a segment, plus a pointer to the function that implements the evaluation. 797 // In the case of table-based, Eval pointer is set to NULL 798 799 // The gamma function main structure 800 struct _cms_curve_struct { 801 802 cmsInterpParams* InterpParams; // Private optimizations for interpolation 803 804 cmsUInt32Number nSegments; // Number of segments in the curve. Zero for a 16-bit based tables 805 cmsCurveSegment* Segments; // The segments 806 cmsInterpParams** SegInterp; // Array of private optimizations for interpolation in table-based segments 807 808 cmsParametricCurveEvaluator* Evals; // Evaluators (one per segment) 809 810 // 16 bit Table-based representation follows 811 cmsUInt32Number nEntries; // Number of table elements 812 cmsUInt16Number* Table16; // The table itself. 813 }; 814 815 816 // Pipelines & Stages --------------------------------------------------------------------------------------------- 817 818 // A single stage 819 struct _cmsStage_struct { 820 821 cmsContext ContextID; 822 823 cmsStageSignature Type; // Identifies the stage 824 cmsStageSignature Implements; // Identifies the *function* of the stage (for optimizations) 825 826 cmsUInt32Number InputChannels; // Input channels -- for optimization purposes 827 cmsUInt32Number OutputChannels; // Output channels -- for optimization purposes 828 829 _cmsStageEvalFn EvalPtr; // Points to fn that evaluates the stage (always in floating point) 830 _cmsStageDupElemFn DupElemPtr; // Points to a fn that duplicates the *data* of the stage 831 _cmsStageFreeElemFn FreePtr; // Points to a fn that sets the *data* of the stage free 832 833 // A generic pointer to whatever memory needed by the stage 834 void* Data; 835 836 // Maintains linked list (used internally) 837 struct _cmsStage_struct* Next; 838 }; 839 840 841 // Special Stages (cannot be saved) 842 cmsStage* _cmsStageAllocLab2XYZ(cmsContext ContextID); 843 cmsStage* _cmsStageAllocXYZ2Lab(cmsContext ContextID); 844 cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID); 845 cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID); 846 cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID); 847 cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID); 848 cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS); 849 cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels); 850 cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan); 851 cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID); 852 cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID); 853 cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID); 854 cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID); 855 856 // For curve set only 857 cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe); 858 859 860 // Pipeline Evaluator (in floating point) 861 typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[], 862 cmsFloat32Number Out[], 863 const void* Data); 864 865 struct _cmsPipeline_struct { 866 867 cmsStage* Elements; // Points to elements chain 868 cmsUInt32Number InputChannels, OutputChannels; 869 870 // Data & evaluators 871 void *Data; 872 873 _cmsOPTeval16Fn Eval16Fn; 874 _cmsPipelineEvalFloatFn EvalFloatFn; 875 _cmsFreeUserDataFn FreeDataFn; 876 _cmsDupUserDataFn DupDataFn; 877 878 cmsContext ContextID; // Environment 879 880 cmsBool SaveAs8Bits; // Implementation-specific: save as 8 bits if possible 881 }; 882 883 // LUT reading & creation ------------------------------------------------------------------------------------------- 884 885 // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy 886 // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources. 887 888 cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent); 889 cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent); 890 cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent); 891 892 // Special values 893 cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile); 894 cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile); 895 896 // Profile linker -------------------------------------------------------------------------------------------------- 897 898 cmsPipeline* _cmsLinkProfiles(cmsContext ContextID, 899 cmsUInt32Number nProfiles, 900 cmsUInt32Number TheIntents[], 901 cmsHPROFILE hProfiles[], 902 cmsBool BPC[], 903 cmsFloat64Number AdaptationStates[], 904 cmsUInt32Number dwFlags); 905 906 // Sequence -------------------------------------------------------------------------------------------------------- 907 908 cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile); 909 cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq); 910 cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]); 911 912 913 // LUT optimization ------------------------------------------------------------------------------------------------ 914 915 cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples); 916 int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags); 917 918 cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space, 919 cmsUInt16Number **White, 920 cmsUInt16Number **Black, 921 cmsUInt32Number *nOutputs); 922 923 cmsBool _cmsOptimizePipeline(cmsContext ContextID, 924 cmsPipeline** Lut, 925 int Intent, 926 cmsUInt32Number* InputFormat, 927 cmsUInt32Number* OutputFormat, 928 cmsUInt32Number* dwFlags ); 929 930 931 // Hi level LUT building ---------------------------------------------------------------------------------------------- 932 933 cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID, 934 cmsHPROFILE hProfiles[], 935 cmsBool BPC[], 936 cmsUInt32Number Intents[], 937 cmsFloat64Number AdaptationStates[], 938 cmsUInt32Number nGamutPCSposition, 939 cmsHPROFILE hGamut); 940 941 942 // Formatters ------------------------------------------------------------------------------------------------------------ 943 944 #define cmsFLAGS_CAN_CHANGE_FORMATTER 0x02000000 // Allow change buffer format 945 946 cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type); 947 cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type); 948 949 cmsFormatter _cmsGetFormatter(cmsContext ContextID, 950 cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 951 cmsFormatterDirection Dir, 952 cmsUInt32Number dwFlags); 953 954 955 #ifndef CMS_NO_HALF_SUPPORT 956 957 // Half float 958 cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h); 959 cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt); 960 961 #endif 962 963 // Transform logic ------------------------------------------------------------------------------------------------------ 964 965 struct _cmstransform_struct; 966 967 typedef struct { 968 969 // 1-pixel cache (16 bits only) 970 cmsUInt16Number CacheIn[cmsMAXCHANNELS]; 971 cmsUInt16Number CacheOut[cmsMAXCHANNELS]; 972 973 } _cmsCACHE; 974 975 976 977 // Transformation 978 typedef struct _cmstransform_struct { 979 980 cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference 981 982 // Points to transform code 983 _cmsTransformFn xform; 984 985 // Formatters, cannot be embedded into LUT because cache 986 cmsFormatter16 FromInput; 987 cmsFormatter16 ToOutput; 988 989 cmsFormatterFloat FromInputFloat; 990 cmsFormatterFloat ToOutputFloat; 991 992 // 1-pixel cache seed for zero as input (16 bits, read only) 993 _cmsCACHE Cache; 994 995 // A Pipeline holding the full (optimized) transform 996 cmsPipeline* Lut; 997 998 // A Pipeline holding the gamut check. It goes from the input space to bilevel 999 cmsPipeline* GamutCheck; 1000 1001 // Colorant tables 1002 cmsNAMEDCOLORLIST* InputColorant; // Input Colorant table 1003 cmsNAMEDCOLORLIST* OutputColorant; // Colorant table (for n chans > CMYK) 1004 1005 // Informational only 1006 cmsColorSpaceSignature EntryColorSpace; 1007 cmsColorSpaceSignature ExitColorSpace; 1008 1009 // White points (informative only) 1010 cmsCIEXYZ EntryWhitePoint; 1011 cmsCIEXYZ ExitWhitePoint; 1012 1013 // Profiles used to create the transform 1014 cmsSEQ* Sequence; 1015 1016 cmsUInt32Number dwOriginalFlags; 1017 cmsFloat64Number AdaptationState; 1018 1019 // The intent of this transform. That is usually the last intent in the profilechain, but may differ 1020 cmsUInt32Number RenderingIntent; 1021 1022 // An id that uniquely identifies the running context. May be null. 1023 cmsContext ContextID; 1024 1025 // A user-defined pointer that can be used to store data for transform plug-ins 1026 void* UserData; 1027 _cmsFreeUserDataFn FreeUserData; 1028 1029 } _cmsTRANSFORM; 1030 1031 // -------------------------------------------------------------------------------------------------- 1032 1033 cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID, 1034 cmsUInt32Number nProfiles, 1035 cmsUInt32Number InputFormat, 1036 cmsUInt32Number OutputFormat, 1037 const cmsUInt32Number Intents[], 1038 const cmsHPROFILE hProfiles[], 1039 const cmsBool BPC[], 1040 const cmsFloat64Number AdaptationStates[], 1041 cmsUInt32Number dwFlags); 1042 1043 1044 cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID, 1045 cmsUInt32Number nPoints, 1046 cmsUInt32Number nProfiles, 1047 const cmsUInt32Number Intents[], 1048 const cmsHPROFILE hProfiles[], 1049 const cmsBool BPC[], 1050 const cmsFloat64Number AdaptationStates[], 1051 cmsUInt32Number dwFlags); 1052 1053 cmsBool _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll); 1054 1055 cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries); 1056 1057 1058 #define _lcms_internal_H 1059 #endif