1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//--------------------------------------------------------------------------------- 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Little Color Management System 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright (c) 1998-2014 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// Tag Serialization ----------------------------------------------------------------------------- 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This file implements every single tag and tag type as described in the ICC spec. Some types 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// have been deprecated, like ncl and Data. There is no implementation for those types as there 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// are no profiles holding them. The programmer can also extend this list by defining his own types 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// by using the appropiate plug-in. There are three types of plug ins regarding that. First type 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// allows to define new tags using any existing type. Next plug-in type allows to define new types 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// and the third one is very specific: allows to extend the number of elements in the multiprocessing 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// elements special type. 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//-------------------------------------------------------------------------------------------------- 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Some broken types 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define cmsCorbisBrokenXYZtype ((cmsTagTypeSignature) 0x17A505B8) 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define cmsMonacoBrokenCurveType ((cmsTagTypeSignature) 0x9478ee00) 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This is the linked list that keeps track of the defined types 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct _cmsTagTypeLinkedList_st { 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsTagTypeHandler Handler; 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov struct _cmsTagTypeLinkedList_st* Next; 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} _cmsTagTypeLinkedList; 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Some macros to define callbacks. 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define READ_FN(x) Type_##x##_Read 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define WRITE_FN(x) Type_##x##_Write 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FREE_FN(x) Type_##x##_Free 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define DUP_FN(x) Type_##x##_Dup 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Helper macro to define a handler. Callbacks do have a fixed naming convention. 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TYPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), DUP_FN(x), FREE_FN(x), NULL, 0 } 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Helper macro to define a MPE handler. Callbacks do have a fixed naming convention 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TYPE_MPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), GenericMPEdup, GenericMPEfree, NULL, 0 } 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Register a new type handler. This routine is shared between normal types and MPE. LinkedList points to the optional list head 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsMemoryClient pos) 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPluginTagType* Plugin = (cmsPluginTagType*) Data; 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(id, pos); 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagTypeLinkedList *pt; 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Calling the function with NULL as plug-in would unregister the plug in. 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Data == NULL) { 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // There is no need to set free the memory, as pool is destroyed as a whole. 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ctx ->TagTypes = NULL; 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Registering happens in plug-in memory pool. 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt = (_cmsTagTypeLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagTypeLinkedList)); 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pt == NULL) return FALSE; 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt ->Handler = Plugin ->Handler; 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt ->Next = ctx ->TagTypes; 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ctx ->TagTypes = pt; 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Return handler for a given type or NULL if not found. Shared between normal types and MPE. It first tries the additons 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// made by plug-ins and then the built-in defaults. 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* PluginLinkedList, _cmsTagTypeLinkedList* DefaultLinkedList) 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagTypeLinkedList* pt; 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (pt = PluginLinkedList; 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt != NULL; 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt = pt ->Next) { 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (sig == pt -> Handler.Signature) return &pt ->Handler; 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (pt = DefaultLinkedList; 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt != NULL; 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt = pt ->Next) { 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (sig == pt -> Handler.Signature) return &pt ->Handler; 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Auxiliar to convert UTF-32 to UTF-16 in some cases 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t* Array) 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAssert(io != NULL); 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAssert(!(Array == NULL && n > 0)); 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < n; i++) { 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) Array[i])) return FALSE; 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Auxiliar to read an array of wchar_t 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array) 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number tmp; 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAssert(io != NULL); 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < n; i++) { 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Array != NULL) { 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &tmp)) return FALSE; 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Array[i] = (wchar_t) tmp; 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, NULL)) return FALSE; 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// To deal with position tables 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef cmsBool (* PositionTableEntryFn)(struct _cms_typehandler_struct* self, 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsIOHANDLER* io, 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* Cargo, 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number n, 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number SizeOfTag); 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Helper function to deal with position tables as decribed in ICC spec 4.3 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// A table of n elements is readed, where first comes n records containing offsets and sizes and 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// then a block containing the data itself. This allows to reuse same data in more than one entry 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool ReadPositionTable(struct _cms_typehandler_struct* self, 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsIOHANDLER* io, 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Count, 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number BaseOffset, 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void *Cargo, 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PositionTableEntryFn ElementFn) 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL; 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Let's take the offsets to each element 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementOffsets == NULL) goto Error; 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ElementSizes = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementSizes == NULL) goto Error; 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Count; i++) { 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &ElementOffsets[i])) goto Error; 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &ElementSizes[i])) goto Error; 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ElementOffsets[i] += BaseOffset; 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Seek to each element and read it 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Count; i++) { 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io -> Seek(io, ElementOffsets[i])) goto Error; 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // This is the reader callback 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ElementFn(self, io, Cargo, i, ElementSizes[i])) goto Error; 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Success 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementOffsets != NULL) _cmsFree(io ->ContextID, ElementOffsets); 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementSizes != NULL) _cmsFree(io ->ContextID, ElementSizes); 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementOffsets != NULL) _cmsFree(io ->ContextID, ElementOffsets); 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementSizes != NULL) _cmsFree(io ->ContextID, ElementSizes); 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Same as anterior, but for write position tables 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool WritePositionTable(struct _cms_typehandler_struct* self, 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsIOHANDLER* io, 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number SizeOfTag, 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Count, 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number BaseOffset, 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void *Cargo, 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PositionTableEntryFn ElementFn) 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number DirectoryPos, CurrentPos, Before; 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL; 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Create table 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementOffsets == NULL) goto Error; 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ElementSizes = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementSizes == NULL) goto Error; 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Keep starting position of curve offsets 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DirectoryPos = io ->Tell(io); 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write a fake directory to be filled latter on 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Count; i++) { 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) goto Error; // Offset 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) goto Error; // size 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write each element. Keep track of the size as well. 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Count; i++) { 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Before = io ->Tell(io); 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ElementOffsets[i] = Before - BaseOffset; 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Callback to write... 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ElementFn(self, io, Cargo, i, SizeOfTag)) goto Error; 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Now the size 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ElementSizes[i] = io ->Tell(io) - Before; 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write the directory 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CurrentPos = io ->Tell(io); 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Seek(io, DirectoryPos)) goto Error; 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Count; i++) { 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, ElementOffsets[i])) goto Error; 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, ElementSizes[i])) goto Error; 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Seek(io, CurrentPos)) goto Error; 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementOffsets != NULL) _cmsFree(io ->ContextID, ElementOffsets); 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementSizes != NULL) _cmsFree(io ->ContextID, ElementSizes); 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementOffsets != NULL) _cmsFree(io ->ContextID, ElementOffsets); 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementSizes != NULL) _cmsFree(io ->ContextID, ElementSizes); 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type XYZ. Only one value is allowed 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//The XYZType contains an array of three encoded values for the XYZ tristimulus 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//values. Tristimulus values must be non-negative. The signed encoding allows for 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//implementation optimizations by minimizing the number of fixed formats. 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_XYZ_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsCIEXYZ* xyz; 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xyz = (cmsCIEXYZ*) _cmsMallocZero(self ->ContextID, sizeof(cmsCIEXYZ)); 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (xyz == NULL) return NULL; 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadXYZNumber(io, xyz)) { 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, xyz); 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) xyz; 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_XYZ_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsWriteXYZNumber(io, (cmsCIEXYZ*) Ptr); 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_XYZ_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsCIEXYZ)); 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_XYZ_Free(struct _cms_typehandler_struct* self, void *Ptr) 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Ptr); 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsTagTypeSignature DecideXYZtype(cmsFloat64Number ICCVersion, const void *Data) 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsSigXYZType; 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(ICCVersion); 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(Data); 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type chromaticity. Only one value is allowed 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The chromaticity tag type provides basic chromaticity data and type of 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// phosphors or colorants of a monitor to applications and utilities. 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_Chromaticity_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsCIExyYTRIPLE* chrm; 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number nChans, Table; 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov chrm = (cmsCIExyYTRIPLE*) _cmsMallocZero(self ->ContextID, sizeof(cmsCIExyYTRIPLE)); 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (chrm == NULL) return NULL; 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &nChans)) goto Error; 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Let's recover from a bug introduced in early versions of lcms1 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nChans == 0 && SizeOfTag == 32) { 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, NULL)) goto Error; 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &nChans)) goto Error; 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nChans != 3) goto Error; 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &Table)) goto Error; 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &chrm ->Red.x)) goto Error; 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &chrm ->Red.y)) goto Error; 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov chrm ->Red.Y = 1.0; 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &chrm ->Green.x)) goto Error; 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &chrm ->Green.y)) goto Error; 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov chrm ->Green.Y = 1.0; 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &chrm ->Blue.x)) goto Error; 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &chrm ->Blue.y)) goto Error; 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov chrm ->Blue.Y = 1.0; 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) chrm; 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, (void*) chrm); 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool SaveOneChromaticity(cmsFloat64Number x, cmsFloat64Number y, cmsIOHANDLER* io) 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, _cmsDoubleTo15Fixed16(x))) return FALSE; 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, _cmsDoubleTo15Fixed16(y))) return FALSE; 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_Chromaticity_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsCIExyYTRIPLE* chrm = (cmsCIExyYTRIPLE*) Ptr; 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 3)) return FALSE; // nChannels 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 0)) return FALSE; // Table 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!SaveOneChromaticity(chrm -> Red.x, chrm -> Red.y, io)) return FALSE; 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!SaveOneChromaticity(chrm -> Green.x, chrm -> Green.y, io)) return FALSE; 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!SaveOneChromaticity(chrm -> Blue.x, chrm -> Blue.y, io)) return FALSE; 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_Chromaticity_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsCIExyYTRIPLE)); 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_Chromaticity_Free(struct _cms_typehandler_struct* self, void* Ptr) 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Ptr); 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigColorantOrderType 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This is an optional tag which specifies the laydown order in which colorants will 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// be printed on an n-colorant device. The laydown order may be the same as the 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// channel generation order listed in the colorantTableTag or the channel order of a 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// colour space such as CMYK, in which case this tag is not needed. When this is not 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// the case (for example, ink-towers sometimes use the order KCMY), this tag may be 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// used to specify the laydown order of the colorants. 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_ColorantOrderType_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* ColorantOrder; 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Count; 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &Count)) return NULL; 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Count > cmsMAXCHANNELS) return NULL; 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ColorantOrder = (cmsUInt8Number*) _cmsCalloc(self ->ContextID, cmsMAXCHANNELS, sizeof(cmsUInt8Number)); 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ColorantOrder == NULL) return NULL; 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // We use FF as end marker 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memset(ColorantOrder, 0xFF, cmsMAXCHANNELS * sizeof(cmsUInt8Number)); 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io ->Read(io, ColorantOrder, sizeof(cmsUInt8Number), Count) != Count) { 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, (void*) ColorantOrder); 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) ColorantOrder; 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_ColorantOrderType_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* ColorantOrder = (cmsUInt8Number*) Ptr; 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, sz, Count; 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get the length 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (Count=i=0; i < cmsMAXCHANNELS; i++) { 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ColorantOrder[i] != 0xFF) Count++; 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, Count)) return FALSE; 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sz = Count * sizeof(cmsUInt8Number); 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io -> Write(io, sz, ColorantOrder)) return FALSE; 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_ColorantOrderType_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsDupMem(self ->ContextID, Ptr, cmsMAXCHANNELS * sizeof(cmsUInt8Number)); 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_ColorantOrderType_Free(struct _cms_typehandler_struct* self, void* Ptr) 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Ptr); 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigS15Fixed16ArrayType 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This type represents an array of generic 4-byte/32-bit fixed point quantity. 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The number of values is determined from the size of the tag. 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_S15Fixed16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number* array_double; 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, n; 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n = SizeOfTag / sizeof(cmsUInt32Number); 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov array_double = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, n, sizeof(cmsFloat64Number)); 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (array_double == NULL) return NULL; 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < n; i++) { 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &array_double[i])) { 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, array_double); 536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = n; 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) array_double; 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_S15Fixed16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number* Value = (cmsFloat64Number*) Ptr; 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nItems; i++) { 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, Value[i])) return FALSE; 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_S15Fixed16_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsDupMem(self ->ContextID, Ptr, n * sizeof(cmsFloat64Number)); 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_S15Fixed16_Free(struct _cms_typehandler_struct* self, void* Ptr) 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Ptr); 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigU16Fixed16ArrayType 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This type represents an array of generic 4-byte/32-bit quantity. 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The number of values is determined from the size of the tag. 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_U16Fixed16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number* array_double; 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number v; 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, n; 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n = SizeOfTag / sizeof(cmsUInt32Number); 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov array_double = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, n, sizeof(cmsFloat64Number)); 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (array_double == NULL) return NULL; 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < n; i++) { 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &v)) { 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, (void*) array_double); 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Convert to cmsFloat64Number 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov array_double[i] = (cmsFloat64Number) (v / 65536.0); 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = n; 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) array_double; 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_U16Fixed16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number* Value = (cmsFloat64Number*) Ptr; 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nItems; i++) { 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number v = (cmsUInt32Number) floor(Value[i]*65536.0 + 0.5); 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, v)) return FALSE; 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_U16Fixed16_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsDupMem(self ->ContextID, Ptr, n * sizeof(cmsFloat64Number)); 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_U16Fixed16_Free(struct _cms_typehandler_struct* self, void* Ptr) 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Ptr); 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigSignatureType 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The signatureType contains a four-byte sequence, Sequences of less than four 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// characters are padded at the end with spaces, 20h. 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Typically this type is used for registered tags that can be displayed on many 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// development systems as a sequence of four characters. 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_Signature_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignature* SigPtr = (cmsSignature*) _cmsMalloc(self ->ContextID, sizeof(cmsSignature)); 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SigPtr == NULL) return NULL; 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, SigPtr)) return NULL; 654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SigPtr; 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_Signature_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignature* SigPtr = (cmsSignature*) Ptr; 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsWriteUInt32Number(io, *SigPtr); 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_Signature_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsDupMem(self ->ContextID, Ptr, n * sizeof(cmsSignature)); 676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_Signature_Free(struct _cms_typehandler_struct* self, void* Ptr) 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Ptr); 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigTextType 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The textType is a simple text structure that contains a 7-bit ASCII text string. 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The length of the string is obtained by subtracting 8 from the element size portion 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// of the tag itself. This string must be terminated with a 00h byte. 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_Text_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* Text = NULL; 697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLU* mlu = NULL; 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Create a container 700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mlu = cmsMLUalloc(self ->ContextID, 1); 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mlu == NULL) return NULL; 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // We need to store the "\0" at the end, so +1 706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag == UINT_MAX) goto Error; 707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Text = (char*) _cmsMalloc(self ->ContextID, SizeOfTag + 1); 709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Text == NULL) goto Error; 710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io -> Read(io, Text, sizeof(char), SizeOfTag) != SizeOfTag) goto Error; 712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Make sure text is properly ended 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Text[SizeOfTag] = 0; 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Keep the result 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsMLUsetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text)) goto Error; 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Text); 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) mlu; 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mlu != NULL) 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLUfree(mlu); 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Text != NULL) 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Text); 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The conversion implies to choose a language. So, we choose the actual language. 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 734ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_Text_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLU* mlu = (cmsMLU*) Ptr; 737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number size; 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsBool rc; 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* Text; 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get the size of the string. Note there is an extra "\0" at the end 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size = cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, NULL, 0); 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (size == 0) return FALSE; // Cannot be zero! 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Create memory 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Text = (char*) _cmsMalloc(self ->ContextID, size); 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Text == NULL) return FALSE; 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text, size); 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write it, including separator 752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rc = io ->Write(io, size, Text); 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Text); 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return rc; 756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_Text_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsMLUdup((cmsMLU*) Ptr); 764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_Text_Free(struct _cms_typehandler_struct* self, void* Ptr) 772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLU* mlu = (cmsMLU*) Ptr; 774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLUfree(mlu); 775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 781ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsTagTypeSignature DecideTextType(cmsFloat64Number ICCVersion, const void *Data) 782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ICCVersion >= 4.0) 784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsSigMultiLocalizedUnicodeType; 785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsSigTextType; 787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(Data); 789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigDataType 794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// General purpose data type 797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_Data_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsICCData* BinData; 801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number LenOfData; 802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL; 806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LenOfData = SizeOfTag - sizeof(cmsUInt32Number); 808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (LenOfData > INT_MAX) return NULL; 809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BinData = (cmsICCData*) _cmsMalloc(self ->ContextID, sizeof(cmsICCData) + LenOfData - 1); 811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (BinData == NULL) return NULL; 812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BinData ->len = LenOfData; 814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &BinData->flag)) { 815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, BinData); 816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io -> Read(io, BinData ->data, sizeof(cmsUInt8Number), LenOfData) != LenOfData) { 820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, BinData); 822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) BinData; 828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 832ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_Data_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsICCData* BinData = (cmsICCData*) Ptr; 835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, BinData ->flag)) return FALSE; 837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return io ->Write(io, BinData ->len, BinData ->data); 839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_Data_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsICCData* BinData = (cmsICCData*) Ptr; 849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsICCData) + BinData ->len - 1); 851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_Data_Free(struct _cms_typehandler_struct* self, void* Ptr) 857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Ptr); 859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigTextDescriptionType 863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_Text_Description_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* Text = NULL; 869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLU* mlu = NULL; 870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number AsciiCount; 871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, UnicodeCode, UnicodeCount; 872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number ScriptCodeCode, Dummy; 873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number ScriptCodeCount; 874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // One dword should be there 878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL; 879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read len of ASCII 881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &AsciiCount)) return NULL; 882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= sizeof(cmsUInt32Number); 883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Check for size 885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < AsciiCount) return NULL; 886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // All seems Ok, allocate the container 888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mlu = cmsMLUalloc(self ->ContextID, 1); 889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mlu == NULL) return NULL; 890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // As many memory as size of tag 892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Text = (char*) _cmsMalloc(self ->ContextID, AsciiCount + 1); 893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Text == NULL) goto Error; 894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read it 896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io ->Read(io, Text, sizeof(char), AsciiCount) != AsciiCount) goto Error; 897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= AsciiCount; 898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Make sure there is a terminator 900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Text[AsciiCount] = 0; 901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Set the MLU entry. From here we can be tolerant to wrong types 903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsMLUsetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text)) goto Error; 904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, (void*) Text); 905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Text = NULL; 906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Skip Unicode code 908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < 2* sizeof(cmsUInt32Number)) goto Done; 909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &UnicodeCode)) goto Done; 910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &UnicodeCount)) goto Done; 911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= 2* sizeof(cmsUInt32Number); 912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < UnicodeCount*sizeof(cmsUInt16Number)) goto Done; 914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < UnicodeCount; i++) { 916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Read(io, &Dummy, sizeof(cmsUInt16Number), 1)) goto Done; 917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= UnicodeCount*sizeof(cmsUInt16Number); 919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Skip ScriptCode code if present. Some buggy profiles does have less 921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // data that stricttly required. We need to skip it as this type may come 922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // embedded in other types. 923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag >= sizeof(cmsUInt16Number) + sizeof(cmsUInt8Number) + 67) { 925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &ScriptCodeCode)) goto Done; 927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, &ScriptCodeCount)) goto Done; 928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Skip rest of tag 930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < 67; i++) { 931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Read(io, &Dummy, sizeof(cmsUInt8Number), 1)) goto Error; 932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 935ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovDone: 936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return mlu; 939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 940ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Text) _cmsFree(self ->ContextID, (void*) Text); 942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mlu) cmsMLUfree(mlu); 943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This tag can come IN UNALIGNED SIZE. In order to prevent issues, we force zeros on description to align it 948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 949ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLU* mlu = (cmsMLU*) Ptr; 952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char *Text = NULL; 953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wchar_t *Wide = NULL; 954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number len, len_aligned, len_filler_alignment; 955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsBool rc = FALSE; 956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char Filler[68]; 957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Used below for writting zeroes 959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memset(Filler, 0, sizeof(Filler)); 960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get the len of string 962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov len = cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, NULL, 0); 963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // From ICC3.4: It has been found that textDescriptionType can contain misaligned data 965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov //(see clause 4.1 for the definition of �aligned?. Because the Unicode language 966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // code and Unicode count immediately follow the ASCII description, their 967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // alignment is not correct if the ASCII count is not a multiple of four. The 968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // ScriptCode code is misaligned when the ASCII count is odd. Profile reading and 969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // writing software must be written carefully in order to handle these alignment 970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // problems. 971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Compute an aligned size 973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov len_aligned = _cmsALIGNLONG(len); 974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov len_filler_alignment = len_aligned - len; 975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Null strings 977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (len <= 0) { 978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Text = (char*) _cmsDupMem(self ->ContextID, "", sizeof(char)); 980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Wide = (wchar_t*) _cmsDupMem(self ->ContextID, L"", sizeof(wchar_t)); 981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Create independent buffers 984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Text = (char*) _cmsCalloc(self ->ContextID, len, sizeof(char)); 985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Text == NULL) goto Error; 986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Wide = (wchar_t*) _cmsCalloc(self ->ContextID, len, sizeof(wchar_t)); 988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Wide == NULL) goto Error; 989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get both representations. 991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text, len * sizeof(char)); 992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLUgetWide(mlu, cmsNoLanguage, cmsNoCountry, Wide, len * sizeof(wchar_t)); 993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // * cmsUInt32Number count; * Description length 996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // * cmsInt8Number desc[count] * NULL terminated ascii string 997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // * cmsUInt32Number ucLangCode; * UniCode language code 998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // * cmsUInt32Number ucCount; * UniCode description length 999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // * cmsInt16Number ucDesc[ucCount];* The UniCode description 1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // * cmsUInt16Number scCode; * ScriptCode code 1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // * cmsUInt8Number scCount; * ScriptCode count 1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // * cmsInt8Number scDesc[67]; * ScriptCode Description 1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, len_aligned)) goto Error; 1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Write(io, len, Text)) goto Error; 1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Write(io, len_filler_alignment, Filler)) goto Error; 1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) goto Error; // ucLanguageCode 1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // This part is tricky: we need an aligned tag size, and the ScriptCode part 1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // takes 70 bytes, so we need 2 extra bytes to do the alignment 1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, len_aligned+1)) goto Error; 1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Note that in some compilers sizeof(cmsUInt16Number) != sizeof(wchar_t) 1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteWCharArray(io, len, Wide)) goto Error; 1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Array(io, len_filler_alignment+1, (cmsUInt16Number*) Filler)) goto Error; 1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // ScriptCode Code & count (unused) 1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 0)) goto Error; 1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, 0)) goto Error; 1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Write(io, 67, Filler)) goto Error; 1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rc = TRUE; 1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Text) _cmsFree(self ->ContextID, Text); 1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Wide) _cmsFree(self ->ContextID, Wide); 1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return rc; 1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_Text_Description_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsMLUdup((cmsMLU*) Ptr); 1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_Text_Description_Free(struct _cms_typehandler_struct* self, void* Ptr) 1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLU* mlu = (cmsMLU*) Ptr; 1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLUfree(mlu); 1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsTagTypeSignature DecideTextDescType(cmsFloat64Number ICCVersion, const void *Data) 1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ICCVersion >= 4.0) 1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsSigMultiLocalizedUnicodeType; 1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsSigTextDescriptionType; 1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(Data); 1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigCurveType 1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_Curve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Count; 1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve* NewGamma; 1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &Count)) return NULL; 1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch (Count) { 1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 0: // Linear. 1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number SingleGamma = 1.0; 1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewGamma = cmsBuildParametricToneCurve(self ->ContextID, 1, &SingleGamma); 1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!NewGamma) return NULL; 1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NewGamma; 1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 1: // Specified as the exponent of gamma function 1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number SingleGammaFixed; 1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number SingleGamma; 1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &SingleGammaFixed)) return NULL; 1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SingleGamma = _cms8Fixed8toDouble(SingleGammaFixed); 1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsBuildParametricToneCurve(self ->ContextID, 1, &SingleGamma); 1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: // Curve 1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Count > 0x7FFF) 1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; // This is to prevent bad guys for doing bad things 1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewGamma = cmsBuildTabulatedToneCurve16(self ->ContextID, Count, NULL); 1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!NewGamma) return NULL; 1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Array(io, Count, NewGamma -> Table16)) return NULL; 1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NewGamma; 1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_Curve_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve* Curve = (cmsToneCurve*) Ptr; 1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Curve ->nSegments == 1 && Curve ->Segments[0].Type == 1) { 1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Single gamma, preserve number 1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number SingleGammaFixed = _cmsDoubleTo8Fixed8(Curve ->Segments[0].Params[0]); 1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 1)) return FALSE; 1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, SingleGammaFixed)) return FALSE; 1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, Curve ->nEntries)) return FALSE; 1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsWriteUInt16Array(io, Curve ->nEntries, Curve ->Table16); 1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_Curve_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsDupToneCurve((cmsToneCurve*) Ptr); 1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_Curve_Free(struct _cms_typehandler_struct* self, void* Ptr) 1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve* gamma = (cmsToneCurve*) Ptr; 1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeToneCurve(gamma); 1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigParametricCurveType 1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Decide which curve type to use on writting 1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsTagTypeSignature DecideCurveType(cmsFloat64Number ICCVersion, const void *Data) 1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve* Curve = (cmsToneCurve*) Data; 1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ICCVersion < 4.0) return cmsSigCurveType; 1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Curve ->nSegments != 1) return cmsSigCurveType; // Only 1-segment curves can be saved as parametric 1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Curve ->Segments[0].Type < 0) return cmsSigCurveType; // Only non-inverted curves 1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Curve ->Segments[0].Type > 5) return cmsSigCurveType; // Only ICC parametric curves 1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsSigParametricCurveType; 1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_ParametricCurve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const int ParamsByType[] = { 1, 3, 4, 5, 7 }; 1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number Params[10]; 1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number Type; 1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i, n; 1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve* NewGamma; 1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &Type)) return NULL; 1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, NULL)) return NULL; // Reserved 1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Type > 4) { 1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown parametric curve type '%d'", Type); 1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memset(Params, 0, sizeof(Params)); 1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n = ParamsByType[Type]; 1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < n; i++) { 1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Params[i])) return NULL; 1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewGamma = cmsBuildParametricToneCurve(self ->ContextID, Type+1, Params); 1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NewGamma; 1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_ParametricCurve_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve* Curve = (cmsToneCurve*) Ptr; 1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i, nParams, typen; 1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const int ParamsByType[] = { 0, 1, 3, 4, 5, 7 }; 1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typen = Curve -> Segments[0].Type; 1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Curve ->nSegments > 1 || typen < 1) { 1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Multisegment or Inverted parametric curves cannot be written"); 1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (typen > 5) { 1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported parametric curve"); 1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nParams = ParamsByType[typen]; 1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) (Curve ->Segments[0].Type - 1))) return FALSE; 1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 0)) return FALSE; // Reserved 1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nParams; i++) { 1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, Curve -> Segments[0].Params[i])) return FALSE; 1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_ParametricCurve_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsDupToneCurve((cmsToneCurve*) Ptr); 1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_ParametricCurve_Free(struct _cms_typehandler_struct* self, void* Ptr) 1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve* gamma = (cmsToneCurve*) Ptr; 1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeToneCurve(gamma); 1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigDateTimeType 1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// A 12-byte value representation of the time and date, where the byte usage is assigned 1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// as specified in table 1. The actual values are encoded as 16-bit unsigned integers 1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// (uInt16Number - see 5.1.6). 1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// All the dateTimeNumber values in a profile shall be in Coordinated Universal Time 1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// (UTC, also known as GMT or ZULU Time). Profile writers are required to convert local 1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// time to UTC when setting these values. Programmes that display these values may show 1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// the dateTimeNumber as UTC, show the equivalent local time (at current locale), or 1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// display both UTC and local versions of the dateTimeNumber. 1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_DateTime_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 1296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsDateTimeNumber timestamp; 1298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov struct tm * NewDateTime; 1299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 1301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewDateTime = (struct tm*) _cmsMalloc(self ->ContextID, sizeof(struct tm)); 1302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (NewDateTime == NULL) return NULL; 1303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io->Read(io, ×tamp, sizeof(cmsDateTimeNumber), 1) != 1) return NULL; 1305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsDecodeDateTimeNumber(×tamp, NewDateTime); 1307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 1309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NewDateTime; 1310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 1312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1316ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_DateTime_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 1317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov struct tm * DateTime = (struct tm*) Ptr; 1319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsDateTimeNumber timestamp; 1320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsEncodeDateTimeNumber(×tamp, DateTime); 1322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Write(io, sizeof(cmsDateTimeNumber), ×tamp)) return FALSE; 1323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 1325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 1327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_DateTime_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 1332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsDupMem(self ->ContextID, Ptr, sizeof(struct tm)); 1334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 1336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_DateTime_Free(struct _cms_typehandler_struct* self, void* Ptr) 1340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Ptr); 1342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type icMeasurementType 1348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 1351ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovThe measurementType information refers only to the internal profile data and is 1352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovmeant to provide profile makers an alternative to the default measurement 1353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovspecifications. 1354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov*/ 1355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_Measurement_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 1358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsICCMeasurementConditions mc; 1360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memset(&mc, 0, sizeof(mc)); 1363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &mc.Observer)) return NULL; 1365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadXYZNumber(io, &mc.Backing)) return NULL; 1366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &mc.Geometry)) return NULL; 1367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &mc.Flare)) return NULL; 1368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &mc.IlluminantType)) return NULL; 1369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 1371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsDupMem(self ->ContextID, &mc, sizeof(cmsICCMeasurementConditions)); 1372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 1374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1378ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_Measurement_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 1379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsICCMeasurementConditions* mc =(cmsICCMeasurementConditions*) Ptr; 1381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, mc->Observer)) return FALSE; 1383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteXYZNumber(io, &mc->Backing)) return FALSE; 1384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, mc->Geometry)) return FALSE; 1385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, mc->Flare)) return FALSE; 1386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, mc->IlluminantType)) return FALSE; 1387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 1389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 1391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_Measurement_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 1396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsICCMeasurementConditions)); 1398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 1400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_Measurement_Free(struct _cms_typehandler_struct* self, void* Ptr) 1404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Ptr); 1406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigMultiLocalizedUnicodeType 1411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 1413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Do NOT trust SizeOfTag as there is an issue on the definition of profileSequenceDescTag. See the TechNote from 1414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Max Derhak and Rohit Patil about this: basically the size of the string table should be guessed and cannot be 1415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// taken from the size of tag if this tag is embedded as part of bigger structures (profileSequenceDescTag, for instance) 1416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 1417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 1420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLU* mlu; 1422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Count, RecLen, NumOfWchar; 1423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number SizeOfHeader; 1424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Len, Offset; 1425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 1426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wchar_t* Block; 1427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number BeginOfThisString, EndOfThisString, LargestPosition; 1428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 1430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &Count)) return NULL; 1431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &RecLen)) return NULL; 1432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (RecLen != 12) { 1434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "multiLocalizedUnicodeType of len != 12 is not supported."); 1436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mlu = cmsMLUalloc(self ->ContextID, Count); 1440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mlu == NULL) return NULL; 1441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mlu ->UsedEntries = Count; 1443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfHeader = 12 * Count + sizeof(_cmsTagBase); 1445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LargestPosition = 0; 1446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Count; i++) { 1448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &mlu ->Entries[i].Language)) goto Error; 1450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &mlu ->Entries[i].Country)) goto Error; 1451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Now deal with Len and offset. 1453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &Len)) goto Error; 1454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &Offset)) goto Error; 1455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Check for overflow 1457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Offset < (SizeOfHeader + 8)) goto Error; 1458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // True begin of the string 1460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BeginOfThisString = Offset - SizeOfHeader - 8; 1461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Ajust to wchar_t elements 1463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mlu ->Entries[i].Len = (Len * sizeof(wchar_t)) / sizeof(cmsUInt16Number); 1464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mlu ->Entries[i].StrW = (BeginOfThisString * sizeof(wchar_t)) / sizeof(cmsUInt16Number); 1465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // To guess maximum size, add offset + len 1467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov EndOfThisString = BeginOfThisString + Len; 1468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (EndOfThisString > LargestPosition) 1469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LargestPosition = EndOfThisString; 1470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Now read the remaining of tag and fill all strings. Substract the directory 1473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number); 1474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag == 0) 1475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Block = NULL; 1477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NumOfWchar = 0; 1478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Block = (wchar_t*) _cmsMalloc(self ->ContextID, SizeOfTag); 1483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Block == NULL) goto Error; 1484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NumOfWchar = SizeOfTag / sizeof(wchar_t); 1485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadWCharArray(io, NumOfWchar, Block)) goto Error; 1486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mlu ->MemPool = Block; 1489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mlu ->PoolSize = SizeOfTag; 1490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mlu ->PoolUsed = SizeOfTag; 1491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 1493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) mlu; 1494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1495ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 1496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mlu) cmsMLUfree(mlu); 1497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1501ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_MLU_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 1502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLU* mlu =(cmsMLU*) Ptr; 1504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number HeaderSize; 1505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Len, Offset; 1506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i; 1507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Ptr == NULL) { 1509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Empty placeholder 1511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) return FALSE; 1512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 12)) return FALSE; 1513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 1514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, mlu ->UsedEntries)) return FALSE; 1517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 12)) return FALSE; 1518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov HeaderSize = 12 * mlu ->UsedEntries + sizeof(_cmsTagBase); 1520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < mlu ->UsedEntries; i++) { 1522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Len = mlu ->Entries[i].Len; 1524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Offset = mlu ->Entries[i].StrW; 1525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Len = (Len * sizeof(cmsUInt16Number)) / sizeof(wchar_t); 1527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Offset = (Offset * sizeof(cmsUInt16Number)) / sizeof(wchar_t) + HeaderSize + 8; 1528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, mlu ->Entries[i].Language)) return FALSE; 1530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, mlu ->Entries[i].Country)) return FALSE; 1531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, Len)) return FALSE; 1532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, Offset)) return FALSE; 1533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteWCharArray(io, mlu ->PoolUsed / sizeof(wchar_t), (wchar_t*) mlu ->MemPool)) return FALSE; 1536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 1538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 1540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_MLU_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 1546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsMLUdup((cmsMLU*) Ptr); 1548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 1550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_MLU_Free(struct _cms_typehandler_struct* self, void* Ptr) 1555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLUfree((cmsMLU*) Ptr); 1557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 1558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigLut8Type 1565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Decide which LUT type to use on writting 1568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1569ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsTagTypeSignature DecideLUTtypeA2B(cmsFloat64Number ICCVersion, const void *Data) 1570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline* Lut = (cmsPipeline*) Data; 1572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ICCVersion < 4.0) { 1574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Lut ->SaveAs8Bits) return cmsSigLut8Type; 1575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsSigLut16Type; 1576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 1578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsSigLutAtoBType; 1579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1583ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsTagTypeSignature DecideLUTtypeB2A(cmsFloat64Number ICCVersion, const void *Data) 1584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline* Lut = (cmsPipeline*) Data; 1586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ICCVersion < 4.0) { 1588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Lut ->SaveAs8Bits) return cmsSigLut8Type; 1589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsSigLut16Type; 1590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 1592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmsSigLutBtoAType; 1593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 1597ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovThis structure represents a colour transform using tables of 8-bit precision. 1598ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovThis type contains four processing elements: a 3 by 3 matrix (which shall be 1599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovthe identity matrix unless the input colour space is XYZ), a set of one dimensional 1600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinput tables, a multidimensional lookup table, and a set of one dimensional output 1601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtables. Data is processed using these elements via the following sequence: 1602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov(matrix) -> (1d input tables) -> (multidimensional lookup table - CLUT) -> (1d output tables) 1603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1604ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovByte Position Field Length (bytes) Content Encoded as... 1605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov8 1 Number of Input Channels (i) uInt8Number 1606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov9 1 Number of Output Channels (o) uInt8Number 1607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov10 1 Number of CLUT grid points (identical for each side) (g) uInt8Number 1608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov11 1 Reserved for padding (fill with 00h) 1609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov12..15 4 Encoded e00 parameter s15Fixed16Number 1611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov*/ 1612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Read 8 bit tables as gamma functions 1615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1616ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Read8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, int nChannels) 1617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* Temp = NULL; 1619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i, j; 1620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve* Tables[cmsMAXCHANNELS]; 1621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nChannels > cmsMAXCHANNELS) return FALSE; 1623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nChannels <= 0) return FALSE; 1624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memset(Tables, 0, sizeof(Tables)); 1626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Temp = (cmsUInt8Number*) _cmsMalloc(ContextID, 256); 1628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Temp == NULL) return FALSE; 1629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nChannels; i++) { 1631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Tables[i] = cmsBuildTabulatedToneCurve16(ContextID, 256, NULL); 1632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Tables[i] == NULL) goto Error; 1633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nChannels; i++) { 1636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io ->Read(io, Temp, 256, 1) != 1) goto Error; 1638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (j=0; j < 256; j++) 1640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Tables[i]->Table16[j] = (cmsUInt16Number) FROM_8_TO_16(Temp[j]); 1641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(ContextID, Temp); 1644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Temp = NULL; 1645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, nChannels, Tables))) 1647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 1648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nChannels; i++) 1650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeToneCurve(Tables[i]); 1651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 1653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1654ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 1655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nChannels; i++) { 1656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Tables[i]) cmsFreeToneCurve(Tables[i]); 1657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Temp) _cmsFree(ContextID, Temp); 1660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 1661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1665ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Write8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsUInt32Number n, _cmsStageToneCurvesData* Tables) 1666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int j; 1668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 1669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number val; 1670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < n; i++) { 1672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Tables) { 1674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Usual case of identity curves 1676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ((Tables ->TheCurves[i]->nEntries == 2) && 1677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (Tables->TheCurves[i]->Table16[0] == 0) && 1678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (Tables->TheCurves[i]->Table16[1] == 65535)) { 1679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (j=0; j < 256; j++) { 1681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) j)) return FALSE; 1682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Tables ->TheCurves[i]->nEntries != 256) { 1686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(ContextID, cmsERROR_RANGE, "LUT8 needs 256 entries on prelinearization"); 1687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 1688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (j=0; j < 256; j++) { 1691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Tables != NULL) 1693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = (cmsUInt8Number) FROM_16_TO_8(Tables->TheCurves[i]->Table16[j]); 1694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = (cmsUInt8Number) j; 1696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, val)) return FALSE; 1698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 1702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Check overflow 1706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1707ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsUInt32Number uipow(cmsUInt32Number n, cmsUInt32Number a, cmsUInt32Number b) 1708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number rv = 1, rc; 1710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (a == 0) return 0; 1712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (n == 0) return 0; 1713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (; b > 0; b--) { 1715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rv *= a; 1717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Check for overflow 1719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (rv > UINT_MAX / a) return (cmsUInt32Number) -1; 1720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rc = rv * n; 1724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (rv != rc / n) return (cmsUInt32Number) -1; 1726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return rc; 1727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// That will create a MPE LUT with Matrix, pre tables, CLUT and post tables. 1731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 8 bit lut may be scaled easely to v4 PCS, but we need also to properly adjust 1732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// PCS on BToAxx tags and AtoB if abstract. We need to fix input direction. 1733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 1736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number InputChannels, OutputChannels, CLUTpoints; 1738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number* Temp = NULL; 1739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline* NewLUT = NULL; 1740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nTabSize, i; 1741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number Matrix[3*3]; 1742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 1744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, &InputChannels)) goto Error; 1746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, &OutputChannels)) goto Error; 1747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, &CLUTpoints)) goto Error; 1748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (CLUTpoints == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least 1750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Padding 1752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, NULL)) goto Error; 1753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Do some checking 1755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (InputChannels > cmsMAXCHANNELS) goto Error; 1756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (OutputChannels > cmsMAXCHANNELS) goto Error; 1757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Allocates an empty Pipeline 1759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels); 1760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (NewLUT == NULL) goto Error; 1761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read the Matrix 1763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[0])) goto Error; 1764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[1])) goto Error; 1765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[2])) goto Error; 1766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[3])) goto Error; 1767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[4])) goto Error; 1768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[5])) goto Error; 1769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[6])) goto Error; 1770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[7])) goto Error; 1771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[8])) goto Error; 1772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Only operates if not identity... 1775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ((InputChannels == 3) && !_cmsMAT3isIdentity((cmsMAT3*) Matrix)) { 1776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_BEGIN, cmsStageAllocMatrix(self ->ContextID, 3, 3, Matrix, NULL))) 1778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 1779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get input tables 1782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!Read8bitTables(self ->ContextID, io, NewLUT, InputChannels)) goto Error; 1783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get 3D CLUT. Check the overflow.... 1785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nTabSize = uipow(OutputChannels, CLUTpoints, InputChannels); 1786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nTabSize == (cmsUInt32Number) -1) goto Error; 1787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nTabSize > 0) { 1788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number *PtrW, *T; 1790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PtrW = T = (cmsUInt16Number*) _cmsCalloc(self ->ContextID, nTabSize, sizeof(cmsUInt16Number)); 1792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (T == NULL) goto Error; 1793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Temp = (cmsUInt8Number*) _cmsMalloc(self ->ContextID, nTabSize); 1795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Temp == NULL) { 1796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, T); 1797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 1798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io ->Read(io, Temp, nTabSize, 1) != 1) { 1801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, T); 1802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Temp); 1803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 1804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i = 0; i < nTabSize; i++) { 1807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *PtrW++ = FROM_8_TO_16(Temp[i]); 1809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Temp); 1811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Temp = NULL; 1812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T))) 1814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 1815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, T); 1816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get output tables 1820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!Read8bitTables(self ->ContextID, io, NewLUT, OutputChannels)) goto Error; 1821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 1823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NewLUT; 1824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1825ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 1826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (NewLUT != NULL) cmsPipelineFree(NewLUT); 1827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 1828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 1830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// We only allow a specific MPE structure: Matrix plus prelin, plus clut, plus post-lin. 1833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1834ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 1835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number j, nTabSize; 1837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number val; 1838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline* NewLUT = (cmsPipeline*) Ptr; 1839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage* mpe; 1840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL; 1841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageMatrixData* MatMPE = NULL; 1842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageCLutData* clut = NULL; 1843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int clutPoints; 1844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Disassemble the LUT into components. 1846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = NewLUT -> Elements; 1847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mpe ->Type == cmsSigMatrixElemType) { 1848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov MatMPE = (_cmsStageMatrixData*) mpe ->Data; 1850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = mpe -> Next; 1851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mpe != NULL && mpe ->Type == cmsSigCurveSetElemType) { 1854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PreMPE = (_cmsStageToneCurvesData*) mpe ->Data; 1855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = mpe -> Next; 1856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mpe != NULL && mpe ->Type == cmsSigCLutElemType) { 1859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clut = (_cmsStageCLutData*) mpe -> Data; 1860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = mpe ->Next; 1861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mpe != NULL && mpe ->Type == cmsSigCurveSetElemType) { 1864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PostMPE = (_cmsStageToneCurvesData*) mpe ->Data; 1865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = mpe -> Next; 1866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // That should be all 1869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mpe != NULL) { 1870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(mpe->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT is not suitable to be saved as LUT8"); 1871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 1872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (clut == NULL) 1876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clutPoints = 0; 1877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clutPoints = clut->Params->nSamples[0]; 1879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) NewLUT ->InputChannels)) return FALSE; 1881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) NewLUT ->OutputChannels)) return FALSE; 1882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) clutPoints)) return FALSE; 1883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, 0)) return FALSE; // Padding 1884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (MatMPE != NULL) { 1887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[0])) return FALSE; 1889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[1])) return FALSE; 1890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[2])) return FALSE; 1891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[3])) return FALSE; 1892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[4])) return FALSE; 1893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[5])) return FALSE; 1894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[6])) return FALSE; 1895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[7])) return FALSE; 1896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[8])) return FALSE; 1897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 1900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE; 1902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 1903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 1904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 1905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE; 1906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 1907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 1908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 1909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE; 1910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // The prelinearization table 1913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!Write8bitTables(self ->ContextID, io, NewLUT ->InputChannels, PreMPE)) return FALSE; 1914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nTabSize = uipow(NewLUT->OutputChannels, clutPoints, NewLUT ->InputChannels); 1916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nTabSize == (cmsUInt32Number) -1) return FALSE; 1917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nTabSize > 0) { 1918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // The 3D CLUT. 1920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (clut != NULL) { 1921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (j=0; j < nTabSize; j++) { 1923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = (cmsUInt8Number) FROM_16_TO_8(clut ->Tab.T[j]); 1925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, val)) return FALSE; 1926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // The postlinearization table 1931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!Write8bitTables(self ->ContextID, io, NewLUT ->OutputChannels, PostMPE)) return FALSE; 1932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 1934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 1936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_LUT8_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 1941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsPipelineDup((cmsPipeline*) Ptr); 1943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 1945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_LUT8_Free(struct _cms_typehandler_struct* self, void* Ptr) 1950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipelineFree((cmsPipeline*) Ptr); 1952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 1953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 1955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 1956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigLut16Type 1959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 1960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Read 16 bit tables as gamma functions 1962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 1963ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Read16bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, int nChannels, int nEntries) 1964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 1965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i; 1966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve* Tables[cmsMAXCHANNELS]; 1967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Maybe an empty table? (this is a lcms extension) 1969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nEntries <= 0) return TRUE; 1970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Check for malicious profiles 1972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nEntries < 2) return FALSE; 1973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nChannels > cmsMAXCHANNELS) return FALSE; 1974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Init table to zero 1976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memset(Tables, 0, sizeof(Tables)); 1977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nChannels; i++) { 1979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Tables[i] = cmsBuildTabulatedToneCurve16(ContextID, nEntries, NULL); 1981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Tables[i] == NULL) goto Error; 1982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Array(io, nEntries, Tables[i]->Table16)) goto Error; 1984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Add the table (which may certainly be an identity, but this is up to the optimizer, not the reading code) 1988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, nChannels, Tables))) 1989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 1990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nChannels; i++) 1992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeToneCurve(Tables[i]); 1993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 1995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1996ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 1997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nChannels; i++) { 1998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Tables[i]) cmsFreeToneCurve(Tables[i]); 1999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 2002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2005ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Write16bitTables(cmsContext ContextID, cmsIOHANDLER* io, _cmsStageToneCurvesData* Tables) 2006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int j; 2008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 2009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number val; 2010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int nEntries; 2011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsAssert(Tables != NULL); 2013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nEntries = Tables->TheCurves[0]->nEntries; 2015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Tables ->nCurves; i++) { 2017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (j=0; j < nEntries; j++) { 2019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov val = Tables->TheCurves[i]->Table16[j]; 2021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, val)) return FALSE; 2022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 2025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(ContextID); 2027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_LUT16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 2031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number InputChannels, OutputChannels, CLUTpoints; 2033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline* NewLUT = NULL; 2034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nTabSize; 2035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number Matrix[3*3]; 2036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number InputEntries, OutputEntries; 2037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 2039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, &InputChannels)) return NULL; 2041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, &OutputChannels)) return NULL; 2042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, &CLUTpoints)) return NULL; // 255 maximum 2043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Padding 2045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, NULL)) return NULL; 2046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Do some checking 2048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (InputChannels > cmsMAXCHANNELS) goto Error; 2049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (OutputChannels > cmsMAXCHANNELS) goto Error; 2050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Allocates an empty LUT 2052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels); 2053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (NewLUT == NULL) goto Error; 2054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read the Matrix 2056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[0])) goto Error; 2057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[1])) goto Error; 2058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[2])) goto Error; 2059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[3])) goto Error; 2060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[4])) goto Error; 2061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[5])) goto Error; 2062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[6])) goto Error; 2063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[7])) goto Error; 2064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Matrix[8])) goto Error; 2065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Only operates on 3 channels 2068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ((InputChannels == 3) && !_cmsMAT3isIdentity((cmsMAT3*) Matrix)) { 2069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocMatrix(self ->ContextID, 3, 3, Matrix, NULL))) 2071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 2072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &InputEntries)) goto Error; 2075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &OutputEntries)) goto Error; 2076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (InputEntries > 0x7FFF || OutputEntries > 0x7FFF) goto Error; 2078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (CLUTpoints == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least 2079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get input tables 2081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!Read16bitTables(self ->ContextID, io, NewLUT, InputChannels, InputEntries)) goto Error; 2082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get 3D CLUT 2084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nTabSize = uipow(OutputChannels, CLUTpoints, InputChannels); 2085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nTabSize == (cmsUInt32Number) -1) goto Error; 2086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nTabSize > 0) { 2087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number *T; 2089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov T = (cmsUInt16Number*) _cmsCalloc(self ->ContextID, nTabSize, sizeof(cmsUInt16Number)); 2091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (T == NULL) goto Error; 2092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Array(io, nTabSize, T)) { 2094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, T); 2095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 2096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T))) { 2099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, T); 2100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 2101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, T); 2103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get output tables 2107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!Read16bitTables(self ->ContextID, io, NewLUT, OutputChannels, OutputEntries)) goto Error; 2108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 2110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NewLUT; 2111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2112ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 2113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (NewLUT != NULL) cmsPipelineFree(NewLUT); 2114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 2115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 2117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// We only allow some specific MPE structures: Matrix plus prelin, plus clut, plus post-lin. 2120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Some empty defaults are created for missing parts 2121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2123ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_LUT16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 2124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nTabSize; 2126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline* NewLUT = (cmsPipeline*) Ptr; 2127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage* mpe; 2128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL; 2129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageMatrixData* MatMPE = NULL; 2130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageCLutData* clut = NULL; 2131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i, InputChannels, OutputChannels, clutPoints; 2132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Disassemble the LUT into components. 2134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = NewLUT -> Elements; 2135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mpe != NULL && mpe ->Type == cmsSigMatrixElemType) { 2136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov MatMPE = (_cmsStageMatrixData*) mpe ->Data; 2138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = mpe -> Next; 2139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mpe != NULL && mpe ->Type == cmsSigCurveSetElemType) { 2143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PreMPE = (_cmsStageToneCurvesData*) mpe ->Data; 2144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = mpe -> Next; 2145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mpe != NULL && mpe ->Type == cmsSigCLutElemType) { 2148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clut = (_cmsStageCLutData*) mpe -> Data; 2149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = mpe ->Next; 2150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mpe != NULL && mpe ->Type == cmsSigCurveSetElemType) { 2153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PostMPE = (_cmsStageToneCurvesData*) mpe ->Data; 2154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = mpe -> Next; 2155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // That should be all 2158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mpe != NULL) { 2159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(mpe->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT is not suitable to be saved as LUT16"); 2160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 2161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov InputChannels = cmsPipelineInputChannels(NewLUT); 2164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov OutputChannels = cmsPipelineOutputChannels(NewLUT); 2165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (clut == NULL) 2167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clutPoints = 0; 2168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clutPoints = clut->Params->nSamples[0]; 2170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) InputChannels)) return FALSE; 2172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) OutputChannels)) return FALSE; 2173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) clutPoints)) return FALSE; 2174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, 0)) return FALSE; // Padding 2175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (MatMPE != NULL) { 2178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[0])) return FALSE; 2180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[1])) return FALSE; 2181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[2])) return FALSE; 2182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[3])) return FALSE; 2183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[4])) return FALSE; 2184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[5])) return FALSE; 2185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[6])) return FALSE; 2186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[7])) return FALSE; 2187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[8])) return FALSE; 2188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 2190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE; 2192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 2193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 2194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 2195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE; 2196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 2197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 2198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 2199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE; 2200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (PreMPE != NULL) { 2204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) PreMPE ->TheCurves[0]->nEntries)) return FALSE; 2205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 2206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 2)) return FALSE; 2207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (PostMPE != NULL) { 2210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) PostMPE ->TheCurves[0]->nEntries)) return FALSE; 2211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 2212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 2)) return FALSE; 2213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // The prelinearization table 2217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (PreMPE != NULL) { 2219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!Write16bitTables(self ->ContextID, io, PreMPE)) return FALSE; 2220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 2222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < InputChannels; i++) { 2223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 0)) return FALSE; 2225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 0xffff)) return FALSE; 2226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nTabSize = uipow(OutputChannels, clutPoints, InputChannels); 2230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nTabSize == (cmsUInt32Number) -1) return FALSE; 2231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nTabSize > 0) { 2232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // The 3D CLUT. 2233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (clut != NULL) { 2234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Array(io, nTabSize, clut->Tab.T)) return FALSE; 2235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // The postlinearization table 2239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (PostMPE != NULL) { 2240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!Write16bitTables(self ->ContextID, io, PostMPE)) return FALSE; 2241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 2243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < OutputChannels; i++) { 2244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 0)) return FALSE; 2246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 0xffff)) return FALSE; 2247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 2251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 2253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_LUT16_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 2257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsPipelineDup((cmsPipeline*) Ptr); 2259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 2261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 2262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_LUT16_Free(struct _cms_typehandler_struct* self, void* Ptr) 2266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipelineFree((cmsPipeline*) Ptr); 2268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 2271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 2275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigLutAToBType 2276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 2277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// V4 stuff. Read matrix for LutAtoB and LutBtoA 2280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2282ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsStage* ReadMatrix(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset) 2283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number dMat[3*3]; 2285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number dOff[3]; 2286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage* Mat; 2287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Go to address 2289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io -> Seek(io, Offset)) return NULL; 2290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read the Matrix 2292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &dMat[0])) return NULL; 2293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &dMat[1])) return NULL; 2294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &dMat[2])) return NULL; 2295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &dMat[3])) return NULL; 2296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &dMat[4])) return NULL; 2297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &dMat[5])) return NULL; 2298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &dMat[6])) return NULL; 2299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &dMat[7])) return NULL; 2300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &dMat[8])) return NULL; 2301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &dOff[0])) return NULL; 2303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &dOff[1])) return NULL; 2304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &dOff[2])) return NULL; 2305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Mat = cmsStageAllocMatrix(self ->ContextID, 3, 3, dMat, dOff); 2307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return Mat; 2309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// V4 stuff. Read CLUT part for LutAtoB and LutBtoA 2315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2317ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsStage* ReadCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset, int InputChannels, int OutputChannels) 2318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number gridPoints8[cmsMAXCHANNELS]; // Number of grid points in each dimension. 2320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number GridPoints[cmsMAXCHANNELS], i; 2321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number Precision; 2322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage* CLUT; 2323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageCLutData* Data; 2324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io -> Seek(io, Offset)) return NULL; 2326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io -> Read(io, gridPoints8, cmsMAXCHANNELS, 1) != 1) return NULL; 2327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < cmsMAXCHANNELS; i++) { 2330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (gridPoints8[i] == 1) return NULL; // Impossible value, 0 for no CLUT and then 2 at least 2332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov GridPoints[i] = gridPoints8[i]; 2333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, &Precision)) return NULL; 2336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, NULL)) return NULL; 2338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, NULL)) return NULL; 2339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, NULL)) return NULL; 2340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CLUT = cmsStageAllocCLut16bitGranular(self ->ContextID, GridPoints, InputChannels, OutputChannels, NULL); 2342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (CLUT == NULL) return NULL; 2343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Data = (_cmsStageCLutData*) CLUT ->Data; 2345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Precision can be 1 or 2 bytes 2347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Precision == 1) { 2348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number v; 2350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Data ->nEntries; i++) { 2352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io ->Read(io, &v, sizeof(cmsUInt8Number), 1) != 1) return NULL; 2354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Data ->Tab.T[i] = FROM_8_TO_16(v); 2355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Precision == 2) { 2360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Array(io, Data->nEntries, Data ->Tab.T)) { 2362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStageFree(CLUT); 2363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 2364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 2367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStageFree(CLUT); 2368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision); 2369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 2370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return CLUT; 2373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2376ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsToneCurve* ReadEmbeddedCurve(struct _cms_typehandler_struct* self, cmsIOHANDLER* io) 2377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsTagTypeSignature BaseType; 2379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nItems; 2380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseType = _cmsReadTypeBase(io); 2382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch (BaseType) { 2383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cmsSigCurveType: 2385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (cmsToneCurve*) Type_Curve_Read(self, io, &nItems, 0); 2386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cmsSigParametricCurveType: 2388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (cmsToneCurve*) Type_ParametricCurve_Read(self, io, &nItems, 0); 2389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 2391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char String[5]; 2393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagSignature2String(String, (cmsTagSignature) BaseType); 2395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve type '%s'", String); 2396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 2398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Read a set of curves from specific offset 2403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2404ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsStage* ReadSetOfCurves(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset, cmsUInt32Number nCurves) 2405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve* Curves[cmsMAXCHANNELS]; 2407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 2408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage* Lin = NULL; 2409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nCurves > cmsMAXCHANNELS) return FALSE; 2411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io -> Seek(io, Offset)) return FALSE; 2413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nCurves; i++) 2415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Curves[i] = NULL; 2416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nCurves; i++) { 2418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Curves[i] = ReadEmbeddedCurve(self, io); 2420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Curves[i] == NULL) goto Error; 2421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadAlignment(io)) goto Error; 2422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Lin = cmsStageAllocToneCurves(self ->ContextID, nCurves, Curves); 2426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2427ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 2428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nCurves; i++) 2429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeToneCurve(Curves[i]); 2430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return Lin; 2432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// LutAtoB type 2436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This structure represents a colour transform. The type contains up to five processing 2438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// elements which are stored in the AtoBTag tag in the following order: a set of one 2439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// dimensional curves, a 3 by 3 matrix with offset terms, a set of one dimensional curves, 2440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// a multidimensional lookup table, and a set of one dimensional output curves. 2441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Data are processed using these elements via the following sequence: 2442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 2443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//("A" curves) -> (multidimensional lookup table - CLUT) -> ("M" curves) -> (matrix) -> ("B" curves). 2444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 2445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 2446ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovIt is possible to use any or all of these processing elements. At least one processing element 2447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovmust be included.Only the following combinations are allowed: 2448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2449ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovB 2450ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovM - Matrix - B 2451ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovA - CLUT - B 2452ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovA - CLUT - M - Matrix - B 2453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov*/ 2455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_LUTA2B_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 2458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number BaseOffset; 2460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number inputChan; // Number of input channels 2461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number outputChan; // Number of output channels 2462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number offsetB; // Offset to first "B" curve 2463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number offsetMat; // Offset to matrix 2464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number offsetM; // Offset to first "M" curve 2465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number offsetC; // Offset to CLUT 2466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number offsetA; // Offset to first "A" curve 2467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline* NewLUT = NULL; 2468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); 2471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, &inputChan)) return NULL; 2473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, &outputChan)) return NULL; 2474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, NULL)) return NULL; 2476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &offsetB)) return NULL; 2478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &offsetMat)) return NULL; 2479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &offsetM)) return NULL; 2480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &offsetC)) return NULL; 2481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &offsetA)) return NULL; 2482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Allocates an empty LUT 2484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewLUT = cmsPipelineAlloc(self ->ContextID, inputChan, outputChan); 2485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (NewLUT == NULL) return NULL; 2486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (offsetA!= 0) { 2488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetA, inputChan))) 2489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 2490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (offsetC != 0) { 2493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan))) 2494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 2495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (offsetM != 0) { 2498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetM, outputChan))) 2499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 2500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (offsetMat != 0) { 2503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadMatrix(self, io, BaseOffset + offsetMat))) 2504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 2505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (offsetB != 0) { 2508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetB, outputChan))) 2509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 2510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 2513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NewLUT; 2514ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 2515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipelineFree(NewLUT); 2516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 2517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 2519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Write a set of curves 2522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2523ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool WriteMatrix(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsStage* mpe) 2524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageMatrixData* m = (_cmsStageMatrixData*) mpe -> Data; 2526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write the Matrix 2528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, m -> Double[0])) return FALSE; 2529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, m -> Double[1])) return FALSE; 2530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, m -> Double[2])) return FALSE; 2531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, m -> Double[3])) return FALSE; 2532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, m -> Double[4])) return FALSE; 2533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, m -> Double[5])) return FALSE; 2534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, m -> Double[6])) return FALSE; 2535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, m -> Double[7])) return FALSE; 2536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, m -> Double[8])) return FALSE; 2537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (m ->Offset != NULL) { 2539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, m -> Offset[0])) return FALSE; 2541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, m -> Offset[1])) return FALSE; 2542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, m -> Offset[2])) return FALSE; 2543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 2545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 2546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 2547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE; 2548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 2553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 2555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Write a set of curves 2559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2560ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool WriteSetOfCurves(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsTagTypeSignature Type, cmsStage* mpe) 2561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, n; 2563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsTagTypeSignature CurrentType; 2564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve** Curves; 2565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n = cmsStageOutputChannels(mpe); 2568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Curves = _cmsStageGetPtrToCurveSet(mpe); 2569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < n; i++) { 2571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // If this is a table-based curve, use curve type even on V4 2573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CurrentType = Type; 2574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ((Curves[i] ->nSegments == 0)|| 2576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ((Curves[i]->nSegments == 2) && (Curves[i] ->Segments[1].Type == 0)) ) 2577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CurrentType = cmsSigCurveType; 2578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Curves[i] ->Segments[0].Type < 0) 2580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CurrentType = cmsSigCurveType; 2581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteTypeBase(io, CurrentType)) return FALSE; 2583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch (CurrentType) { 2585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cmsSigCurveType: 2587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!Type_Curve_Write(self, io, Curves[i], 1)) return FALSE; 2588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cmsSigParametricCurveType: 2591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!Type_ParametricCurve_Write(self, io, Curves[i], 1)) return FALSE; 2592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 2595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char String[5]; 2597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagSignature2String(String, (cmsTagSignature) Type); 2599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve type '%s'", String); 2600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 2602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteAlignment(io)) return FALSE; 2605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 2609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2613ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool WriteCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt8Number Precision, cmsStage* mpe) 2614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number gridPoints[cmsMAXCHANNELS]; // Number of grid points in each dimension. 2616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 2617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageCLutData* CLUT = ( _cmsStageCLutData*) mpe -> Data; 2618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (CLUT ->HasFloatValues) { 2620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self ->ContextID, cmsERROR_NOT_SUITABLE, "Cannot save floating point data, CLUT are 8 or 16 bit only"); 2621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 2622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memset(gridPoints, 0, sizeof(gridPoints)); 2625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < (cmsUInt32Number) CLUT ->Params ->nInputs; i++) 2626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gridPoints[i] = (cmsUInt8Number) CLUT ->Params ->nSamples[i]; 2627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io -> Write(io, cmsMAXCHANNELS*sizeof(cmsUInt8Number), gridPoints)) return FALSE; 2629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) Precision)) return FALSE; 2631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, 0)) return FALSE; 2632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, 0)) return FALSE; 2633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, 0)) return FALSE; 2634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Precision can be 1 or 2 bytes 2636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Precision == 1) { 2637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < CLUT->nEntries; i++) { 2639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, FROM_16_TO_8(CLUT->Tab.T[i]))) return FALSE; 2641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Precision == 2) { 2645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Array(io, CLUT->nEntries, CLUT ->Tab.T)) return FALSE; 2647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 2649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision); 2650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 2651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteAlignment(io)) return FALSE; 2654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 2656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2662ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_LUTA2B_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 2663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline* Lut = (cmsPipeline*) Ptr; 2665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int inputChan, outputChan; 2666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage *A = NULL, *B = NULL, *M = NULL; 2667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage * Matrix = NULL; 2668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage * CLUT = NULL; 2669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number offsetB = 0, offsetMat = 0, offsetM = 0, offsetC = 0, offsetA = 0; 2670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number BaseOffset, DirectoryPos, CurrentPos; 2671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get the base for all offsets 2673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); 2674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Lut ->Elements != NULL) 2676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineCheckAndRetreiveStages(Lut, 1, cmsSigCurveSetElemType, &B)) 2677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineCheckAndRetreiveStages(Lut, 3, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType, &M, &Matrix, &B)) 2678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineCheckAndRetreiveStages(Lut, 3, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, &A, &CLUT, &B)) 2679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineCheckAndRetreiveStages(Lut, 5, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, 2680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSigMatrixElemType, cmsSigCurveSetElemType, &A, &CLUT, &M, &Matrix, &B)) { 2681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_NOT_SUITABLE, "LUT is not suitable to be saved as LutAToB"); 2683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 2684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get input, output channels 2687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inputChan = cmsPipelineInputChannels(Lut); 2688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outputChan = cmsPipelineOutputChannels(Lut); 2689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write channel count 2691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) inputChan)) return FALSE; 2692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) outputChan)) return FALSE; 2693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 0)) return FALSE; 2694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Keep directory to be filled latter 2696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DirectoryPos = io ->Tell(io); 2697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write the directory 2699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) return FALSE; 2700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) return FALSE; 2701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) return FALSE; 2702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) return FALSE; 2703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) return FALSE; 2704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (A != NULL) { 2706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offsetA = io ->Tell(io) - BaseOffset; 2708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, A)) return FALSE; 2709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (CLUT != NULL) { 2712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offsetC = io ->Tell(io) - BaseOffset; 2713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteCLUT(self, io, Lut ->SaveAs8Bits ? 1 : 2, CLUT)) return FALSE; 2714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (M != NULL) { 2717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offsetM = io ->Tell(io) - BaseOffset; 2719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, M)) return FALSE; 2720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Matrix != NULL) { 2723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offsetMat = io ->Tell(io) - BaseOffset; 2724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteMatrix(self, io, Matrix)) return FALSE; 2725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (B != NULL) { 2728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offsetB = io ->Tell(io) - BaseOffset; 2730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, B)) return FALSE; 2731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CurrentPos = io ->Tell(io); 2734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Seek(io, DirectoryPos)) return FALSE; 2736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, offsetB)) return FALSE; 2738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, offsetMat)) return FALSE; 2739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, offsetM)) return FALSE; 2740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, offsetC)) return FALSE; 2741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, offsetA)) return FALSE; 2742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Seek(io, CurrentPos)) return FALSE; 2744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 2746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 2748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_LUTA2B_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 2753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsPipelineDup((cmsPipeline*) Ptr); 2755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 2757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 2758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_LUTA2B_Free(struct _cms_typehandler_struct* self, void* Ptr) 2762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipelineFree((cmsPipeline*) Ptr); 2764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 2767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// LutBToA type 2771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_LUTB2A_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 2774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number inputChan; // Number of input channels 2776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number outputChan; // Number of output channels 2777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number BaseOffset; // Actual position in file 2778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number offsetB; // Offset to first "B" curve 2779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number offsetMat; // Offset to matrix 2780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number offsetM; // Offset to first "M" curve 2781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number offsetC; // Offset to CLUT 2782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number offsetA; // Offset to first "A" curve 2783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline* NewLUT = NULL; 2784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); 2787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, &inputChan)) return NULL; 2789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, &outputChan)) return NULL; 2790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Padding 2792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, NULL)) return NULL; 2793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &offsetB)) return NULL; 2795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &offsetMat)) return NULL; 2796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &offsetM)) return NULL; 2797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &offsetC)) return NULL; 2798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &offsetA)) return NULL; 2799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Allocates an empty LUT 2801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewLUT = cmsPipelineAlloc(self ->ContextID, inputChan, outputChan); 2802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (NewLUT == NULL) return NULL; 2803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (offsetB != 0) { 2805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetB, inputChan))) 2806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 2807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (offsetMat != 0) { 2810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadMatrix(self, io, BaseOffset + offsetMat))) 2811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 2812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (offsetM != 0) { 2815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetM, inputChan))) 2816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 2817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (offsetC != 0) { 2820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan))) 2821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 2822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (offsetA!= 0) { 2825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetA, outputChan))) 2826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 2827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 2830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NewLUT; 2831ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 2832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipelineFree(NewLUT); 2833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 2834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 2836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 2840ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovB 2841ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovB - Matrix - M 2842ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovB - CLUT - A 2843ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovB - Matrix - M - CLUT - A 2844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov*/ 2845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2847ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_LUTB2A_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 2848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline* Lut = (cmsPipeline*) Ptr; 2850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int inputChan, outputChan; 2851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage *A = NULL, *B = NULL, *M = NULL; 2852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage *Matrix = NULL; 2853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage *CLUT = NULL; 2854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number offsetB = 0, offsetMat = 0, offsetM = 0, offsetC = 0, offsetA = 0; 2855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number BaseOffset, DirectoryPos, CurrentPos; 2856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); 2859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineCheckAndRetreiveStages(Lut, 1, cmsSigCurveSetElemType, &B)) 2861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineCheckAndRetreiveStages(Lut, 3, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType, &B, &Matrix, &M)) 2862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineCheckAndRetreiveStages(Lut, 3, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, &B, &CLUT, &A)) 2863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineCheckAndRetreiveStages(Lut, 5, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType, 2864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSigCLutElemType, cmsSigCurveSetElemType, &B, &Matrix, &M, &CLUT, &A)) { 2865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_NOT_SUITABLE, "LUT is not suitable to be saved as LutBToA"); 2866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 2867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inputChan = cmsPipelineInputChannels(Lut); 2870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outputChan = cmsPipelineOutputChannels(Lut); 2871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) inputChan)) return FALSE; 2873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) outputChan)) return FALSE; 2874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 0)) return FALSE; 2875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DirectoryPos = io ->Tell(io); 2877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) return FALSE; 2879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) return FALSE; 2880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) return FALSE; 2881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) return FALSE; 2882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) return FALSE; 2883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (A != NULL) { 2885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offsetA = io ->Tell(io) - BaseOffset; 2887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, A)) return FALSE; 2888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (CLUT != NULL) { 2891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offsetC = io ->Tell(io) - BaseOffset; 2892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteCLUT(self, io, Lut ->SaveAs8Bits ? 1 : 2, CLUT)) return FALSE; 2893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (M != NULL) { 2896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offsetM = io ->Tell(io) - BaseOffset; 2898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, M)) return FALSE; 2899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Matrix != NULL) { 2902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offsetMat = io ->Tell(io) - BaseOffset; 2903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteMatrix(self, io, Matrix)) return FALSE; 2904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (B != NULL) { 2907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov offsetB = io ->Tell(io) - BaseOffset; 2909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, B)) return FALSE; 2910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CurrentPos = io ->Tell(io); 2913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Seek(io, DirectoryPos)) return FALSE; 2915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, offsetB)) return FALSE; 2917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, offsetMat)) return FALSE; 2918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, offsetM)) return FALSE; 2919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, offsetC)) return FALSE; 2920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, offsetA)) return FALSE; 2921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Seek(io, CurrentPos)) return FALSE; 2923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 2925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 2927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_LUTB2A_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 2933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsPipelineDup((cmsPipeline*) Ptr); 2935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 2937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 2938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_LUTB2A_Free(struct _cms_typehandler_struct* self, void* Ptr) 2942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipelineFree((cmsPipeline*) Ptr); 2944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 2947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 2948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 2952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigColorantTableType 2953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 2954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 2955ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovThe purpose of this tag is to identify the colorants used in the profile by a 2956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovunique name and set of XYZ or L*a*b* values to give the colorant an unambiguous 2957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvalue. The first colorant listed is the colorant of the first device channel of 2958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganova lut tag. The second colorant listed is the colorant of the second device channel 2959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovof a lut tag, and so on. 2960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov*/ 2961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 2963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_ColorantTable_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 2964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 2965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, Count; 2966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsNAMEDCOLORLIST* List; 2967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char Name[34]; 2968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number PCS[3]; 2969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &Count)) return NULL; 2972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Count > cmsMAXCHANNELS) { 2974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many colorants '%d'", Count); 2975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 2976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov List = cmsAllocNamedColorList(self ->ContextID, Count, 0, "", ""); 2979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Count; i++) { 2980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io ->Read(io, Name, 32, 1) != 1) goto Error; 2982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Name[33] = 0; 2983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error; 2985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsAppendNamedColor(List, Name, PCS, NULL)) goto Error; 2987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 2991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return List; 2992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2993ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 2994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 2995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeNamedColorList(List); 2996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 2997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 2999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Saves a colorant table. It is using the named color structure for simplicity sake 3004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3005ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_ColorantTable_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 3006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr; 3008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i, nColors; 3009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nColors = cmsNamedColorCount(NamedColorList); 3011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, nColors)) return FALSE; 3013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nColors; i++) { 3015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char root[33]; 3017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number PCS[3]; 3018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsNamedColorInfo(NamedColorList, i, root, NULL, NULL, PCS, NULL)) return 0; 3020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov root[32] = 0; 3021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Write(io, 32, root)) return FALSE; 3023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Array(io, 3, PCS)) return FALSE; 3024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 3027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 3029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_ColorantTable_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n) 3035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) Ptr; 3037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsDupNamedColorList(nc); 3038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 3040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_ColorantTable_Free(struct _cms_typehandler_struct* self, void* Ptr) 3046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeNamedColorList((cmsNAMEDCOLORLIST*) Ptr); 3048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 3049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigNamedColor2Type 3056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 3058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//The namedColor2Type is a count value and array of structures that provide color 3059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//coordinates for 7-bit ASCII color names. For each named color, a PCS and optional 3060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//device representation of the color are given. Both representations are 16-bit values. 3061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//The device representation corresponds to the header�s �color space of data?field. 3062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//This representation should be consistent with the �number of device components?//field in the namedColor2Type. If this field is 0, device coordinates are not provided. 3063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//The PCS representation corresponds to the header�s PCS field. The PCS representation 3064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//is always provided. Color names are fixed-length, 32-byte fields including null 3065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//termination. In order to maintain maximum portability, it is strongly recommended 3066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//that special characters of the 7-bit ASCII set not be used. 3067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 3070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number vendorFlag; // Bottom 16 bits for ICC use 3073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number count; // Count of named colors 3074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nDeviceCoords; // Num of device coordinates 3075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char prefix[32]; // Prefix for each color name 3076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char suffix[32]; // Suffix for each color name 3077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsNAMEDCOLORLIST* v; 3078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 3079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 3082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &vendorFlag)) return NULL; 3083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &count)) return NULL; 3084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &nDeviceCoords)) return NULL; 3085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io -> Read(io, prefix, 32, 1) != 1) return NULL; 3087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io -> Read(io, suffix, 32, 1) != 1) return NULL; 3088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prefix[31] = suffix[31] = 0; 3090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v = cmsAllocNamedColorList(self ->ContextID, count, nDeviceCoords, prefix, suffix); 3092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (v == NULL) { 3093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many named colors '%d'", count); 3094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nDeviceCoords > cmsMAXCHANNELS) { 3098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many device coordinates '%d'", nDeviceCoords); 3099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 3100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < count; i++) { 3102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number PCS[3]; 3104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number Colorant[cmsMAXCHANNELS]; 3105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char Root[33]; 3106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memset(Colorant, 0, sizeof(Colorant)); 3108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io -> Read(io, Root, 32, 1) != 1) return NULL; 3109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error; 3110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Array(io, nDeviceCoords, Colorant)) goto Error; 3111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsAppendNamedColor(v, Root, PCS, Colorant)) goto Error; 3113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 3116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) v ; 3117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3118ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 3119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeNamedColorList(v); 3120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 3123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Saves a named color list into a named color profile 3127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3128ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 3129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr; 3131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char prefix[32]; // Prefix for each color name 3132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char suffix[32]; // Suffix for each color name 3133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i, nColors; 3134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nColors = cmsNamedColorCount(NamedColorList); 3136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) return FALSE; 3138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, nColors)) return FALSE; 3139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, NamedColorList ->ColorantCount)) return FALSE; 3140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov strncpy(prefix, (const char*) NamedColorList->Prefix, 32); 3142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov strncpy(suffix, (const char*) NamedColorList->Suffix, 32); 3143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov suffix[31] = prefix[31] = 0; 3145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Write(io, 32, prefix)) return FALSE; 3147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Write(io, 32, suffix)) return FALSE; 3148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nColors; i++) { 3150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number PCS[3]; 3152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number Colorant[cmsMAXCHANNELS]; 3153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char Root[33]; 3154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsNamedColorInfo(NamedColorList, i, Root, NULL, NULL, PCS, Colorant)) return 0; 3156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Write(io, 32 , Root)) return FALSE; 3157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Array(io, 3, PCS)) return FALSE; 3158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Array(io, NamedColorList ->ColorantCount, Colorant)) return FALSE; 3159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 3162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 3164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_NamedColor_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n) 3169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) Ptr; 3171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsDupNamedColorList(nc); 3173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 3175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_NamedColor_Free(struct _cms_typehandler_struct* self, void* Ptr) 3181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeNamedColorList((cmsNAMEDCOLORLIST*) Ptr); 3183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 3184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigProfileSequenceDescType 3191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This type is an array of structures, each of which contains information from the 3194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// header fields and tags from the original profiles which were combined to create 3195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// the final profile. The order of the structures is the order in which the profiles 3196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// were combined and includes a structure for the final profile. This provides a 3197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// description of the profile sequence from source to destination, 3198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// typically used with the DeviceLink profile. 3199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3201ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool ReadEmbeddedText(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU** mlu, cmsUInt32Number SizeOfTag) 3202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsTagTypeSignature BaseType; 3204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nItems; 3205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseType = _cmsReadTypeBase(io); 3207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch (BaseType) { 3209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cmsSigTextType: 3211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (*mlu) cmsMLUfree(*mlu); 3212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *mlu = (cmsMLU*)Type_Text_Read(self, io, &nItems, SizeOfTag); 3213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (*mlu != NULL); 3214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cmsSigTextDescriptionType: 3216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (*mlu) cmsMLUfree(*mlu); 3217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *mlu = (cmsMLU*) Type_Text_Description_Read(self, io, &nItems, SizeOfTag); 3218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (*mlu != NULL); 3219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 3221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TBD: Size is needed for MLU, and we have no idea on which is the available size 3222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 3223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cmsSigMultiLocalizedUnicodeType: 3225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (*mlu) cmsMLUfree(*mlu); 3226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *mlu = (cmsMLU*) Type_MLU_Read(self, io, &nItems, SizeOfTag); 3227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (*mlu != NULL); 3228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: return FALSE; 3230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_ProfileSequenceDesc_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 3236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSEQ* OutSeq; 3238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, Count; 3239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 3241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &Count)) return NULL; 3243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL; 3245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= sizeof(cmsUInt32Number); 3246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov OutSeq = cmsAllocProfileSequenceDescription(self ->ContextID, Count); 3249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (OutSeq == NULL) return NULL; 3250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov OutSeq ->n = Count; 3252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get structures as well 3254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Count; i++) { 3256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPSEQDESC* sec = &OutSeq -> seq[i]; 3258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &sec ->deviceMfg)) goto Error; 3260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error; 3261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= sizeof(cmsUInt32Number); 3262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &sec ->deviceModel)) goto Error; 3264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error; 3265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= sizeof(cmsUInt32Number); 3266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt64Number(io, &sec ->attributes)) goto Error; 3268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < sizeof(cmsUInt64Number)) goto Error; 3269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= sizeof(cmsUInt64Number); 3270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, (cmsUInt32Number *)&sec ->technology)) goto Error; 3272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error; 3273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= sizeof(cmsUInt32Number); 3274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadEmbeddedText(self, io, &sec ->Manufacturer, SizeOfTag)) goto Error; 3276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadEmbeddedText(self, io, &sec ->Model, SizeOfTag)) goto Error; 3277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 3280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return OutSeq; 3281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3282ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 3283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeProfileSequenceDescription(OutSeq); 3284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Aux--Embed a text description type. It can be of type text description or multilocalized unicode 3289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// and it depends of the version number passed on cmsTagDescriptor structure instead of stack 3290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3291ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool SaveDescription(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* Text) 3292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (self ->ICCVersion < 0x4000000) { 3294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteTypeBase(io, cmsSigTextDescriptionType)) return FALSE; 3296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return Type_Text_Description_Write(self, io, Text, 1); 3297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 3299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteTypeBase(io, cmsSigMultiLocalizedUnicodeType)) return FALSE; 3300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return Type_MLU_Write(self, io, Text, 1); 3301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3306ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_ProfileSequenceDesc_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 3307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSEQ* Seq = (cmsSEQ*) Ptr; 3309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 3310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, Seq->n)) return FALSE; 3312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Seq ->n; i++) { 3314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPSEQDESC* sec = &Seq -> seq[i]; 3316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, sec ->deviceMfg)) return FALSE; 3318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, sec ->deviceModel)) return FALSE; 3319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt64Number(io, &sec ->attributes)) return FALSE; 3320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, sec ->technology)) return FALSE; 3321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!SaveDescription(self, io, sec ->Manufacturer)) return FALSE; 3323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!SaveDescription(self, io, sec ->Model)) return FALSE; 3324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 3327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 3329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_ProfileSequenceDesc_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n) 3334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsDupProfileSequenceDescription((cmsSEQ*) Ptr); 3336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 3338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_ProfileSequenceDesc_Free(struct _cms_typehandler_struct* self, void* Ptr) 3343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeProfileSequenceDescription((cmsSEQ*) Ptr); 3345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 3346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigProfileSequenceIdType 3353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 3355ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovIn certain workflows using ICC Device Link Profiles, it is necessary to identify the 3356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovoriginal profiles that were combined to create the Device Link Profile. 3357ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovThis type is an array of structures, each of which contains information for 3358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovidentification of a profile used in a sequence 3359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov*/ 3360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3363ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool ReadSeqID(struct _cms_typehandler_struct* self, 3364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsIOHANDLER* io, 3365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* Cargo, 3366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number n, 3367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number SizeOfTag) 3368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSEQ* OutSeq = (cmsSEQ*) Cargo; 3370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPSEQDESC* seq = &OutSeq ->seq[n]; 3371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io -> Read(io, seq ->ProfileID.ID8, 16, 1) != 1) return FALSE; 3373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadEmbeddedText(self, io, &seq ->Description, SizeOfTag)) return FALSE; 3374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 3376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_ProfileSequenceId_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 3382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSEQ* OutSeq; 3384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Count; 3385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number BaseOffset; 3386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 3388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get actual position as a basis for element offsets 3390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); 3391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get table count 3393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &Count)) return NULL; 3394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= sizeof(cmsUInt32Number); 3395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Allocate an empty structure 3397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov OutSeq = cmsAllocProfileSequenceDescription(self ->ContextID, Count); 3398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (OutSeq == NULL) return NULL; 3399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read the position table 3402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadPositionTable(self, io, Count, BaseOffset, OutSeq, ReadSeqID)) { 3403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeProfileSequenceDescription(OutSeq); 3405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Success 3409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 3410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return OutSeq; 3411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3416ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool WriteSeqID(struct _cms_typehandler_struct* self, 3417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsIOHANDLER* io, 3418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* Cargo, 3419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number n, 3420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number SizeOfTag) 3421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSEQ* Seq = (cmsSEQ*) Cargo; 3423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Write(io, 16, Seq ->seq[n].ProfileID.ID8)) return FALSE; 3425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Store here the MLU 3427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!SaveDescription(self, io, Seq ->seq[n].Description)) return FALSE; 3428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 3430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 3432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3435ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_ProfileSequenceId_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 3436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSEQ* Seq = (cmsSEQ*) Ptr; 3438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number BaseOffset; 3439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Keep the base offset 3441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); 3442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // This is the table count 3444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, Seq ->n)) return FALSE; 3445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // This is the position table and content 3447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WritePositionTable(self, io, 0, Seq ->n, BaseOffset, Seq, WriteSeqID)) return FALSE; 3448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 3450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 3452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_ProfileSequenceId_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n) 3456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsDupProfileSequenceDescription((cmsSEQ*) Ptr); 3458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 3460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_ProfileSequenceId_Free(struct _cms_typehandler_struct* self, void* Ptr) 3465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeProfileSequenceDescription((cmsSEQ*) Ptr); 3467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 3468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigUcrBgType 3475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 3477ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovThis type contains curves representing the under color removal and black 3478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovgeneration and a text string which is a general description of the method used 3479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovfor the ucr/bg. 3480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov*/ 3481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_UcrBg_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 3484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUcrBg* n = (cmsUcrBg*) _cmsMallocZero(self ->ContextID, sizeof(cmsUcrBg)); 3486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number CountUcr, CountBg; 3487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* ASCIIString; 3488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 3490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (n == NULL) return NULL; 3491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // First curve is Under color removal 3493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &CountUcr)) return NULL; 3494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL; 3495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= sizeof(cmsUInt32Number); 3496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n ->Ucr = cmsBuildTabulatedToneCurve16(self ->ContextID, CountUcr, NULL); 3498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (n ->Ucr == NULL) return NULL; 3499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Array(io, CountUcr, n ->Ucr->Table16)) return NULL; 3501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL; 3502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= CountUcr * sizeof(cmsUInt16Number); 3503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Second curve is Black generation 3505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &CountBg)) return NULL; 3506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL; 3507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= sizeof(cmsUInt32Number); 3508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n ->Bg = cmsBuildTabulatedToneCurve16(self ->ContextID, CountBg, NULL); 3510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (n ->Bg == NULL) return NULL; 3511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Array(io, CountBg, n ->Bg->Table16)) return NULL; 3512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag < CountBg * sizeof(cmsUInt16Number)) return NULL; 3513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= CountBg * sizeof(cmsUInt16Number); 3514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (SizeOfTag == UINT_MAX) return NULL; 3515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Now comes the text. The length is specified by the tag size 3517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n ->Desc = cmsMLUalloc(self ->ContextID, 1); 3518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (n ->Desc == NULL) return NULL; 3519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ASCIIString = (char*) _cmsMalloc(self ->ContextID, SizeOfTag + 1); 3521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io ->Read(io, ASCIIString, sizeof(char), SizeOfTag) != SizeOfTag) return NULL; 3522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ASCIIString[SizeOfTag] = 0; 3523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLUsetASCII(n ->Desc, cmsNoLanguage, cmsNoCountry, ASCIIString); 3524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, ASCIIString); 3525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 3527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) n; 3528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3531ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_UcrBg_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 3532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUcrBg* Value = (cmsUcrBg*) Ptr; 3534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number TextSize; 3535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* Text; 3536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // First curve is Under color removal 3538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, Value ->Ucr ->nEntries)) return FALSE; 3539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Array(io, Value ->Ucr ->nEntries, Value ->Ucr ->Table16)) return FALSE; 3540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Then black generation 3542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, Value ->Bg ->nEntries)) return FALSE; 3543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Array(io, Value ->Bg ->nEntries, Value ->Bg ->Table16)) return FALSE; 3544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Now comes the text. The length is specified by the tag size 3546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TextSize = cmsMLUgetASCII(Value ->Desc, cmsNoLanguage, cmsNoCountry, NULL, 0); 3547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Text = (char*) _cmsMalloc(self ->ContextID, TextSize); 3548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (cmsMLUgetASCII(Value ->Desc, cmsNoLanguage, cmsNoCountry, Text, TextSize) != TextSize) return FALSE; 3549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Write(io, TextSize, Text)) return FALSE; 3551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Text); 3552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 3554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 3556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_UcrBg_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 3560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUcrBg* Src = (cmsUcrBg*) Ptr; 3562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUcrBg* NewUcrBg = (cmsUcrBg*) _cmsMallocZero(self ->ContextID, sizeof(cmsUcrBg)); 3563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (NewUcrBg == NULL) return NULL; 3565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewUcrBg ->Bg = cmsDupToneCurve(Src ->Bg); 3567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewUcrBg ->Ucr = cmsDupToneCurve(Src ->Ucr); 3568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewUcrBg ->Desc = cmsMLUdup(Src ->Desc); 3569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) NewUcrBg; 3571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 3573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_UcrBg_Free(struct _cms_typehandler_struct* self, void *Ptr) 3577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUcrBg* Src = (cmsUcrBg*) Ptr; 3579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Src ->Ucr) cmsFreeToneCurve(Src ->Ucr); 3581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Src ->Bg) cmsFreeToneCurve(Src ->Bg); 3582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Src ->Desc) cmsMLUfree(Src ->Desc); 3583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Ptr); 3585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigCrdInfoType 3589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 3592ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovThis type contains the PostScript product name to which this profile corresponds 3593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovand the names of the companion CRDs. Recall that a single profile can generate 3594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovmultiple CRDs. It is implemented as a MLU being the language code "PS" and then 3595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovcountry varies for each element: 3596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nm: PostScript product name 3598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov #0: Rendering intent 0 CRD name 3599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov #1: Rendering intent 1 CRD name 3600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov #2: Rendering intent 2 CRD name 3601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov #3: Rendering intent 3 CRD name 3602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov*/ 3603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Auxiliar, read an string specified as count + string 3607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3608ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool ReadCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, cmsUInt32Number* SizeOfTag, const char* Section) 3609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Count; 3611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* Text; 3612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (*SizeOfTag < sizeof(cmsUInt32Number)) return FALSE; 3614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &Count)) return FALSE; 3616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Count > UINT_MAX - sizeof(cmsUInt32Number)) return FALSE; 3618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (*SizeOfTag < Count + sizeof(cmsUInt32Number)) return FALSE; 3619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Text = (char*) _cmsMalloc(self ->ContextID, Count+1); 3621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Text == NULL) return FALSE; 3622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io ->Read(io, Text, sizeof(cmsUInt8Number), Count) != Count) { 3624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Text); 3625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 3626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Text[Count] = 0; 3629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLUsetASCII(mlu, "PS", Section, Text); 3631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Text); 3632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *SizeOfTag -= (Count + sizeof(cmsUInt32Number)); 3634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 3635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3638ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool WriteCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, const char* Section) 3639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number TextSize; 3641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* Text; 3642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TextSize = cmsMLUgetASCII(mlu, "PS", Section, NULL, 0); 3644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Text = (char*) _cmsMalloc(self ->ContextID, TextSize); 3645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, TextSize)) return FALSE; 3647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (cmsMLUgetASCII(mlu, "PS", Section, Text, TextSize) == 0) return FALSE; 3649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Write(io, TextSize, Text)) return FALSE; 3651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Text); 3652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 3654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_CrdInfo_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 3658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLU* mlu = cmsMLUalloc(self ->ContextID, 5); 3660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 3662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "nm")) goto Error; 3663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "#0")) goto Error; 3664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "#1")) goto Error; 3665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "#2")) goto Error; 3666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "#3")) goto Error; 3667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 3669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) mlu; 3670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3671ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 3672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLUfree(mlu); 3673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3678ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_CrdInfo_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 3679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLU* mlu = (cmsMLU*) Ptr; 3682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteCountAndSting(self, io, mlu, "nm")) goto Error; 3684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteCountAndSting(self, io, mlu, "#0")) goto Error; 3685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteCountAndSting(self, io, mlu, "#1")) goto Error; 3686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteCountAndSting(self, io, mlu, "#2")) goto Error; 3687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteCountAndSting(self, io, mlu, "#3")) goto Error; 3688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 3690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3691ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 3692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 3693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 3695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_CrdInfo_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 3700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsMLUdup((cmsMLU*) Ptr); 3702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 3704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_CrdInfo_Free(struct _cms_typehandler_struct* self, void *Ptr) 3709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLUfree((cmsMLU*) Ptr); 3711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 3712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigScreeningType 3718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 3720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//The screeningType describes various screening parameters including screen 3721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//frequency, screening angle, and spot shape. 3722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_Screening_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 3725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsScreening* sc = NULL; 3727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 3728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sc = (cmsScreening*) _cmsMallocZero(self ->ContextID, sizeof(cmsScreening)); 3730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (sc == NULL) return NULL; 3731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 3733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &sc ->Flag)) goto Error; 3735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &sc ->nChannels)) goto Error; 3736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (sc ->nChannels > cmsMAXCHANNELS - 1) 3738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov sc ->nChannels = cmsMAXCHANNELS - 1; 3739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < sc ->nChannels; i++) { 3741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &sc ->Channels[i].Frequency)) goto Error; 3743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &sc ->Channels[i].ScreenAngle)) goto Error; 3744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &sc ->Channels[i].SpotShape)) goto Error; 3745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 3749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) sc; 3751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3752ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 3753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (sc != NULL) 3754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, sc); 3755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 3759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3763ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_Screening_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 3764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsScreening* sc = (cmsScreening* ) Ptr; 3766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 3767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, sc ->Flag)) return FALSE; 3769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, sc ->nChannels)) return FALSE; 3770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < sc ->nChannels; i++) { 3772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, sc ->Channels[i].Frequency)) return FALSE; 3774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, sc ->Channels[i].ScreenAngle)) return FALSE; 3775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, sc ->Channels[i].SpotShape)) return FALSE; 3776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 3779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 3781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_Screening_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 3787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsScreening)); 3789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 3791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_Screening_Free(struct _cms_typehandler_struct* self, void* Ptr) 3796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Ptr); 3798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigViewingConditionsType 3802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 3804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//This type represents a set of viewing condition parameters including: 3805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//CIE �absolute?illuminant white point tristimulus values and CIE �absolute?//surround tristimulus values. 3806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_ViewingConditions_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 3809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsICCViewingConditions* vc = NULL; 3811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vc = (cmsICCViewingConditions*) _cmsMallocZero(self ->ContextID, sizeof(cmsICCViewingConditions)); 3813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (vc == NULL) return NULL; 3814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 3816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadXYZNumber(io, &vc ->IlluminantXYZ)) goto Error; 3818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadXYZNumber(io, &vc ->SurroundXYZ)) goto Error; 3819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &vc ->IlluminantType)) goto Error; 3820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 3822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) vc; 3824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3825ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 3826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (vc != NULL) 3827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, vc); 3828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 3832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3836ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_ViewingConditions_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 3837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsICCViewingConditions* sc = (cmsICCViewingConditions* ) Ptr; 3839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteXYZNumber(io, &sc ->IlluminantXYZ)) return FALSE; 3841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteXYZNumber(io, &sc ->SurroundXYZ)) return FALSE; 3842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, sc ->IlluminantType)) return FALSE; 3843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 3845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 3847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_ViewingConditions_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 3853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsScreening)); 3855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 3857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_ViewingConditions_Free(struct _cms_typehandler_struct* self, void* Ptr) 3862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Ptr); 3864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigMultiProcessElementType 3869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 3870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* GenericMPEdup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 3874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsStageDup((cmsStage*) Ptr); 3876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 3878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid GenericMPEfree(struct _cms_typehandler_struct* self, void *Ptr) 3883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStageFree((cmsStage*) Ptr); 3885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 3886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 3888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 3889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Each curve is stored in one or more curve segments, with break-points specified between curve segments. 3891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The first curve segment always starts at �Infinity, and the last curve segment always ends at +Infinity. The 3892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// first and last curve segments shall be specified in terms of a formula, whereas the other segments shall be 3893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// specified either in terms of a formula, or by a sampled curve. 3894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Read an embedded segmented curve 3897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 3898ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHANDLER* io) 3899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 3900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsCurveSegSignature ElementSig; 3901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, j; 3902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number nSegments; 3903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsCurveSegment* Segments; 3904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve* Curve; 3905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat32Number PrevBreak = -1E22F; // - infinite 3906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Take signature and channels for each element. 3908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return NULL; 3909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // That should be a segmented curve 3911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementSig != cmsSigSegmentedCurve) return NULL; 3912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, NULL)) return NULL; 3914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &nSegments)) return NULL; 3915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, NULL)) return NULL; 3916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nSegments < 1) return NULL; 3918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Segments = (cmsCurveSegment*) _cmsCalloc(self ->ContextID, nSegments, sizeof(cmsCurveSegment)); 3919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Segments == NULL) return NULL; 3920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read breakpoints 3922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < (cmsUInt32Number) nSegments - 1; i++) { 3923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Segments[i].x0 = PrevBreak; 3925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadFloat32Number(io, &Segments[i].x1)) goto Error; 3926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PrevBreak = Segments[i].x1; 3927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Segments[nSegments-1].x0 = PrevBreak; 3930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Segments[nSegments-1].x1 = 1E22F; // A big cmsFloat32Number number 3931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read segments 3933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nSegments; i++) { 3934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) goto Error; 3936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, NULL)) goto Error; 3937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch (ElementSig) { 3939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cmsSigFormulaCurveSeg: { 3941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number Type; 3943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number ParamsByType[] = {4, 5, 5 }; 3944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &Type)) goto Error; 3946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, NULL)) goto Error; 3947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Segments[i].Type = Type + 6; 3949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Type > 2) goto Error; 3950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (j=0; j < ParamsByType[Type]; j++) { 3952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat32Number f; 3954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadFloat32Number(io, &f)) goto Error; 3955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Segments[i].Params[j] = f; 3956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 3959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cmsSigSampledCurveSeg: { 3962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Count; 3963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &Count)) return NULL; 3965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Segments[i].nGridPoints = Count; 3967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Segments[i].SampledPoints = (cmsFloat32Number*) _cmsCalloc(self ->ContextID, Count, sizeof(cmsFloat32Number)); 3968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Segments[i].SampledPoints == NULL) goto Error; 3969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (j=0; j < Count; j++) { 3971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadFloat32Number(io, &Segments[i].SampledPoints[j])) goto Error; 3972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 3975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 3977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char String[5]; 3979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagSignature2String(String, (cmsTagSignature) ElementSig); 3981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve element type '%s' found.", String); 3982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Curve = cmsBuildSegmentedToneCurve(self ->ContextID, nSegments, Segments); 3989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nSegments; i++) { 3991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Segments[i].SampledPoints) _cmsFree(self ->ContextID, Segments[i].SampledPoints); 3992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Segments); 3994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return Curve; 3995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3996ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 3997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Segments) _cmsFree(self ->ContextID, Segments); 3998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 3999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4003ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool ReadMPECurve(struct _cms_typehandler_struct* self, 4004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsIOHANDLER* io, 4005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* Cargo, 4006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number n, 4007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number SizeOfTag) 4008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve** GammaTables = ( cmsToneCurve**) Cargo; 4010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov GammaTables[n] = ReadSegmentedCurve(self, io); 4012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (GammaTables[n] != NULL); 4013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 4015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_MPEcurve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 4019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage* mpe = NULL; 4021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number InputChans, OutputChans; 4022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, BaseOffset; 4023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve** GammaTables; 4024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 4026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get actual position as a basis for element offsets 4028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); 4029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &InputChans)) return NULL; 4031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; 4032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (InputChans != OutputChans) return NULL; 4034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov GammaTables = (cmsToneCurve**) _cmsCalloc(self ->ContextID, InputChans, sizeof(cmsToneCurve*)); 4036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (GammaTables == NULL) return NULL; 4037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ReadPositionTable(self, io, InputChans, BaseOffset, GammaTables, ReadMPECurve)) { 4039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = cmsStageAllocToneCurves(self ->ContextID, InputChans, GammaTables); 4041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 4043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = NULL; 4044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < InputChans; i++) { 4047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (GammaTables[i]) cmsFreeToneCurve(GammaTables[i]); 4048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, GammaTables); 4051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = (mpe != NULL) ? 1 : 0; 4052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return mpe; 4053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 4055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Write a single segmented curve. NO CHECK IS PERFORMED ON VALIDITY 4059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4060ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool WriteSegmentedCurve(cmsIOHANDLER* io, cmsToneCurve* g) 4061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, j; 4063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsCurveSegment* Segments = g ->Segments; 4064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nSegments = g ->nSegments; 4065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, cmsSigSegmentedCurve)) goto Error; 4067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) goto Error; 4068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) nSegments)) goto Error; 4069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 0)) goto Error; 4070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write the break-points 4072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nSegments - 1; i++) { 4073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteFloat32Number(io, Segments[i].x1)) goto Error; 4074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write the segments 4077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < g ->nSegments; i++) { 4078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsCurveSegment* ActualSeg = Segments + i; 4080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ActualSeg -> Type == 0) { 4082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // This is a sampled curve 4084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) cmsSigSampledCurveSeg)) goto Error; 4085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) goto Error; 4086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, ActualSeg -> nGridPoints)) goto Error; 4087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (j=0; j < g ->Segments[i].nGridPoints; j++) { 4089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteFloat32Number(io, ActualSeg -> SampledPoints[j])) goto Error; 4090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 4094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int Type; 4095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number ParamsByType[] = { 4, 5, 5 }; 4096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // This is a formula-based 4098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) cmsSigFormulaCurveSeg)) goto Error; 4099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) goto Error; 4100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // We only allow 1, 2 and 3 as types 4102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Type = ActualSeg ->Type - 6; 4103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Type > 2 || Type < 0) goto Error; 4104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) Type)) goto Error; 4106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 0)) goto Error; 4107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (j=0; j < ParamsByType[Type]; j++) { 4109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteFloat32Number(io, (cmsFloat32Number) ActualSeg ->Params[j])) goto Error; 4110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // It seems there is no need to align. Code is here, and for safety commented out 4114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // if (!_cmsWriteAlignment(io)) goto Error; 4115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4119ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 4120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 4121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4125ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool WriteMPECurve(struct _cms_typehandler_struct* self, 4126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsIOHANDLER* io, 4127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* Cargo, 4128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number n, 4129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number SizeOfTag) 4130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageToneCurvesData* Curves = (_cmsStageToneCurvesData*) Cargo; 4132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return WriteSegmentedCurve(io, Curves ->TheCurves[n]); 4134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 4136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 4137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Write a curve, checking first for validity 4140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4141ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_MPEcurve_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 4142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number BaseOffset; 4144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage* mpe = (cmsStage*) Ptr; 4145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageToneCurvesData* Curves = (_cmsStageToneCurvesData*) mpe ->Data; 4146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); 4148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write the header. Since those are curves, input and output channels are same 4150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE; 4151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE; 4152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WritePositionTable(self, io, 0, 4154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe ->InputChannels, BaseOffset, Curves, WriteMPECurve)) return FALSE; 4155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 4160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The matrix is organized as an array of PxQ+Q elements, where P is the number of input channels to the 4165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// matrix, and Q is the number of output channels. The matrix elements are each float32Numbers. The array 4166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// is organized as follows: 4167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// array = [e11, e12, ? e1P, e21, e22, ? e2P, ? eQ1, eQ2, ? eQP, e1, e2, ? eQ] 4168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 4171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage* mpe; 4173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number InputChans, OutputChans; 4174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nElems, i; 4175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number* Matrix; 4176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat64Number* Offsets; 4177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &InputChans)) return NULL; 4179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; 4180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nElems = InputChans * OutputChans; 4183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Input and output chans may be ANY (up to 0xffff) 4185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Matrix = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, nElems, sizeof(cmsFloat64Number)); 4186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Matrix == NULL) return NULL; 4187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Offsets = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, OutputChans, sizeof(cmsFloat64Number)); 4189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Offsets == NULL) { 4190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Matrix); 4192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 4193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nElems; i++) { 4196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat32Number v; 4198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadFloat32Number(io, &v)) return NULL; 4200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Matrix[i] = v; 4201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < OutputChans; i++) { 4205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat32Number v; 4207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadFloat32Number(io, &v)) return NULL; 4209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Offsets[i] = v; 4210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = cmsStageAllocMatrix(self ->ContextID, OutputChans, InputChans, Matrix, Offsets); 4214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Matrix); 4215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Offsets); 4216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 4218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return mpe; 4220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 4222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4225ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_MPEmatrix_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 4226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, nElems; 4228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage* mpe = (cmsStage*) Ptr; 4229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageMatrixData* Matrix = (_cmsStageMatrixData*) mpe ->Data; 4230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE; 4232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->OutputChannels)) return FALSE; 4233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nElems = mpe ->InputChannels * mpe ->OutputChannels; 4235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nElems; i++) { 4237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteFloat32Number(io, (cmsFloat32Number) Matrix->Double[i])) return FALSE; 4238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < mpe ->OutputChannels; i++) { 4242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Matrix ->Offset == NULL) { 4244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteFloat32Number(io, 0)) return FALSE; 4246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 4248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteFloat32Number(io, (cmsFloat32Number) Matrix->Offset[i])) return FALSE; 4249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 4255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 4256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 4262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage* mpe = NULL; 4264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number InputChans, OutputChans; 4265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number Dimensions8[16]; 4266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, nMaxGrids, GridPoints[MAX_INPUT_DIMENSIONS]; 4267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageCLutData* clut; 4268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &InputChans)) return NULL; 4270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; 4271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (InputChans == 0) goto Error; 4273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (OutputChans == 0) goto Error; 4274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (io ->Read(io, Dimensions8, sizeof(cmsUInt8Number), 16) != 16) 4276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 4277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Copy MAX_INPUT_DIMENSIONS at most. Expand to cmsUInt32Number 4279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? MAX_INPUT_DIMENSIONS : InputChans; 4280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nMaxGrids; i++) GridPoints[i] = (cmsUInt32Number) Dimensions8[i]; 4281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Allocate the true CLUT 4283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL); 4284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mpe == NULL) goto Error; 4285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read the data 4287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clut = (_cmsStageCLutData*) mpe ->Data; 4288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < clut ->nEntries; i++) { 4289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadFloat32Number(io, &clut ->Tab.TFloat[i])) goto Error; 4291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 4294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return mpe; 4295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4296ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 4297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 4298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mpe != NULL) cmsStageFree(mpe); 4299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 4300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 4302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Write a CLUT in floating point 4305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4306ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_MPEclut_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 4307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number Dimensions8[16]; 4309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 4310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage* mpe = (cmsStage*) Ptr; 4311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsStageCLutData* clut = (_cmsStageCLutData*) mpe ->Data; 4312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Check for maximum number of channels 4314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mpe -> InputChannels > 15) return FALSE; 4315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Only floats are supported in MPE 4317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (clut ->HasFloatValues == FALSE) return FALSE; 4318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE; 4320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->OutputChannels)) return FALSE; 4321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memset(Dimensions8, 0, sizeof(Dimensions8)); 4323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < mpe ->InputChannels; i++) 4325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Dimensions8[i] = (cmsUInt8Number) clut ->Params ->nSamples[i]; 4326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Write(io, 16, Dimensions8)) return FALSE; 4328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < clut ->nEntries; i++) { 4330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteFloat32Number(io, clut ->Tab.TFloat[i])) return FALSE; 4332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 4337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 4338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This is the list of built-in MPE types 4343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic _cmsTagTypeLinkedList SupportedMPEtypes[] = { 4344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{{ (cmsTagTypeSignature) cmsSigBAcsElemType, NULL, NULL, NULL, NULL, NULL, 0 }, &SupportedMPEtypes[1] }, // Ignore those elements for now 4346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{{ (cmsTagTypeSignature) cmsSigEAcsElemType, NULL, NULL, NULL, NULL, NULL, 0 }, &SupportedMPEtypes[2] }, // (That's what the spec says) 4347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigCurveSetElemType, MPEcurve), &SupportedMPEtypes[3] }, 4349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigMatrixElemType, MPEmatrix), &SupportedMPEtypes[4] }, 4350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigCLutElemType, MPEclut), NULL }, 4351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}; 4352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov_cmsTagTypePluginChunkType _cmsMPETypePluginChunk = { NULL }; 4354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4356ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool ReadMPEElem(struct _cms_typehandler_struct* self, 4357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsIOHANDLER* io, 4358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* Cargo, 4359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number n, 4360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number SizeOfTag) 4361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStageSignature ElementSig; 4363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsTagTypeHandler* TypeHandler; 4364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nItems; 4365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline *NewLUT = (cmsPipeline *) Cargo; 4366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagTypePluginChunkType* MPETypePluginChunk = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(self->ContextID, MPEPlugin); 4367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Take signature and channels for each element. 4370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return FALSE; 4371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // The reserved placeholder 4373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, NULL)) return FALSE; 4374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read diverse MPE types 4376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, MPETypePluginChunk ->TagTypes, SupportedMPEtypes); 4377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (TypeHandler == NULL) { 4378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char String[5]; 4380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagSignature2String(String, (cmsTagSignature) ElementSig); 4382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // An unknown element was found. 4384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown MPE type '%s' found.", String); 4385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 4386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // If no read method, just ignore the element (valid for cmsSigBAcsElemType and cmsSigEAcsElemType) 4389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read the MPE. No size is given 4390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (TypeHandler ->ReadPtr != NULL) { 4391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // This is a real element which should be read and processed 4393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, (cmsStage*) TypeHandler ->ReadPtr(self, io, &nItems, SizeOfTag))) 4394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 4395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 4400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 4401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This is the main dispatcher for MPE 4405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_MPE_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 4407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number InputChans, OutputChans; 4409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number ElementCount; 4410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline *NewLUT = NULL; 4411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number BaseOffset; 4412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get actual position as a basis for element offsets 4414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); 4415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read channels and element count 4417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &InputChans)) return NULL; 4418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; 4419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Allocates an empty LUT 4421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewLUT = cmsPipelineAlloc(self ->ContextID, InputChans, OutputChans); 4422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (NewLUT == NULL) return NULL; 4423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &ElementCount)) return NULL; 4425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadPositionTable(self, io, ElementCount, BaseOffset, NewLUT, ReadMPEElem)) { 4427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (NewLUT != NULL) cmsPipelineFree(NewLUT); 4428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 4429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 4430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Success 4433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 4434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NewLUT; 4435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 4437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This one is a liitle bit more complex, so we don't use position tables this time. 4442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4443ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_MPE_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 4444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, BaseOffset, DirectoryPos, CurrentPos; 4446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int inputChan, outputChan; 4447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number ElemCount; 4448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL, Before; 4449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStageSignature ElementSig; 4450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipeline* Lut = (cmsPipeline*) Ptr; 4451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsStage* Elem = Lut ->Elements; 4452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsTagTypeHandler* TypeHandler; 4453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagTypePluginChunkType* MPETypePluginChunk = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(self->ContextID, MPEPlugin); 4454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); 4456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inputChan = cmsPipelineInputChannels(Lut); 4458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outputChan = cmsPipelineOutputChannels(Lut); 4459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ElemCount = cmsPipelineStageCount(Lut); 4460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ElementOffsets = (cmsUInt32Number *) _cmsCalloc(self ->ContextID, ElemCount, sizeof(cmsUInt32Number)); 4462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementOffsets == NULL) goto Error; 4463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ElementSizes = (cmsUInt32Number *) _cmsCalloc(self ->ContextID, ElemCount, sizeof(cmsUInt32Number)); 4465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementSizes == NULL) goto Error; 4466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write the head 4468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) inputChan)) goto Error; 4469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) outputChan)) goto Error; 4470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, (cmsUInt16Number) ElemCount)) goto Error; 4471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DirectoryPos = io ->Tell(io); 4473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write a fake directory to be filled latter on 4475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < ElemCount; i++) { 4476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) goto Error; // Offset 4477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) goto Error; // size 4478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write each single tag. Keep track of the size as well. 4481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < ElemCount; i++) { 4482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ElementOffsets[i] = io ->Tell(io) - BaseOffset; 4484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ElementSig = Elem ->Type; 4486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, MPETypePluginChunk->TagTypes, SupportedMPEtypes); 4488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (TypeHandler == NULL) { 4489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char String[5]; 4491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagSignature2String(String, (cmsTagSignature) ElementSig); 4493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // An unknow element was found. 4495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Found unknown MPE type '%s'", String); 4496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 4497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, ElementSig)) goto Error; 4500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, 0)) goto Error; 4501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Before = io ->Tell(io); 4502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!TypeHandler ->WritePtr(self, io, Elem, 1)) goto Error; 4503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteAlignment(io)) goto Error; 4504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ElementSizes[i] = io ->Tell(io) - Before; 4506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Elem = Elem ->Next; 4508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write the directory 4511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CurrentPos = io ->Tell(io); 4512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Seek(io, DirectoryPos)) goto Error; 4514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < ElemCount; i++) { 4516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, ElementOffsets[i])) goto Error; 4517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, ElementSizes[i])) goto Error; 4518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Seek(io, CurrentPos)) goto Error; 4521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementOffsets != NULL) _cmsFree(self ->ContextID, ElementOffsets); 4523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementSizes != NULL) _cmsFree(self ->ContextID, ElementSizes); 4524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4526ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 4527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementOffsets != NULL) _cmsFree(self ->ContextID, ElementOffsets); 4528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ElementSizes != NULL) _cmsFree(self ->ContextID, ElementSizes); 4529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 4530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 4532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_MPE_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 4537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsPipelineDup((cmsPipeline*) Ptr); 4539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 4541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 4542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_MPE_Free(struct _cms_typehandler_struct* self, void *Ptr) 4546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPipelineFree((cmsPipeline*) Ptr); 4548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 4549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 4551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 4555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigVcgtType 4556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 4557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define cmsVideoCardGammaTableType 0 4560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define cmsVideoCardGammaFormulaType 1 4561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Used internally 4563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct { 4564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov double Gamma; 4565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov double Min; 4566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov double Max; 4567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} _cmsVCGTGAMMA; 4568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_vcgt_Read(struct _cms_typehandler_struct* self, 4572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsIOHANDLER* io, 4573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number* nItems, 4574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number SizeOfTag) 4575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number TagType, n, i; 4577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve** Curves; 4578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 4580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read tag type 4582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &TagType)) return NULL; 4583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Allocate space for the array 4585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Curves = ( cmsToneCurve**) _cmsCalloc(self ->ContextID, 3, sizeof(cmsToneCurve*)); 4586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Curves == NULL) return NULL; 4587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // There are two possible flavors 4589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch (TagType) { 4590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Gamma is stored as a table 4592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cmsVideoCardGammaTableType: 4593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number nChannels, nElems, nBytes; 4595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Check channel count, which should be 3 (we don't support monochrome this time) 4597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &nChannels)) goto Error; 4598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nChannels != 3) { 4600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported number of channels for VCGT '%d'", nChannels); 4601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 4602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get Table element count and bytes per element 4605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &nElems)) goto Error; 4606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Number(io, &nBytes)) goto Error; 4607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Adobe's quirk fixup. Fixing broken profiles... 4609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (nElems == 256 && nBytes == 1 && SizeOfTag == 1576) 4610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nBytes = 2; 4611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Populate tone curves 4614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (n=0; n < 3; n++) { 4615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Curves[n] = cmsBuildTabulatedToneCurve16(self ->ContextID, nElems, NULL); 4617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Curves[n] == NULL) goto Error; 4618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // On depending on byte depth 4620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch (nBytes) { 4621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // One byte, 0..255 4623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 1: 4624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < nElems; i++) { 4625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt8Number v; 4627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt8Number(io, &v)) goto Error; 4629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Curves[n] ->Table16[i] = FROM_8_TO_16(v); 4630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 4632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // One word 0..65535 4634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 2: 4635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt16Array(io, nElems, Curves[n]->Table16)) goto Error; 4636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 4637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Unsupported 4639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 4640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported bit depth for VCGT '%d'", nBytes * 8); 4641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 4642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } // For all 3 channels 4644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 4646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // In this case, gamma is stored as a formula 4648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case cmsVideoCardGammaFormulaType: 4649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 4650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsVCGTGAMMA Colorant[3]; 4651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Populate tone curves 4653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (n=0; n < 3; n++) { 4654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov double Params[10]; 4656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Colorant[n].Gamma)) goto Error; 4658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Colorant[n].Min)) goto Error; 4659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsRead15Fixed16Number(io, &Colorant[n].Max)) goto Error; 4660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Parametric curve type 5 is: 4662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Y = (aX + b)^Gamma + e | X >= d 4663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Y = cX + f | X < d 4664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // vcgt formula is: 4666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Y = (Max ?Min) * (X ^ Gamma) + Min 4667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // So, the translation is 4669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // a = (Max ?Min) ^ ( 1 / Gamma) 4670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // e = Min 4671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // b=c=d=f=0 4672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Params[0] = Colorant[n].Gamma; 4674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Params[1] = pow((Colorant[n].Max - Colorant[n].Min), (1.0 / Colorant[n].Gamma)); 4675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Params[2] = 0; 4676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Params[3] = 0; 4677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Params[4] = 0; 4678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Params[5] = Colorant[n].Min; 4679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Params[6] = 0; 4680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Curves[n] = cmsBuildParametricToneCurve(self ->ContextID, 5, Params); 4682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Curves[n] == NULL) goto Error; 4683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 4686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Unsupported 4688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 4689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported tag type for VCGT '%d'", TagType); 4690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Error; 4691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 4694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) Curves; 4695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Regret, free all resources 4697ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 4698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeToneCurveTriple(Curves); 4700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Curves); 4701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 4702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(SizeOfTag); 4704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// We don't support all flavors, only 16bits tables and formula 4708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4709ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_vcgt_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 4710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve** Curves = (cmsToneCurve**) Ptr; 4712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, j; 4713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (cmsGetToneCurveParametricType(Curves[0]) == 5 && 4715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsGetToneCurveParametricType(Curves[1]) == 5 && 4716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsGetToneCurveParametricType(Curves[2]) == 5) { 4717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, cmsVideoCardGammaFormulaType)) return FALSE; 4719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Save parameters 4721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < 3; i++) { 4722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsVCGTGAMMA v; 4724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v.Gamma = Curves[i] ->Segments[0].Params[0]; 4726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v.Min = Curves[i] ->Segments[0].Params[5]; 4727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v.Max = pow(Curves[i] ->Segments[0].Params[1], v.Gamma) + v.Min; 4728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, v.Gamma)) return FALSE; 4730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, v.Min)) return FALSE; 4731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWrite15Fixed16Number(io, v.Max)) return FALSE; 4732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 4736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Always store as a table of 256 words 4738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, cmsVideoCardGammaTableType)) return FALSE; 4739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 3)) return FALSE; 4740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 256)) return FALSE; 4741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, 2)) return FALSE; 4742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < 3; i++) { 4744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (j=0; j < 256; j++) { 4745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFloat32Number v = cmsEvalToneCurveFloat(Curves[i], (cmsFloat32Number) (j / 255.0)); 4747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt16Number n = _cmsQuickSaturateWord(v * 65535.0); 4748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt16Number(io, n)) return FALSE; 4750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 4757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 4758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_vcgt_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 4762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve** OldCurves = (cmsToneCurve**) Ptr; 4764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsToneCurve** NewCurves; 4765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewCurves = ( cmsToneCurve**) _cmsCalloc(self ->ContextID, 3, sizeof(cmsToneCurve*)); 4767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (NewCurves == NULL) return NULL; 4768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewCurves[0] = cmsDupToneCurve(OldCurves[0]); 4770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewCurves[1] = cmsDupToneCurve(OldCurves[1]); 4771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov NewCurves[2] = cmsDupToneCurve(OldCurves[2]); 4772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) NewCurves; 4774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 4776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_vcgt_Free(struct _cms_typehandler_struct* self, void* Ptr) 4781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsFreeToneCurveTriple((cmsToneCurve**) Ptr); 4783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(self ->ContextID, Ptr); 4784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 4788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type cmsSigDictType 4789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 4790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Single column of the table can point to wchar or MLUC elements. Holds arrays of data 4792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct { 4793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsContext ContextID; 4794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number *Offsets; 4795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number *Sizes; 4796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} _cmsDICelem; 4797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct { 4799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsDICelem Name, Value, DisplayName, DisplayValue; 4800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} _cmsDICarray; 4802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Allocate an empty array element 4804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4805ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool AllocElem(cmsContext ContextID, _cmsDICelem* e, cmsUInt32Number Count) 4806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e->Offsets = (cmsUInt32Number *) _cmsCalloc(ContextID, Count, sizeof(cmsUInt32Number)); 4808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (e->Offsets == NULL) return FALSE; 4809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e->Sizes = (cmsUInt32Number *) _cmsCalloc(ContextID, Count, sizeof(cmsUInt32Number)); 4811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (e->Sizes == NULL) { 4812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(ContextID, e -> Offsets); 4814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 4815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e ->ContextID = ContextID; 4818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Free an array element 4822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid FreeElem(_cmsDICelem* e) 4824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (e ->Offsets != NULL) _cmsFree(e -> ContextID, e -> Offsets); 4826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (e ->Sizes != NULL) _cmsFree(e -> ContextID, e -> Sizes); 4827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e->Offsets = e ->Sizes = NULL; 4828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Get rid of whole array 4831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid FreeArray( _cmsDICarray* a) 4833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (a ->Name.Offsets != NULL) FreeElem(&a->Name); 4835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (a ->Value.Offsets != NULL) FreeElem(&a ->Value); 4836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (a ->DisplayName.Offsets != NULL) FreeElem(&a->DisplayName); 4837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (a ->DisplayValue.Offsets != NULL) FreeElem(&a ->DisplayValue); 4838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Allocate whole array 4842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4843ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool AllocArray(cmsContext ContextID, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length) 4844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Empty values 4846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov memset(a, 0, sizeof(_cmsDICarray)); 4847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // On depending on record size, create column arrays 4849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!AllocElem(ContextID, &a ->Name, Count)) goto Error; 4850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!AllocElem(ContextID, &a ->Value, Count)) goto Error; 4851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Length > 16) { 4853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!AllocElem(ContextID, &a -> DisplayName, Count)) goto Error; 4854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Length > 24) { 4857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!AllocElem(ContextID, &a ->DisplayValue, Count)) goto Error; 4858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4861ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 4862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FreeArray(a); 4863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 4864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Read one element 4867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4868ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool ReadOneElem(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, cmsUInt32Number BaseOffset) 4869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &e->Offsets[i])) return FALSE; 4871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &e ->Sizes[i])) return FALSE; 4872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // An offset of zero has special meaning and shal be preserved 4874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (e ->Offsets[i] > 0) 4875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e ->Offsets[i] += BaseOffset; 4876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4881ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool ReadOffsetArray(cmsIOHANDLER* io, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length, cmsUInt32Number BaseOffset) 4882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 4884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read column arrays 4886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Count; i++) { 4887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadOneElem(io, &a -> Name, i, BaseOffset)) return FALSE; 4889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadOneElem(io, &a -> Value, i, BaseOffset)) return FALSE; 4890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Length > 16) { 4892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadOneElem(io, &a ->DisplayName, i, BaseOffset)) return FALSE; 4894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Length > 24) { 4898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadOneElem(io, & a -> DisplayValue, i, BaseOffset)) return FALSE; 4900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Write one element 4907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4908ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool WriteOneElem(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i) 4909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, e->Offsets[i])) return FALSE; 4911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, e ->Sizes[i])) return FALSE; 4912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4917ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool WriteOffsetArray(cmsIOHANDLER* io, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length) 4918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i; 4920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Count; i++) { 4922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteOneElem(io, &a -> Name, i)) return FALSE; 4924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteOneElem(io, &a -> Value, i)) return FALSE; 4925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Length > 16) { 4927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteOneElem(io, &a -> DisplayName, i)) return FALSE; 4929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Length > 24) { 4932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteOneElem(io, &a -> DisplayValue, i)) return FALSE; 4934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4941ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool ReadOneWChar(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, wchar_t ** wcstr) 4942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nChars; 4945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Special case for undefined strings (see ICC Votable 4947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Proposal Submission, Dictionary Type and Metadata TAG Definition) 4948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (e -> Offsets[i] == 0) { 4949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *wcstr = NULL; 4951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io -> Seek(io, e -> Offsets[i])) return FALSE; 4955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nChars = e ->Sizes[i] / sizeof(cmsUInt16Number); 4957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *wcstr = (wchar_t*) _cmsMallocZero(e ->ContextID, (nChars + 1) * sizeof(wchar_t)); 4960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (*wcstr == NULL) return FALSE; 4961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadWCharArray(io, nChars, *wcstr)) { 4963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsFree(e ->ContextID, *wcstr); 4964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 4965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // End of string marker 4968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*wcstr)[nChars] = 0; 4969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4973ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsUInt32Number mywcslen(const wchar_t *s) 4974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const wchar_t *p; 4976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = s; 4978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while (*p) 4979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p++; 4980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (cmsUInt32Number)(p - s); 4982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 4983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 4985ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool WriteOneWChar(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, const wchar_t * wcstr, cmsUInt32Number BaseOffset) 4986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 4987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Before = io ->Tell(io); 4988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number n; 4989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e ->Offsets[i] = Before - BaseOffset; 4991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (wcstr == NULL) { 4993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e ->Sizes[i] = 0; 4994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e ->Offsets[i] = 0; 4995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 4996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 4997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 4998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n = mywcslen(wcstr); 4999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteWCharArray(io, n, wcstr)) return FALSE; 5000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e ->Sizes[i] = io ->Tell(io) - Before; 5002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 5003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 5006ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool ReadOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, cmsMLU** mlu) 5007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number nItems = 0; 5009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // A way to get null MLUCs 5011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (e -> Offsets[i] == 0 || e ->Sizes[i] == 0) { 5012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *mlu = NULL; 5014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 5015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io -> Seek(io, e -> Offsets[i])) return FALSE; 5018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *mlu = (cmsMLU*) Type_MLU_Read(self, io, &nItems, e ->Sizes[i]); 5020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return *mlu != NULL; 5021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 5024ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool WriteOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, const cmsMLU* mlu, cmsUInt32Number BaseOffset) 5025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number Before; 5027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Special case for undefined strings (see ICC Votable 5029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Proposal Submission, Dictionary Type and Metadata TAG Definition) 5030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (mlu == NULL) { 5031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e ->Sizes[i] = 0; 5032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e ->Offsets[i] = 0; 5033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 5034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Before = io ->Tell(io); 5037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e ->Offsets[i] = Before - BaseOffset; 5038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!Type_MLU_Write(self, io, (void*) mlu, 1)) return FALSE; 5040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e ->Sizes[i] = io ->Tell(io) - Before; 5042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 5043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 5047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid *Type_Dictionary_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) 5048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHANDLE hDict; 5050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, Count, Length; 5051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number BaseOffset; 5052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsDICarray a; 5053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov wchar_t *NameWCS = NULL, *ValueWCS = NULL; 5054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsMLU *DisplayNameMLU = NULL, *DisplayValueMLU=NULL; 5055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsBool rc; 5056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 0; 5058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get actual position as a basis for element offsets 5060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); 5061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get name-value record count 5063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &Count)) return NULL; 5064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= sizeof(cmsUInt32Number); 5065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Get rec length 5067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsReadUInt32Number(io, &Length)) return NULL; 5068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SizeOfTag -= sizeof(cmsUInt32Number); 5069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Check for valid lengths 5071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Length != 16 && Length != 24 && Length != 32) { 5072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown record length in dictionary '%d'", Length); 5073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 5074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Creates an empty dictionary 5077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov hDict = cmsDictAlloc(self -> ContextID); 5078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (hDict == NULL) return NULL; 5079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // On depending on record size, create column arrays 5081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!AllocArray(self -> ContextID, &a, Count, Length)) goto Error; 5082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Read column arrays 5084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadOffsetArray(io, &a, Count, Length, BaseOffset)) goto Error; 5085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Seek to each element and read it 5087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Count; i++) { 5088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadOneWChar(io, &a.Name, i, &NameWCS)) goto Error; 5090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadOneWChar(io, &a.Value, i, &ValueWCS)) goto Error; 5091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Length > 16) { 5093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadOneMLUC(self, io, &a.DisplayName, i, &DisplayNameMLU)) goto Error; 5094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Length > 24) { 5097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!ReadOneMLUC(self, io, &a.DisplayValue, i, &DisplayValueMLU)) goto Error; 5098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (NameWCS == NULL || ValueWCS == NULL) { 5101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSignalError(self->ContextID, cmsERROR_CORRUPTION_DETECTED, "Bad dictionary Name/Value"); 5103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rc = FALSE; 5104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 5106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rc = cmsDictAddEntry(hDict, NameWCS, ValueWCS, DisplayNameMLU, DisplayValueMLU); 5108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (NameWCS != NULL) _cmsFree(self ->ContextID, NameWCS); 5111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (ValueWCS != NULL) _cmsFree(self ->ContextID, ValueWCS); 5112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (DisplayNameMLU != NULL) cmsMLUfree(DisplayNameMLU); 5113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (DisplayValueMLU != NULL) cmsMLUfree(DisplayValueMLU); 5114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!rc) goto Error; 5116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FreeArray(&a); 5119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *nItems = 1; 5120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) hDict; 5121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5122ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 5123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FreeArray(&a); 5124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsDictFree(hDict); 5125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 5126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 5130ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool Type_Dictionary_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) 5131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsHANDLE hDict = (cmsHANDLE) Ptr; 5133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const cmsDICTentry* p; 5134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsBool AnyName, AnyValue; 5135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number i, Count, Length; 5136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUInt32Number DirectoryPos, CurrentPos, BaseOffset; 5137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsDICarray a; 5138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (hDict == NULL) return FALSE; 5140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); 5142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Let's inspect the dictionary 5144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Count = 0; AnyName = FALSE; AnyValue = FALSE; 5145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (p = cmsDictGetEntryList(hDict); p != NULL; p = cmsDictNextEntry(p)) { 5146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (p ->DisplayName != NULL) AnyName = TRUE; 5148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (p ->DisplayValue != NULL) AnyValue = TRUE; 5149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Count++; 5150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Length = 16; 5153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (AnyName) Length += 8; 5154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (AnyValue) Length += 8; 5155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, Count)) return FALSE; 5157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!_cmsWriteUInt32Number(io, Length)) return FALSE; 5158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Keep starting position of offsets table 5160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DirectoryPos = io ->Tell(io); 5161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Allocate offsets array 5163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!AllocArray(self ->ContextID, &a, Count, Length)) goto Error; 5164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write a fake directory to be filled latter on 5166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteOffsetArray(io, &a, Count, Length)) goto Error; 5167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write each element. Keep track of the size as well. 5169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmsDictGetEntryList(hDict); 5170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i=0; i < Count; i++) { 5171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteOneWChar(io, &a.Name, i, p ->Name, BaseOffset)) goto Error; 5173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteOneWChar(io, &a.Value, i, p ->Value, BaseOffset)) goto Error; 5174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (p ->DisplayName != NULL) { 5176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteOneMLUC(self, io, &a.DisplayName, i, p ->DisplayName, BaseOffset)) goto Error; 5177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (p ->DisplayValue != NULL) { 5180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteOneMLUC(self, io, &a.DisplayValue, i, p ->DisplayValue, BaseOffset)) goto Error; 5181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = cmsDictNextEntry(p); 5184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Write the directory 5187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CurrentPos = io ->Tell(io); 5188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Seek(io, DirectoryPos)) goto Error; 5189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!WriteOffsetArray(io, &a, Count, Length)) goto Error; 5191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!io ->Seek(io, CurrentPos)) goto Error; 5193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FreeArray(&a); 5195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 5196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5197ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovError: 5198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FreeArray(&a); 5199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FALSE; 5200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(nItems); 5202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 5206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* Type_Dictionary_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) 5207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (void*) cmsDictDup((cmsHANDLE) Ptr); 5209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(n); 5211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 5212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 5216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid Type_Dictionary_Free(struct _cms_typehandler_struct* self, void* Ptr) 5217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsDictFree((cmsHANDLE) Ptr); 5219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsUNUSED_PARAMETER(self); 5220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 5224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Type support main routines 5225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 5226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This is the list of built-in types 5229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic _cmsTagTypeLinkedList SupportedTagTypes[] = { 5230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigChromaticityType, Chromaticity), &SupportedTagTypes[1] }, 5232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigColorantOrderType, ColorantOrderType), &SupportedTagTypes[2] }, 5233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigS15Fixed16ArrayType, S15Fixed16), &SupportedTagTypes[3] }, 5234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigU16Fixed16ArrayType, U16Fixed16), &SupportedTagTypes[4] }, 5235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigTextType, Text), &SupportedTagTypes[5] }, 5236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigTextDescriptionType, Text_Description), &SupportedTagTypes[6] }, 5237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigCurveType, Curve), &SupportedTagTypes[7] }, 5238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigParametricCurveType, ParametricCurve), &SupportedTagTypes[8] }, 5239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigDateTimeType, DateTime), &SupportedTagTypes[9] }, 5240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigLut8Type, LUT8), &SupportedTagTypes[10] }, 5241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigLut16Type, LUT16), &SupportedTagTypes[11] }, 5242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigColorantTableType, ColorantTable), &SupportedTagTypes[12] }, 5243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigNamedColor2Type, NamedColor), &SupportedTagTypes[13] }, 5244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigMultiLocalizedUnicodeType, MLU), &SupportedTagTypes[14] }, 5245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigProfileSequenceDescType, ProfileSequenceDesc), &SupportedTagTypes[15] }, 5246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigSignatureType, Signature), &SupportedTagTypes[16] }, 5247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigMeasurementType, Measurement), &SupportedTagTypes[17] }, 5248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigDataType, Data), &SupportedTagTypes[18] }, 5249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigLutAtoBType, LUTA2B), &SupportedTagTypes[19] }, 5250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigLutBtoAType, LUTB2A), &SupportedTagTypes[20] }, 5251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigUcrBgType, UcrBg), &SupportedTagTypes[21] }, 5252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigCrdInfoType, CrdInfo), &SupportedTagTypes[22] }, 5253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigMultiProcessElementType, MPE), &SupportedTagTypes[23] }, 5254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigScreeningType, Screening), &SupportedTagTypes[24] }, 5255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigViewingConditionsType, ViewingConditions), &SupportedTagTypes[25] }, 5256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigXYZType, XYZ), &SupportedTagTypes[26] }, 5257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsCorbisBrokenXYZtype, XYZ), &SupportedTagTypes[27] }, 5258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsMonacoBrokenCurveType, Curve), &SupportedTagTypes[28] }, 5259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigProfileSequenceIdType, ProfileSequenceId), &SupportedTagTypes[29] }, 5260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigDictType, Dictionary), &SupportedTagTypes[30] }, 5261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{TYPE_HANDLER(cmsSigVcgtType, vcgt), NULL } 5262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}; 5263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov_cmsTagTypePluginChunkType _cmsTagTypePluginChunk = { NULL }; 5266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Duplicates the zone of memory used by the plug-in in the new context 5270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 5271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid DupTagTypeList(struct _cmsContext_struct* ctx, 5272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const struct _cmsContext_struct* src, 5273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int loc) 5274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagTypePluginChunkType newHead = { NULL }; 5276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagTypeLinkedList* entry; 5277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagTypeLinkedList* Anterior = NULL; 5278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagTypePluginChunkType* head = (_cmsTagTypePluginChunkType*) src->chunks[loc]; 5279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Walk the list copying all nodes 5281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (entry = head->TagTypes; 5282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry != NULL; 5283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry = entry ->Next) { 5284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagTypeLinkedList *newEntry = ( _cmsTagTypeLinkedList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTagTypeLinkedList)); 5286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (newEntry == NULL) 5288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 5289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // We want to keep the linked list order, so this is a little bit tricky 5291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov newEntry -> Next = NULL; 5292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Anterior) 5293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Anterior -> Next = newEntry; 5294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Anterior = newEntry; 5296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (newHead.TagTypes == NULL) 5298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov newHead.TagTypes = newEntry; 5299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ctx ->chunks[loc] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTagTypePluginChunkType)); 5302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx, 5306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const struct _cmsContext_struct* src) 5307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (src != NULL) { 5309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Duplicate the LIST 5311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DupTagTypeList(ctx, src, TagTypePlugin); 5312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 5314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static _cmsTagTypePluginChunkType TagTypePluginChunk = { NULL }; 5315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ctx ->chunks[TagTypePlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagTypePluginChunk, sizeof(_cmsTagTypePluginChunkType)); 5316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx, 5320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const struct _cmsContext_struct* src) 5321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (src != NULL) { 5323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Duplicate the LIST 5325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DupTagTypeList(ctx, src, MPEPlugin); 5326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 5328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static _cmsTagTypePluginChunkType TagTypePluginChunk = { NULL }; 5329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ctx ->chunks[MPEPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagTypePluginChunk, sizeof(_cmsTagTypePluginChunkType)); 5330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Both kind of plug-ins share same structure 5336ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool _cmsRegisterTagTypePlugin(cmsContext id, cmsPluginBase* Data) 5337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return RegisterTypesPlugin(id, Data, TagTypePlugin); 5339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5341ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext id, cmsPluginBase* Data) 5342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return RegisterTypesPlugin(id, Data,MPEPlugin); 5344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Wrapper for tag types 5348ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig) 5349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(ContextID, TagTypePlugin); 5351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return GetHandler(sig, ctx->TagTypes, SupportedTagTypes); 5353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 5356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Tag support main routines 5357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ******************************************************************************** 5358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct _cmsTagLinkedList_st { 5360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsTagSignature Signature; 5362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsTagDescriptor Descriptor; 5363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov struct _cmsTagLinkedList_st* Next; 5364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} _cmsTagLinkedList; 5366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This is the list of built-in tags 5368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic _cmsTagLinkedList SupportedTags[] = { 5369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigAToB0Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutAtoBType, cmsSigLut8Type}, DecideLUTtypeA2B}, &SupportedTags[1]}, 5371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigAToB1Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutAtoBType, cmsSigLut8Type}, DecideLUTtypeA2B}, &SupportedTags[2]}, 5372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigAToB2Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutAtoBType, cmsSigLut8Type}, DecideLUTtypeA2B}, &SupportedTags[3]}, 5373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigBToA0Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type}, DecideLUTtypeB2A}, &SupportedTags[4]}, 5374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigBToA1Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type}, DecideLUTtypeB2A}, &SupportedTags[5]}, 5375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigBToA2Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type}, DecideLUTtypeB2A}, &SupportedTags[6]}, 5376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Allow corbis and its broken XYZ type 5378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigRedColorantTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, DecideXYZtype}, &SupportedTags[7]}, 5379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigGreenColorantTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, DecideXYZtype}, &SupportedTags[8]}, 5380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigBlueColorantTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, DecideXYZtype}, &SupportedTags[9]}, 5381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigRedTRCTag, { 1, 3, { cmsSigCurveType, cmsSigParametricCurveType, cmsMonacoBrokenCurveType }, DecideCurveType}, &SupportedTags[10]}, 5383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigGreenTRCTag, { 1, 3, { cmsSigCurveType, cmsSigParametricCurveType, cmsMonacoBrokenCurveType }, DecideCurveType}, &SupportedTags[11]}, 5384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigBlueTRCTag, { 1, 3, { cmsSigCurveType, cmsSigParametricCurveType, cmsMonacoBrokenCurveType }, DecideCurveType}, &SupportedTags[12]}, 5385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigCalibrationDateTimeTag, { 1, 1, { cmsSigDateTimeType }, NULL}, &SupportedTags[13]}, 5387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigCharTargetTag, { 1, 1, { cmsSigTextType }, NULL}, &SupportedTags[14]}, 5388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigChromaticAdaptationTag, { 9, 1, { cmsSigS15Fixed16ArrayType }, NULL}, &SupportedTags[15]}, 5390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigChromaticityTag, { 1, 1, { cmsSigChromaticityType }, NULL}, &SupportedTags[16]}, 5391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigColorantOrderTag, { 1, 1, { cmsSigColorantOrderType }, NULL}, &SupportedTags[17]}, 5392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigColorantTableTag, { 1, 1, { cmsSigColorantTableType }, NULL}, &SupportedTags[18]}, 5393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigColorantTableOutTag, { 1, 1, { cmsSigColorantTableType }, NULL}, &SupportedTags[19]}, 5394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigCopyrightTag, { 1, 3, { cmsSigTextType, cmsSigMultiLocalizedUnicodeType, cmsSigTextDescriptionType}, DecideTextType}, &SupportedTags[20]}, 5396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigDateTimeTag, { 1, 1, { cmsSigDateTimeType }, NULL}, &SupportedTags[21]}, 5397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigDeviceMfgDescTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[22]}, 5399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigDeviceModelDescTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[23]}, 5400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigGamutTag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[24]}, 5402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigGrayTRCTag, { 1, 2, { cmsSigCurveType, cmsSigParametricCurveType }, DecideCurveType}, &SupportedTags[25]}, 5404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigLuminanceTag, { 1, 1, { cmsSigXYZType }, NULL}, &SupportedTags[26]}, 5405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigMediaBlackPointTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, NULL}, &SupportedTags[27]}, 5407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigMediaWhitePointTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, NULL}, &SupportedTags[28]}, 5408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigNamedColor2Tag, { 1, 1, { cmsSigNamedColor2Type }, NULL}, &SupportedTags[29]}, 5410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigPreview0Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[30]}, 5412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigPreview1Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[31]}, 5413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigPreview2Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[32]}, 5414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigProfileDescriptionTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[33]}, 5416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigProfileSequenceDescTag, { 1, 1, { cmsSigProfileSequenceDescType }, NULL}, &SupportedTags[34]}, 5417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigTechnologyTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[35]}, 5418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigColorimetricIntentImageStateTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[36]}, 5420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigPerceptualRenderingIntentGamutTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[37]}, 5421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigSaturationRenderingIntentGamutTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[38]}, 5422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigMeasurementTag, { 1, 1, { cmsSigMeasurementType }, NULL}, &SupportedTags[39]}, 5424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigPs2CRD0Tag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[40]}, 5426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigPs2CRD1Tag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[41]}, 5427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigPs2CRD2Tag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[42]}, 5428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigPs2CRD3Tag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[43]}, 5429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigPs2CSATag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[44]}, 5430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigPs2RenderingIntentTag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[45]}, 5431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigViewingCondDescTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[46]}, 5433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigUcrBgTag, { 1, 1, { cmsSigUcrBgType}, NULL}, &SupportedTags[47]}, 5435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigCrdInfoTag, { 1, 1, { cmsSigCrdInfoType}, NULL}, &SupportedTags[48]}, 5436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigDToB0Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[49]}, 5438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigDToB1Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[50]}, 5439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigDToB2Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[51]}, 5440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigDToB3Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[52]}, 5441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigBToD0Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[53]}, 5442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigBToD1Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[54]}, 5443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigBToD2Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[55]}, 5444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigBToD3Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[56]}, 5445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigScreeningDescTag, { 1, 1, { cmsSigTextDescriptionType }, NULL}, &SupportedTags[57]}, 5447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigViewingConditionsTag, { 1, 1, { cmsSigViewingConditionsType }, NULL}, &SupportedTags[58]}, 5448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigScreeningTag, { 1, 1, { cmsSigScreeningType}, NULL }, &SupportedTags[59]}, 5450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]}, 5451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]}, 5452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]}, 5453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, NULL} 5454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}; 5457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 5459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Not supported Why 5460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ======================= ========================================= 5461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSigOutputResponseTag ==> WARNING, POSSIBLE PATENT ON THIS SUBJECT! 5462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSigNamedColorTag ==> Deprecated 5463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSigDataTag ==> Ancient, unused 5464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsSigDeviceSettingsTag ==> Deprecated, useless 5465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov*/ 5466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov_cmsTagPluginChunkType _cmsTagPluginChunk = { NULL }; 5469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Duplicates the zone of memory used by the plug-in in the new context 5472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic 5473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid DupTagList(struct _cmsContext_struct* ctx, 5474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const struct _cmsContext_struct* src) 5475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagPluginChunkType newHead = { NULL }; 5477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagLinkedList* entry; 5478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagLinkedList* Anterior = NULL; 5479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagPluginChunkType* head = (_cmsTagPluginChunkType*) src->chunks[TagPlugin]; 5480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // Walk the list copying all nodes 5482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (entry = head->Tag; 5483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry != NULL; 5484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov entry = entry ->Next) { 5485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagLinkedList *newEntry = ( _cmsTagLinkedList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTagLinkedList)); 5487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (newEntry == NULL) 5489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 5490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov // We want to keep the linked list order, so this is a little bit tricky 5492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov newEntry -> Next = NULL; 5493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Anterior) 5494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Anterior -> Next = newEntry; 5495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Anterior = newEntry; 5497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (newHead.Tag == NULL) 5499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov newHead.Tag = newEntry; 5500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ctx ->chunks[TagPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTagPluginChunkType)); 5503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx, 5506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const struct _cmsContext_struct* src) 5507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (src != NULL) { 5509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DupTagList(ctx, src); 5511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else { 5513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static _cmsTagPluginChunkType TagPluginChunk = { NULL }; 5514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ctx ->chunks[TagPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagPluginChunk, sizeof(_cmsTagPluginChunkType)); 5515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5519ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool _cmsRegisterTagPlugin(cmsContext id, cmsPluginBase* Data) 5520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmsPluginTag* Plugin = (cmsPluginTag*) Data; 5522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagLinkedList *pt; 5523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagPluginChunkType* TagPluginChunk = ( _cmsTagPluginChunkType*) _cmsContextGetClientChunk(id, TagPlugin); 5524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (Data == NULL) { 5526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TagPluginChunk->Tag = NULL; 5528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 5529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt = (_cmsTagLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagLinkedList)); 5532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pt == NULL) return FALSE; 5533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt ->Signature = Plugin ->Signature; 5535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt ->Descriptor = Plugin ->Descriptor; 5536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt ->Next = TagPluginChunk ->Tag; 5537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TagPluginChunk ->Tag = pt; 5539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return TRUE; 5541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Return a descriptor for a given tag or NULL 5544ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig) 5545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 5546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagLinkedList* pt; 5547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov _cmsTagPluginChunkType* TagPluginChunk = ( _cmsTagPluginChunkType*) _cmsContextGetClientChunk(ContextID, TagPlugin); 5548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (pt = TagPluginChunk->Tag; 5550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt != NULL; 5551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt = pt ->Next) { 5552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (sig == pt -> Signature) return &pt ->Descriptor; 5554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (pt = SupportedTags; 5557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt != NULL; 5558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pt = pt ->Next) { 5559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (sig == pt -> Signature) return &pt ->Descriptor; 5561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 5562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 5564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 5565