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 122cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a) { return a + ((a + 0x7fff) / 0xffff); } 123cmsINLINE 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. 131cmsINLINE 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 153cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d) 154{ 155 return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U; 156} 157 158// Floor to word, taking care of saturation 159cmsINLINE 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 200typedef CRITICAL_SECTION _cmsMutex; 201 202#define CMS_MUTEX_INITIALIZER {(void*) -1,-1,0,0,0,0} 203 204cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) 205{ 206 EnterCriticalSection(m); 207 return 0; 208} 209 210cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) 211{ 212 LeaveCriticalSection(m); 213 return 0; 214} 215 216cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) 217{ 218 InitializeCriticalSection(m); 219 return 0; 220} 221 222cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) 223{ 224 DeleteCriticalSection(m); 225 return 0; 226} 227 228cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) 229{ 230 EnterCriticalSection(m); 231 return 0; 232} 233 234cmsINLINE 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 246typedef pthread_mutex_t _cmsMutex; 247 248 249cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) 250{ 251 return pthread_mutex_lock(m); 252} 253 254cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) 255{ 256 return pthread_mutex_unlock(m); 257} 258 259cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) 260{ 261 return pthread_mutex_init(m, NULL); 262} 263 264cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) 265{ 266 return pthread_mutex_destroy(m); 267} 268 269cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) 270{ 271 return pthread_mutex_lock(m); 272} 273 274cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m) 275{ 276 return pthread_mutex_unlock(m); 277} 278 279#endif 280#else 281 282#define CMS_MUTEX_INITIALIZER 0 283typedef int _cmsMutex; 284 285 286cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) 287{ 288 return 0; 289 cmsUNUSED_PARAMETER(m); 290} 291 292cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m) 293{ 294 return 0; 295 cmsUNUSED_PARAMETER(m); 296} 297 298cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m) 299{ 300 return 0; 301 cmsUNUSED_PARAMETER(m); 302} 303 304cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m) 305{ 306 return 0; 307 cmsUNUSED_PARAMETER(m); 308} 309 310cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m) 311{ 312 return 0; 313 cmsUNUSED_PARAMETER(m); 314} 315 316cmsINLINE 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. 326void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size); 327 328// Memory management 329cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 330 331// Interpolation 332cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 333 334// Parametric curves 335cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 336 337// Formatters management 338cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 339 340// Tag type management 341cmsBool _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin); 342 343// Tag management 344cmsBool _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 345 346// Intent management 347cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 348 349// Multi Process elements 350cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 351 352// Optimization 353cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 354 355// Transform 356cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 357 358// Mutex 359cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin); 360 361// --------------------------------------------------------------------------------------------------------- 362 363// Suballocators. 364typedef 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 375typedef struct { 376 377 cmsContext ContextID; 378 _cmsSubAllocator_chunk* h; 379 380} _cmsSubAllocator; 381 382 383_cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial); 384void _cmsSubAllocDestroy(_cmsSubAllocator* s); 385void* _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size); 386void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size); 387 388// ---------------------------------------------------------------------------------- 389 390// The context clients. 391typedef 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. 416typedef 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 428void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr); 429 430// Internal structure for context 431struct _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. 444struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID); 445 446// Returns the block assigned to the specific zone. 447void* _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 455typedef struct { 456 457 cmsLogErrorHandlerFunction LogErrorHandler; // Set to NULL for Context0 fallback 458 459} _cmsLogErrorChunkType; 460 461// The global Context0 storage for error logger 462extern _cmsLogErrorChunkType _cmsLogErrorChunk; 463 464// Allocate and init error logger container. 465void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx, 466 const struct _cmsContext_struct* src); 467 468// Container for alarm codes -- not a plug-in 469typedef struct { 470 471 cmsUInt16Number AlarmCodes[cmsMAXCHANNELS]; 472 473} _cmsAlarmCodesChunkType; 474 475// The global Context0 storage for alarm codes 476extern _cmsAlarmCodesChunkType _cmsAlarmCodesChunk; 477 478// Allocate and init alarm codes container. 479void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx, 480 const struct _cmsContext_struct* src); 481 482// Container for adaptation state -- not a plug-in 483typedef struct { 484 485 cmsFloat64Number AdaptationState; 486 487} _cmsAdaptationStateChunkType; 488 489// The global Context0 storage for adaptation state 490extern _cmsAdaptationStateChunkType _cmsAdaptationStateChunk; 491 492// Allocate and init adaptation state container. 493void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx, 494 const struct _cmsContext_struct* src); 495 496 497// The global Context0 storage for memory management 498extern _cmsMemPluginChunkType _cmsMemPluginChunk; 499 500// Allocate and init memory management container. 501void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx, 502 const struct _cmsContext_struct* src); 503 504// Container for interpolation plug-in 505typedef struct { 506 507 cmsInterpFnFactory Interpolators; 508 509} _cmsInterpPluginChunkType; 510 511// The global Context0 storage for interpolation plug-in 512extern _cmsInterpPluginChunkType _cmsInterpPluginChunk; 513 514// Allocate and init interpolation container. 515void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx, 516 const struct _cmsContext_struct* src); 517 518// Container for parametric curves plug-in 519typedef struct { 520 521 struct _cmsParametricCurvesCollection_st* ParametricCurves; 522 523} _cmsCurvesPluginChunkType; 524 525// The global Context0 storage for tone curves plug-in 526extern _cmsCurvesPluginChunkType _cmsCurvesPluginChunk; 527 528// Allocate and init parametric curves container. 529void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx, 530 const struct _cmsContext_struct* src); 531 532// Container for formatters plug-in 533typedef struct { 534 535 struct _cms_formatters_factory_list* FactoryList; 536 537} _cmsFormattersPluginChunkType; 538 539// The global Context0 storage for formatters plug-in 540extern _cmsFormattersPluginChunkType _cmsFormattersPluginChunk; 541 542// Allocate and init formatters container. 543void _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 547typedef struct { 548 549 struct _cmsTagTypeLinkedList_st* TagTypes; 550 551} _cmsTagTypePluginChunkType; 552 553 554// The global Context0 storage for tag types plug-in 555extern _cmsTagTypePluginChunkType _cmsTagTypePluginChunk; 556 557 558// The global Context0 storage for mult process elements plug-in 559extern _cmsTagTypePluginChunkType _cmsMPETypePluginChunk; 560 561// Allocate and init Tag types container. 562void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx, 563 const struct _cmsContext_struct* src); 564// Allocate and init MPE container. 565void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx, 566 const struct _cmsContext_struct* src); 567// Container for tag plug-in 568typedef struct { 569 570 struct _cmsTagLinkedList_st* Tag; 571 572} _cmsTagPluginChunkType; 573 574 575// The global Context0 storage for tag plug-in 576extern _cmsTagPluginChunkType _cmsTagPluginChunk; 577 578// Allocate and init Tag container. 579void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx, 580 const struct _cmsContext_struct* src); 581 582// Container for intents plug-in 583typedef struct { 584 585 struct _cms_intents_list* Intents; 586 587} _cmsIntentsPluginChunkType; 588 589 590// The global Context0 storage for intents plug-in 591extern _cmsIntentsPluginChunkType _cmsIntentsPluginChunk; 592 593// Allocate and init intents container. 594void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx, 595 const struct _cmsContext_struct* src); 596 597// Container for optimization plug-in 598typedef struct { 599 600 struct _cmsOptimizationCollection_st* OptimizationCollection; 601 602} _cmsOptimizationPluginChunkType; 603 604 605// The global Context0 storage for optimizers plug-in 606extern _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk; 607 608// Allocate and init optimizers container. 609void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx, 610 const struct _cmsContext_struct* src); 611 612// Container for transform plug-in 613typedef struct { 614 615 struct _cmsTransformCollection_st* TransformCollection; 616 617} _cmsTransformPluginChunkType; 618 619// The global Context0 storage for full-transform replacement plug-in 620extern _cmsTransformPluginChunkType _cmsTransformPluginChunk; 621 622// Allocate and init transform container. 623void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx, 624 const struct _cmsContext_struct* src); 625 626// Container for mutex plug-in 627typedef 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 637extern _cmsMutexPluginChunkType _cmsMutexPluginChunk; 638 639// Allocate and init mutex container. 640void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx, 641 const struct _cmsContext_struct* src); 642 643// ---------------------------------------------------------------------------------- 644// MLU internal representation 645typedef 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 655struct _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 671typedef struct { 672 673 char Name[cmsMAX_PATH]; 674 cmsUInt16Number PCS[3]; 675 cmsUInt16Number DeviceColorant[cmsMAXCHANNELS]; 676 677} _cmsNAMEDCOLOR; 678 679struct _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 701typedef 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 746cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc); 747cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace); 748int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks); 749 750// Tag types 751cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig); 752cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig); 753cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig); 754 755// Error logging --------------------------------------------------------------------------------------------------------- 756 757void _cmsTagSignature2String(char String[5], cmsTagSignature sig); 758 759// Interpolation --------------------------------------------------------------------------------------------------------- 760 761cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags); 762cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags); 763void _cmsFreeInterpParams(cmsInterpParams* p); 764cmsBool _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 772struct _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 791struct _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) 814cmsStage* _cmsStageAllocLab2XYZ(cmsContext ContextID); 815cmsStage* _cmsStageAllocXYZ2Lab(cmsContext ContextID); 816cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID); 817cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID); 818cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID); 819cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID); 820cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS); 821cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels); 822cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan); 823cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID); 824cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID); 825cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID); 826cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID); 827 828// For curve set only 829cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe); 830 831 832// Pipeline Evaluator (in floating point) 833typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[], 834 cmsFloat32Number Out[], 835 const void* Data); 836 837struct _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 860cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent); 861cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent); 862cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent); 863 864// Special values 865cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile); 866cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile); 867 868// Profile linker -------------------------------------------------------------------------------------------------- 869 870cmsPipeline* _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 880cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile); 881cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq); 882cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]); 883 884 885// LUT optimization ------------------------------------------------------------------------------------------------ 886 887cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples); 888int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags); 889 890cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space, 891 cmsUInt16Number **White, 892 cmsUInt16Number **Black, 893 cmsUInt32Number *nOutputs); 894 895cmsBool _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 905cmsPipeline* _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 918cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type); 919cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type); 920 921cmsFormatter _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 930cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h); 931cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt); 932 933#endif 934 935// Transform logic ------------------------------------------------------------------------------------------------------ 936 937struct _cmstransform_struct; 938 939typedef 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 950typedef 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 1005cmsHTRANSFORM _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 1016cmsToneCurve* _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 1025cmsBool _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll); 1026 1027cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries); 1028 1029 1030#define _lcms_internal_H 1031#endif 1032//<<<+++OPENSOURCE_MUST_END 1033