1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//--------------------------------------------------------------------------------- 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Little Color Management System 4d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Copyright (c) 1998-2016 Marti Maria Saguer 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Permission is hereby granted, free of charge, to any person obtaining 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// a copy of this software and associated documentation files (the "Software"), 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// to deal in the Software without restriction, including without limitation 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// the rights to use, copy, modify, merge, publish, distribute, sublicense, 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// and/or sell copies of the Software, and to permit persons to whom the Software 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// is furnished to do so, subject to the following conditions: 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The above copyright notice and this permission notice shall be included in 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// all copies or substantial portions of the Software. 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//--------------------------------------------------------------------------------- 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "lcms2_internal.h" 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Transformations stuff 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ----------------------------------------------------------------------- 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define DEFAULT_OBSERVER_ADAPTATION_STATE 1.0 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The Context0 observer adaptation state. 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov_cmsAdaptationStateChunkType _cmsAdaptationStateChunk = { DEFAULT_OBSERVER_ADAPTATION_STATE }; 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Init and duplicate observer adaptation state 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _cmsAllocAdaptationStateChunk(struct _cmsContext_struct* ctx, 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const struct _cmsContext_struct* src) 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static _cmsAdaptationStateChunkType AdaptationStateChunk = { DEFAULT_OBSERVER_ADAPTATION_STATE }; 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* from; 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (src != NULL) { 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov from = src ->chunks[AdaptationStateContext]; 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov from = &AdaptationStateChunk; 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ctx ->chunks[AdaptationStateContext] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsAdaptationStateChunkType)); 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Sets adaptation state for absolute colorimetric intent in the given context. Adaptation state applies on all 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// but cmsCreateExtendedTransformTHR(). Little CMS can handle incomplete adaptation states. 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsFloat64Number CMSEXPORT cmsSetAdaptationStateTHR(cmsContext ContextID, cmsFloat64Number d) 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number prev; 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAdaptationStateChunkType* ptr = (_cmsAdaptationStateChunkType*) _cmsContextGetClientChunk(ContextID, AdaptationStateContext); 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get previous value for return 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prev = ptr ->AdaptationState; 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Set the value if d is positive or zero 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (d >= 0.0) { 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ptr ->AdaptationState = d; 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Always return previous value 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return prev; 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The adaptation state may be defaulted by this function. If you don't like it, use the extended transform routine 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d) 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsSetAdaptationStateTHR(NULL, d); 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ----------------------------------------------------------------------- 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Alarm codes for 16-bit transformations, because the fixed range of containers there are 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// no values left to mark out of gamut. 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define DEFAULT_ALARM_CODES_VALUE {0x7F00, 0x7F00, 0x7F00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov_cmsAlarmCodesChunkType _cmsAlarmCodesChunk = { DEFAULT_ALARM_CODES_VALUE }; 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Sets the codes used to mark out-out-gamut on Proofing transforms for a given context. Values are meant to be 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// encoded in 16 bits. 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT cmsSetAlarmCodesTHR(cmsContext ContextID, const cmsUInt16Number AlarmCodesP[cmsMAXCHANNELS]) 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(ContextID, AlarmCodesContext); 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAssert(ContextAlarmCodes != NULL); // Can't happen 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memcpy(ContextAlarmCodes->AlarmCodes, AlarmCodesP, sizeof(ContextAlarmCodes->AlarmCodes)); 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Gets the current codes used to mark out-out-gamut on Proofing transforms for the given context. 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Values are meant to be encoded in 16 bits. 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT cmsGetAlarmCodesTHR(cmsContext ContextID, cmsUInt16Number AlarmCodesP[cmsMAXCHANNELS]) 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(ContextID, AlarmCodesContext); 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAssert(ContextAlarmCodes != NULL); // Can't happen 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memcpy(AlarmCodesP, ContextAlarmCodes->AlarmCodes, sizeof(ContextAlarmCodes->AlarmCodes)); 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT cmsSetAlarmCodes(const cmsUInt16Number NewAlarm[cmsMAXCHANNELS]) 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAssert(NewAlarm != NULL); 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSetAlarmCodesTHR(NULL, NewAlarm); 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number OldAlarm[cmsMAXCHANNELS]) 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAssert(OldAlarm != NULL); 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsGetAlarmCodesTHR(NULL, OldAlarm); 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Init and duplicate alarm codes 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _cmsAllocAlarmCodesChunk(struct _cmsContext_struct* ctx, 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const struct _cmsContext_struct* src) 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static _cmsAlarmCodesChunkType AlarmCodesChunk = { DEFAULT_ALARM_CODES_VALUE }; 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* from; 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (src != NULL) { 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov from = src ->chunks[AlarmCodesContext]; 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov from = &AlarmCodesChunk; 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ctx ->chunks[AlarmCodesContext] = _cmsSubAllocDup(ctx ->MemPool, from, sizeof(_cmsAlarmCodesChunkType)); 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ----------------------------------------------------------------------- 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Get rid of transform resources 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT cmsDeleteTransform(cmsHTRANSFORM hTransform) 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTRANSFORM* p = (_cmsTRANSFORM*) hTransform; 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAssert(p != NULL); 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (p -> GamutCheck) 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipelineFree(p -> GamutCheck); 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (p -> Lut) 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipelineFree(p -> Lut); 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (p ->InputColorant) 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeNamedColorList(p ->InputColorant); 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (p -> OutputColorant) 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeNamedColorList(p ->OutputColorant); 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (p ->Sequence) 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeProfileSequenceDescription(p ->Sequence); 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (p ->UserData) 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->FreeUserData(p ->ContextID, p ->UserData); 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(p ->ContextID, (void *) p); 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Apply transform. 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform, 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const void* InputBuffer, 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* OutputBuffer, 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Size) 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform; 182d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsStride stride; 183d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 184d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann stride.BytesPerLineIn = 0; // Not used 185d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann stride.BytesPerLineOut = 0; 186d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann stride.BytesPerPlaneIn = Size; 187d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann stride.BytesPerPlaneOut = Size; 188d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 189d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p -> xform(p, InputBuffer, OutputBuffer, Size, 1, &stride); 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 193d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// This is a legacy stride for planar 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform, 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const void* InputBuffer, 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* OutputBuffer, 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Size, cmsUInt32Number Stride) 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform; 201d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsStride stride; 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 203d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann stride.BytesPerLineIn = 0; 204d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann stride.BytesPerLineOut = 0; 205d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann stride.BytesPerPlaneIn = Stride; 206d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann stride.BytesPerPlaneOut = Stride; 207d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 208d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p -> xform(p, InputBuffer, OutputBuffer, Size, 1, &stride); 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 211d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// This is the "fast" function for plugins 212d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid CMSEXPORT cmsDoTransformLineStride(cmsHTRANSFORM Transform, 213d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const void* InputBuffer, 214d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann void* OutputBuffer, 215d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number PixelsPerLine, 216d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number LineCount, 217d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number BytesPerLineIn, 218d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number BytesPerLineOut, 219d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number BytesPerPlaneIn, 220d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number BytesPerPlaneOut) 221d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 222d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann{ 223d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann _cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform; 224d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsStride stride; 225d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 226d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann stride.BytesPerLineIn = BytesPerLineIn; 227d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann stride.BytesPerLineOut = BytesPerLineOut; 228d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann stride.BytesPerPlaneIn = BytesPerPlaneIn; 229d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann stride.BytesPerPlaneOut = BytesPerPlaneOut; 230d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 231d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->xform(p, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, &stride); 232d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann} 233d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 234d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Transform routines ---------------------------------------------------------------------------------------------------------- 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Float xform converts floats. Since there are no performance issues, one routine does all job, including gamut check. 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Note that because extended range, we can use a -1.0 value for out of gamut in this case. 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid FloatXFORM(_cmsTRANSFORM* p, 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const void* in, 243d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann void* out, 244d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number PixelsPerLine, 245d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number LineCount, 246d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const cmsStride* Stride) 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* accum; 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* output; 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat32Number fIn[cmsMAXCHANNELS], fOut[cmsMAXCHANNELS]; 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat32Number OutOfGamut; 252d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number i, j, c, strideIn, strideOut; 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 254d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 256d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn = 0; 257d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut = 0; 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 259d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (i = 0; i < LineCount; i++) { 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 261d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = (cmsUInt8Number*)in + strideIn; 262d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = (cmsUInt8Number*)out + strideOut; 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 264d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (j = 0; j < PixelsPerLine; j++) { 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 266d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = p->FromInputFloat(p, fIn, accum, Stride->BytesPerPlaneIn); 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 268d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Any gamut chack to do? 269d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (p->GamutCheck != NULL) { 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 271d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Evaluate gamut marker. 272d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsPipelineEvalFloat(fIn, &OutOfGamut, p->GamutCheck); 273d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 274d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Is current color out of gamut? 275d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (OutOfGamut > 0.0) { 276d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 277d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Certainly, out of gamut 278d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (c = 0; c < cmsMAXCHANNELS; c++) 279d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann fOut[c] = -1.0; 280d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 281d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 282d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann else { 283d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // No, proceed normally 284d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsPipelineEvalFloat(fIn, fOut, p->Lut); 285d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 288d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 289d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // No gamut check at all 290d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsPipelineEvalFloat(fIn, fOut, p->Lut); 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 293d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 294d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = p->ToOutputFloat(p, fOut, output, Stride->BytesPerPlaneOut); 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 297d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn += Stride->BytesPerLineIn; 298d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut += Stride->BytesPerLineOut; 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 300d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid NullFloatXFORM(_cmsTRANSFORM* p, 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const void* in, 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* out, 308d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number PixelsPerLine, 309d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number LineCount, 310d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const cmsStride* Stride) 311d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* accum; 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* output; 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat32Number fIn[cmsMAXCHANNELS]; 316d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number i, j, strideIn, strideOut; 317d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 318d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); 319d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 320d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn = 0; 321d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut = 0; 322d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 323d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (i = 0; i < LineCount; i++) { 324d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 325d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = (cmsUInt8Number*) in + strideIn; 326d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = (cmsUInt8Number*) out + strideOut; 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 328d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (j = 0; j < PixelsPerLine; j++) { 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 330d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = p->FromInputFloat(p, fIn, accum, Stride ->BytesPerPlaneIn); 331d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = p->ToOutputFloat(p, fIn, output, Stride->BytesPerPlaneOut); 332d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 334d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn += Stride->BytesPerLineIn; 335d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut += Stride->BytesPerLineOut; 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 16 bit precision ----------------------------------------------------------------------------------------------------------- 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 341d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Null transformation, only applies formatters. No cache 342d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstatic 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid NullXFORM(_cmsTRANSFORM* p, 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const void* in, 345d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann void* out, 346d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number PixelsPerLine, 347d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number LineCount, 348d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const cmsStride* Stride) 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* accum; 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* output; 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number wIn[cmsMAXCHANNELS]; 353d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number i, j, strideIn, strideOut; 354d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 355d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); 356d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 357d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn = 0; 358d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut = 0; 359d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 360d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (i = 0; i < LineCount; i++) { 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 362d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = (cmsUInt8Number*)in + strideIn; 363d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = (cmsUInt8Number*)out + strideOut; 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 365d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (j = 0; j < PixelsPerLine; j++) { 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 367d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); 368d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = p->ToOutput(p, wIn, output, Stride->BytesPerPlaneOut); 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 370d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 371d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn += Stride->BytesPerLineIn; 372d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut += Stride->BytesPerLineOut; 373d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 374d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// No gamut check, no cache, 16 bits 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid PrecalculatedXFORM(_cmsTRANSFORM* p, 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const void* in, 382d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann void* out, 383d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number PixelsPerLine, 384d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number LineCount, 385d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const cmsStride* Stride) 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register cmsUInt8Number* accum; 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register cmsUInt8Number* output; 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS]; 390d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number i, j, strideIn, strideOut; 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 392d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 394d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn = 0; 395d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut = 0; 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 397d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (i = 0; i < LineCount; i++) { 398d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 399d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = (cmsUInt8Number*)in + strideIn; 400d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = (cmsUInt8Number*)out + strideOut; 401d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 402d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (j = 0; j < PixelsPerLine; j++) { 403d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 404d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); 405d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->Lut->Eval16Fn(wIn, wOut, p->Lut->Data); 406d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut); 407d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 408d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 409d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn += Stride->BytesPerLineIn; 410d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut += Stride->BytesPerLineOut; 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 412d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 416d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Auxiliary: Handle precalculated gamut check. The retrieval of context may be alittle bit slow, but this function is not critical. 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p, 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const cmsUInt16Number wIn[], 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number wOut[]) 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number wOutOfGamut; 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->GamutCheck ->Eval16Fn(wIn, &wOutOfGamut, p ->GamutCheck ->Data); 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (wOutOfGamut >= 1) { 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number i; 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(p->ContextID, AlarmCodesContext); 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < p ->Lut->OutputChannels; i++) { 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wOut[i] = ContextAlarmCodes ->AlarmCodes[i]; 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data); 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 439d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Gamut check, No cache, 16 bits. 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p, 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const void* in, 443d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann void* out, 444d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number PixelsPerLine, 445d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number LineCount, 446d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const cmsStride* Stride) 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* accum; 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* output; 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS]; 451d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number i, j, strideIn, strideOut; 452d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 453d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); 454d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 455d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn = 0; 456d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut = 0; 457d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 458d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (i = 0; i < LineCount; i++) { 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 460d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = (cmsUInt8Number*)in + strideIn; 461d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = (cmsUInt8Number*)out + strideOut; 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 463d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (j = 0; j < PixelsPerLine; j++) { 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 465d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); 466d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann TransformOnePixelWithGamutCheck(p, wIn, wOut); 467d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut); 468d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 469d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 470d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn += Stride->BytesPerLineIn; 471d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut += Stride->BytesPerLineOut; 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 476d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// No gamut check, Cache, 16 bits, 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CachedXFORM(_cmsTRANSFORM* p, 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const void* in, 480d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann void* out, 481d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number PixelsPerLine, 482d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number LineCount, 483d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const cmsStride* Stride) 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* accum; 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* output; 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS]; 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsCACHE Cache; 489d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number i, j, strideIn, strideOut; 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 491d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Empty buffers for quick memcmp 494d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memset(wIn, 0, sizeof(wIn)); 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memset(wOut, 0, sizeof(wOut)); 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get copy of zero cache 498d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memcpy(&Cache, &p->Cache, sizeof(Cache)); 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 500d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn = 0; 501d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut = 0; 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 503d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (i = 0; i < LineCount; i++) { 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 505d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = (cmsUInt8Number*)in + strideIn; 506d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = (cmsUInt8Number*)out + strideOut; 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 508d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (j = 0; j < PixelsPerLine; j++) { 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 510d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 512d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) { 513d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 514d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut)); 515d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 516d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann else { 517d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->Lut->Eval16Fn(wIn, wOut, p->Lut->Data); 518d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 519d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn)); 520d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut)); 521d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 522d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 523d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut); 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 526d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn += Stride->BytesPerLineIn; 527d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut += Stride->BytesPerLineOut; 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// All those nice features together 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CachedXFORMGamutCheck(_cmsTRANSFORM* p, 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const void* in, 535d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann void* out, 536d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number PixelsPerLine, 537d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number LineCount, 538d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const cmsStride* Stride) 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 540d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt8Number* accum; 541d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt8Number* output; 542d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS]; 543d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann _cmsCACHE Cache; 544d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number i, j, strideIn, strideOut; 545d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 546d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann _cmsHandleExtraChannels(p, in, out, PixelsPerLine, LineCount, Stride); 547d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 548d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Empty buffers for quick memcmp 549d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memset(wIn, 0, sizeof(wIn)); 550d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memset(wOut, 0, sizeof(wOut)); 551d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 552d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Get copy of zero cache 553d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memcpy(&Cache, &p->Cache, sizeof(Cache)); 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 555d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn = 0; 556d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut = 0; 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 558d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (i = 0; i < LineCount; i++) { 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 560d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = (cmsUInt8Number*)in + strideIn; 561d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = (cmsUInt8Number*)out + strideOut; 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 563d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (j = 0; j < PixelsPerLine; j++) { 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 565d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann accum = p->FromInput(p, wIn, accum, Stride->BytesPerPlaneIn); 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) { 568d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 569d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut)); 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 572d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann TransformOnePixelWithGamutCheck(p, wIn, wOut); 573d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 574d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn)); 575d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut)); 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 578d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann output = p->ToOutput(p, wOut, output, Stride->BytesPerPlaneOut); 579d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 581d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn += Stride->BytesPerLineIn; 582d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut += Stride->BytesPerLineOut; 583d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 586d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Transform plug-ins ---------------------------------------------------------------------------------------------------- 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// List of used-defined transform factories 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct _cmsTransformCollection_st { 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 591d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann _cmsTransform2Factory Factory; 592d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsBool OldXform; // Factory returns xform function in the old style 593d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov struct _cmsTransformCollection_st *Next; 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} _cmsTransformCollection; 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The linked list head 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov_cmsTransformPluginChunkType _cmsTransformPluginChunk = { NULL }; 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Duplicates the zone of memory used by the plug-in in the new context 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid DupPluginTransformList(struct _cmsContext_struct* ctx, 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const struct _cmsContext_struct* src) 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTransformPluginChunkType newHead = { NULL }; 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTransformCollection* entry; 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTransformCollection* Anterior = NULL; 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTransformPluginChunkType* head = (_cmsTransformPluginChunkType*) src->chunks[TransformPlugin]; 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Walk the list copying all nodes 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (entry = head->TransformCollection; 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry != NULL; 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry = entry ->Next) { 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTransformCollection *newEntry = ( _cmsTransformCollection *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTransformCollection)); 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (newEntry == NULL) 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // We want to keep the linked list order, so this is a little bit tricky 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov newEntry -> Next = NULL; 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Anterior) 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Anterior -> Next = newEntry; 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Anterior = newEntry; 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (newHead.TransformCollection == NULL) 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov newHead.TransformCollection = newEntry; 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTransformPluginChunkType)); 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 636d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Allocates memory for transform plugin factory 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _cmsAllocTransformPluginChunk(struct _cmsContext_struct* ctx, 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const struct _cmsContext_struct* src) 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (src != NULL) { 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Copy all linked list 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DupPluginTransformList(ctx, src); 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static _cmsTransformPluginChunkType TransformPluginChunkType = { NULL }; 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ctx ->chunks[TransformPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TransformPluginChunkType, sizeof(_cmsTransformPluginChunkType)); 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 651d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Adaptor for old versions of plug-in 652d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstatic 653d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid _cmsTransform2toTransformAdaptor(struct _cmstransform_struct *CMMcargo, 654d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const void* InputBuffer, 655d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann void* OutputBuffer, 656d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number PixelsPerLine, 657d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number LineCount, 658d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann const cmsStride* Stride) 659d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann{ 660d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 661d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsUInt32Number i, strideIn, strideOut; 662d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 663d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann _cmsHandleExtraChannels(CMMcargo, InputBuffer, OutputBuffer, PixelsPerLine, LineCount, Stride); 664d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 665d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn = 0; 666d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut = 0; 667d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 668d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (i = 0; i < LineCount; i++) { 669d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 670d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann void *accum = (cmsUInt8Number*)InputBuffer + strideIn; 671d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann void *output = (cmsUInt8Number*)OutputBuffer + strideOut; 672d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 673d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann CMMcargo->OldXform(CMMcargo, accum, output, PixelsPerLine, Stride->BytesPerPlaneIn); 674d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 675d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideIn += Stride->BytesPerLineIn; 676d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann strideOut += Stride->BytesPerLineOut; 677d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 678d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann} 679d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Register new ways to transform 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool _cmsRegisterTransformPlugin(cmsContext ContextID, cmsPluginBase* Data) 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPluginTransform* Plugin = (cmsPluginTransform*) Data; 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTransformCollection* fl; 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID,TransformPlugin); 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Data == NULL) { 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Free the chain. Memory is safely freed at exit 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ctx->TransformCollection = NULL; 693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Factory callback is required 697d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (Plugin->factories.xform == NULL) return FALSE; 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fl = (_cmsTransformCollection*) _cmsPluginMalloc(ContextID, sizeof(_cmsTransformCollection)); 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (fl == NULL) return FALSE; 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 703d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Check for full xform plug-ins previous to 2.8, we would need an adapter in that case 704d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (Plugin->base.ExpectedVersion < 2080) { 705d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 706d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann fl->OldXform = TRUE; 707d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 708d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann else 709d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann fl->OldXform = FALSE; 710d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Copy the parameters 712d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann fl->Factory = Plugin->factories.xform; 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Keep linked list 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fl ->Next = ctx->TransformCollection; 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ctx->TransformCollection = fl; 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // All is ok 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT _cmsSetTransformUserData(struct _cmstransform_struct *CMMcargo, void* ptr, _cmsFreeUserDataFn FreePrivateDataFn) 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAssert(CMMcargo != NULL); 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CMMcargo ->UserData = ptr; 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CMMcargo ->FreeUserData = FreePrivateDataFn; 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// returns the pointer defined by the plug-in to store private data 731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid * CMSEXPORT _cmsGetTransformUserData(struct _cmstransform_struct *CMMcargo) 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAssert(CMMcargo != NULL); 734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return CMMcargo ->UserData; 735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// returns the current formatters 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT _cmsGetTransformFormatters16(struct _cmstransform_struct *CMMcargo, cmsFormatter16* FromInput, cmsFormatter16* ToOutput) 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAssert(CMMcargo != NULL); 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (FromInput) *FromInput = CMMcargo ->FromInput; 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ToOutput) *ToOutput = CMMcargo ->ToOutput; 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT _cmsGetTransformFormattersFloat(struct _cmstransform_struct *CMMcargo, cmsFormatterFloat* FromInput, cmsFormatterFloat* ToOutput) 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAssert(CMMcargo != NULL); 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (FromInput) *FromInput = CMMcargo ->FromInputFloat; 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ToOutput) *ToOutput = CMMcargo ->ToOutputFloat; 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Allocate transform struct and set it to defaults. Ask the optimization plug-in about if those formats are proper 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// for separated transforms. If this is the case, 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov_cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut, 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags) 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTransformPluginChunkType* ctx = ( _cmsTransformPluginChunkType*) _cmsContextGetClientChunk(ContextID, TransformPlugin); 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTransformCollection* Plugin; 761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 762d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Allocate needed memory 763d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann _cmsTRANSFORM* p = (_cmsTRANSFORM*)_cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM)); 764d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (!p) { 765d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann cmsPipelineFree(lut); 766d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return NULL; 767d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 768d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 769d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Store the proposed pipeline 770d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->Lut = lut; 771d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 772d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Let's see if any plug-in want to do the transform by itself 773d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (p->Lut != NULL) { 774d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 775d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (Plugin = ctx->TransformCollection; 776d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann Plugin != NULL; 777d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann Plugin = Plugin->Next) { 778d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 779d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (Plugin->Factory(&p->xform, &p->UserData, &p->FreeUserData, &p->Lut, InputFormat, OutputFormat, dwFlags)) { 780d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 781d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Last plugin in the declaration order takes control. We just keep 782d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // the original parameters as a logging. 783d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Note that cmsFLAGS_CAN_CHANGE_FORMATTER is not set, so by default 784d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // an optimized transform is not reusable. The plug-in can, however, change 785d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // the flags and make it suitable. 786d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 787d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->ContextID = ContextID; 788d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->InputFormat = *InputFormat; 789d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->OutputFormat = *OutputFormat; 790d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->dwOriginalFlags = *dwFlags; 791d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 792d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Fill the formatters just in case the optimized routine is interested. 793d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // No error is thrown if the formatter doesn't exist. It is up to the optimization 794d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // factory to decide what to do in those cases. 795d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; 796d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; 797d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat; 798d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat; 799d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 800d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Save the day? 801d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann if (Plugin->OldXform) { 802d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->OldXform = (_cmsTransformFn) p->xform; 803d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p->xform = _cmsTransform2toTransformAdaptor; 804d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 805d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 806d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann return p; 807d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 808d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 809d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 810d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Not suitable for the transform plug-in, let's check the pipeline plug-in 811d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann _cmsOptimizePipeline(ContextID, &p->Lut, Intent, InputFormat, OutputFormat, dwFlags); 812d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Check whatever this is a true floating point transform 815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (_cmsFormatterIsFloat(*InputFormat) && _cmsFormatterIsFloat(*OutputFormat)) { 816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get formatter function always return a valid union, but the contents of this union may be NULL. 818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat; 819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat; 820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER; 821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (p ->FromInputFloat == NULL || p ->ToOutputFloat == NULL) { 823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format"); 8254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmsDeleteTransform(p); 826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (*dwFlags & cmsFLAGS_NULLTRANSFORM) { 830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->xform = NullFloatXFORM; 832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 834d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann // Float transforms don't use cache, always are non-NULL 835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->xform = FloatXFORM; 836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (*InputFormat == 0 && *OutputFormat == 0) { 842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->FromInput = p ->ToOutput = NULL; 843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER; 844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int BytesPerPixelInput; 848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; 850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; 851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (p ->FromInput == NULL || p ->ToOutput == NULL) { 853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format"); 8554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann cmsDeleteTransform(p); 856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BytesPerPixelInput = T_BYTES(p ->InputFormat); 860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (BytesPerPixelInput == 0 || BytesPerPixelInput >= 2) 861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER; 862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (*dwFlags & cmsFLAGS_NULLTRANSFORM) { 866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->xform = NullXFORM; 868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (*dwFlags & cmsFLAGS_NOCACHE) { 871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (*dwFlags & cmsFLAGS_GAMUTCHECK) 873d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p ->xform = PrecalculatedXFORMGamutCheck; // Gamut check, no cache 8744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 875d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p ->xform = PrecalculatedXFORM; // No cache, no gamut check 876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (*dwFlags & cmsFLAGS_GAMUTCHECK) 880d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p ->xform = CachedXFORMGamutCheck; // Gamut check, cache 8814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else 882d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann p ->xform = CachedXFORM; // No gamut check, cache 883d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->InputFormat = *InputFormat; 889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->OutputFormat = *OutputFormat; 890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->dwOriginalFlags = *dwFlags; 891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->ContextID = ContextID; 892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p ->UserData = NULL; 893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return p; 894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 897ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool GetXFormColorSpaces(int nProfiles, cmsHPROFILE hProfiles[], cmsColorSpaceSignature* Input, cmsColorSpaceSignature* Output) 898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsColorSpaceSignature ColorSpaceIn, ColorSpaceOut; 900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsColorSpaceSignature PostColorSpace; 901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i; 902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nProfiles <= 0) return FALSE; 904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (hProfiles[0] == NULL) return FALSE; 905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *Input = PostColorSpace = cmsGetColorSpace(hProfiles[0]); 907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nProfiles; i++) { 909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsProfileClassSignature cls; 911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHPROFILE hProfile = hProfiles[i]; 912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int lIsInput = (PostColorSpace != cmsSigXYZData) && 914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (PostColorSpace != cmsSigLabData); 915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (hProfile == NULL) return FALSE; 917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cls = cmsGetDeviceClass(hProfile); 919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (cls == cmsSigNamedColorClass) { 921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ColorSpaceIn = cmsSig1colorData; 923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ColorSpaceOut = (nProfiles > 1) ? cmsGetPCS(hProfile) : cmsGetColorSpace(hProfile); 924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (lIsInput || (cls == cmsSigLinkClass)) { 927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ColorSpaceIn = cmsGetColorSpace(hProfile); 929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ColorSpaceOut = cmsGetPCS(hProfile); 930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ColorSpaceIn = cmsGetPCS(hProfile); 934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ColorSpaceOut = cmsGetColorSpace(hProfile); 935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (i==0) 938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *Input = ColorSpaceIn; 939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PostColorSpace = ColorSpaceOut; 941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *Output = PostColorSpace; 944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Check colorspace 949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 950ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool IsProperColorSpace(cmsColorSpaceSignature Check, cmsUInt32Number dwFormat) 951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int Space1 = T_COLORSPACE(dwFormat); 953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int Space2 = _cmsLCMScolorSpace(Check); 954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Space1 == PT_ANY) return TRUE; 956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Space1 == Space2) return TRUE; 957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Space1 == PT_LabV2 && Space2 == PT_Lab) return TRUE; 959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Space1 == PT_Lab && Space2 == PT_LabV2) return TRUE; 960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ---------------------------------------------------------------------------------------------------------------- 965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 966d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Jun-21-2000: Some profiles (those that comes with W2K) comes 967d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// with the media white (media black?) x 100. Add a sanity check 968d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 969d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstatic 970d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid NormalizeXYZ(cmsCIEXYZ* Dest) 971d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann{ 972d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann while (Dest -> X > 2. && 973d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann Dest -> Y > 2. && 974d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann Dest -> Z > 2.) { 975d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 976d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann Dest -> X /= 10.; 977d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann Dest -> Y /= 10.; 978d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann Dest -> Z /= 10.; 979d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann } 980d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann} 981d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid SetWhitePoint(cmsCIEXYZ* wtPt, const cmsCIEXYZ* src) 984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (src == NULL) { 986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wtPt ->X = cmsD50X; 987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wtPt ->Y = cmsD50Y; 988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wtPt ->Z = cmsD50Z; 989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wtPt ->X = src->X; 992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wtPt ->Y = src->Y; 993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wtPt ->Z = src->Z; 994d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann 995d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann NormalizeXYZ(wtPt); 996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// New to lcms 2.0 -- have all parameters available. 1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsHTRANSFORM CMSEXPORT cmsCreateExtendedTransform(cmsContext ContextID, 1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[], 1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsBool BPC[], 1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Intents[], 1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number AdaptationStates[], 1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHPROFILE hGamutProfile, 1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nGamutPCSposition, 1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number InputFormat, 1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number OutputFormat, 1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number dwFlags) 1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTRANSFORM* xform; 1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsColorSpaceSignature EntryColorSpace; 1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsColorSpaceSignature ExitColorSpace; 1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline* Lut; 1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number LastIntent = Intents[nProfiles-1]; 1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // If it is a fake transform 1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (dwFlags & cmsFLAGS_NULLTRANSFORM) 1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return AllocEmptyTransform(ContextID, NULL, INTENT_PERCEPTUAL, &InputFormat, &OutputFormat, &dwFlags); 1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // If gamut check is requested, make sure we have a gamut profile 1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (dwFlags & cmsFLAGS_GAMUTCHECK) { 1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (hGamutProfile == NULL) dwFlags &= ~cmsFLAGS_GAMUTCHECK; 1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // On floating point transforms, inhibit cache 1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (_cmsFormatterIsFloat(InputFormat) || _cmsFormatterIsFloat(OutputFormat)) 1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dwFlags |= cmsFLAGS_NOCACHE; 1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Mark entry/exit spaces 1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!GetXFormColorSpaces(nProfiles, hProfiles, &EntryColorSpace, &ExitColorSpace)) { 1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(ContextID, cmsERROR_NULL, "NULL input profiles on transform"); 1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Check if proper colorspaces 1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!IsProperColorSpace(EntryColorSpace, InputFormat)) { 1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "Wrong input color space on transform"); 1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!IsProperColorSpace(ExitColorSpace, OutputFormat)) { 1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "Wrong output color space on transform"); 1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Create a pipeline with all transformations 1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Lut = _cmsLinkProfiles(ContextID, nProfiles, Intents, hProfiles, BPC, AdaptationStates, dwFlags); 1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Lut == NULL) { 1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Couldn't link the profiles"); 1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Check channel count 1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ((cmsChannelsOf(EntryColorSpace) != cmsPipelineInputChannels(Lut)) || 1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (cmsChannelsOf(ExitColorSpace) != cmsPipelineOutputChannels(Lut))) { 1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipelineFree(Lut); 1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Channel count doesn't match. Profile is corrupted"); 1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // All seems ok 1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform = AllocEmptyTransform(ContextID, Lut, LastIntent, &InputFormat, &OutputFormat, &dwFlags); 1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (xform == NULL) { 1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Keep values 1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform ->EntryColorSpace = EntryColorSpace; 1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform ->ExitColorSpace = ExitColorSpace; 1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform ->RenderingIntent = Intents[nProfiles-1]; 1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Take white points 1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SetWhitePoint(&xform->EntryWhitePoint, (cmsCIEXYZ*) cmsReadTag(hProfiles[0], cmsSigMediaWhitePointTag)); 1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SetWhitePoint(&xform->ExitWhitePoint, (cmsCIEXYZ*) cmsReadTag(hProfiles[nProfiles-1], cmsSigMediaWhitePointTag)); 1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Create a gamut check LUT if requested 1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (hGamutProfile != NULL && (dwFlags & cmsFLAGS_GAMUTCHECK)) 1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform ->GamutCheck = _cmsCreateGamutCheckPipeline(ContextID, hProfiles, 1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BPC, Intents, 1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov AdaptationStates, 1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nGamutPCSposition, 1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov hGamutProfile); 1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Try to read input and output colorant table 1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (cmsIsTag(hProfiles[0], cmsSigColorantTableTag)) { 1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Input table can only come in this way. 1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform ->InputColorant = cmsDupNamedColorList((cmsNAMEDCOLORLIST*) cmsReadTag(hProfiles[0], cmsSigColorantTableTag)); 1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Output is a little bit more complex. 1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (cmsGetDeviceClass(hProfiles[nProfiles-1]) == cmsSigLinkClass) { 1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // This tag may exist only on devicelink profiles. 1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (cmsIsTag(hProfiles[nProfiles-1], cmsSigColorantTableOutTag)) { 1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // It may be NULL if error 1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform ->OutputColorant = cmsDupNamedColorList((cmsNAMEDCOLORLIST*) cmsReadTag(hProfiles[nProfiles-1], cmsSigColorantTableOutTag)); 1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (cmsIsTag(hProfiles[nProfiles-1], cmsSigColorantTableTag)) { 1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform -> OutputColorant = cmsDupNamedColorList((cmsNAMEDCOLORLIST*) cmsReadTag(hProfiles[nProfiles-1], cmsSigColorantTableTag)); 1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Store the sequence of profiles 1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (dwFlags & cmsFLAGS_KEEP_SEQUENCE) { 1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform ->Sequence = _cmsCompileProfileSequence(ContextID, nProfiles, hProfiles); 1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform ->Sequence = NULL; 1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // If this is a cached transform, init first value, which is zero (16 bits only) 1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!(dwFlags & cmsFLAGS_NOCACHE)) { 1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memset(&xform ->Cache.CacheIn, 0, sizeof(xform ->Cache.CacheIn)); 1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (xform ->GamutCheck != NULL) { 1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TransformOnePixelWithGamutCheck(xform, xform ->Cache.CacheIn, xform->Cache.CacheOut); 1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform ->Lut ->Eval16Fn(xform ->Cache.CacheIn, xform->Cache.CacheOut, xform -> Lut->Data); 1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (cmsHTRANSFORM) xform; 1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Multiprofile transforms: Gamut check is not available here, as it is unclear from which profile the gamut comes. 1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsHTRANSFORM CMSEXPORT cmsCreateMultiprofileTransformTHR(cmsContext ContextID, 1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHPROFILE hProfiles[], 1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nProfiles, 1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number InputFormat, 1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number OutputFormat, 1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Intent, 1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number dwFlags) 1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsBool BPC[256]; 1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Intents[256]; 1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number AdaptationStates[256]; 1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nProfiles <= 0 || nProfiles > 255) { 1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(ContextID, cmsERROR_RANGE, "Wrong number of profiles. 1..255 expected, %d found.", nProfiles); 1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nProfiles; i++) { 1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BPC[i] = dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION ? TRUE : FALSE; 1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Intents[i] = Intent; 1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov AdaptationStates[i] = cmsSetAdaptationStateTHR(ContextID, -1); 1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsCreateExtendedTransform(ContextID, nProfiles, hProfiles, BPC, Intents, AdaptationStates, NULL, 0, InputFormat, OutputFormat, dwFlags); 1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsHTRANSFORM CMSEXPORT cmsCreateMultiprofileTransform(cmsHPROFILE hProfiles[], 1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nProfiles, 1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number InputFormat, 1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number OutputFormat, 1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Intent, 1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number dwFlags) 1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nProfiles <= 0 || nProfiles > 255) { 1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(NULL, cmsERROR_RANGE, "Wrong number of profiles. 1..255 expected, %d found.", nProfiles); 1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsCreateMultiprofileTransformTHR(cmsGetProfileContextID(hProfiles[0]), 1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov hProfiles, 1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nProfiles, 1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov InputFormat, 1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov OutputFormat, 1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Intent, 1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dwFlags); 1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsHTRANSFORM CMSEXPORT cmsCreateTransformTHR(cmsContext ContextID, 1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHPROFILE Input, 1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number InputFormat, 1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHPROFILE Output, 1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number OutputFormat, 1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Intent, 1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number dwFlags) 1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHPROFILE hArray[2]; 1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov hArray[0] = Input; 1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov hArray[1] = Output; 1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsCreateMultiprofileTransformTHR(ContextID, hArray, Output == NULL ? 1 : 2, InputFormat, OutputFormat, Intent, dwFlags); 1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCMSAPI cmsHTRANSFORM CMSEXPORT cmsCreateTransform(cmsHPROFILE Input, 1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number InputFormat, 1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHPROFILE Output, 1214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number OutputFormat, 1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Intent, 1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number dwFlags) 1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsCreateTransformTHR(cmsGetProfileContextID(Input), Input, InputFormat, Output, OutputFormat, Intent, dwFlags); 1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsHTRANSFORM CMSEXPORT cmsCreateProofingTransformTHR(cmsContext ContextID, 1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHPROFILE InputProfile, 1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number InputFormat, 1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHPROFILE OutputProfile, 1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number OutputFormat, 1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHPROFILE ProofingProfile, 1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nIntent, 1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number ProofingIntent, 1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number dwFlags) 1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHPROFILE hArray[4]; 1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Intents[4]; 1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsBool BPC[4]; 1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number Adaptation[4]; 1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsBool DoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION) ? TRUE : FALSE; 1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov hArray[0] = InputProfile; hArray[1] = ProofingProfile; hArray[2] = ProofingProfile; hArray[3] = OutputProfile; 1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Intents[0] = nIntent; Intents[1] = nIntent; Intents[2] = INTENT_RELATIVE_COLORIMETRIC; Intents[3] = ProofingIntent; 1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BPC[0] = DoBPC; BPC[1] = DoBPC; BPC[2] = 0; BPC[3] = 0; 1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Adaptation[0] = Adaptation[1] = Adaptation[2] = Adaptation[3] = cmsSetAdaptationStateTHR(ContextID, -1); 1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!(dwFlags & (cmsFLAGS_SOFTPROOFING|cmsFLAGS_GAMUTCHECK))) 1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsCreateTransformTHR(ContextID, InputProfile, InputFormat, OutputProfile, OutputFormat, nIntent, dwFlags); 1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsCreateExtendedTransform(ContextID, 4, hArray, BPC, Intents, Adaptation, 1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ProofingProfile, 1, InputFormat, OutputFormat, dwFlags); 1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsHTRANSFORM CMSEXPORT cmsCreateProofingTransform(cmsHPROFILE InputProfile, 1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number InputFormat, 1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHPROFILE OutputProfile, 1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number OutputFormat, 1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHPROFILE ProofingProfile, 1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nIntent, 1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number ProofingIntent, 1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number dwFlags) 1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsCreateProofingTransformTHR(cmsGetProfileContextID(InputProfile), 1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov InputProfile, 1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov InputFormat, 1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov OutputProfile, 1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov OutputFormat, 1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ProofingProfile, 1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nIntent, 1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ProofingIntent, 1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dwFlags); 1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Grab the ContextID from an open transform. Returns NULL if a NULL transform is passed 1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsContext CMSEXPORT cmsGetTransformContextID(cmsHTRANSFORM hTransform) 1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform; 1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (xform == NULL) return NULL; 1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return xform -> ContextID; 1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Grab the input/output formats 1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsUInt32Number CMSEXPORT cmsGetTransformInputFormat(cmsHTRANSFORM hTransform) 1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform; 1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (xform == NULL) return 0; 1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return xform->InputFormat; 1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsUInt32Number CMSEXPORT cmsGetTransformOutputFormat(cmsHTRANSFORM hTransform) 1294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform; 1296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (xform == NULL) return 0; 1298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return xform->OutputFormat; 1299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// For backwards compatibility 1302ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform, 1303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number InputFormat, 1304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number OutputFormat) 1305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform; 1307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFormatter16 FromInput, ToOutput; 1308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // We only can afford to change formatters if previous transform is at least 16 bits 1311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!(xform ->dwOriginalFlags & cmsFLAGS_CAN_CHANGE_FORMATTER)) { 1312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(xform ->ContextID, cmsERROR_NOT_SUITABLE, "cmsChangeBuffersFormat works only on transforms created originally with at least 16 bits of precision"); 1314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 1315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FromInput = _cmsGetFormatter(xform->ContextID, InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; 1318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ToOutput = _cmsGetFormatter(xform->ContextID, OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; 1319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (FromInput == NULL || ToOutput == NULL) { 1321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(xform -> ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format"); 1323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 1324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform ->InputFormat = InputFormat; 1327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform ->OutputFormat = OutputFormat; 1328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform ->FromInput = FromInput; 1329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xform ->ToOutput = ToOutput; 1330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 1331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1332