Path: blob/master/src/java.desktop/share/native/liblcms/lcms2_internal.h
41149 views
/*1* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.2*3* This code is free software; you can redistribute it and/or modify it4* under the terms of the GNU General Public License version 2 only, as5* published by the Free Software Foundation. Oracle designates this6* particular file as subject to the "Classpath" exception as provided7* by Oracle in the LICENSE file that accompanied this code.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*/2324// This file is available under and governed by the GNU General Public25// License version 2 only, as published by the Free Software Foundation.26// However, the following notice accompanied the original version of this27// file:28//2930//31// Little Color Management System32// Copyright (c) 1998-2020 Marti Maria Saguer33//34// Permission is hereby granted, free of charge, to any person obtaining35// a copy of this software and associated documentation files (the "Software"),36// to deal in the Software without restriction, including without limitation37// the rights to use, copy, modify, merge, publish, distribute, sublicense,38// and/or sell copies of the Software, and to permit persons to whom the Software39// is furnished to do so, subject to the following conditions:40//41// The above copyright notice and this permission notice shall be included in42// all copies or substantial portions of the Software.43//44// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,45// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO46// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND47// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE48// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION49// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION50// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.51//52//---------------------------------------------------------------------------------53//5455#ifndef _lcms_internal_H5657// Include plug-in foundation58#ifndef _lcms_plugin_H59# include "lcms2_plugin.h"60#endif6162// ctype is part of C99 as per 7.1.263#include <ctype.h>6465// assert macro is part of C99 as per 7.266#include <assert.h>6768// Some needed constants69#ifndef M_PI70# define M_PI 3.1415926535897932384671#endif7273#ifndef M_LOG10E74# define M_LOG10E 0.43429448190325182765175#endif7677// BorlandC 5.5, VC2003 are broken on that78#if defined(__BORLANDC__) || (defined(_MSC_VER) && (_MSC_VER < 1400)) // 1400 == VC++ 8.079#define sinf(x) (float)sin((float)x)80#define sqrtf(x) (float)sqrt((float)x)81#endif828384// Alignment of ICC file format uses 4 bytes (cmsUInt32Number)85#define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & ~(sizeof(cmsUInt32Number)-1))8687// Alignment to memory pointer8889// (Ultra)SPARC with gcc requires ptr alignment of 8 bytes90// even though sizeof(void *) is only four: for greatest flexibility91// allow the build to specify ptr alignment.92#ifndef CMS_PTR_ALIGNMENT93# define CMS_PTR_ALIGNMENT sizeof(void *)94#endif9596#define _cmsALIGNMEM(x) (((x)+(CMS_PTR_ALIGNMENT - 1)) & ~(CMS_PTR_ALIGNMENT - 1))9798// Maximum encodeable values in floating point99#define MAX_ENCODEABLE_XYZ (1.0 + 32767.0/32768.0)100#define MIN_ENCODEABLE_ab2 (-128.0)101#define MAX_ENCODEABLE_ab2 ((65535.0/256.0) - 128.0)102#define MIN_ENCODEABLE_ab4 (-128.0)103#define MAX_ENCODEABLE_ab4 (127.0)104105// Maximum of channels for internal pipeline evaluation106#define MAX_STAGE_CHANNELS 128107108// Unused parameter warning suppression109#define cmsUNUSED_PARAMETER(x) ((void)x)110111// The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999).112// unfortunately VisualC++ does not conform that113#if defined(_MSC_VER) || defined(__BORLANDC__)114# define cmsINLINE __inline115#else116# define cmsINLINE static inline117#endif118119// Allow signed overflow, we know this is harmless in this particular context120#if defined(__clang__)121# define CMS_NO_SANITIZE __attribute__((no_sanitize("signed-integer-overflow")))122#else123# define CMS_NO_SANITIZE124#endif125126// Other replacement functions127#ifdef _MSC_VER128# ifndef snprintf129# define snprintf _snprintf130# endif131# ifndef vsnprintf132# define vsnprintf _vsnprintf133# endif134135/// Properly define some macros to accommodate136/// older MSVC versions.137# if defined(_MSC_VER) && _MSC_VER <= 1700138#include <float.h>139#define isnan _isnan140#define isinf(x) (!_finite((x)))141# endif142143#if !defined(_MSC_VER) && (defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L)144#if !defined(isinf)145#define isinf(x) (!finite((x)))146#endif147#endif148149150#endif151152// A fast way to convert from/to 16 <-> 8 bits153#define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))154#define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((cmsUInt32Number)(rgb) * 65281U + 8388608U) >> 24) & 0xFFU)155156// Code analysis is broken on asserts157#ifdef _MSC_VER158# if (_MSC_VER >= 1500)159# define _cmsAssert(a) { assert((a)); __analysis_assume((a)); }160# else161# define _cmsAssert(a) assert((a))162# endif163#else164# define _cmsAssert(a) assert((a))165#endif166167//---------------------------------------------------------------------------------168169// Determinant lower than that are assumed zero (used on matrix invert)170#define MATRIX_DET_TOLERANCE 0.0001171172//---------------------------------------------------------------------------------173174// Fixed point175#define FIXED_TO_INT(x) ((x)>>16)176#define FIXED_REST_TO_INT(x) ((x)&0xFFFFU)177#define ROUND_FIXED_TO_INT(x) (((x)+0x8000)>>16)178179cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a) { return a + ((a + 0x7fff) / 0xffff); }180cmsINLINE int _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }181182// -----------------------------------------------------------------------------------------------------------183184// Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon185// note than this only works in the range ..-32767...+32767 because186// mantissa is interpreted as 15.16 fixed point.187// The union is to avoid pointer aliasing overoptimization.188cmsINLINE int _cmsQuickFloor(cmsFloat64Number val)189{190#ifdef CMS_DONT_USE_FAST_FLOOR191return (int) floor(val);192#else193const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5; // 2^36 * 1.5, (52-16=36) uses limited precision to floor194union {195cmsFloat64Number val;196int halves[2];197} temp;198199temp.val = val + _lcms_double2fixmagic;200201#ifdef CMS_USE_BIG_ENDIAN202return temp.halves[1] >> 16;203#else204return temp.halves[0] >> 16;205#endif206#endif207}208209// Fast floor restricted to 0..65535.0210cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)211{212return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;213}214215// Floor to word, taking care of saturation216cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)217{218d += 0.5;219if (d <= 0) return 0;220if (d >= 65535.0) return 0xffff;221222return _cmsQuickFloorWord(d);223}224225// Test bed entry points---------------------------------------------------------------226#define CMSCHECKPOINT CMSAPI227228// Pthread support --------------------------------------------------------------------229#ifndef CMS_NO_PTHREADS230231// This is the threading support. Unfortunately, it has to be platform-dependent because232// windows does not support pthreads.233#ifdef CMS_IS_WINDOWS_234235#define WIN32_LEAN_AND_MEAN 1236#include <windows.h>237238239// The locking scheme in LCMS requires a single 'top level' mutex240// to work. This is actually implemented on Windows as a241// CriticalSection, because they are lighter weight. With242// pthreads, this is statically inited. Unfortunately, windows243// can't officially statically init critical sections.244//245// We can work around this in 2 ways.246//247// 1) We can use a proper mutex purely to protect the init248// of the CriticalSection. This in turns requires us to protect249// the Mutex creation, which we can do using the snappily250// named InterlockedCompareExchangePointer API (present on251// windows XP and above).252//253// 2) In cases where we want to work on pre-Windows XP, we254// can use an even more horrible hack described below.255//256// So why wouldn't we always use 2)? Because not calling257// the init function for a critical section means it fails258// testing with ApplicationVerifier (and presumably similar259// tools).260//261// We therefore default to 1, and people who want to be able262// to run on pre-Windows XP boxes can build with:263// CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT264// defined. This is automatically set for builds using265// versions of MSVC that don't have this API available.266//267// From: http://locklessinc.com/articles/pthreads_on_windows/268// The pthreads API has an initialization macro that has no correspondence to anything in269// the windows API. By investigating the internal definition of the critical section type,270// one may work out how to initialize one without calling InitializeCriticalSection().271// The trick here is that InitializeCriticalSection() is not allowed to fail. It tries272// to allocate a critical section debug object, but if no memory is available, it sets273// the pointer to a specific value. (One would expect that value to be NULL, but it is274// actually (void *)-1 for some reason.) Thus we can use this special value for that275// pointer, and the critical section code will work.276277// The other important part of the critical section type to initialize is the number278// of waiters. This controls whether or not the mutex is locked. Fortunately, this279// part of the critical section is unlikely to change. Apparently, many programs280// already test critical sections to see if they are locked using this value, so281// Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical282// section, even when they changed the underlying algorithm to be more scalable.283// The final parts of the critical section object are unimportant, and can be set284// to zero for their defaults. This yields to an initialization macro:285286typedef CRITICAL_SECTION _cmsMutex;287288#ifdef _MSC_VER289# if (_MSC_VER >= 1800)290# pragma warning(disable : 26135)291# endif292#endif293294#ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT295// If we are building with a version of MSVC smaller296// than 1400 (i.e. before VS2005) then we don't have297// the InterlockedCompareExchangePointer API, so use298// the old version.299# ifdef _MSC_VER300# if _MSC_VER < 1400301# define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT302# endif303# endif304#endif305306#ifdef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT307# define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0}308#else309# define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG)NULL,-1,0,0,0,0}310#endif311312cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)313{314EnterCriticalSection(m);315return 0;316}317318cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)319{320LeaveCriticalSection(m);321return 0;322}323324cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)325{326InitializeCriticalSection(m);327return 0;328}329330cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)331{332DeleteCriticalSection(m);333return 0;334}335336cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)337{338EnterCriticalSection(m);339return 0;340}341342cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)343{344LeaveCriticalSection(m);345return 0;346}347348#else349350// Rest of the wide world351#include <pthread.h>352353#define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER354typedef pthread_mutex_t _cmsMutex;355356357cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)358{359return pthread_mutex_lock(m);360}361362cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)363{364return pthread_mutex_unlock(m);365}366367cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)368{369return pthread_mutex_init(m, NULL);370}371372cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)373{374return pthread_mutex_destroy(m);375}376377cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)378{379return pthread_mutex_lock(m);380}381382cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)383{384return pthread_mutex_unlock(m);385}386387#endif388#else389390#define CMS_MUTEX_INITIALIZER 0391typedef int _cmsMutex;392393394cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)395{396cmsUNUSED_PARAMETER(m);397return 0;398}399400cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)401{402cmsUNUSED_PARAMETER(m);403return 0;404}405406cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)407{408cmsUNUSED_PARAMETER(m);409return 0;410}411412cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)413{414cmsUNUSED_PARAMETER(m);415return 0;416}417418cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)419{420cmsUNUSED_PARAMETER(m);421return 0;422}423424cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)425{426cmsUNUSED_PARAMETER(m);427return 0;428}429#endif430431// Plug-In registration ---------------------------------------------------------------432433// Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.434void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size);435436// Memory management437cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);438439// Interpolation440cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin);441442// Parametric curves443cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin);444445// Formatters management446cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin);447448// Tag type management449cmsBool _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin);450451// Tag management452cmsBool _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin);453454// Intent management455cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin);456457// Multi Process elements458cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin);459460// Optimization461cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);462463// Transform464cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin);465466// Mutex467cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);468469// ---------------------------------------------------------------------------------------------------------470471// Suballocators.472typedef struct _cmsSubAllocator_chunk_st {473474cmsUInt8Number* Block;475cmsUInt32Number BlockSize;476cmsUInt32Number Used;477478struct _cmsSubAllocator_chunk_st* next;479480} _cmsSubAllocator_chunk;481482483typedef struct {484485cmsContext ContextID;486_cmsSubAllocator_chunk* h;487488} _cmsSubAllocator;489490491_cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);492void _cmsSubAllocDestroy(_cmsSubAllocator* s);493void* _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);494void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);495496// ----------------------------------------------------------------------------------497498// The context clients.499typedef enum {500501UserPtr, // User-defined pointer502Logger,503AlarmCodesContext,504AdaptationStateContext,505MemPlugin,506InterpPlugin,507CurvesPlugin,508FormattersPlugin,509TagTypePlugin,510TagPlugin,511IntentPlugin,512MPEPlugin,513OptimizationPlugin,514TransformPlugin,515MutexPlugin,516517// Last in list518MemoryClientMax519520} _cmsMemoryClient;521522523// Container for memory management plug-in.524typedef struct {525526_cmsMallocFnPtrType MallocPtr;527_cmsMalloZerocFnPtrType MallocZeroPtr;528_cmsFreeFnPtrType FreePtr;529_cmsReallocFnPtrType ReallocPtr;530_cmsCallocFnPtrType CallocPtr;531_cmsDupFnPtrType DupPtr;532533} _cmsMemPluginChunkType;534535// Copy memory management function pointers from plug-in to chunk, taking care of missing routines536void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);537538// Internal structure for context539struct _cmsContext_struct {540541struct _cmsContext_struct* Next; // Points to next context in the new style542_cmsSubAllocator* MemPool; // The memory pool that stores context data543544void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator.545// If NULL, then it reverts to global Context0546547_cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overridden548};549550// Returns a pointer to a valid context structure, including the global one if id is zero.551// Verifies the magic number.552struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);553554// Returns the block assigned to the specific zone.555void* _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc);556557558// Chunks of context memory by plug-in client -------------------------------------------------------559560// Those structures encapsulates all variables needed by the several context clients (mostly plug-ins)561562// Container for error logger -- not a plug-in563typedef struct {564565cmsLogErrorHandlerFunction LogErrorHandler; // Set to NULL for Context0 fallback566567} _cmsLogErrorChunkType;568569// The global Context0 storage for error logger570extern _cmsLogErrorChunkType _cmsLogErrorChunk;571572// Allocate and init error logger container.573void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,574const struct _cmsContext_struct* src);575576// Container for alarm codes -- not a plug-in577typedef struct {578579cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];580581} _cmsAlarmCodesChunkType;582583// The global Context0 storage for alarm codes584extern _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;585586// Allocate and init alarm codes container.587void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,588const struct _cmsContext_struct* src);589590// Container for adaptation state -- not a plug-in591typedef struct {592593cmsFloat64Number AdaptationState;594595} _cmsAdaptationStateChunkType;596597// The global Context0 storage for adaptation state598extern _cmsAdaptationStateChunkType _cmsAdaptationStateChunk;599600// Allocate and init adaptation state container.601void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,602const struct _cmsContext_struct* src);603604605// The global Context0 storage for memory management606extern _cmsMemPluginChunkType _cmsMemPluginChunk;607608// Allocate and init memory management container.609void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,610const struct _cmsContext_struct* src);611612// Container for interpolation plug-in613typedef struct {614615cmsInterpFnFactory Interpolators;616617} _cmsInterpPluginChunkType;618619// The global Context0 storage for interpolation plug-in620extern _cmsInterpPluginChunkType _cmsInterpPluginChunk;621622// Allocate and init interpolation container.623void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,624const struct _cmsContext_struct* src);625626// Container for parametric curves plug-in627typedef struct {628629struct _cmsParametricCurvesCollection_st* ParametricCurves;630631} _cmsCurvesPluginChunkType;632633// The global Context0 storage for tone curves plug-in634extern _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;635636// Allocate and init parametric curves container.637void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,638const struct _cmsContext_struct* src);639640// Container for formatters plug-in641typedef struct {642643struct _cms_formatters_factory_list* FactoryList;644645} _cmsFormattersPluginChunkType;646647// The global Context0 storage for formatters plug-in648extern _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;649650// Allocate and init formatters container.651void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,652const struct _cmsContext_struct* src);653654// This chunk type is shared by TagType plug-in and MPE Plug-in655typedef struct {656657struct _cmsTagTypeLinkedList_st* TagTypes;658659} _cmsTagTypePluginChunkType;660661662// The global Context0 storage for tag types plug-in663extern _cmsTagTypePluginChunkType _cmsTagTypePluginChunk;664665666// The global Context0 storage for mult process elements plug-in667extern _cmsTagTypePluginChunkType _cmsMPETypePluginChunk;668669// Allocate and init Tag types container.670void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,671const struct _cmsContext_struct* src);672// Allocate and init MPE container.673void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,674const struct _cmsContext_struct* src);675// Container for tag plug-in676typedef struct {677678struct _cmsTagLinkedList_st* Tag;679680} _cmsTagPluginChunkType;681682683// The global Context0 storage for tag plug-in684extern _cmsTagPluginChunkType _cmsTagPluginChunk;685686// Allocate and init Tag container.687void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,688const struct _cmsContext_struct* src);689690// Container for intents plug-in691typedef struct {692693struct _cms_intents_list* Intents;694695} _cmsIntentsPluginChunkType;696697698// The global Context0 storage for intents plug-in699extern _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;700701// Allocate and init intents container.702void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,703const struct _cmsContext_struct* src);704705// Container for optimization plug-in706typedef struct {707708struct _cmsOptimizationCollection_st* OptimizationCollection;709710} _cmsOptimizationPluginChunkType;711712713// The global Context0 storage for optimizers plug-in714extern _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;715716// Allocate and init optimizers container.717void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,718const struct _cmsContext_struct* src);719720// Container for transform plug-in721typedef struct {722723struct _cmsTransformCollection_st* TransformCollection;724725} _cmsTransformPluginChunkType;726727// The global Context0 storage for full-transform replacement plug-in728extern _cmsTransformPluginChunkType _cmsTransformPluginChunk;729730// Allocate and init transform container.731void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,732const struct _cmsContext_struct* src);733734// Container for mutex plug-in735typedef struct {736737_cmsCreateMutexFnPtrType CreateMutexPtr;738_cmsDestroyMutexFnPtrType DestroyMutexPtr;739_cmsLockMutexFnPtrType LockMutexPtr;740_cmsUnlockMutexFnPtrType UnlockMutexPtr;741742} _cmsMutexPluginChunkType;743744// The global Context0 storage for mutex plug-in745extern _cmsMutexPluginChunkType _cmsMutexPluginChunk;746747// Allocate and init mutex container.748void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,749const struct _cmsContext_struct* src);750751// ----------------------------------------------------------------------------------752// MLU internal representation753typedef struct {754755cmsUInt16Number Language;756cmsUInt16Number Country;757758cmsUInt32Number StrW; // Offset to current unicode string759cmsUInt32Number Len; // Length in bytes760761} _cmsMLUentry;762763struct _cms_MLU_struct {764765cmsContext ContextID;766767// The directory768cmsUInt32Number AllocatedEntries;769cmsUInt32Number UsedEntries;770_cmsMLUentry* Entries; // Array of pointers to strings allocated in MemPool771772// The Pool773cmsUInt32Number PoolSize; // The maximum allocated size774cmsUInt32Number PoolUsed; // The used size775void* MemPool; // Pointer to begin of memory pool776};777778// Named color list internal representation779typedef struct {780781char Name[cmsMAX_PATH];782cmsUInt16Number PCS[3];783cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];784785} _cmsNAMEDCOLOR;786787struct _cms_NAMEDCOLORLIST_struct {788789cmsUInt32Number nColors;790cmsUInt32Number Allocated;791cmsUInt32Number ColorantCount;792793char Prefix[33]; // Prefix and suffix are defined to be 32 characters at most794char Suffix[33];795796_cmsNAMEDCOLOR* List;797798cmsContext ContextID;799};800801802// ----------------------------------------------------------------------------------803804// This is the internal struct holding profile details.805806// Maximum supported tags in a profile807#define MAX_TABLE_TAG 100808809typedef struct _cms_iccprofile_struct {810811// I/O handler812cmsIOHANDLER* IOhandler;813814// The thread ID815cmsContext ContextID;816817// Creation time818struct tm Created;819820// Only most important items found in ICC profiles821cmsUInt32Number Version;822cmsProfileClassSignature DeviceClass;823cmsColorSpaceSignature ColorSpace;824cmsColorSpaceSignature PCS;825cmsUInt32Number RenderingIntent;826827cmsUInt32Number flags;828cmsUInt32Number manufacturer, model;829cmsUInt64Number attributes;830cmsUInt32Number creator;831832cmsProfileID ProfileID;833834// Dictionary835cmsUInt32Number TagCount;836cmsTagSignature TagNames[MAX_TABLE_TAG];837cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to which is linked (0=none)838cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk839cmsUInt32Number TagOffsets[MAX_TABLE_TAG];840cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked841void * TagPtrs[MAX_TABLE_TAG];842cmsTagTypeHandler* TagTypeHandlers[MAX_TABLE_TAG]; // Same structure may be serialized on different types843// depending on profile version, so we keep track of the844// type handler for each tag in the list.845// Special846cmsBool IsWrite;847848// Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin849void * UsrMutex;850851} _cmsICCPROFILE;852853// IO helpers for profiles854cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc);855cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);856int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);857858// Tag types859cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);860cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);861cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);862863// Error logging ---------------------------------------------------------------------------------------------------------864865void _cmsTagSignature2String(char String[5], cmsTagSignature sig);866867// Interpolation ---------------------------------------------------------------------------------------------------------868869CMSCHECKPOINT cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);870cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags);871CMSCHECKPOINT void CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p);872cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);873874// Curves ----------------------------------------------------------------------------------------------------------------875876// This struct holds information about a segment, plus a pointer to the function that implements the evaluation.877// In the case of table-based, Eval pointer is set to NULL878879// The gamma function main structure880struct _cms_curve_struct {881882cmsInterpParams* InterpParams; // Private optimizations for interpolation883884cmsUInt32Number nSegments; // Number of segments in the curve. Zero for a 16-bit based tables885cmsCurveSegment* Segments; // The segments886cmsInterpParams** SegInterp; // Array of private optimizations for interpolation in table-based segments887888cmsParametricCurveEvaluator* Evals; // Evaluators (one per segment)889890// 16 bit Table-based representation follows891cmsUInt32Number nEntries; // Number of table elements892cmsUInt16Number* Table16; // The table itself.893};894895896// Pipelines & Stages ---------------------------------------------------------------------------------------------897898// A single stage899struct _cmsStage_struct {900901cmsContext ContextID;902903cmsStageSignature Type; // Identifies the stage904cmsStageSignature Implements; // Identifies the *function* of the stage (for optimizations)905906cmsUInt32Number InputChannels; // Input channels -- for optimization purposes907cmsUInt32Number OutputChannels; // Output channels -- for optimization purposes908909_cmsStageEvalFn EvalPtr; // Points to fn that evaluates the stage (always in floating point)910_cmsStageDupElemFn DupElemPtr; // Points to a fn that duplicates the *data* of the stage911_cmsStageFreeElemFn FreePtr; // Points to a fn that sets the *data* of the stage free912913// A generic pointer to whatever memory needed by the stage914void* Data;915916// Maintains linked list (used internally)917struct _cmsStage_struct* Next;918};919920921// Special Stages (cannot be saved)922CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID);923CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID);924cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID);925CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID);926cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);927CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID);928CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);929CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels);930CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan);931cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID);932cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);933cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID);934cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID);935cmsStage* _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels);936937938// For curve set only939cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe);940941struct _cmsPipeline_struct {942943cmsStage* Elements; // Points to elements chain944cmsUInt32Number InputChannels, OutputChannels;945946// Data & evaluators947void *Data;948949_cmsPipelineEval16Fn Eval16Fn;950_cmsPipelineEvalFloatFn EvalFloatFn;951_cmsFreeUserDataFn FreeDataFn;952_cmsDupUserDataFn DupDataFn;953954cmsContext ContextID; // Environment955956cmsBool SaveAs8Bits; // Implementation-specific: save as 8 bits if possible957};958959// LUT reading & creation -------------------------------------------------------------------------------------------960961// Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy962// of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.963964CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);965CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);966CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent);967968// Special values969cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);970cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);971972// Profile linker --------------------------------------------------------------------------------------------------973974// Link several profiles to obtain a single LUT modelling the whole color transform. Intents, Black point975// compensation and Adaptation parameters may vary across profiles. BPC and Adaptation refers to the PCS976// after the profile. I.e, BPC[0] refers to connexion between profile(0) and profile(1)977cmsPipeline* _cmsLinkProfiles(cmsContext ContextID,978cmsUInt32Number nProfiles,979cmsUInt32Number TheIntents[],980cmsHPROFILE hProfiles[],981cmsBool BPC[],982cmsFloat64Number AdaptationStates[],983cmsUInt32Number dwFlags);984985// Sequence --------------------------------------------------------------------------------------------------------986987cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile);988cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq);989cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);990991992// LUT optimization ------------------------------------------------------------------------------------------------993994CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples);995996CMSAPI cmsUInt32Number CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);997998cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,999cmsUInt16Number **White,1000cmsUInt16Number **Black,1001cmsUInt32Number *nOutputs);10021003CMSAPI cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,1004cmsPipeline** Lut,1005cmsUInt32Number Intent,1006cmsUInt32Number* InputFormat,1007cmsUInt32Number* OutputFormat,1008cmsUInt32Number* dwFlags );100910101011// Hi level LUT building ----------------------------------------------------------------------------------------------10121013cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,1014cmsHPROFILE hProfiles[],1015cmsBool BPC[],1016cmsUInt32Number Intents[],1017cmsFloat64Number AdaptationStates[],1018cmsUInt32Number nGamutPCSposition,1019cmsHPROFILE hGamut);102010211022// Formatters ------------------------------------------------------------------------------------------------------------10231024#define cmsFLAGS_CAN_CHANGE_FORMATTER 0x02000000 // Allow change buffer format10251026cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type);1027cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type);10281029CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID,1030cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_81031cmsFormatterDirection Dir,1032cmsUInt32Number dwFlags);103310341035#ifndef CMS_NO_HALF_SUPPORT10361037// Half float1038CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h);1039CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt);10401041#endif10421043// Transform logic ------------------------------------------------------------------------------------------------------10441045struct _cmstransform_struct;10461047typedef struct {10481049// 1-pixel cache (16 bits only)1050cmsUInt16Number CacheIn[cmsMAXCHANNELS];1051cmsUInt16Number CacheOut[cmsMAXCHANNELS];10521053} _cmsCACHE;1054105510561057// Transformation1058typedef struct _cmstransform_struct {10591060cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference10611062// Points to transform code1063_cmsTransform2Fn xform;10641065// Formatters, cannot be embedded into LUT because cache1066cmsFormatter16 FromInput;1067cmsFormatter16 ToOutput;10681069cmsFormatterFloat FromInputFloat;1070cmsFormatterFloat ToOutputFloat;10711072// 1-pixel cache seed for zero as input (16 bits, read only)1073_cmsCACHE Cache;10741075// A Pipeline holding the full (optimized) transform1076cmsPipeline* Lut;10771078// A Pipeline holding the gamut check. It goes from the input space to bilevel1079cmsPipeline* GamutCheck;10801081// Colorant tables1082cmsNAMEDCOLORLIST* InputColorant; // Input Colorant table1083cmsNAMEDCOLORLIST* OutputColorant; // Colorant table (for n chans > CMYK)10841085// Informational only1086cmsColorSpaceSignature EntryColorSpace;1087cmsColorSpaceSignature ExitColorSpace;10881089// White points (informative only)1090cmsCIEXYZ EntryWhitePoint;1091cmsCIEXYZ ExitWhitePoint;10921093// Profiles used to create the transform1094cmsSEQ* Sequence;10951096cmsUInt32Number dwOriginalFlags;1097cmsFloat64Number AdaptationState;10981099// The intent of this transform. That is usually the last intent in the profilechain, but may differ1100cmsUInt32Number RenderingIntent;11011102// An id that uniquely identifies the running context. May be null.1103cmsContext ContextID;11041105// A user-defined pointer that can be used to store data for transform plug-ins1106void* UserData;1107_cmsFreeUserDataFn FreeUserData;11081109// A way to provide backwards compatibility with full xform plugins1110_cmsTransformFn OldXform;11111112} _cmsTRANSFORM;11131114// Copies extra channels from input to output if the original flags in the transform structure1115// instructs to do so. This function is called on all standard transform functions.1116void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,1117void* out,1118cmsUInt32Number PixelsPerLine,1119cmsUInt32Number LineCount,1120const cmsStride* Stride);11211122// -----------------------------------------------------------------------------------------------------------------------11231124cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,1125cmsUInt32Number nProfiles,1126cmsUInt32Number InputFormat,1127cmsUInt32Number OutputFormat,1128const cmsUInt32Number Intents[],1129const cmsHPROFILE hProfiles[],1130const cmsBool BPC[],1131const cmsFloat64Number AdaptationStates[],1132cmsUInt32Number dwFlags);113311341135cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID,1136cmsUInt32Number nPoints,1137cmsUInt32Number nProfiles,1138const cmsUInt32Number Intents[],1139const cmsHPROFILE hProfiles[],1140const cmsBool BPC[],1141const cmsFloat64Number AdaptationStates[],1142cmsUInt32Number dwFlags);11431144cmsBool _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);11451146cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);114711481149#define _lcms_internal_H1150#endif115111521153