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