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