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