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 | |