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