comparison mupdf-source/thirdparty/lcms2/src/lcms2_internal.h @ 2:b50eed0cc0ef upstream

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