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