2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
//
|
|
|
|
// Little Color Management System
|
2016-04-30 17:58:04 +02:00
|
|
|
// Copyright (c) 1998-2016 Marti Maria Saguer
|
2011-03-20 23:45:24 +01:00
|
|
|
//
|
2015-07-21 23:49:11 +02:00
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
// a copy of this software and associated documentation files (the "Software"),
|
|
|
|
// to deal in the Software without restriction, including without limitation
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the Software
|
2011-03-20 23:45:24 +01:00
|
|
|
// is furnished to do so, subject to the following conditions:
|
|
|
|
//
|
2015-07-21 23:49:11 +02:00
|
|
|
// The above copyright notice and this permission notice shall be included in
|
2011-03-20 23:45:24 +01:00
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
2015-07-21 23:49:11 +02:00
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
|
|
// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
2011-03-20 23:45:24 +01:00
|
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef _lcms_internal_H
|
|
|
|
|
|
|
|
// Include plug-in foundation
|
|
|
|
#ifndef _lcms_plugin_H
|
|
|
|
# include "lcms2_plugin.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// ctype is part of C99 as per 7.1.2
|
|
|
|
#include <ctype.h>
|
|
|
|
|
|
|
|
// assert macro is part of C99 as per 7.2
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
// Some needed constants
|
|
|
|
#ifndef M_PI
|
|
|
|
# define M_PI 3.14159265358979323846
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef M_LOG10E
|
|
|
|
# define M_LOG10E 0.434294481903251827651
|
|
|
|
#endif
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
// BorlandC 5.5, VC2003 are broken on that
|
|
|
|
#if defined(__BORLANDC__) || (_MSC_VER < 1400) // 1400 == VC++ 8.0
|
2011-03-20 23:45:24 +01:00
|
|
|
#define sinf(x) (float)sin((float)x)
|
|
|
|
#define sqrtf(x) (float)sqrt((float)x)
|
|
|
|
#endif
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
// Alignment of ICC file format uses 4 bytes (cmsUInt32Number)
|
2015-07-21 23:49:11 +02:00
|
|
|
#define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & ~(sizeof(cmsUInt32Number)-1))
|
|
|
|
|
|
|
|
// Alignment to memory pointer
|
2016-04-30 17:58:04 +02:00
|
|
|
|
|
|
|
// (Ultra)SPARC with gcc requires ptr alignment of 8 bytes
|
|
|
|
// even though sizeof(void *) is only four: for greatest flexibility
|
|
|
|
// allow the build to specify ptr alignment.
|
|
|
|
#ifndef CMS_PTR_ALIGNMENT
|
|
|
|
# define CMS_PTR_ALIGNMENT sizeof(void *)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define _cmsALIGNMEM(x) (((x)+(CMS_PTR_ALIGNMENT - 1)) & ~(CMS_PTR_ALIGNMENT - 1))
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Maximum encodeable values in floating point
|
|
|
|
#define MAX_ENCODEABLE_XYZ (1.0 + 32767.0/32768.0)
|
|
|
|
#define MIN_ENCODEABLE_ab2 (-128.0)
|
|
|
|
#define MAX_ENCODEABLE_ab2 ((65535.0/256.0) - 128.0)
|
|
|
|
#define MIN_ENCODEABLE_ab4 (-128.0)
|
|
|
|
#define MAX_ENCODEABLE_ab4 (127.0)
|
|
|
|
|
|
|
|
// Maximum of channels for internal pipeline evaluation
|
2015-07-21 23:49:11 +02:00
|
|
|
#define MAX_STAGE_CHANNELS 128
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Unused parameter warning supression
|
2015-07-21 23:49:11 +02:00
|
|
|
#define cmsUNUSED_PARAMETER(x) ((void)x)
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999).
|
|
|
|
// unfortunately VisualC++ does not conform that
|
|
|
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
|
|
|
# define cmsINLINE __inline
|
|
|
|
#else
|
|
|
|
# define cmsINLINE static inline
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Other replacement functions
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
# ifndef snprintf
|
|
|
|
# define snprintf _snprintf
|
|
|
|
# endif
|
|
|
|
# ifndef vsnprintf
|
|
|
|
# define vsnprintf _vsnprintf
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// A fast way to convert from/to 16 <-> 8 bits
|
2015-07-21 23:49:11 +02:00
|
|
|
#define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
|
2016-05-03 22:22:03 +02:00
|
|
|
#define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((cmsUInt32Number)(rgb) * 65281U + 8388608U) >> 24) & 0xFFU)
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Code analysis is broken on asserts
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
# if (_MSC_VER >= 1500)
|
|
|
|
# define _cmsAssert(a) { assert((a)); __analysis_assume((a)); }
|
|
|
|
# else
|
|
|
|
# define _cmsAssert(a) assert((a))
|
|
|
|
# endif
|
|
|
|
#else
|
|
|
|
# define _cmsAssert(a) assert((a))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Determinant lower than that are assumed zero (used on matrix invert)
|
|
|
|
#define MATRIX_DET_TOLERANCE 0.0001
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Fixed point
|
|
|
|
#define FIXED_TO_INT(x) ((x)>>16)
|
|
|
|
#define FIXED_REST_TO_INT(x) ((x)&0xFFFFU)
|
|
|
|
#define ROUND_FIXED_TO_INT(x) (((x)+0x8000)>>16)
|
|
|
|
|
|
|
|
cmsINLINE cmsS15Fixed16Number _cmsToFixedDomain(int a) { return a + ((a + 0x7fff) / 0xffff); }
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsINLINE int _cmsFromFixedDomain(cmsS15Fixed16Number a) { return a - ((a + 0x7fff) >> 16); }
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
// Fast floor conversion logic. Thanks to Sree Kotay and Stuart Nixon
|
|
|
|
// note than this only works in the range ..-32767...+32767 because
|
2011-03-20 23:45:24 +01:00
|
|
|
// mantissa is interpreted as 15.16 fixed point.
|
|
|
|
// The union is to avoid pointer aliasing overoptimization.
|
|
|
|
cmsINLINE int _cmsQuickFloor(cmsFloat64Number val)
|
|
|
|
{
|
|
|
|
#ifdef CMS_DONT_USE_FAST_FLOOR
|
|
|
|
return (int) floor(val);
|
|
|
|
#else
|
|
|
|
const cmsFloat64Number _lcms_double2fixmagic = 68719476736.0 * 1.5; // 2^36 * 1.5, (52-16=36) uses limited precision to floor
|
|
|
|
union {
|
|
|
|
cmsFloat64Number val;
|
|
|
|
int halves[2];
|
|
|
|
} temp;
|
2015-07-21 23:49:11 +02:00
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
temp.val = val + _lcms_double2fixmagic;
|
2015-07-21 23:49:11 +02:00
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
#ifdef CMS_USE_BIG_ENDIAN
|
|
|
|
return temp.halves[1] >> 16;
|
|
|
|
#else
|
|
|
|
return temp.halves[0] >> 16;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fast floor restricted to 0..65535.0
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsINLINE cmsUInt16Number _cmsQuickFloorWord(cmsFloat64Number d)
|
|
|
|
{
|
|
|
|
return (cmsUInt16Number) _cmsQuickFloor(d - 32767.0) + 32767U;
|
2011-03-20 23:45:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Floor to word, taking care of saturation
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsINLINE cmsUInt16Number _cmsQuickSaturateWord(cmsFloat64Number d)
|
2011-03-20 23:45:24 +01:00
|
|
|
{
|
|
|
|
d += 0.5;
|
|
|
|
if (d <= 0) return 0;
|
|
|
|
if (d >= 65535.0) return 0xffff;
|
|
|
|
|
|
|
|
return _cmsQuickFloorWord(d);
|
|
|
|
}
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
|
|
|
|
// Pthread support --------------------------------------------------------------------
|
|
|
|
#ifndef CMS_NO_PTHREADS
|
|
|
|
|
|
|
|
// This is the threading support. Unfortunately, it has to be platform-dependent because
|
|
|
|
// windows does not support pthreads.
|
|
|
|
|
|
|
|
#ifdef CMS_IS_WINDOWS_
|
|
|
|
|
|
|
|
#define WIN32_LEAN_AND_MEAN 1
|
|
|
|
#include <windows.h>
|
|
|
|
|
|
|
|
|
|
|
|
// From: http://locklessinc.com/articles/pthreads_on_windows/
|
|
|
|
// The pthreads API has an initialization macro that has no correspondence to anything in
|
|
|
|
// the windows API. By investigating the internal definition of the critical section type,
|
|
|
|
// one may work out how to initialize one without calling InitializeCriticalSection().
|
|
|
|
// The trick here is that InitializeCriticalSection() is not allowed to fail. It tries
|
|
|
|
// to allocate a critical section debug object, but if no memory is available, it sets
|
|
|
|
// the pointer to a specific value. (One would expect that value to be NULL, but it is
|
|
|
|
// actually (void *)-1 for some reason.) Thus we can use this special value for that
|
|
|
|
// pointer, and the critical section code will work.
|
|
|
|
|
|
|
|
// The other important part of the critical section type to initialize is the number
|
|
|
|
// of waiters. This controls whether or not the mutex is locked. Fortunately, this
|
|
|
|
// part of the critical section is unlikely to change. Apparently, many programs
|
|
|
|
// already test critical sections to see if they are locked using this value, so
|
|
|
|
// Microsoft felt that it was necessary to keep it set at -1 for an unlocked critical
|
|
|
|
// section, even when they changed the underlying algorithm to be more scalable.
|
|
|
|
// The final parts of the critical section object are unimportant, and can be set
|
2016-04-30 17:58:04 +02:00
|
|
|
// to zero for their defaults. This yields to an initialization macro:
|
2015-07-21 23:49:11 +02:00
|
|
|
|
|
|
|
typedef CRITICAL_SECTION _cmsMutex;
|
|
|
|
|
2016-04-30 17:58:04 +02:00
|
|
|
#define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0}
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
# if (_MSC_VER >= 1800)
|
|
|
|
# pragma warning(disable : 26135)
|
|
|
|
# endif
|
|
|
|
#endif
|
2015-07-21 23:49:11 +02:00
|
|
|
|
|
|
|
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
EnterCriticalSection(m);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
LeaveCriticalSection(m);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
InitializeCriticalSection(m);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
DeleteCriticalSection(m);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
EnterCriticalSection(m);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
LeaveCriticalSection(m);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
// Rest of the wide world
|
|
|
|
#include <pthread.h>
|
|
|
|
|
|
|
|
#define CMS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
|
|
|
typedef pthread_mutex_t _cmsMutex;
|
|
|
|
|
|
|
|
|
|
|
|
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
return pthread_mutex_lock(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
return pthread_mutex_unlock(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
return pthread_mutex_init(m, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
return pthread_mutex_destroy(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
return pthread_mutex_lock(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
return pthread_mutex_unlock(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
|
|
|
|
#define CMS_MUTEX_INITIALIZER 0
|
|
|
|
typedef int _cmsMutex;
|
|
|
|
|
|
|
|
|
|
|
|
cmsINLINE int _cmsLockPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
cmsUNUSED_PARAMETER(m);
|
2016-04-30 17:58:04 +02:00
|
|
|
return 0;
|
2015-07-21 23:49:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsUnlockPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
cmsUNUSED_PARAMETER(m);
|
2016-04-30 17:58:04 +02:00
|
|
|
return 0;
|
2015-07-21 23:49:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsInitMutexPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
cmsUNUSED_PARAMETER(m);
|
2016-04-30 17:58:04 +02:00
|
|
|
return 0;
|
2015-07-21 23:49:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsDestroyMutexPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
cmsUNUSED_PARAMETER(m);
|
2016-04-30 17:58:04 +02:00
|
|
|
return 0;
|
2015-07-21 23:49:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsEnterCriticalSectionPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
cmsUNUSED_PARAMETER(m);
|
2016-04-30 17:58:04 +02:00
|
|
|
return 0;
|
2015-07-21 23:49:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
cmsINLINE int _cmsLeaveCriticalSectionPrimitive(_cmsMutex *m)
|
|
|
|
{
|
|
|
|
cmsUNUSED_PARAMETER(m);
|
2016-04-30 17:58:04 +02:00
|
|
|
return 0;
|
2015-07-21 23:49:11 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Plug-In registration ---------------------------------------------------------------
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Specialized function for plug-in memory management. No pairing free() since whole pool is freed at once.
|
2015-07-21 23:49:11 +02:00
|
|
|
void* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Memory management
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsBool _cmsRegisterMemHandlerPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Interpolation
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsBool _cmsRegisterInterpPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Parametric curves
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsBool _cmsRegisterParametricCurvesPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Formatters management
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsBool _cmsRegisterFormattersPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Tag type management
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsBool _cmsRegisterTagTypePlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Tag management
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsBool _cmsRegisterTagPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Intent management
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsBool _cmsRegisterRenderingIntentPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Multi Process elements
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Optimization
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsBool _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
|
|
|
|
|
|
|
// Transform
|
|
|
|
cmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
// Mutex
|
|
|
|
cmsBool _cmsRegisterMutexPlugin(cmsContext ContextID, cmsPluginBase* Plugin);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------------------------------
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
// Suballocators.
|
2011-03-20 23:45:24 +01:00
|
|
|
typedef struct _cmsSubAllocator_chunk_st {
|
|
|
|
|
|
|
|
cmsUInt8Number* Block;
|
|
|
|
cmsUInt32Number BlockSize;
|
|
|
|
cmsUInt32Number Used;
|
|
|
|
|
|
|
|
struct _cmsSubAllocator_chunk_st* next;
|
|
|
|
|
|
|
|
} _cmsSubAllocator_chunk;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
cmsContext ContextID;
|
|
|
|
_cmsSubAllocator_chunk* h;
|
|
|
|
|
|
|
|
} _cmsSubAllocator;
|
|
|
|
|
|
|
|
|
|
|
|
_cmsSubAllocator* _cmsCreateSubAlloc(cmsContext ContextID, cmsUInt32Number Initial);
|
|
|
|
void _cmsSubAllocDestroy(_cmsSubAllocator* s);
|
|
|
|
void* _cmsSubAlloc(_cmsSubAllocator* s, cmsUInt32Number size);
|
2015-07-21 23:49:11 +02:00
|
|
|
void* _cmsSubAllocDup(_cmsSubAllocator* s, const void *ptr, cmsUInt32Number size);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
// The context clients.
|
|
|
|
typedef enum {
|
|
|
|
|
|
|
|
UserPtr, // User-defined pointer
|
|
|
|
Logger,
|
|
|
|
AlarmCodesContext,
|
|
|
|
AdaptationStateContext,
|
|
|
|
MemPlugin,
|
|
|
|
InterpPlugin,
|
|
|
|
CurvesPlugin,
|
|
|
|
FormattersPlugin,
|
|
|
|
TagTypePlugin,
|
|
|
|
TagPlugin,
|
|
|
|
IntentPlugin,
|
|
|
|
MPEPlugin,
|
|
|
|
OptimizationPlugin,
|
|
|
|
TransformPlugin,
|
|
|
|
MutexPlugin,
|
|
|
|
|
|
|
|
// Last in list
|
|
|
|
MemoryClientMax
|
|
|
|
|
|
|
|
} _cmsMemoryClient;
|
|
|
|
|
|
|
|
|
|
|
|
// Container for memory management plug-in.
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
_cmsMallocFnPtrType MallocPtr;
|
|
|
|
_cmsMalloZerocFnPtrType MallocZeroPtr;
|
|
|
|
_cmsFreeFnPtrType FreePtr;
|
|
|
|
_cmsReallocFnPtrType ReallocPtr;
|
|
|
|
_cmsCallocFnPtrType CallocPtr;
|
|
|
|
_cmsDupFnPtrType DupPtr;
|
|
|
|
|
|
|
|
} _cmsMemPluginChunkType;
|
|
|
|
|
|
|
|
// Copy memory management function pointers from plug-in to chunk, taking care of missing routines
|
|
|
|
void _cmsInstallAllocFunctions(cmsPluginMemHandler* Plugin, _cmsMemPluginChunkType* ptr);
|
|
|
|
|
|
|
|
// Internal structure for context
|
|
|
|
struct _cmsContext_struct {
|
|
|
|
|
|
|
|
struct _cmsContext_struct* Next; // Points to next context in the new style
|
|
|
|
_cmsSubAllocator* MemPool; // The memory pool that stores context data
|
|
|
|
|
|
|
|
void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator.
|
|
|
|
// If NULL, then it reverts to global Context0
|
|
|
|
|
|
|
|
_cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overriden
|
|
|
|
};
|
|
|
|
|
|
|
|
// Returns a pointer to a valid context structure, including the global one if id is zero.
|
|
|
|
// Verifies the magic number.
|
|
|
|
struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID);
|
|
|
|
|
|
|
|
// Returns the block assigned to the specific zone.
|
|
|
|
void* _cmsContextGetClientChunk(cmsContext id, _cmsMemoryClient mc);
|
|
|
|
|
|
|
|
|
|
|
|
// Chunks of context memory by plug-in client -------------------------------------------------------
|
|
|
|
|
|
|
|
// Those structures encapsulates all variables needed by the several context clients (mostly plug-ins)
|
|
|
|
|
|
|
|
// Container for error logger -- not a plug-in
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
cmsLogErrorHandlerFunction LogErrorHandler; // Set to NULL for Context0 fallback
|
|
|
|
|
|
|
|
} _cmsLogErrorChunkType;
|
|
|
|
|
|
|
|
// The global Context0 storage for error logger
|
|
|
|
extern _cmsLogErrorChunkType _cmsLogErrorChunk;
|
|
|
|
|
|
|
|
// Allocate and init error logger container.
|
|
|
|
void _cmsAllocLogErrorChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
|
|
|
|
// Container for alarm codes -- not a plug-in
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
cmsUInt16Number AlarmCodes[cmsMAXCHANNELS];
|
|
|
|
|
|
|
|
} _cmsAlarmCodesChunkType;
|
|
|
|
|
|
|
|
// The global Context0 storage for alarm codes
|
|
|
|
extern _cmsAlarmCodesChunkType _cmsAlarmCodesChunk;
|
|
|
|
|
|
|
|
// Allocate and init alarm codes container.
|
|
|
|
void _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
|
|
|
|
// Container for adaptation state -- not a plug-in
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
cmsFloat64Number AdaptationState;
|
|
|
|
|
|
|
|
} _cmsAdaptationStateChunkType;
|
|
|
|
|
|
|
|
// The global Context0 storage for adaptation state
|
|
|
|
extern _cmsAdaptationStateChunkType _cmsAdaptationStateChunk;
|
|
|
|
|
|
|
|
// Allocate and init adaptation state container.
|
|
|
|
void _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
|
|
|
|
|
|
|
|
// The global Context0 storage for memory management
|
|
|
|
extern _cmsMemPluginChunkType _cmsMemPluginChunk;
|
|
|
|
|
|
|
|
// Allocate and init memory management container.
|
|
|
|
void _cmsAllocMemPluginChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
|
|
|
|
// Container for interpolation plug-in
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
cmsInterpFnFactory Interpolators;
|
|
|
|
|
|
|
|
} _cmsInterpPluginChunkType;
|
|
|
|
|
|
|
|
// The global Context0 storage for interpolation plug-in
|
|
|
|
extern _cmsInterpPluginChunkType _cmsInterpPluginChunk;
|
|
|
|
|
|
|
|
// Allocate and init interpolation container.
|
|
|
|
void _cmsAllocInterpPluginChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
|
|
|
|
// Container for parametric curves plug-in
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
struct _cmsParametricCurvesCollection_st* ParametricCurves;
|
|
|
|
|
|
|
|
} _cmsCurvesPluginChunkType;
|
|
|
|
|
|
|
|
// The global Context0 storage for tone curves plug-in
|
|
|
|
extern _cmsCurvesPluginChunkType _cmsCurvesPluginChunk;
|
|
|
|
|
|
|
|
// Allocate and init parametric curves container.
|
|
|
|
void _cmsAllocCurvesPluginChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
|
|
|
|
// Container for formatters plug-in
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
struct _cms_formatters_factory_list* FactoryList;
|
|
|
|
|
|
|
|
} _cmsFormattersPluginChunkType;
|
|
|
|
|
|
|
|
// The global Context0 storage for formatters plug-in
|
|
|
|
extern _cmsFormattersPluginChunkType _cmsFormattersPluginChunk;
|
|
|
|
|
|
|
|
// Allocate and init formatters container.
|
|
|
|
void _cmsAllocFormattersPluginChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
|
|
|
|
// This chunk type is shared by TagType plug-in and MPE Plug-in
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
struct _cmsTagTypeLinkedList_st* TagTypes;
|
|
|
|
|
|
|
|
} _cmsTagTypePluginChunkType;
|
|
|
|
|
|
|
|
|
|
|
|
// The global Context0 storage for tag types plug-in
|
|
|
|
extern _cmsTagTypePluginChunkType _cmsTagTypePluginChunk;
|
|
|
|
|
|
|
|
|
|
|
|
// The global Context0 storage for mult process elements plug-in
|
|
|
|
extern _cmsTagTypePluginChunkType _cmsMPETypePluginChunk;
|
|
|
|
|
|
|
|
// Allocate and init Tag types container.
|
|
|
|
void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
// Allocate and init MPE container.
|
|
|
|
void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
// Container for tag plug-in
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
struct _cmsTagLinkedList_st* Tag;
|
|
|
|
|
|
|
|
} _cmsTagPluginChunkType;
|
|
|
|
|
|
|
|
|
|
|
|
// The global Context0 storage for tag plug-in
|
|
|
|
extern _cmsTagPluginChunkType _cmsTagPluginChunk;
|
|
|
|
|
|
|
|
// Allocate and init Tag container.
|
|
|
|
void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
|
|
|
|
// Container for intents plug-in
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
struct _cms_intents_list* Intents;
|
|
|
|
|
|
|
|
} _cmsIntentsPluginChunkType;
|
|
|
|
|
|
|
|
|
|
|
|
// The global Context0 storage for intents plug-in
|
|
|
|
extern _cmsIntentsPluginChunkType _cmsIntentsPluginChunk;
|
|
|
|
|
|
|
|
// Allocate and init intents container.
|
|
|
|
void _cmsAllocIntentsPluginChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
|
|
|
|
// Container for optimization plug-in
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
struct _cmsOptimizationCollection_st* OptimizationCollection;
|
|
|
|
|
|
|
|
} _cmsOptimizationPluginChunkType;
|
|
|
|
|
|
|
|
|
|
|
|
// The global Context0 storage for optimizers plug-in
|
|
|
|
extern _cmsOptimizationPluginChunkType _cmsOptimizationPluginChunk;
|
|
|
|
|
|
|
|
// Allocate and init optimizers container.
|
|
|
|
void _cmsAllocOptimizationPluginChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
|
|
|
|
// Container for transform plug-in
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
struct _cmsTransformCollection_st* TransformCollection;
|
|
|
|
|
|
|
|
} _cmsTransformPluginChunkType;
|
|
|
|
|
|
|
|
// The global Context0 storage for full-transform replacement plug-in
|
|
|
|
extern _cmsTransformPluginChunkType _cmsTransformPluginChunk;
|
|
|
|
|
|
|
|
// Allocate and init transform container.
|
|
|
|
void _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
|
|
|
|
// Container for mutex plug-in
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
_cmsCreateMutexFnPtrType CreateMutexPtr;
|
|
|
|
_cmsDestroyMutexFnPtrType DestroyMutexPtr;
|
|
|
|
_cmsLockMutexFnPtrType LockMutexPtr;
|
|
|
|
_cmsUnlockMutexFnPtrType UnlockMutexPtr;
|
|
|
|
|
|
|
|
} _cmsMutexPluginChunkType;
|
|
|
|
|
|
|
|
// The global Context0 storage for mutex plug-in
|
|
|
|
extern _cmsMutexPluginChunkType _cmsMutexPluginChunk;
|
|
|
|
|
|
|
|
// Allocate and init mutex container.
|
|
|
|
void _cmsAllocMutexPluginChunk(struct _cmsContext_struct* ctx,
|
|
|
|
const struct _cmsContext_struct* src);
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------------
|
2011-03-20 23:45:24 +01:00
|
|
|
// MLU internal representation
|
|
|
|
typedef struct {
|
|
|
|
|
|
|
|
cmsUInt16Number Language;
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsUInt16Number Country;
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
cmsUInt32Number StrW; // Offset to current unicode string
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsUInt32Number Len; // Length in bytes
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
} _cmsMLUentry;
|
|
|
|
|
|
|
|
struct _cms_MLU_struct {
|
2015-07-21 23:49:11 +02:00
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsContext ContextID;
|
|
|
|
|
|
|
|
// The directory
|
2016-04-30 17:58:04 +02:00
|
|
|
cmsUInt32Number AllocatedEntries;
|
|
|
|
cmsUInt32Number UsedEntries;
|
2011-03-20 23:45:24 +01:00
|
|
|
_cmsMLUentry* Entries; // Array of pointers to strings allocated in MemPool
|
|
|
|
|
|
|
|
// The Pool
|
|
|
|
cmsUInt32Number PoolSize; // The maximum allocated size
|
|
|
|
cmsUInt32Number PoolUsed; // The used size
|
2015-07-21 23:49:11 +02:00
|
|
|
void* MemPool; // Pointer to begin of memory pool
|
2011-03-20 23:45:24 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// Named color list internal representation
|
2015-07-21 23:49:11 +02:00
|
|
|
typedef struct {
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
char Name[cmsMAX_PATH];
|
|
|
|
cmsUInt16Number PCS[3];
|
|
|
|
cmsUInt16Number DeviceColorant[cmsMAXCHANNELS];
|
|
|
|
|
|
|
|
} _cmsNAMEDCOLOR;
|
|
|
|
|
|
|
|
struct _cms_NAMEDCOLORLIST_struct {
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsUInt32Number nColors;
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsUInt32Number Allocated;
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsUInt32Number ColorantCount;
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
char Prefix[33]; // Prefix and suffix are defined to be 32 characters at most
|
2015-07-21 23:49:11 +02:00
|
|
|
char Suffix[33];
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
_cmsNAMEDCOLOR* List;
|
|
|
|
|
|
|
|
cmsContext ContextID;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// This is the internal struct holding profile details.
|
|
|
|
|
|
|
|
// Maximum supported tags in a profile
|
|
|
|
#define MAX_TABLE_TAG 100
|
|
|
|
|
|
|
|
typedef struct _cms_iccprofile_struct {
|
|
|
|
|
|
|
|
// I/O handler
|
|
|
|
cmsIOHANDLER* IOhandler;
|
|
|
|
|
|
|
|
// The thread ID
|
|
|
|
cmsContext ContextID;
|
|
|
|
|
|
|
|
// Creation time
|
|
|
|
struct tm Created;
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
// Only most important items found in ICC profiles
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsUInt32Number Version;
|
|
|
|
cmsProfileClassSignature DeviceClass;
|
|
|
|
cmsColorSpaceSignature ColorSpace;
|
|
|
|
cmsColorSpaceSignature PCS;
|
|
|
|
cmsUInt32Number RenderingIntent;
|
2015-07-21 23:49:11 +02:00
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsUInt32Number flags;
|
|
|
|
cmsUInt32Number manufacturer, model;
|
|
|
|
cmsUInt64Number attributes;
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsUInt32Number creator;
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
cmsProfileID ProfileID;
|
|
|
|
|
|
|
|
// Dictionary
|
|
|
|
cmsUInt32Number TagCount;
|
|
|
|
cmsTagSignature TagNames[MAX_TABLE_TAG];
|
2016-08-06 13:04:56 +02:00
|
|
|
cmsTagSignature TagLinked[MAX_TABLE_TAG]; // The tag to which is linked (0=none)
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsUInt32Number TagSizes[MAX_TABLE_TAG]; // Size on disk
|
|
|
|
cmsUInt32Number TagOffsets[MAX_TABLE_TAG];
|
|
|
|
cmsBool TagSaveAsRaw[MAX_TABLE_TAG]; // True to write uncooked
|
|
|
|
void * TagPtrs[MAX_TABLE_TAG];
|
|
|
|
cmsTagTypeHandler* TagTypeHandlers[MAX_TABLE_TAG]; // Same structure may be serialized on different types
|
2015-07-21 23:49:11 +02:00
|
|
|
// depending on profile version, so we keep track of the
|
|
|
|
// type handler for each tag in the list.
|
2011-03-20 23:45:24 +01:00
|
|
|
// Special
|
|
|
|
cmsBool IsWrite;
|
2015-07-21 23:49:11 +02:00
|
|
|
|
|
|
|
// Keep a mutex for cmsReadTag -- Note that this only works if the user includes a mutex plugin
|
|
|
|
void * UsrMutex;
|
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
} _cmsICCPROFILE;
|
|
|
|
|
|
|
|
// IO helpers for profiles
|
|
|
|
cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc);
|
|
|
|
cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace);
|
|
|
|
int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cmsBool lFollowLinks);
|
|
|
|
|
|
|
|
// Tag types
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Error logging ---------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void _cmsTagSignature2String(char String[5], cmsTagSignature sig);
|
|
|
|
|
|
|
|
// Interpolation ---------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
|
|
|
|
cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
|
|
|
|
void _cmsFreeInterpParams(cmsInterpParams* p);
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Curves ----------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// This struct holds information about a segment, plus a pointer to the function that implements the evaluation.
|
|
|
|
// In the case of table-based, Eval pointer is set to NULL
|
|
|
|
|
|
|
|
// The gamma function main structure
|
|
|
|
struct _cms_curve_struct {
|
|
|
|
|
|
|
|
cmsInterpParams* InterpParams; // Private optimizations for interpolation
|
|
|
|
|
|
|
|
cmsUInt32Number nSegments; // Number of segments in the curve. Zero for a 16-bit based tables
|
|
|
|
cmsCurveSegment* Segments; // The segments
|
|
|
|
cmsInterpParams** SegInterp; // Array of private optimizations for interpolation in table-based segments
|
|
|
|
|
|
|
|
cmsParametricCurveEvaluator* Evals; // Evaluators (one per segment)
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
// 16 bit Table-based representation follows
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsUInt32Number nEntries; // Number of table elements
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsUInt16Number* Table16; // The table itself.
|
|
|
|
};
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
|
|
|
|
// Pipelines & Stages ---------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// A single stage
|
|
|
|
struct _cmsStage_struct {
|
2015-07-21 23:49:11 +02:00
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsContext ContextID;
|
2015-07-21 23:49:11 +02:00
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsStageSignature Type; // Identifies the stage
|
|
|
|
cmsStageSignature Implements; // Identifies the *function* of the stage (for optimizations)
|
|
|
|
|
|
|
|
cmsUInt32Number InputChannels; // Input channels -- for optimization purposes
|
|
|
|
cmsUInt32Number OutputChannels; // Output channels -- for optimization purposes
|
|
|
|
|
|
|
|
_cmsStageEvalFn EvalPtr; // Points to fn that evaluates the stage (always in floating point)
|
|
|
|
_cmsStageDupElemFn DupElemPtr; // Points to a fn that duplicates the *data* of the stage
|
|
|
|
_cmsStageFreeElemFn FreePtr; // Points to a fn that sets the *data* of the stage free
|
|
|
|
|
|
|
|
// A generic pointer to whatever memory needed by the stage
|
|
|
|
void* Data;
|
|
|
|
|
|
|
|
// Maintains linked list (used internally)
|
|
|
|
struct _cmsStage_struct* Next;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Special Stages (cannot be saved)
|
|
|
|
cmsStage* _cmsStageAllocLab2XYZ(cmsContext ContextID);
|
|
|
|
cmsStage* _cmsStageAllocXYZ2Lab(cmsContext ContextID);
|
|
|
|
cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID);
|
|
|
|
cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID);
|
|
|
|
cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
|
|
|
|
cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID);
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels);
|
|
|
|
cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan);
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
|
|
|
|
cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
|
|
|
|
cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID);
|
|
|
|
cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
|
2016-04-30 17:58:04 +02:00
|
|
|
cmsStage* _cmsStageClipNegatives(cmsContext ContextID, int nChannels);
|
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
// For curve set only
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
|
|
|
|
|
|
|
|
|
|
|
|
// Pipeline Evaluator (in floating point)
|
2015-07-21 23:49:11 +02:00
|
|
|
typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[],
|
|
|
|
cmsFloat32Number Out[],
|
|
|
|
const void* Data);
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
struct _cmsPipeline_struct {
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsStage* Elements; // Points to elements chain
|
|
|
|
cmsUInt32Number InputChannels, OutputChannels;
|
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
// Data & evaluators
|
|
|
|
void *Data;
|
|
|
|
|
|
|
|
_cmsOPTeval16Fn Eval16Fn;
|
|
|
|
_cmsPipelineEvalFloatFn EvalFloatFn;
|
2015-07-21 23:49:11 +02:00
|
|
|
_cmsFreeUserDataFn FreeDataFn;
|
|
|
|
_cmsDupUserDataFn DupDataFn;
|
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsContext ContextID; // Environment
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsBool SaveAs8Bits; // Implementation-specific: save as 8 bits if possible
|
2011-03-20 23:45:24 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// LUT reading & creation -------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy
|
|
|
|
// of the LUTS, since ownership of original is up to the profile. The user should free allocated resources.
|
|
|
|
|
|
|
|
cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent);
|
|
|
|
cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent);
|
|
|
|
cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent);
|
|
|
|
|
|
|
|
// Special values
|
|
|
|
cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile);
|
|
|
|
cmsBool _cmsReadCHAD(cmsMAT3* Dest, cmsHPROFILE hProfile);
|
|
|
|
|
|
|
|
// Profile linker --------------------------------------------------------------------------------------------------
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsPipeline* _cmsLinkProfiles(cmsContext ContextID,
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsUInt32Number nProfiles,
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsUInt32Number TheIntents[],
|
|
|
|
cmsHPROFILE hProfiles[],
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsBool BPC[],
|
|
|
|
cmsFloat64Number AdaptationStates[],
|
|
|
|
cmsUInt32Number dwFlags);
|
|
|
|
|
|
|
|
// Sequence --------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile);
|
|
|
|
cmsBool _cmsWriteProfileSequence(cmsHPROFILE hProfile, const cmsSEQ* seq);
|
|
|
|
cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[]);
|
|
|
|
|
|
|
|
|
|
|
|
// LUT optimization ------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples);
|
|
|
|
int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
|
|
|
|
cmsUInt16Number **White,
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsUInt16Number **Black,
|
|
|
|
cmsUInt32Number *nOutputs);
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsBool _cmsOptimizePipeline(cmsContext ContextID,
|
|
|
|
cmsPipeline** Lut,
|
2011-03-20 23:45:24 +01:00
|
|
|
int Intent,
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsUInt32Number* InputFormat,
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsUInt32Number* OutputFormat,
|
|
|
|
cmsUInt32Number* dwFlags );
|
|
|
|
|
|
|
|
|
|
|
|
// Hi level LUT building ----------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
cmsPipeline* _cmsCreateGamutCheckPipeline(cmsContext ContextID,
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsHPROFILE hProfiles[],
|
|
|
|
cmsBool BPC[],
|
|
|
|
cmsUInt32Number Intents[],
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsFloat64Number AdaptationStates[],
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsUInt32Number nGamutPCSposition,
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsHPROFILE hGamut);
|
|
|
|
|
|
|
|
|
|
|
|
// Formatters ------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#define cmsFLAGS_CAN_CHANGE_FORMATTER 0x02000000 // Allow change buffer format
|
|
|
|
|
|
|
|
cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type);
|
|
|
|
cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type);
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsFormatter _cmsGetFormatter(cmsContext ContextID,
|
|
|
|
cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
|
|
|
|
cmsFormatterDirection Dir,
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsUInt32Number dwFlags);
|
|
|
|
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
#ifndef CMS_NO_HALF_SUPPORT
|
|
|
|
|
|
|
|
// Half float
|
|
|
|
cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h);
|
|
|
|
cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
// Transform logic ------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
struct _cmstransform_struct;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
// 1-pixel cache (16 bits only)
|
|
|
|
cmsUInt16Number CacheIn[cmsMAXCHANNELS];
|
|
|
|
cmsUInt16Number CacheOut[cmsMAXCHANNELS];
|
|
|
|
|
|
|
|
} _cmsCACHE;
|
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
|
|
|
|
// Transformation
|
|
|
|
typedef struct _cmstransform_struct {
|
|
|
|
|
|
|
|
cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
|
|
|
|
|
|
|
|
// Points to transform code
|
2016-04-30 17:58:04 +02:00
|
|
|
_cmsTransform2Fn xform;
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// Formatters, cannot be embedded into LUT because cache
|
|
|
|
cmsFormatter16 FromInput;
|
|
|
|
cmsFormatter16 ToOutput;
|
|
|
|
|
|
|
|
cmsFormatterFloat FromInputFloat;
|
|
|
|
cmsFormatterFloat ToOutputFloat;
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
// 1-pixel cache seed for zero as input (16 bits, read only)
|
|
|
|
_cmsCACHE Cache;
|
|
|
|
|
|
|
|
// A Pipeline holding the full (optimized) transform
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsPipeline* Lut;
|
2015-07-21 23:49:11 +02:00
|
|
|
|
|
|
|
// A Pipeline holding the gamut check. It goes from the input space to bilevel
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsPipeline* GamutCheck;
|
|
|
|
|
|
|
|
// Colorant tables
|
|
|
|
cmsNAMEDCOLORLIST* InputColorant; // Input Colorant table
|
|
|
|
cmsNAMEDCOLORLIST* OutputColorant; // Colorant table (for n chans > CMYK)
|
|
|
|
|
|
|
|
// Informational only
|
|
|
|
cmsColorSpaceSignature EntryColorSpace;
|
|
|
|
cmsColorSpaceSignature ExitColorSpace;
|
2015-07-21 23:49:11 +02:00
|
|
|
|
|
|
|
// White points (informative only)
|
|
|
|
cmsCIEXYZ EntryWhitePoint;
|
|
|
|
cmsCIEXYZ ExitWhitePoint;
|
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
// Profiles used to create the transform
|
|
|
|
cmsSEQ* Sequence;
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsUInt32Number dwOriginalFlags;
|
|
|
|
cmsFloat64Number AdaptationState;
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
// The intent of this transform. That is usually the last intent in the profilechain, but may differ
|
|
|
|
cmsUInt32Number RenderingIntent;
|
|
|
|
|
|
|
|
// An id that uniquely identifies the running context. May be null.
|
|
|
|
cmsContext ContextID;
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
// A user-defined pointer that can be used to store data for transform plug-ins
|
|
|
|
void* UserData;
|
|
|
|
_cmsFreeUserDataFn FreeUserData;
|
|
|
|
|
2016-04-30 17:58:04 +02:00
|
|
|
// A way to provide backwards compatibility with full xform plugins
|
|
|
|
_cmsTransformFn OldXform;
|
|
|
|
|
2011-03-20 23:45:24 +01:00
|
|
|
} _cmsTRANSFORM;
|
|
|
|
|
2016-04-30 17:58:04 +02:00
|
|
|
// Copies extra channels from input to output if the original flags in the transform structure
|
|
|
|
// instructs to do so. This function is called on all standard transform functions.
|
|
|
|
void _cmsHandleExtraChannels(_cmsTRANSFORM* p, const void* in,
|
|
|
|
void* out,
|
|
|
|
cmsUInt32Number PixelsPerLine,
|
|
|
|
cmsUInt32Number LineCount,
|
|
|
|
const cmsStride* Stride);
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------------------------------------------------
|
2011-03-20 23:45:24 +01:00
|
|
|
|
|
|
|
cmsHTRANSFORM _cmsChain2Lab(cmsContext ContextID,
|
|
|
|
cmsUInt32Number nProfiles,
|
|
|
|
cmsUInt32Number InputFormat,
|
|
|
|
cmsUInt32Number OutputFormat,
|
2015-07-21 23:49:11 +02:00
|
|
|
const cmsUInt32Number Intents[],
|
|
|
|
const cmsHPROFILE hProfiles[],
|
2011-03-20 23:45:24 +01:00
|
|
|
const cmsBool BPC[],
|
|
|
|
const cmsFloat64Number AdaptationStates[],
|
|
|
|
cmsUInt32Number dwFlags);
|
|
|
|
|
|
|
|
|
2015-07-21 23:49:11 +02:00
|
|
|
cmsToneCurve* _cmsBuildKToneCurve(cmsContext ContextID,
|
2011-03-20 23:45:24 +01:00
|
|
|
cmsUInt32Number nPoints,
|
|
|
|
cmsUInt32Number nProfiles,
|
2015-07-21 23:49:11 +02:00
|
|
|
const cmsUInt32Number Intents[],
|
|
|
|
const cmsHPROFILE hProfiles[],
|
2011-03-20 23:45:24 +01:00
|
|
|
const cmsBool BPC[],
|
|
|
|
const cmsFloat64Number AdaptationStates[],
|
|
|
|
cmsUInt32Number dwFlags);
|
|
|
|
|
|
|
|
cmsBool _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll);
|
|
|
|
|
|
|
|
cmsBool _cmsBuildRGB2XYZtransferMatrix(cmsMAT3* r, const cmsCIExyY* WhitePoint, const cmsCIExyYTRIPLE* Primaries);
|
|
|
|
|
|
|
|
|
|
|
|
#define _lcms_internal_H
|
|
|
|
#endif
|