This source file includes following definitions.
- RegisterTypesPlugin
- GetHandler
- _cmsWriteWCharArray
- _cmsReadWCharArray
- ReadPositionTable
- WritePositionTable
- Type_XYZ_Read
- Type_XYZ_Write
- Type_XYZ_Dup
- Type_XYZ_Free
- DecideXYZtype
- Type_Chromaticity_Read
- SaveOneChromaticity
- Type_Chromaticity_Write
- Type_Chromaticity_Dup
- Type_Chromaticity_Free
- Type_ColorantOrderType_Read
- Type_ColorantOrderType_Write
- Type_ColorantOrderType_Dup
- Type_ColorantOrderType_Free
- Type_S15Fixed16_Read
- Type_S15Fixed16_Write
- Type_S15Fixed16_Dup
- Type_S15Fixed16_Free
- Type_U16Fixed16_Read
- Type_U16Fixed16_Write
- Type_U16Fixed16_Dup
- Type_U16Fixed16_Free
- Type_Signature_Read
- Type_Signature_Write
- Type_Signature_Dup
- Type_Signature_Free
- Type_Text_Read
- Type_Text_Write
- Type_Text_Dup
- Type_Text_Free
- DecideTextType
- Type_Data_Read
- Type_Data_Write
- Type_Data_Dup
- Type_Data_Free
- Type_Text_Description_Read
- Type_Text_Description_Write
- Type_Text_Description_Dup
- Type_Text_Description_Free
- DecideTextDescType
- Type_Curve_Read
- Type_Curve_Write
- Type_Curve_Dup
- Type_Curve_Free
- DecideCurveType
- Type_ParametricCurve_Read
- Type_ParametricCurve_Write
- Type_ParametricCurve_Dup
- Type_ParametricCurve_Free
- Type_DateTime_Read
- Type_DateTime_Write
- Type_DateTime_Dup
- Type_DateTime_Free
- Type_Measurement_Read
- Type_Measurement_Write
- Type_Measurement_Dup
- Type_Measurement_Free
- Type_MLU_Read
- Type_MLU_Write
- Type_MLU_Dup
- Type_MLU_Free
- DecideLUTtypeA2B
- DecideLUTtypeB2A
- Read8bitTables
- Write8bitTables
- uipow
- Type_LUT8_Read
- Type_LUT8_Write
- Type_LUT8_Dup
- Type_LUT8_Free
- Read16bitTables
- Write16bitTables
- Type_LUT16_Read
- Type_LUT16_Write
- Type_LUT16_Dup
- Type_LUT16_Free
- ReadMatrix
- ReadCLUT
- ReadEmbeddedCurve
- ReadSetOfCurves
- Type_LUTA2B_Read
- WriteMatrix
- WriteSetOfCurves
- WriteCLUT
- Type_LUTA2B_Write
- Type_LUTA2B_Dup
- Type_LUTA2B_Free
- Type_LUTB2A_Read
- Type_LUTB2A_Write
- Type_LUTB2A_Dup
- Type_LUTB2A_Free
- Type_ColorantTable_Read
- Type_ColorantTable_Write
- Type_ColorantTable_Dup
- Type_ColorantTable_Free
- Type_NamedColor_Read
- Type_NamedColor_Write
- Type_NamedColor_Dup
- Type_NamedColor_Free
- ReadEmbeddedText
- Type_ProfileSequenceDesc_Read
- SaveDescription
- Type_ProfileSequenceDesc_Write
- Type_ProfileSequenceDesc_Dup
- Type_ProfileSequenceDesc_Free
- ReadSeqID
- Type_ProfileSequenceId_Read
- WriteSeqID
- Type_ProfileSequenceId_Write
- Type_ProfileSequenceId_Dup
- Type_ProfileSequenceId_Free
- Type_UcrBg_Read
- Type_UcrBg_Write
- Type_UcrBg_Dup
- Type_UcrBg_Free
- ReadCountAndSting
- WriteCountAndSting
- Type_CrdInfo_Read
- Type_CrdInfo_Write
- Type_CrdInfo_Dup
- Type_CrdInfo_Free
- Type_Screening_Read
- Type_Screening_Write
- Type_Screening_Dup
- Type_Screening_Free
- Type_ViewingConditions_Read
- Type_ViewingConditions_Write
- Type_ViewingConditions_Dup
- Type_ViewingConditions_Free
- GenericMPEdup
- GenericMPEfree
- ReadSegmentedCurve
- ReadMPECurve
- Type_MPEcurve_Read
- WriteSegmentedCurve
- WriteMPECurve
- Type_MPEcurve_Write
- Type_MPEmatrix_Read
- Type_MPEmatrix_Write
- Type_MPEclut_Read
- Type_MPEclut_Write
- ReadMPEElem
- Type_MPE_Read
- Type_MPE_Write
- Type_MPE_Dup
- Type_MPE_Free
- Type_vcgt_Read
- Type_vcgt_Write
- Type_vcgt_Dup
- Type_vcgt_Free
- AllocElem
- FreeElem
- FreeArray
- AllocArray
- ReadOneElem
- ReadOffsetArray
- WriteOneElem
- WriteOffsetArray
- ReadOneWChar
- mywcslen
- WriteOneWChar
- ReadOneMLUC
- WriteOneMLUC
- Type_Dictionary_Read
- Type_Dictionary_Write
- Type_Dictionary_Dup
- Type_Dictionary_Free
- DupTagTypeList
- _cmsAllocTagTypePluginChunk
- _cmsAllocMPETypePluginChunk
- _cmsRegisterTagTypePlugin
- _cmsRegisterMultiProcessElementPlugin
- _cmsGetTagTypeHandler
- DupTagList
- _cmsAllocTagPluginChunk
- _cmsRegisterTagPlugin
- _cmsGetTagDescriptor
#include "lcms2_internal.h"
#define cmsCorbisBrokenXYZtype ((cmsTagTypeSignature) 0x17A505B8)
#define cmsMonacoBrokenCurveType ((cmsTagTypeSignature) 0x9478ee00)
typedef struct _cmsTagTypeLinkedList_st {
cmsTagTypeHandler Handler;
struct _cmsTagTypeLinkedList_st* Next;
} _cmsTagTypeLinkedList;
#define READ_FN(x) Type_##x##_Read
#define WRITE_FN(x) Type_##x##_Write
#define FREE_FN(x) Type_##x##_Free
#define DUP_FN(x) Type_##x##_Dup
#define TYPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), DUP_FN(x), FREE_FN(x), NULL, 0 }
#define TYPE_MPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), GenericMPEdup, GenericMPEfree, NULL, 0 }
static
cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsMemoryClient pos)
{
cmsPluginTagType* Plugin = (cmsPluginTagType*) Data;
_cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(id, pos);
_cmsTagTypeLinkedList *pt;
if (Data == NULL) {
ctx ->TagTypes = NULL;
return TRUE;
}
pt = (_cmsTagTypeLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagTypeLinkedList));
if (pt == NULL) return FALSE;
pt ->Handler = Plugin ->Handler;
pt ->Next = ctx ->TagTypes;
ctx ->TagTypes = pt;
return TRUE;
}
static
cmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* PluginLinkedList, _cmsTagTypeLinkedList* DefaultLinkedList)
{
_cmsTagTypeLinkedList* pt;
for (pt = PluginLinkedList;
pt != NULL;
pt = pt ->Next) {
if (sig == pt -> Handler.Signature) return &pt ->Handler;
}
for (pt = DefaultLinkedList;
pt != NULL;
pt = pt ->Next) {
if (sig == pt -> Handler.Signature) return &pt ->Handler;
}
return NULL;
}
static
cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t* Array)
{
cmsUInt32Number i;
_cmsAssert(io != NULL);
_cmsAssert(!(Array == NULL && n > 0));
for (i=0; i < n; i++) {
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) Array[i])) return FALSE;
}
return TRUE;
}
static
cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array)
{
cmsUInt32Number i;
cmsUInt16Number tmp;
_cmsAssert(io != NULL);
for (i=0; i < n; i++) {
if (Array != NULL) {
if (!_cmsReadUInt16Number(io, &tmp)) return FALSE;
Array[i] = (wchar_t) tmp;
}
else {
if (!_cmsReadUInt16Number(io, NULL)) return FALSE;
}
}
return TRUE;
}
typedef cmsBool (* PositionTableEntryFn)(struct _cms_typehandler_struct* self,
cmsIOHANDLER* io,
void* Cargo,
cmsUInt32Number n,
cmsUInt32Number SizeOfTag);
static
cmsBool ReadPositionTable(struct _cms_typehandler_struct* self,
cmsIOHANDLER* io,
cmsUInt32Number Count,
cmsUInt32Number BaseOffset,
void *Cargo,
PositionTableEntryFn ElementFn)
{
cmsUInt32Number i;
cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL;
ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number));
if (ElementOffsets == NULL) goto Error;
ElementSizes = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number));
if (ElementSizes == NULL) goto Error;
for (i=0; i < Count; i++) {
if (!_cmsReadUInt32Number(io, &ElementOffsets[i])) goto Error;
if (!_cmsReadUInt32Number(io, &ElementSizes[i])) goto Error;
ElementOffsets[i] += BaseOffset;
}
for (i=0; i < Count; i++) {
if (!io -> Seek(io, ElementOffsets[i])) goto Error;
if (!ElementFn(self, io, Cargo, i, ElementSizes[i])) goto Error;
}
if (ElementOffsets != NULL) _cmsFree(io ->ContextID, ElementOffsets);
if (ElementSizes != NULL) _cmsFree(io ->ContextID, ElementSizes);
return TRUE;
Error:
if (ElementOffsets != NULL) _cmsFree(io ->ContextID, ElementOffsets);
if (ElementSizes != NULL) _cmsFree(io ->ContextID, ElementSizes);
return FALSE;
}
static
cmsBool WritePositionTable(struct _cms_typehandler_struct* self,
cmsIOHANDLER* io,
cmsUInt32Number SizeOfTag,
cmsUInt32Number Count,
cmsUInt32Number BaseOffset,
void *Cargo,
PositionTableEntryFn ElementFn)
{
cmsUInt32Number i;
cmsUInt32Number DirectoryPos, CurrentPos, Before;
cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL;
ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number));
if (ElementOffsets == NULL) goto Error;
ElementSizes = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number));
if (ElementSizes == NULL) goto Error;
DirectoryPos = io ->Tell(io);
for (i=0; i < Count; i++) {
if (!_cmsWriteUInt32Number(io, 0)) goto Error;
if (!_cmsWriteUInt32Number(io, 0)) goto Error;
}
for (i=0; i < Count; i++) {
Before = io ->Tell(io);
ElementOffsets[i] = Before - BaseOffset;
if (!ElementFn(self, io, Cargo, i, SizeOfTag)) goto Error;
ElementSizes[i] = io ->Tell(io) - Before;
}
CurrentPos = io ->Tell(io);
if (!io ->Seek(io, DirectoryPos)) goto Error;
for (i=0; i < Count; i++) {
if (!_cmsWriteUInt32Number(io, ElementOffsets[i])) goto Error;
if (!_cmsWriteUInt32Number(io, ElementSizes[i])) goto Error;
}
if (!io ->Seek(io, CurrentPos)) goto Error;
if (ElementOffsets != NULL) _cmsFree(io ->ContextID, ElementOffsets);
if (ElementSizes != NULL) _cmsFree(io ->ContextID, ElementSizes);
return TRUE;
Error:
if (ElementOffsets != NULL) _cmsFree(io ->ContextID, ElementOffsets);
if (ElementSizes != NULL) _cmsFree(io ->ContextID, ElementSizes);
return FALSE;
}
static
void *Type_XYZ_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsCIEXYZ* xyz;
*nItems = 0;
xyz = (cmsCIEXYZ*) _cmsMallocZero(self ->ContextID, sizeof(cmsCIEXYZ));
if (xyz == NULL) return NULL;
if (!_cmsReadXYZNumber(io, xyz)) {
_cmsFree(self ->ContextID, xyz);
return NULL;
}
*nItems = 1;
return (void*) xyz;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_XYZ_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
return _cmsWriteXYZNumber(io, (cmsCIEXYZ*) Ptr);
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void* Type_XYZ_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsCIEXYZ));
cmsUNUSED_PARAMETER(n);
}
static
void Type_XYZ_Free(struct _cms_typehandler_struct* self, void *Ptr)
{
_cmsFree(self ->ContextID, Ptr);
}
static
cmsTagTypeSignature DecideXYZtype(cmsFloat64Number ICCVersion, const void *Data)
{
return cmsSigXYZType;
cmsUNUSED_PARAMETER(ICCVersion);
cmsUNUSED_PARAMETER(Data);
}
static
void *Type_Chromaticity_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsCIExyYTRIPLE* chrm;
cmsUInt16Number nChans, Table;
*nItems = 0;
chrm = (cmsCIExyYTRIPLE*) _cmsMallocZero(self ->ContextID, sizeof(cmsCIExyYTRIPLE));
if (chrm == NULL) return NULL;
if (!_cmsReadUInt16Number(io, &nChans)) goto Error;
if (nChans == 0 && SizeOfTag == 32) {
if (!_cmsReadUInt16Number(io, NULL)) goto Error;
if (!_cmsReadUInt16Number(io, &nChans)) goto Error;
}
if (nChans != 3) goto Error;
if (!_cmsReadUInt16Number(io, &Table)) goto Error;
if (!_cmsRead15Fixed16Number(io, &chrm ->Red.x)) goto Error;
if (!_cmsRead15Fixed16Number(io, &chrm ->Red.y)) goto Error;
chrm ->Red.Y = 1.0;
if (!_cmsRead15Fixed16Number(io, &chrm ->Green.x)) goto Error;
if (!_cmsRead15Fixed16Number(io, &chrm ->Green.y)) goto Error;
chrm ->Green.Y = 1.0;
if (!_cmsRead15Fixed16Number(io, &chrm ->Blue.x)) goto Error;
if (!_cmsRead15Fixed16Number(io, &chrm ->Blue.y)) goto Error;
chrm ->Blue.Y = 1.0;
*nItems = 1;
return (void*) chrm;
Error:
_cmsFree(self ->ContextID, (void*) chrm);
return NULL;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool SaveOneChromaticity(cmsFloat64Number x, cmsFloat64Number y, cmsIOHANDLER* io)
{
if (!_cmsWriteUInt32Number(io, _cmsDoubleTo15Fixed16(x))) return FALSE;
if (!_cmsWriteUInt32Number(io, _cmsDoubleTo15Fixed16(y))) return FALSE;
return TRUE;
}
static
cmsBool Type_Chromaticity_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsCIExyYTRIPLE* chrm = (cmsCIExyYTRIPLE*) Ptr;
if (!_cmsWriteUInt16Number(io, 3)) return FALSE;
if (!_cmsWriteUInt16Number(io, 0)) return FALSE;
if (!SaveOneChromaticity(chrm -> Red.x, chrm -> Red.y, io)) return FALSE;
if (!SaveOneChromaticity(chrm -> Green.x, chrm -> Green.y, io)) return FALSE;
if (!SaveOneChromaticity(chrm -> Blue.x, chrm -> Blue.y, io)) return FALSE;
return TRUE;
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void* Type_Chromaticity_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsCIExyYTRIPLE));
cmsUNUSED_PARAMETER(n);
}
static
void Type_Chromaticity_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
_cmsFree(self ->ContextID, Ptr);
}
static
void *Type_ColorantOrderType_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsUInt8Number* ColorantOrder;
cmsUInt32Number Count;
*nItems = 0;
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
if (Count > cmsMAXCHANNELS) return NULL;
ColorantOrder = (cmsUInt8Number*) _cmsCalloc(self ->ContextID, cmsMAXCHANNELS, sizeof(cmsUInt8Number));
if (ColorantOrder == NULL) return NULL;
memset(ColorantOrder, 0xFF, cmsMAXCHANNELS * sizeof(cmsUInt8Number));
if (io ->Read(io, ColorantOrder, sizeof(cmsUInt8Number), Count) != Count) {
_cmsFree(self ->ContextID, (void*) ColorantOrder);
return NULL;
}
*nItems = 1;
return (void*) ColorantOrder;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_ColorantOrderType_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsUInt8Number* ColorantOrder = (cmsUInt8Number*) Ptr;
cmsUInt32Number i, sz, Count;
for (Count=i=0; i < cmsMAXCHANNELS; i++) {
if (ColorantOrder[i] != 0xFF) Count++;
}
if (!_cmsWriteUInt32Number(io, Count)) return FALSE;
sz = Count * sizeof(cmsUInt8Number);
if (!io -> Write(io, sz, ColorantOrder)) return FALSE;
return TRUE;
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void* Type_ColorantOrderType_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return _cmsDupMem(self ->ContextID, Ptr, cmsMAXCHANNELS * sizeof(cmsUInt8Number));
cmsUNUSED_PARAMETER(n);
}
static
void Type_ColorantOrderType_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
_cmsFree(self ->ContextID, Ptr);
}
static
void *Type_S15Fixed16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsFloat64Number* array_double;
cmsUInt32Number i, n;
*nItems = 0;
n = SizeOfTag / sizeof(cmsUInt32Number);
array_double = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, n, sizeof(cmsFloat64Number));
if (array_double == NULL) return NULL;
for (i=0; i < n; i++) {
if (!_cmsRead15Fixed16Number(io, &array_double[i])) {
_cmsFree(self ->ContextID, array_double);
return NULL;
}
}
*nItems = n;
return (void*) array_double;
}
static
cmsBool Type_S15Fixed16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsFloat64Number* Value = (cmsFloat64Number*) Ptr;
cmsUInt32Number i;
for (i=0; i < nItems; i++) {
if (!_cmsWrite15Fixed16Number(io, Value[i])) return FALSE;
}
return TRUE;
cmsUNUSED_PARAMETER(self);
}
static
void* Type_S15Fixed16_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return _cmsDupMem(self ->ContextID, Ptr, n * sizeof(cmsFloat64Number));
}
static
void Type_S15Fixed16_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
_cmsFree(self ->ContextID, Ptr);
}
static
void *Type_U16Fixed16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsFloat64Number* array_double;
cmsUInt32Number v;
cmsUInt32Number i, n;
*nItems = 0;
n = SizeOfTag / sizeof(cmsUInt32Number);
array_double = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, n, sizeof(cmsFloat64Number));
if (array_double == NULL) return NULL;
for (i=0; i < n; i++) {
if (!_cmsReadUInt32Number(io, &v)) {
_cmsFree(self ->ContextID, (void*) array_double);
return NULL;
}
array_double[i] = (cmsFloat64Number) (v / 65536.0);
}
*nItems = n;
return (void*) array_double;
}
static
cmsBool Type_U16Fixed16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsFloat64Number* Value = (cmsFloat64Number*) Ptr;
cmsUInt32Number i;
for (i=0; i < nItems; i++) {
cmsUInt32Number v = (cmsUInt32Number) floor(Value[i]*65536.0 + 0.5);
if (!_cmsWriteUInt32Number(io, v)) return FALSE;
}
return TRUE;
cmsUNUSED_PARAMETER(self);
}
static
void* Type_U16Fixed16_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return _cmsDupMem(self ->ContextID, Ptr, n * sizeof(cmsFloat64Number));
}
static
void Type_U16Fixed16_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
_cmsFree(self ->ContextID, Ptr);
}
static
void *Type_Signature_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsSignature* SigPtr = (cmsSignature*) _cmsMalloc(self ->ContextID, sizeof(cmsSignature));
if (SigPtr == NULL) return NULL;
if (!_cmsReadUInt32Number(io, SigPtr)) return NULL;
*nItems = 1;
return SigPtr;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_Signature_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsSignature* SigPtr = (cmsSignature*) Ptr;
return _cmsWriteUInt32Number(io, *SigPtr);
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void* Type_Signature_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return _cmsDupMem(self ->ContextID, Ptr, n * sizeof(cmsSignature));
}
static
void Type_Signature_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
_cmsFree(self ->ContextID, Ptr);
}
static
void *Type_Text_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
char* Text = NULL;
cmsMLU* mlu = NULL;
mlu = cmsMLUalloc(self ->ContextID, 1);
if (mlu == NULL) return NULL;
*nItems = 0;
if (SizeOfTag == UINT_MAX) goto Error;
Text = (char*) _cmsMalloc(self ->ContextID, SizeOfTag + 1);
if (Text == NULL) goto Error;
if (io -> Read(io, Text, sizeof(char), SizeOfTag) != SizeOfTag) goto Error;
Text[SizeOfTag] = 0;
*nItems = 1;
if (!cmsMLUsetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text)) goto Error;
_cmsFree(self ->ContextID, Text);
return (void*) mlu;
Error:
if (mlu != NULL)
cmsMLUfree(mlu);
if (Text != NULL)
_cmsFree(self ->ContextID, Text);
return NULL;
}
static
cmsBool Type_Text_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsMLU* mlu = (cmsMLU*) Ptr;
cmsUInt32Number size;
cmsBool rc;
char* Text;
size = cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, NULL, 0);
if (size == 0) return FALSE;
Text = (char*) _cmsMalloc(self ->ContextID, size);
if (Text == NULL) return FALSE;
cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text, size);
rc = io ->Write(io, size, Text);
_cmsFree(self ->ContextID, Text);
return rc;
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_Text_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return (void*) cmsMLUdup((cmsMLU*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_Text_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsMLU* mlu = (cmsMLU*) Ptr;
cmsMLUfree(mlu);
return;
cmsUNUSED_PARAMETER(self);
}
static
cmsTagTypeSignature DecideTextType(cmsFloat64Number ICCVersion, const void *Data)
{
if (ICCVersion >= 4.0)
return cmsSigMultiLocalizedUnicodeType;
return cmsSigTextType;
cmsUNUSED_PARAMETER(Data);
}
static
void *Type_Data_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsICCData* BinData;
cmsUInt32Number LenOfData;
*nItems = 0;
if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
LenOfData = SizeOfTag - sizeof(cmsUInt32Number);
if (LenOfData > INT_MAX) return NULL;
BinData = (cmsICCData*) _cmsMalloc(self ->ContextID, sizeof(cmsICCData) + LenOfData - 1);
if (BinData == NULL) return NULL;
BinData ->len = LenOfData;
if (!_cmsReadUInt32Number(io, &BinData->flag)) {
_cmsFree(self ->ContextID, BinData);
return NULL;
}
if (io -> Read(io, BinData ->data, sizeof(cmsUInt8Number), LenOfData) != LenOfData) {
_cmsFree(self ->ContextID, BinData);
return NULL;
}
*nItems = 1;
return (void*) BinData;
}
static
cmsBool Type_Data_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsICCData* BinData = (cmsICCData*) Ptr;
if (!_cmsWriteUInt32Number(io, BinData ->flag)) return FALSE;
return io ->Write(io, BinData ->len, BinData ->data);
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void* Type_Data_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
cmsICCData* BinData = (cmsICCData*) Ptr;
return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsICCData) + BinData ->len - 1);
cmsUNUSED_PARAMETER(n);
}
static
void Type_Data_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
_cmsFree(self ->ContextID, Ptr);
}
static
void *Type_Text_Description_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
char* Text = NULL;
cmsMLU* mlu = NULL;
cmsUInt32Number AsciiCount;
cmsUInt32Number i, UnicodeCode, UnicodeCount;
cmsUInt16Number ScriptCodeCode, Dummy;
cmsUInt8Number ScriptCodeCount;
*nItems = 0;
if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
if (!_cmsReadUInt32Number(io, &AsciiCount)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
if (SizeOfTag < AsciiCount) return NULL;
mlu = cmsMLUalloc(self ->ContextID, 1);
if (mlu == NULL) return NULL;
Text = (char*) _cmsMalloc(self ->ContextID, AsciiCount + 1);
if (Text == NULL) goto Error;
if (io ->Read(io, Text, sizeof(char), AsciiCount) != AsciiCount) goto Error;
SizeOfTag -= AsciiCount;
Text[AsciiCount] = 0;
if (!cmsMLUsetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text)) goto Error;
_cmsFree(self ->ContextID, (void*) Text);
Text = NULL;
if (SizeOfTag < 2* sizeof(cmsUInt32Number)) goto Done;
if (!_cmsReadUInt32Number(io, &UnicodeCode)) goto Done;
if (!_cmsReadUInt32Number(io, &UnicodeCount)) goto Done;
SizeOfTag -= 2* sizeof(cmsUInt32Number);
if (SizeOfTag < UnicodeCount*sizeof(cmsUInt16Number)) goto Done;
for (i=0; i < UnicodeCount; i++) {
if (!io ->Read(io, &Dummy, sizeof(cmsUInt16Number), 1)) goto Done;
}
SizeOfTag -= UnicodeCount*sizeof(cmsUInt16Number);
if (SizeOfTag >= sizeof(cmsUInt16Number) + sizeof(cmsUInt8Number) + 67) {
if (!_cmsReadUInt16Number(io, &ScriptCodeCode)) goto Done;
if (!_cmsReadUInt8Number(io, &ScriptCodeCount)) goto Done;
for (i=0; i < 67; i++) {
if (!io ->Read(io, &Dummy, sizeof(cmsUInt8Number), 1)) goto Error;
}
}
Done:
*nItems = 1;
return mlu;
Error:
if (Text) _cmsFree(self ->ContextID, (void*) Text);
if (mlu) cmsMLUfree(mlu);
return NULL;
}
static
cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsMLU* mlu = (cmsMLU*) Ptr;
char *Text = NULL;
wchar_t *Wide = NULL;
cmsUInt32Number len, len_aligned, len_filler_alignment;
cmsBool rc = FALSE;
char Filler[68];
memset(Filler, 0, sizeof(Filler));
len = cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, NULL, 0);
len_aligned = _cmsALIGNLONG(len);
len_filler_alignment = len_aligned - len;
if (len <= 0) {
Text = (char*) _cmsDupMem(self ->ContextID, "", sizeof(char));
Wide = (wchar_t*) _cmsDupMem(self ->ContextID, L"", sizeof(wchar_t));
}
else {
Text = (char*) _cmsCalloc(self ->ContextID, len, sizeof(char));
if (Text == NULL) goto Error;
Wide = (wchar_t*) _cmsCalloc(self ->ContextID, len, sizeof(wchar_t));
if (Wide == NULL) goto Error;
cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, Text, len * sizeof(char));
cmsMLUgetWide(mlu, cmsNoLanguage, cmsNoCountry, Wide, len * sizeof(wchar_t));
}
if (!_cmsWriteUInt32Number(io, len_aligned)) goto Error;
if (!io ->Write(io, len, Text)) goto Error;
if (!io ->Write(io, len_filler_alignment, Filler)) goto Error;
if (!_cmsWriteUInt32Number(io, 0)) goto Error;
if (!_cmsWriteUInt32Number(io, len_aligned+1)) goto Error;
if (!_cmsWriteWCharArray(io, len, Wide)) goto Error;
if (!_cmsWriteUInt16Array(io, len_filler_alignment+1, (cmsUInt16Number*) Filler)) goto Error;
if (!_cmsWriteUInt16Number(io, 0)) goto Error;
if (!_cmsWriteUInt8Number(io, 0)) goto Error;
if (!io ->Write(io, 67, Filler)) goto Error;
rc = TRUE;
Error:
if (Text) _cmsFree(self ->ContextID, Text);
if (Wide) _cmsFree(self ->ContextID, Wide);
return rc;
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_Text_Description_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return (void*) cmsMLUdup((cmsMLU*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_Text_Description_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsMLU* mlu = (cmsMLU*) Ptr;
cmsMLUfree(mlu);
return;
cmsUNUSED_PARAMETER(self);
}
static
cmsTagTypeSignature DecideTextDescType(cmsFloat64Number ICCVersion, const void *Data)
{
if (ICCVersion >= 4.0)
return cmsSigMultiLocalizedUnicodeType;
return cmsSigTextDescriptionType;
cmsUNUSED_PARAMETER(Data);
}
static
void *Type_Curve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsUInt32Number Count;
cmsToneCurve* NewGamma;
*nItems = 0;
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
switch (Count) {
case 0:
{
cmsFloat64Number SingleGamma = 1.0;
NewGamma = cmsBuildParametricToneCurve(self ->ContextID, 1, &SingleGamma);
if (!NewGamma) return NULL;
*nItems = 1;
return NewGamma;
}
case 1:
{
cmsUInt16Number SingleGammaFixed;
cmsFloat64Number SingleGamma;
if (!_cmsReadUInt16Number(io, &SingleGammaFixed)) return NULL;
SingleGamma = _cms8Fixed8toDouble(SingleGammaFixed);
*nItems = 1;
return cmsBuildParametricToneCurve(self ->ContextID, 1, &SingleGamma);
}
default:
if (Count > 0x7FFF)
return NULL;
NewGamma = cmsBuildTabulatedToneCurve16(self ->ContextID, Count, NULL);
if (!NewGamma) return NULL;
if (!_cmsReadUInt16Array(io, Count, NewGamma -> Table16)) return NULL;
*nItems = 1;
return NewGamma;
}
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_Curve_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsToneCurve* Curve = (cmsToneCurve*) Ptr;
if (Curve ->nSegments == 1 && Curve ->Segments[0].Type == 1) {
cmsUInt16Number SingleGammaFixed = _cmsDoubleTo8Fixed8(Curve ->Segments[0].Params[0]);
if (!_cmsWriteUInt32Number(io, 1)) return FALSE;
if (!_cmsWriteUInt16Number(io, SingleGammaFixed)) return FALSE;
return TRUE;
}
if (!_cmsWriteUInt32Number(io, Curve ->nEntries)) return FALSE;
return _cmsWriteUInt16Array(io, Curve ->nEntries, Curve ->Table16);
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void* Type_Curve_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return (void*) cmsDupToneCurve((cmsToneCurve*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_Curve_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsToneCurve* gamma = (cmsToneCurve*) Ptr;
cmsFreeToneCurve(gamma);
return;
cmsUNUSED_PARAMETER(self);
}
static
cmsTagTypeSignature DecideCurveType(cmsFloat64Number ICCVersion, const void *Data)
{
cmsToneCurve* Curve = (cmsToneCurve*) Data;
if (ICCVersion < 4.0) return cmsSigCurveType;
if (Curve ->nSegments != 1) return cmsSigCurveType;
if (Curve ->Segments[0].Type < 0) return cmsSigCurveType;
if (Curve ->Segments[0].Type > 5) return cmsSigCurveType;
return cmsSigParametricCurveType;
}
static
void *Type_ParametricCurve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
static const int ParamsByType[] = { 1, 3, 4, 5, 7 };
cmsFloat64Number Params[10];
cmsUInt16Number Type;
int i, n;
cmsToneCurve* NewGamma;
if (!_cmsReadUInt16Number(io, &Type)) return NULL;
if (!_cmsReadUInt16Number(io, NULL)) return NULL;
if (Type > 4) {
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown parametric curve type '%d'", Type);
return NULL;
}
memset(Params, 0, sizeof(Params));
n = ParamsByType[Type];
for (i=0; i < n; i++) {
if (!_cmsRead15Fixed16Number(io, &Params[i])) return NULL;
}
NewGamma = cmsBuildParametricToneCurve(self ->ContextID, Type+1, Params);
*nItems = 1;
return NewGamma;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_ParametricCurve_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsToneCurve* Curve = (cmsToneCurve*) Ptr;
int i, nParams, typen;
static const int ParamsByType[] = { 0, 1, 3, 4, 5, 7 };
typen = Curve -> Segments[0].Type;
if (Curve ->nSegments > 1 || typen < 1) {
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Multisegment or Inverted parametric curves cannot be written");
return FALSE;
}
if (typen > 5) {
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported parametric curve");
return FALSE;
}
nParams = ParamsByType[typen];
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) (Curve ->Segments[0].Type - 1))) return FALSE;
if (!_cmsWriteUInt16Number(io, 0)) return FALSE;
for (i=0; i < nParams; i++) {
if (!_cmsWrite15Fixed16Number(io, Curve -> Segments[0].Params[i])) return FALSE;
}
return TRUE;
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_ParametricCurve_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return (void*) cmsDupToneCurve((cmsToneCurve*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_ParametricCurve_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsToneCurve* gamma = (cmsToneCurve*) Ptr;
cmsFreeToneCurve(gamma);
return;
cmsUNUSED_PARAMETER(self);
}
static
void *Type_DateTime_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsDateTimeNumber timestamp;
struct tm * NewDateTime;
*nItems = 0;
NewDateTime = (struct tm*) _cmsMalloc(self ->ContextID, sizeof(struct tm));
if (NewDateTime == NULL) return NULL;
if (io->Read(io, ×tamp, sizeof(cmsDateTimeNumber), 1) != 1) return NULL;
_cmsDecodeDateTimeNumber(×tamp, NewDateTime);
*nItems = 1;
return NewDateTime;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_DateTime_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
struct tm * DateTime = (struct tm*) Ptr;
cmsDateTimeNumber timestamp;
_cmsEncodeDateTimeNumber(×tamp, DateTime);
if (!io ->Write(io, sizeof(cmsDateTimeNumber), ×tamp)) return FALSE;
return TRUE;
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void* Type_DateTime_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return _cmsDupMem(self ->ContextID, Ptr, sizeof(struct tm));
cmsUNUSED_PARAMETER(n);
}
static
void Type_DateTime_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
_cmsFree(self ->ContextID, Ptr);
}
static
void *Type_Measurement_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsICCMeasurementConditions mc;
memset(&mc, 0, sizeof(mc));
if (!_cmsReadUInt32Number(io, &mc.Observer)) return NULL;
if (!_cmsReadXYZNumber(io, &mc.Backing)) return NULL;
if (!_cmsReadUInt32Number(io, &mc.Geometry)) return NULL;
if (!_cmsRead15Fixed16Number(io, &mc.Flare)) return NULL;
if (!_cmsReadUInt32Number(io, &mc.IlluminantType)) return NULL;
*nItems = 1;
return _cmsDupMem(self ->ContextID, &mc, sizeof(cmsICCMeasurementConditions));
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_Measurement_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsICCMeasurementConditions* mc =(cmsICCMeasurementConditions*) Ptr;
if (!_cmsWriteUInt32Number(io, mc->Observer)) return FALSE;
if (!_cmsWriteXYZNumber(io, &mc->Backing)) return FALSE;
if (!_cmsWriteUInt32Number(io, mc->Geometry)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, mc->Flare)) return FALSE;
if (!_cmsWriteUInt32Number(io, mc->IlluminantType)) return FALSE;
return TRUE;
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void* Type_Measurement_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsICCMeasurementConditions));
cmsUNUSED_PARAMETER(n);
}
static
void Type_Measurement_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
_cmsFree(self ->ContextID, Ptr);
}
static
void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsMLU* mlu;
cmsUInt32Number Count, RecLen, NumOfWchar;
cmsUInt32Number SizeOfHeader;
cmsUInt32Number Len, Offset;
cmsUInt32Number i;
wchar_t* Block;
cmsUInt32Number BeginOfThisString, EndOfThisString, LargestPosition;
*nItems = 0;
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
if (!_cmsReadUInt32Number(io, &RecLen)) return NULL;
if (RecLen != 12) {
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "multiLocalizedUnicodeType of len != 12 is not supported.");
return NULL;
}
mlu = cmsMLUalloc(self ->ContextID, Count);
if (mlu == NULL) return NULL;
mlu ->UsedEntries = Count;
SizeOfHeader = 12 * Count + sizeof(_cmsTagBase);
LargestPosition = 0;
for (i=0; i < Count; i++) {
if (!_cmsReadUInt16Number(io, &mlu ->Entries[i].Language)) goto Error;
if (!_cmsReadUInt16Number(io, &mlu ->Entries[i].Country)) goto Error;
if (!_cmsReadUInt32Number(io, &Len)) goto Error;
if (!_cmsReadUInt32Number(io, &Offset)) goto Error;
if (Offset < (SizeOfHeader + 8)) goto Error;
BeginOfThisString = Offset - SizeOfHeader - 8;
mlu ->Entries[i].Len = (Len * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
mlu ->Entries[i].StrW = (BeginOfThisString * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
EndOfThisString = BeginOfThisString + Len;
if (EndOfThisString > LargestPosition)
LargestPosition = EndOfThisString;
}
SizeOfTag = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
if (SizeOfTag == 0)
{
Block = NULL;
NumOfWchar = 0;
}
else
{
Block = (wchar_t*) _cmsMalloc(self ->ContextID, SizeOfTag);
if (Block == NULL) goto Error;
NumOfWchar = SizeOfTag / sizeof(wchar_t);
if (!_cmsReadWCharArray(io, NumOfWchar, Block)) goto Error;
}
mlu ->MemPool = Block;
mlu ->PoolSize = SizeOfTag;
mlu ->PoolUsed = SizeOfTag;
*nItems = 1;
return (void*) mlu;
Error:
if (mlu) cmsMLUfree(mlu);
return NULL;
}
static
cmsBool Type_MLU_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsMLU* mlu =(cmsMLU*) Ptr;
cmsUInt32Number HeaderSize;
cmsUInt32Number Len, Offset;
int i;
if (Ptr == NULL) {
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
if (!_cmsWriteUInt32Number(io, 12)) return FALSE;
return TRUE;
}
if (!_cmsWriteUInt32Number(io, mlu ->UsedEntries)) return FALSE;
if (!_cmsWriteUInt32Number(io, 12)) return FALSE;
HeaderSize = 12 * mlu ->UsedEntries + sizeof(_cmsTagBase);
for (i=0; i < mlu ->UsedEntries; i++) {
Len = mlu ->Entries[i].Len;
Offset = mlu ->Entries[i].StrW;
Len = (Len * sizeof(cmsUInt16Number)) / sizeof(wchar_t);
Offset = (Offset * sizeof(cmsUInt16Number)) / sizeof(wchar_t) + HeaderSize + 8;
if (!_cmsWriteUInt16Number(io, mlu ->Entries[i].Language)) return FALSE;
if (!_cmsWriteUInt16Number(io, mlu ->Entries[i].Country)) return FALSE;
if (!_cmsWriteUInt32Number(io, Len)) return FALSE;
if (!_cmsWriteUInt32Number(io, Offset)) return FALSE;
}
if (!_cmsWriteWCharArray(io, mlu ->PoolUsed / sizeof(wchar_t), (wchar_t*) mlu ->MemPool)) return FALSE;
return TRUE;
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void* Type_MLU_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return (void*) cmsMLUdup((cmsMLU*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_MLU_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsMLUfree((cmsMLU*) Ptr);
return;
cmsUNUSED_PARAMETER(self);
}
static
cmsTagTypeSignature DecideLUTtypeA2B(cmsFloat64Number ICCVersion, const void *Data)
{
cmsPipeline* Lut = (cmsPipeline*) Data;
if (ICCVersion < 4.0) {
if (Lut ->SaveAs8Bits) return cmsSigLut8Type;
return cmsSigLut16Type;
}
else {
return cmsSigLutAtoBType;
}
}
static
cmsTagTypeSignature DecideLUTtypeB2A(cmsFloat64Number ICCVersion, const void *Data)
{
cmsPipeline* Lut = (cmsPipeline*) Data;
if (ICCVersion < 4.0) {
if (Lut ->SaveAs8Bits) return cmsSigLut8Type;
return cmsSigLut16Type;
}
else {
return cmsSigLutBtoAType;
}
}
static
cmsBool Read8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, int nChannels)
{
cmsUInt8Number* Temp = NULL;
int i, j;
cmsToneCurve* Tables[cmsMAXCHANNELS];
if (nChannels > cmsMAXCHANNELS) return FALSE;
if (nChannels <= 0) return FALSE;
memset(Tables, 0, sizeof(Tables));
Temp = (cmsUInt8Number*) _cmsMalloc(ContextID, 256);
if (Temp == NULL) return FALSE;
for (i=0; i < nChannels; i++) {
Tables[i] = cmsBuildTabulatedToneCurve16(ContextID, 256, NULL);
if (Tables[i] == NULL) goto Error;
}
for (i=0; i < nChannels; i++) {
if (io ->Read(io, Temp, 256, 1) != 1) goto Error;
for (j=0; j < 256; j++)
Tables[i]->Table16[j] = (cmsUInt16Number) FROM_8_TO_16(Temp[j]);
}
_cmsFree(ContextID, Temp);
Temp = NULL;
if (!cmsPipelineInsertStage(lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, nChannels, Tables)))
goto Error;
for (i=0; i < nChannels; i++)
cmsFreeToneCurve(Tables[i]);
return TRUE;
Error:
for (i=0; i < nChannels; i++) {
if (Tables[i]) cmsFreeToneCurve(Tables[i]);
}
if (Temp) _cmsFree(ContextID, Temp);
return FALSE;
}
static
cmsBool Write8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsUInt32Number n, _cmsStageToneCurvesData* Tables)
{
int j;
cmsUInt32Number i;
cmsUInt8Number val;
for (i=0; i < n; i++) {
if (Tables) {
if ((Tables ->TheCurves[i]->nEntries == 2) &&
(Tables->TheCurves[i]->Table16[0] == 0) &&
(Tables->TheCurves[i]->Table16[1] == 65535)) {
for (j=0; j < 256; j++) {
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) j)) return FALSE;
}
}
else
if (Tables ->TheCurves[i]->nEntries != 256) {
cmsSignalError(ContextID, cmsERROR_RANGE, "LUT8 needs 256 entries on prelinearization");
return FALSE;
}
else
for (j=0; j < 256; j++) {
val = (cmsUInt8Number) FROM_16_TO_8(Tables->TheCurves[i]->Table16[j]);
if (!_cmsWriteUInt8Number(io, val)) return FALSE;
}
}
}
return TRUE;
}
static
cmsUInt32Number uipow(cmsUInt32Number n, cmsUInt32Number a, cmsUInt32Number b)
{
cmsUInt32Number rv = 1, rc;
if (a == 0) return 0;
if (n == 0) return 0;
for (; b > 0; b--) {
rv *= a;
if (rv > UINT_MAX / a) return (cmsUInt32Number) -1;
}
rc = rv * n;
if (rv != rc / n) return (cmsUInt32Number) -1;
return rc;
}
static
void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsUInt8Number InputChannels, OutputChannels, CLUTpoints;
cmsUInt8Number* Temp = NULL;
cmsPipeline* NewLUT = NULL;
cmsUInt32Number nTabSize, i;
cmsFloat64Number Matrix[3*3];
*nItems = 0;
if (!_cmsReadUInt8Number(io, &InputChannels)) goto Error;
if (!_cmsReadUInt8Number(io, &OutputChannels)) goto Error;
if (!_cmsReadUInt8Number(io, &CLUTpoints)) goto Error;
if (CLUTpoints == 1) goto Error;
if (!_cmsReadUInt8Number(io, NULL)) goto Error;
if (InputChannels > cmsMAXCHANNELS) goto Error;
if (OutputChannels > cmsMAXCHANNELS) goto Error;
NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels);
if (NewLUT == NULL) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[0])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[1])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[2])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[3])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[4])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[5])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[6])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[7])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[8])) goto Error;
if ((InputChannels == 3) && !_cmsMAT3isIdentity((cmsMAT3*) Matrix)) {
if (!cmsPipelineInsertStage(NewLUT, cmsAT_BEGIN, cmsStageAllocMatrix(self ->ContextID, 3, 3, Matrix, NULL)))
goto Error;
}
if (!Read8bitTables(self ->ContextID, io, NewLUT, InputChannels)) goto Error;
nTabSize = uipow(OutputChannels, CLUTpoints, InputChannels);
if (nTabSize == (cmsUInt32Number) -1) goto Error;
if (nTabSize > 0) {
cmsUInt16Number *PtrW, *T;
PtrW = T = (cmsUInt16Number*) _cmsCalloc(self ->ContextID, nTabSize, sizeof(cmsUInt16Number));
if (T == NULL) goto Error;
Temp = (cmsUInt8Number*) _cmsMalloc(self ->ContextID, nTabSize);
if (Temp == NULL) {
_cmsFree(self ->ContextID, T);
goto Error;
}
if (io ->Read(io, Temp, nTabSize, 1) != 1) {
_cmsFree(self ->ContextID, T);
_cmsFree(self ->ContextID, Temp);
goto Error;
}
for (i = 0; i < nTabSize; i++) {
*PtrW++ = FROM_8_TO_16(Temp[i]);
}
_cmsFree(self ->ContextID, Temp);
Temp = NULL;
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T)))
goto Error;
_cmsFree(self ->ContextID, T);
}
if (!Read8bitTables(self ->ContextID, io, NewLUT, OutputChannels)) goto Error;
*nItems = 1;
return NewLUT;
Error:
if (NewLUT != NULL) cmsPipelineFree(NewLUT);
return NULL;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsUInt32Number j, nTabSize;
cmsUInt8Number val;
cmsPipeline* NewLUT = (cmsPipeline*) Ptr;
cmsStage* mpe;
_cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL;
_cmsStageMatrixData* MatMPE = NULL;
_cmsStageCLutData* clut = NULL;
int clutPoints;
mpe = NewLUT -> Elements;
if (mpe ->Type == cmsSigMatrixElemType) {
MatMPE = (_cmsStageMatrixData*) mpe ->Data;
mpe = mpe -> Next;
}
if (mpe != NULL && mpe ->Type == cmsSigCurveSetElemType) {
PreMPE = (_cmsStageToneCurvesData*) mpe ->Data;
mpe = mpe -> Next;
}
if (mpe != NULL && mpe ->Type == cmsSigCLutElemType) {
clut = (_cmsStageCLutData*) mpe -> Data;
mpe = mpe ->Next;
}
if (mpe != NULL && mpe ->Type == cmsSigCurveSetElemType) {
PostMPE = (_cmsStageToneCurvesData*) mpe ->Data;
mpe = mpe -> Next;
}
if (mpe != NULL) {
cmsSignalError(mpe->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT is not suitable to be saved as LUT8");
return FALSE;
}
if (clut == NULL)
clutPoints = 0;
else
clutPoints = clut->Params->nSamples[0];
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) NewLUT ->InputChannels)) return FALSE;
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) NewLUT ->OutputChannels)) return FALSE;
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) clutPoints)) return FALSE;
if (!_cmsWriteUInt8Number(io, 0)) return FALSE;
if (MatMPE != NULL) {
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[0])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[1])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[2])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[3])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[4])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[5])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[6])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[7])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[8])) return FALSE;
}
else {
if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE;
}
if (!Write8bitTables(self ->ContextID, io, NewLUT ->InputChannels, PreMPE)) return FALSE;
nTabSize = uipow(NewLUT->OutputChannels, clutPoints, NewLUT ->InputChannels);
if (nTabSize == (cmsUInt32Number) -1) return FALSE;
if (nTabSize > 0) {
if (clut != NULL) {
for (j=0; j < nTabSize; j++) {
val = (cmsUInt8Number) FROM_16_TO_8(clut ->Tab.T[j]);
if (!_cmsWriteUInt8Number(io, val)) return FALSE;
}
}
}
if (!Write8bitTables(self ->ContextID, io, NewLUT ->OutputChannels, PostMPE)) return FALSE;
return TRUE;
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_LUT8_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return (void*) cmsPipelineDup((cmsPipeline*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_LUT8_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsPipelineFree((cmsPipeline*) Ptr);
return;
cmsUNUSED_PARAMETER(self);
}
static
cmsBool Read16bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, int nChannels, int nEntries)
{
int i;
cmsToneCurve* Tables[cmsMAXCHANNELS];
if (nEntries <= 0) return TRUE;
if (nEntries < 2) return FALSE;
if (nChannels > cmsMAXCHANNELS) return FALSE;
memset(Tables, 0, sizeof(Tables));
for (i=0; i < nChannels; i++) {
Tables[i] = cmsBuildTabulatedToneCurve16(ContextID, nEntries, NULL);
if (Tables[i] == NULL) goto Error;
if (!_cmsReadUInt16Array(io, nEntries, Tables[i]->Table16)) goto Error;
}
if (!cmsPipelineInsertStage(lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, nChannels, Tables)))
goto Error;
for (i=0; i < nChannels; i++)
cmsFreeToneCurve(Tables[i]);
return TRUE;
Error:
for (i=0; i < nChannels; i++) {
if (Tables[i]) cmsFreeToneCurve(Tables[i]);
}
return FALSE;
}
static
cmsBool Write16bitTables(cmsContext ContextID, cmsIOHANDLER* io, _cmsStageToneCurvesData* Tables)
{
int j;
cmsUInt32Number i;
cmsUInt16Number val;
int nEntries;
_cmsAssert(Tables != NULL);
nEntries = Tables->TheCurves[0]->nEntries;
for (i=0; i < Tables ->nCurves; i++) {
for (j=0; j < nEntries; j++) {
val = Tables->TheCurves[i]->Table16[j];
if (!_cmsWriteUInt16Number(io, val)) return FALSE;
}
}
return TRUE;
cmsUNUSED_PARAMETER(ContextID);
}
static
void *Type_LUT16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsUInt8Number InputChannels, OutputChannels, CLUTpoints;
cmsPipeline* NewLUT = NULL;
cmsUInt32Number nTabSize;
cmsFloat64Number Matrix[3*3];
cmsUInt16Number InputEntries, OutputEntries;
*nItems = 0;
if (!_cmsReadUInt8Number(io, &InputChannels)) return NULL;
if (!_cmsReadUInt8Number(io, &OutputChannels)) return NULL;
if (!_cmsReadUInt8Number(io, &CLUTpoints)) return NULL;
if (!_cmsReadUInt8Number(io, NULL)) return NULL;
if (InputChannels > cmsMAXCHANNELS) goto Error;
if (OutputChannels > cmsMAXCHANNELS) goto Error;
NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels);
if (NewLUT == NULL) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[0])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[1])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[2])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[3])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[4])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[5])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[6])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[7])) goto Error;
if (!_cmsRead15Fixed16Number(io, &Matrix[8])) goto Error;
if ((InputChannels == 3) && !_cmsMAT3isIdentity((cmsMAT3*) Matrix)) {
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocMatrix(self ->ContextID, 3, 3, Matrix, NULL)))
goto Error;
}
if (!_cmsReadUInt16Number(io, &InputEntries)) goto Error;
if (!_cmsReadUInt16Number(io, &OutputEntries)) goto Error;
if (InputEntries > 0x7FFF || OutputEntries > 0x7FFF) goto Error;
if (CLUTpoints == 1) goto Error;
if (!Read16bitTables(self ->ContextID, io, NewLUT, InputChannels, InputEntries)) goto Error;
nTabSize = uipow(OutputChannels, CLUTpoints, InputChannels);
if (nTabSize == (cmsUInt32Number) -1) goto Error;
if (nTabSize > 0) {
cmsUInt16Number *T;
T = (cmsUInt16Number*) _cmsCalloc(self ->ContextID, nTabSize, sizeof(cmsUInt16Number));
if (T == NULL) goto Error;
if (!_cmsReadUInt16Array(io, nTabSize, T)) {
_cmsFree(self ->ContextID, T);
goto Error;
}
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T))) {
_cmsFree(self ->ContextID, T);
goto Error;
}
_cmsFree(self ->ContextID, T);
}
if (!Read16bitTables(self ->ContextID, io, NewLUT, OutputChannels, OutputEntries)) goto Error;
*nItems = 1;
return NewLUT;
Error:
if (NewLUT != NULL) cmsPipelineFree(NewLUT);
return NULL;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_LUT16_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsUInt32Number nTabSize;
cmsPipeline* NewLUT = (cmsPipeline*) Ptr;
cmsStage* mpe;
_cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL;
_cmsStageMatrixData* MatMPE = NULL;
_cmsStageCLutData* clut = NULL;
int i, InputChannels, OutputChannels, clutPoints;
mpe = NewLUT -> Elements;
if (mpe != NULL && mpe ->Type == cmsSigMatrixElemType) {
MatMPE = (_cmsStageMatrixData*) mpe ->Data;
mpe = mpe -> Next;
}
if (mpe != NULL && mpe ->Type == cmsSigCurveSetElemType) {
PreMPE = (_cmsStageToneCurvesData*) mpe ->Data;
mpe = mpe -> Next;
}
if (mpe != NULL && mpe ->Type == cmsSigCLutElemType) {
clut = (_cmsStageCLutData*) mpe -> Data;
mpe = mpe ->Next;
}
if (mpe != NULL && mpe ->Type == cmsSigCurveSetElemType) {
PostMPE = (_cmsStageToneCurvesData*) mpe ->Data;
mpe = mpe -> Next;
}
if (mpe != NULL) {
cmsSignalError(mpe->ContextID, cmsERROR_UNKNOWN_EXTENSION, "LUT is not suitable to be saved as LUT16");
return FALSE;
}
InputChannels = cmsPipelineInputChannels(NewLUT);
OutputChannels = cmsPipelineOutputChannels(NewLUT);
if (clut == NULL)
clutPoints = 0;
else
clutPoints = clut->Params->nSamples[0];
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) InputChannels)) return FALSE;
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) OutputChannels)) return FALSE;
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) clutPoints)) return FALSE;
if (!_cmsWriteUInt8Number(io, 0)) return FALSE;
if (MatMPE != NULL) {
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[0])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[1])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[2])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[3])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[4])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[5])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[6])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[7])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, MatMPE -> Double[8])) return FALSE;
}
else {
if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE;
}
if (PreMPE != NULL) {
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) PreMPE ->TheCurves[0]->nEntries)) return FALSE;
} else {
if (!_cmsWriteUInt16Number(io, 2)) return FALSE;
}
if (PostMPE != NULL) {
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) PostMPE ->TheCurves[0]->nEntries)) return FALSE;
} else {
if (!_cmsWriteUInt16Number(io, 2)) return FALSE;
}
if (PreMPE != NULL) {
if (!Write16bitTables(self ->ContextID, io, PreMPE)) return FALSE;
}
else {
for (i=0; i < InputChannels; i++) {
if (!_cmsWriteUInt16Number(io, 0)) return FALSE;
if (!_cmsWriteUInt16Number(io, 0xffff)) return FALSE;
}
}
nTabSize = uipow(OutputChannels, clutPoints, InputChannels);
if (nTabSize == (cmsUInt32Number) -1) return FALSE;
if (nTabSize > 0) {
if (clut != NULL) {
if (!_cmsWriteUInt16Array(io, nTabSize, clut->Tab.T)) return FALSE;
}
}
if (PostMPE != NULL) {
if (!Write16bitTables(self ->ContextID, io, PostMPE)) return FALSE;
}
else {
for (i=0; i < OutputChannels; i++) {
if (!_cmsWriteUInt16Number(io, 0)) return FALSE;
if (!_cmsWriteUInt16Number(io, 0xffff)) return FALSE;
}
}
return TRUE;
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_LUT16_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return (void*) cmsPipelineDup((cmsPipeline*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_LUT16_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsPipelineFree((cmsPipeline*) Ptr);
return;
cmsUNUSED_PARAMETER(self);
}
static
cmsStage* ReadMatrix(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset)
{
cmsFloat64Number dMat[3*3];
cmsFloat64Number dOff[3];
cmsStage* Mat;
if (!io -> Seek(io, Offset)) return NULL;
if (!_cmsRead15Fixed16Number(io, &dMat[0])) return NULL;
if (!_cmsRead15Fixed16Number(io, &dMat[1])) return NULL;
if (!_cmsRead15Fixed16Number(io, &dMat[2])) return NULL;
if (!_cmsRead15Fixed16Number(io, &dMat[3])) return NULL;
if (!_cmsRead15Fixed16Number(io, &dMat[4])) return NULL;
if (!_cmsRead15Fixed16Number(io, &dMat[5])) return NULL;
if (!_cmsRead15Fixed16Number(io, &dMat[6])) return NULL;
if (!_cmsRead15Fixed16Number(io, &dMat[7])) return NULL;
if (!_cmsRead15Fixed16Number(io, &dMat[8])) return NULL;
if (!_cmsRead15Fixed16Number(io, &dOff[0])) return NULL;
if (!_cmsRead15Fixed16Number(io, &dOff[1])) return NULL;
if (!_cmsRead15Fixed16Number(io, &dOff[2])) return NULL;
Mat = cmsStageAllocMatrix(self ->ContextID, 3, 3, dMat, dOff);
return Mat;
}
static
cmsStage* ReadCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset, int InputChannels, int OutputChannels)
{
cmsUInt8Number gridPoints8[cmsMAXCHANNELS];
cmsUInt32Number GridPoints[cmsMAXCHANNELS], i;
cmsUInt8Number Precision;
cmsStage* CLUT;
_cmsStageCLutData* Data;
if (!io -> Seek(io, Offset)) return NULL;
if (io -> Read(io, gridPoints8, cmsMAXCHANNELS, 1) != 1) return NULL;
for (i=0; i < cmsMAXCHANNELS; i++) {
if (gridPoints8[i] == 1) return NULL;
GridPoints[i] = gridPoints8[i];
}
if (!_cmsReadUInt8Number(io, &Precision)) return NULL;
if (!_cmsReadUInt8Number(io, NULL)) return NULL;
if (!_cmsReadUInt8Number(io, NULL)) return NULL;
if (!_cmsReadUInt8Number(io, NULL)) return NULL;
CLUT = cmsStageAllocCLut16bitGranular(self ->ContextID, GridPoints, InputChannels, OutputChannels, NULL);
if (CLUT == NULL) return NULL;
Data = (_cmsStageCLutData*) CLUT ->Data;
if (Precision == 1) {
cmsUInt8Number v;
for (i=0; i < Data ->nEntries; i++) {
if (io ->Read(io, &v, sizeof(cmsUInt8Number), 1) != 1) return NULL;
Data ->Tab.T[i] = FROM_8_TO_16(v);
}
}
else
if (Precision == 2) {
if (!_cmsReadUInt16Array(io, Data->nEntries, Data ->Tab.T)) {
cmsStageFree(CLUT);
return NULL;
}
}
else {
cmsStageFree(CLUT);
cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision);
return NULL;
}
return CLUT;
}
static
cmsToneCurve* ReadEmbeddedCurve(struct _cms_typehandler_struct* self, cmsIOHANDLER* io)
{
cmsTagTypeSignature BaseType;
cmsUInt32Number nItems;
BaseType = _cmsReadTypeBase(io);
switch (BaseType) {
case cmsSigCurveType:
return (cmsToneCurve*) Type_Curve_Read(self, io, &nItems, 0);
case cmsSigParametricCurveType:
return (cmsToneCurve*) Type_ParametricCurve_Read(self, io, &nItems, 0);
default:
{
char String[5];
_cmsTagSignature2String(String, (cmsTagSignature) BaseType);
cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve type '%s'", String);
}
return NULL;
}
}
static
cmsStage* ReadSetOfCurves(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset, cmsUInt32Number nCurves)
{
cmsToneCurve* Curves[cmsMAXCHANNELS];
cmsUInt32Number i;
cmsStage* Lin = NULL;
if (nCurves > cmsMAXCHANNELS) return FALSE;
if (!io -> Seek(io, Offset)) return FALSE;
for (i=0; i < nCurves; i++)
Curves[i] = NULL;
for (i=0; i < nCurves; i++) {
Curves[i] = ReadEmbeddedCurve(self, io);
if (Curves[i] == NULL) goto Error;
if (!_cmsReadAlignment(io)) goto Error;
}
Lin = cmsStageAllocToneCurves(self ->ContextID, nCurves, Curves);
Error:
for (i=0; i < nCurves; i++)
cmsFreeToneCurve(Curves[i]);
return Lin;
}
static
void* Type_LUTA2B_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsUInt32Number BaseOffset;
cmsUInt8Number inputChan;
cmsUInt8Number outputChan;
cmsUInt32Number offsetB;
cmsUInt32Number offsetMat;
cmsUInt32Number offsetM;
cmsUInt32Number offsetC;
cmsUInt32Number offsetA;
cmsPipeline* NewLUT = NULL;
BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
if (!_cmsReadUInt8Number(io, &inputChan)) return NULL;
if (!_cmsReadUInt8Number(io, &outputChan)) return NULL;
if (!_cmsReadUInt16Number(io, NULL)) return NULL;
if (!_cmsReadUInt32Number(io, &offsetB)) return NULL;
if (!_cmsReadUInt32Number(io, &offsetMat)) return NULL;
if (!_cmsReadUInt32Number(io, &offsetM)) return NULL;
if (!_cmsReadUInt32Number(io, &offsetC)) return NULL;
if (!_cmsReadUInt32Number(io, &offsetA)) return NULL;
NewLUT = cmsPipelineAlloc(self ->ContextID, inputChan, outputChan);
if (NewLUT == NULL) return NULL;
if (offsetA!= 0) {
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetA, inputChan)))
goto Error;
}
if (offsetC != 0) {
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan)))
goto Error;
}
if (offsetM != 0) {
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetM, outputChan)))
goto Error;
}
if (offsetMat != 0) {
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadMatrix(self, io, BaseOffset + offsetMat)))
goto Error;
}
if (offsetB != 0) {
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetB, outputChan)))
goto Error;
}
*nItems = 1;
return NewLUT;
Error:
cmsPipelineFree(NewLUT);
return NULL;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool WriteMatrix(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsStage* mpe)
{
_cmsStageMatrixData* m = (_cmsStageMatrixData*) mpe -> Data;
if (!_cmsWrite15Fixed16Number(io, m -> Double[0])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, m -> Double[1])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, m -> Double[2])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, m -> Double[3])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, m -> Double[4])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, m -> Double[5])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, m -> Double[6])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, m -> Double[7])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, m -> Double[8])) return FALSE;
if (m ->Offset != NULL) {
if (!_cmsWrite15Fixed16Number(io, m -> Offset[0])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, m -> Offset[1])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, m -> Offset[2])) return FALSE;
}
else {
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
}
return TRUE;
cmsUNUSED_PARAMETER(self);
}
static
cmsBool WriteSetOfCurves(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsTagTypeSignature Type, cmsStage* mpe)
{
cmsUInt32Number i, n;
cmsTagTypeSignature CurrentType;
cmsToneCurve** Curves;
n = cmsStageOutputChannels(mpe);
Curves = _cmsStageGetPtrToCurveSet(mpe);
for (i=0; i < n; i++) {
CurrentType = Type;
if ((Curves[i] ->nSegments == 0)||
((Curves[i]->nSegments == 2) && (Curves[i] ->Segments[1].Type == 0)) )
CurrentType = cmsSigCurveType;
else
if (Curves[i] ->Segments[0].Type < 0)
CurrentType = cmsSigCurveType;
if (!_cmsWriteTypeBase(io, CurrentType)) return FALSE;
switch (CurrentType) {
case cmsSigCurveType:
if (!Type_Curve_Write(self, io, Curves[i], 1)) return FALSE;
break;
case cmsSigParametricCurveType:
if (!Type_ParametricCurve_Write(self, io, Curves[i], 1)) return FALSE;
break;
default:
{
char String[5];
_cmsTagSignature2String(String, (cmsTagSignature) Type);
cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve type '%s'", String);
}
return FALSE;
}
if (!_cmsWriteAlignment(io)) return FALSE;
}
return TRUE;
}
static
cmsBool WriteCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt8Number Precision, cmsStage* mpe)
{
cmsUInt8Number gridPoints[cmsMAXCHANNELS];
cmsUInt32Number i;
_cmsStageCLutData* CLUT = ( _cmsStageCLutData*) mpe -> Data;
if (CLUT ->HasFloatValues) {
cmsSignalError(self ->ContextID, cmsERROR_NOT_SUITABLE, "Cannot save floating point data, CLUT are 8 or 16 bit only");
return FALSE;
}
memset(gridPoints, 0, sizeof(gridPoints));
for (i=0; i < (cmsUInt32Number) CLUT ->Params ->nInputs; i++)
gridPoints[i] = (cmsUInt8Number) CLUT ->Params ->nSamples[i];
if (!io -> Write(io, cmsMAXCHANNELS*sizeof(cmsUInt8Number), gridPoints)) return FALSE;
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) Precision)) return FALSE;
if (!_cmsWriteUInt8Number(io, 0)) return FALSE;
if (!_cmsWriteUInt8Number(io, 0)) return FALSE;
if (!_cmsWriteUInt8Number(io, 0)) return FALSE;
if (Precision == 1) {
for (i=0; i < CLUT->nEntries; i++) {
if (!_cmsWriteUInt8Number(io, FROM_16_TO_8(CLUT->Tab.T[i]))) return FALSE;
}
}
else
if (Precision == 2) {
if (!_cmsWriteUInt16Array(io, CLUT->nEntries, CLUT ->Tab.T)) return FALSE;
}
else {
cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision);
return FALSE;
}
if (!_cmsWriteAlignment(io)) return FALSE;
return TRUE;
}
static
cmsBool Type_LUTA2B_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsPipeline* Lut = (cmsPipeline*) Ptr;
int inputChan, outputChan;
cmsStage *A = NULL, *B = NULL, *M = NULL;
cmsStage * Matrix = NULL;
cmsStage * CLUT = NULL;
cmsUInt32Number offsetB = 0, offsetMat = 0, offsetM = 0, offsetC = 0, offsetA = 0;
cmsUInt32Number BaseOffset, DirectoryPos, CurrentPos;
BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
if (Lut ->Elements != NULL)
if (!cmsPipelineCheckAndRetreiveStages(Lut, 1, cmsSigCurveSetElemType, &B))
if (!cmsPipelineCheckAndRetreiveStages(Lut, 3, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType, &M, &Matrix, &B))
if (!cmsPipelineCheckAndRetreiveStages(Lut, 3, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, &A, &CLUT, &B))
if (!cmsPipelineCheckAndRetreiveStages(Lut, 5, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType,
cmsSigMatrixElemType, cmsSigCurveSetElemType, &A, &CLUT, &M, &Matrix, &B)) {
cmsSignalError(self->ContextID, cmsERROR_NOT_SUITABLE, "LUT is not suitable to be saved as LutAToB");
return FALSE;
}
inputChan = cmsPipelineInputChannels(Lut);
outputChan = cmsPipelineOutputChannels(Lut);
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) inputChan)) return FALSE;
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) outputChan)) return FALSE;
if (!_cmsWriteUInt16Number(io, 0)) return FALSE;
DirectoryPos = io ->Tell(io);
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
if (A != NULL) {
offsetA = io ->Tell(io) - BaseOffset;
if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, A)) return FALSE;
}
if (CLUT != NULL) {
offsetC = io ->Tell(io) - BaseOffset;
if (!WriteCLUT(self, io, Lut ->SaveAs8Bits ? 1 : 2, CLUT)) return FALSE;
}
if (M != NULL) {
offsetM = io ->Tell(io) - BaseOffset;
if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, M)) return FALSE;
}
if (Matrix != NULL) {
offsetMat = io ->Tell(io) - BaseOffset;
if (!WriteMatrix(self, io, Matrix)) return FALSE;
}
if (B != NULL) {
offsetB = io ->Tell(io) - BaseOffset;
if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, B)) return FALSE;
}
CurrentPos = io ->Tell(io);
if (!io ->Seek(io, DirectoryPos)) return FALSE;
if (!_cmsWriteUInt32Number(io, offsetB)) return FALSE;
if (!_cmsWriteUInt32Number(io, offsetMat)) return FALSE;
if (!_cmsWriteUInt32Number(io, offsetM)) return FALSE;
if (!_cmsWriteUInt32Number(io, offsetC)) return FALSE;
if (!_cmsWriteUInt32Number(io, offsetA)) return FALSE;
if (!io ->Seek(io, CurrentPos)) return FALSE;
return TRUE;
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_LUTA2B_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return (void*) cmsPipelineDup((cmsPipeline*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_LUTA2B_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsPipelineFree((cmsPipeline*) Ptr);
return;
cmsUNUSED_PARAMETER(self);
}
static
void* Type_LUTB2A_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsUInt8Number inputChan;
cmsUInt8Number outputChan;
cmsUInt32Number BaseOffset;
cmsUInt32Number offsetB;
cmsUInt32Number offsetMat;
cmsUInt32Number offsetM;
cmsUInt32Number offsetC;
cmsUInt32Number offsetA;
cmsPipeline* NewLUT = NULL;
BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
if (!_cmsReadUInt8Number(io, &inputChan)) return NULL;
if (!_cmsReadUInt8Number(io, &outputChan)) return NULL;
if (!_cmsReadUInt16Number(io, NULL)) return NULL;
if (!_cmsReadUInt32Number(io, &offsetB)) return NULL;
if (!_cmsReadUInt32Number(io, &offsetMat)) return NULL;
if (!_cmsReadUInt32Number(io, &offsetM)) return NULL;
if (!_cmsReadUInt32Number(io, &offsetC)) return NULL;
if (!_cmsReadUInt32Number(io, &offsetA)) return NULL;
NewLUT = cmsPipelineAlloc(self ->ContextID, inputChan, outputChan);
if (NewLUT == NULL) return NULL;
if (offsetB != 0) {
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetB, inputChan)))
goto Error;
}
if (offsetMat != 0) {
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadMatrix(self, io, BaseOffset + offsetMat)))
goto Error;
}
if (offsetM != 0) {
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetM, inputChan)))
goto Error;
}
if (offsetC != 0) {
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan)))
goto Error;
}
if (offsetA!= 0) {
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, ReadSetOfCurves(self, io, BaseOffset + offsetA, outputChan)))
goto Error;
}
*nItems = 1;
return NewLUT;
Error:
cmsPipelineFree(NewLUT);
return NULL;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_LUTB2A_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsPipeline* Lut = (cmsPipeline*) Ptr;
int inputChan, outputChan;
cmsStage *A = NULL, *B = NULL, *M = NULL;
cmsStage *Matrix = NULL;
cmsStage *CLUT = NULL;
cmsUInt32Number offsetB = 0, offsetMat = 0, offsetM = 0, offsetC = 0, offsetA = 0;
cmsUInt32Number BaseOffset, DirectoryPos, CurrentPos;
BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
if (!cmsPipelineCheckAndRetreiveStages(Lut, 1, cmsSigCurveSetElemType, &B))
if (!cmsPipelineCheckAndRetreiveStages(Lut, 3, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType, &B, &Matrix, &M))
if (!cmsPipelineCheckAndRetreiveStages(Lut, 3, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, &B, &CLUT, &A))
if (!cmsPipelineCheckAndRetreiveStages(Lut, 5, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType,
cmsSigCLutElemType, cmsSigCurveSetElemType, &B, &Matrix, &M, &CLUT, &A)) {
cmsSignalError(self->ContextID, cmsERROR_NOT_SUITABLE, "LUT is not suitable to be saved as LutBToA");
return FALSE;
}
inputChan = cmsPipelineInputChannels(Lut);
outputChan = cmsPipelineOutputChannels(Lut);
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) inputChan)) return FALSE;
if (!_cmsWriteUInt8Number(io, (cmsUInt8Number) outputChan)) return FALSE;
if (!_cmsWriteUInt16Number(io, 0)) return FALSE;
DirectoryPos = io ->Tell(io);
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
if (A != NULL) {
offsetA = io ->Tell(io) - BaseOffset;
if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, A)) return FALSE;
}
if (CLUT != NULL) {
offsetC = io ->Tell(io) - BaseOffset;
if (!WriteCLUT(self, io, Lut ->SaveAs8Bits ? 1 : 2, CLUT)) return FALSE;
}
if (M != NULL) {
offsetM = io ->Tell(io) - BaseOffset;
if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, M)) return FALSE;
}
if (Matrix != NULL) {
offsetMat = io ->Tell(io) - BaseOffset;
if (!WriteMatrix(self, io, Matrix)) return FALSE;
}
if (B != NULL) {
offsetB = io ->Tell(io) - BaseOffset;
if (!WriteSetOfCurves(self, io, cmsSigParametricCurveType, B)) return FALSE;
}
CurrentPos = io ->Tell(io);
if (!io ->Seek(io, DirectoryPos)) return FALSE;
if (!_cmsWriteUInt32Number(io, offsetB)) return FALSE;
if (!_cmsWriteUInt32Number(io, offsetMat)) return FALSE;
if (!_cmsWriteUInt32Number(io, offsetM)) return FALSE;
if (!_cmsWriteUInt32Number(io, offsetC)) return FALSE;
if (!_cmsWriteUInt32Number(io, offsetA)) return FALSE;
if (!io ->Seek(io, CurrentPos)) return FALSE;
return TRUE;
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_LUTB2A_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return (void*) cmsPipelineDup((cmsPipeline*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_LUTB2A_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsPipelineFree((cmsPipeline*) Ptr);
return;
cmsUNUSED_PARAMETER(self);
}
static
void *Type_ColorantTable_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsUInt32Number i, Count;
cmsNAMEDCOLORLIST* List;
char Name[34];
cmsUInt16Number PCS[3];
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
if (Count > cmsMAXCHANNELS) {
cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many colorants '%d'", Count);
return NULL;
}
List = cmsAllocNamedColorList(self ->ContextID, Count, 0, "", "");
for (i=0; i < Count; i++) {
if (io ->Read(io, Name, 32, 1) != 1) goto Error;
Name[33] = 0;
if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error;
if (!cmsAppendNamedColor(List, Name, PCS, NULL)) goto Error;
}
*nItems = 1;
return List;
Error:
*nItems = 0;
cmsFreeNamedColorList(List);
return NULL;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_ColorantTable_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr;
int i, nColors;
nColors = cmsNamedColorCount(NamedColorList);
if (!_cmsWriteUInt32Number(io, nColors)) return FALSE;
for (i=0; i < nColors; i++) {
char root[33];
cmsUInt16Number PCS[3];
if (!cmsNamedColorInfo(NamedColorList, i, root, NULL, NULL, PCS, NULL)) return 0;
root[32] = 0;
if (!io ->Write(io, 32, root)) return FALSE;
if (!_cmsWriteUInt16Array(io, 3, PCS)) return FALSE;
}
return TRUE;
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void* Type_ColorantTable_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n)
{
cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) Ptr;
return (void*) cmsDupNamedColorList(nc);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_ColorantTable_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsFreeNamedColorList((cmsNAMEDCOLORLIST*) Ptr);
return;
cmsUNUSED_PARAMETER(self);
}
static
void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsUInt32Number vendorFlag;
cmsUInt32Number count;
cmsUInt32Number nDeviceCoords;
char prefix[32];
char suffix[32];
cmsNAMEDCOLORLIST* v;
cmsUInt32Number i;
*nItems = 0;
if (!_cmsReadUInt32Number(io, &vendorFlag)) return NULL;
if (!_cmsReadUInt32Number(io, &count)) return NULL;
if (!_cmsReadUInt32Number(io, &nDeviceCoords)) return NULL;
if (io -> Read(io, prefix, 32, 1) != 1) return NULL;
if (io -> Read(io, suffix, 32, 1) != 1) return NULL;
prefix[31] = suffix[31] = 0;
v = cmsAllocNamedColorList(self ->ContextID, count, nDeviceCoords, prefix, suffix);
if (v == NULL) {
cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many named colors '%d'", count);
return NULL;
}
if (nDeviceCoords > cmsMAXCHANNELS) {
cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many device coordinates '%d'", nDeviceCoords);
return 0;
}
for (i=0; i < count; i++) {
cmsUInt16Number PCS[3];
cmsUInt16Number Colorant[cmsMAXCHANNELS];
char Root[33];
memset(Colorant, 0, sizeof(Colorant));
if (io -> Read(io, Root, 32, 1) != 1) return NULL;
if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error;
if (!_cmsReadUInt16Array(io, nDeviceCoords, Colorant)) goto Error;
if (!cmsAppendNamedColor(v, Root, PCS, Colorant)) goto Error;
}
*nItems = 1;
return (void*) v ;
Error:
cmsFreeNamedColorList(v);
return NULL;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr;
char prefix[32];
char suffix[32];
int i, nColors;
nColors = cmsNamedColorCount(NamedColorList);
if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
if (!_cmsWriteUInt32Number(io, nColors)) return FALSE;
if (!_cmsWriteUInt32Number(io, NamedColorList ->ColorantCount)) return FALSE;
strncpy(prefix, (const char*) NamedColorList->Prefix, 32);
strncpy(suffix, (const char*) NamedColorList->Suffix, 32);
suffix[31] = prefix[31] = 0;
if (!io ->Write(io, 32, prefix)) return FALSE;
if (!io ->Write(io, 32, suffix)) return FALSE;
for (i=0; i < nColors; i++) {
cmsUInt16Number PCS[3];
cmsUInt16Number Colorant[cmsMAXCHANNELS];
char Root[33];
if (!cmsNamedColorInfo(NamedColorList, i, Root, NULL, NULL, PCS, Colorant)) return 0;
if (!io ->Write(io, 32 , Root)) return FALSE;
if (!_cmsWriteUInt16Array(io, 3, PCS)) return FALSE;
if (!_cmsWriteUInt16Array(io, NamedColorList ->ColorantCount, Colorant)) return FALSE;
}
return TRUE;
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void* Type_NamedColor_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n)
{
cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) Ptr;
return (void*) cmsDupNamedColorList(nc);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_NamedColor_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsFreeNamedColorList((cmsNAMEDCOLORLIST*) Ptr);
return;
cmsUNUSED_PARAMETER(self);
}
static
cmsBool ReadEmbeddedText(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU** mlu, cmsUInt32Number SizeOfTag)
{
cmsTagTypeSignature BaseType;
cmsUInt32Number nItems;
BaseType = _cmsReadTypeBase(io);
switch (BaseType) {
case cmsSigTextType:
if (*mlu) cmsMLUfree(*mlu);
*mlu = (cmsMLU*)Type_Text_Read(self, io, &nItems, SizeOfTag);
return (*mlu != NULL);
case cmsSigTextDescriptionType:
if (*mlu) cmsMLUfree(*mlu);
*mlu = (cmsMLU*) Type_Text_Description_Read(self, io, &nItems, SizeOfTag);
return (*mlu != NULL);
case cmsSigMultiLocalizedUnicodeType:
if (*mlu) cmsMLUfree(*mlu);
*mlu = (cmsMLU*) Type_MLU_Read(self, io, &nItems, SizeOfTag);
return (*mlu != NULL);
default: return FALSE;
}
}
static
void *Type_ProfileSequenceDesc_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsSEQ* OutSeq;
cmsUInt32Number i, Count;
*nItems = 0;
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
OutSeq = cmsAllocProfileSequenceDescription(self ->ContextID, Count);
if (OutSeq == NULL) return NULL;
OutSeq ->n = Count;
for (i=0; i < Count; i++) {
cmsPSEQDESC* sec = &OutSeq -> seq[i];
if (!_cmsReadUInt32Number(io, &sec ->deviceMfg)) goto Error;
if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error;
SizeOfTag -= sizeof(cmsUInt32Number);
if (!_cmsReadUInt32Number(io, &sec ->deviceModel)) goto Error;
if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error;
SizeOfTag -= sizeof(cmsUInt32Number);
if (!_cmsReadUInt64Number(io, &sec ->attributes)) goto Error;
if (SizeOfTag < sizeof(cmsUInt64Number)) goto Error;
SizeOfTag -= sizeof(cmsUInt64Number);
if (!_cmsReadUInt32Number(io, (cmsUInt32Number *)&sec ->technology)) goto Error;
if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error;
SizeOfTag -= sizeof(cmsUInt32Number);
if (!ReadEmbeddedText(self, io, &sec ->Manufacturer, SizeOfTag)) goto Error;
if (!ReadEmbeddedText(self, io, &sec ->Model, SizeOfTag)) goto Error;
}
*nItems = 1;
return OutSeq;
Error:
cmsFreeProfileSequenceDescription(OutSeq);
return NULL;
}
static
cmsBool SaveDescription(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* Text)
{
if (self ->ICCVersion < 0x4000000) {
if (!_cmsWriteTypeBase(io, cmsSigTextDescriptionType)) return FALSE;
return Type_Text_Description_Write(self, io, Text, 1);
}
else {
if (!_cmsWriteTypeBase(io, cmsSigMultiLocalizedUnicodeType)) return FALSE;
return Type_MLU_Write(self, io, Text, 1);
}
}
static
cmsBool Type_ProfileSequenceDesc_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsSEQ* Seq = (cmsSEQ*) Ptr;
cmsUInt32Number i;
if (!_cmsWriteUInt32Number(io, Seq->n)) return FALSE;
for (i=0; i < Seq ->n; i++) {
cmsPSEQDESC* sec = &Seq -> seq[i];
if (!_cmsWriteUInt32Number(io, sec ->deviceMfg)) return FALSE;
if (!_cmsWriteUInt32Number(io, sec ->deviceModel)) return FALSE;
if (!_cmsWriteUInt64Number(io, &sec ->attributes)) return FALSE;
if (!_cmsWriteUInt32Number(io, sec ->technology)) return FALSE;
if (!SaveDescription(self, io, sec ->Manufacturer)) return FALSE;
if (!SaveDescription(self, io, sec ->Model)) return FALSE;
}
return TRUE;
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_ProfileSequenceDesc_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n)
{
return (void*) cmsDupProfileSequenceDescription((cmsSEQ*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_ProfileSequenceDesc_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsFreeProfileSequenceDescription((cmsSEQ*) Ptr);
return;
cmsUNUSED_PARAMETER(self);
}
static
cmsBool ReadSeqID(struct _cms_typehandler_struct* self,
cmsIOHANDLER* io,
void* Cargo,
cmsUInt32Number n,
cmsUInt32Number SizeOfTag)
{
cmsSEQ* OutSeq = (cmsSEQ*) Cargo;
cmsPSEQDESC* seq = &OutSeq ->seq[n];
if (io -> Read(io, seq ->ProfileID.ID8, 16, 1) != 1) return FALSE;
if (!ReadEmbeddedText(self, io, &seq ->Description, SizeOfTag)) return FALSE;
return TRUE;
}
static
void *Type_ProfileSequenceId_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsSEQ* OutSeq;
cmsUInt32Number Count;
cmsUInt32Number BaseOffset;
*nItems = 0;
BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
OutSeq = cmsAllocProfileSequenceDescription(self ->ContextID, Count);
if (OutSeq == NULL) return NULL;
if (!ReadPositionTable(self, io, Count, BaseOffset, OutSeq, ReadSeqID)) {
cmsFreeProfileSequenceDescription(OutSeq);
return NULL;
}
*nItems = 1;
return OutSeq;
}
static
cmsBool WriteSeqID(struct _cms_typehandler_struct* self,
cmsIOHANDLER* io,
void* Cargo,
cmsUInt32Number n,
cmsUInt32Number SizeOfTag)
{
cmsSEQ* Seq = (cmsSEQ*) Cargo;
if (!io ->Write(io, 16, Seq ->seq[n].ProfileID.ID8)) return FALSE;
if (!SaveDescription(self, io, Seq ->seq[n].Description)) return FALSE;
return TRUE;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_ProfileSequenceId_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsSEQ* Seq = (cmsSEQ*) Ptr;
cmsUInt32Number BaseOffset;
BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
if (!_cmsWriteUInt32Number(io, Seq ->n)) return FALSE;
if (!WritePositionTable(self, io, 0, Seq ->n, BaseOffset, Seq, WriteSeqID)) return FALSE;
return TRUE;
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_ProfileSequenceId_Dup(struct _cms_typehandler_struct* self, const void* Ptr, cmsUInt32Number n)
{
return (void*) cmsDupProfileSequenceDescription((cmsSEQ*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_ProfileSequenceId_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsFreeProfileSequenceDescription((cmsSEQ*) Ptr);
return;
cmsUNUSED_PARAMETER(self);
}
static
void *Type_UcrBg_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsUcrBg* n = (cmsUcrBg*) _cmsMallocZero(self ->ContextID, sizeof(cmsUcrBg));
cmsUInt32Number CountUcr, CountBg;
char* ASCIIString;
*nItems = 0;
if (n == NULL) return NULL;
if (!_cmsReadUInt32Number(io, &CountUcr)) return NULL;
if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
n ->Ucr = cmsBuildTabulatedToneCurve16(self ->ContextID, CountUcr, NULL);
if (n ->Ucr == NULL) return NULL;
if (!_cmsReadUInt16Array(io, CountUcr, n ->Ucr->Table16)) return NULL;
if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= CountUcr * sizeof(cmsUInt16Number);
if (!_cmsReadUInt32Number(io, &CountBg)) return NULL;
if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
n ->Bg = cmsBuildTabulatedToneCurve16(self ->ContextID, CountBg, NULL);
if (n ->Bg == NULL) return NULL;
if (!_cmsReadUInt16Array(io, CountBg, n ->Bg->Table16)) return NULL;
if (SizeOfTag < CountBg * sizeof(cmsUInt16Number)) return NULL;
SizeOfTag -= CountBg * sizeof(cmsUInt16Number);
if (SizeOfTag == UINT_MAX) return NULL;
n ->Desc = cmsMLUalloc(self ->ContextID, 1);
if (n ->Desc == NULL) return NULL;
ASCIIString = (char*) _cmsMalloc(self ->ContextID, SizeOfTag + 1);
if (io ->Read(io, ASCIIString, sizeof(char), SizeOfTag) != SizeOfTag) return NULL;
ASCIIString[SizeOfTag] = 0;
cmsMLUsetASCII(n ->Desc, cmsNoLanguage, cmsNoCountry, ASCIIString);
_cmsFree(self ->ContextID, ASCIIString);
*nItems = 1;
return (void*) n;
}
static
cmsBool Type_UcrBg_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsUcrBg* Value = (cmsUcrBg*) Ptr;
cmsUInt32Number TextSize;
char* Text;
if (!_cmsWriteUInt32Number(io, Value ->Ucr ->nEntries)) return FALSE;
if (!_cmsWriteUInt16Array(io, Value ->Ucr ->nEntries, Value ->Ucr ->Table16)) return FALSE;
if (!_cmsWriteUInt32Number(io, Value ->Bg ->nEntries)) return FALSE;
if (!_cmsWriteUInt16Array(io, Value ->Bg ->nEntries, Value ->Bg ->Table16)) return FALSE;
TextSize = cmsMLUgetASCII(Value ->Desc, cmsNoLanguage, cmsNoCountry, NULL, 0);
Text = (char*) _cmsMalloc(self ->ContextID, TextSize);
if (cmsMLUgetASCII(Value ->Desc, cmsNoLanguage, cmsNoCountry, Text, TextSize) != TextSize) return FALSE;
if (!io ->Write(io, TextSize, Text)) return FALSE;
_cmsFree(self ->ContextID, Text);
return TRUE;
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_UcrBg_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
cmsUcrBg* Src = (cmsUcrBg*) Ptr;
cmsUcrBg* NewUcrBg = (cmsUcrBg*) _cmsMallocZero(self ->ContextID, sizeof(cmsUcrBg));
if (NewUcrBg == NULL) return NULL;
NewUcrBg ->Bg = cmsDupToneCurve(Src ->Bg);
NewUcrBg ->Ucr = cmsDupToneCurve(Src ->Ucr);
NewUcrBg ->Desc = cmsMLUdup(Src ->Desc);
return (void*) NewUcrBg;
cmsUNUSED_PARAMETER(n);
}
static
void Type_UcrBg_Free(struct _cms_typehandler_struct* self, void *Ptr)
{
cmsUcrBg* Src = (cmsUcrBg*) Ptr;
if (Src ->Ucr) cmsFreeToneCurve(Src ->Ucr);
if (Src ->Bg) cmsFreeToneCurve(Src ->Bg);
if (Src ->Desc) cmsMLUfree(Src ->Desc);
_cmsFree(self ->ContextID, Ptr);
}
static
cmsBool ReadCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, cmsUInt32Number* SizeOfTag, const char* Section)
{
cmsUInt32Number Count;
char* Text;
if (*SizeOfTag < sizeof(cmsUInt32Number)) return FALSE;
if (!_cmsReadUInt32Number(io, &Count)) return FALSE;
if (Count > UINT_MAX - sizeof(cmsUInt32Number)) return FALSE;
if (*SizeOfTag < Count + sizeof(cmsUInt32Number)) return FALSE;
Text = (char*) _cmsMalloc(self ->ContextID, Count+1);
if (Text == NULL) return FALSE;
if (io ->Read(io, Text, sizeof(cmsUInt8Number), Count) != Count) {
_cmsFree(self ->ContextID, Text);
return FALSE;
}
Text[Count] = 0;
cmsMLUsetASCII(mlu, "PS", Section, Text);
_cmsFree(self ->ContextID, Text);
*SizeOfTag -= (Count + sizeof(cmsUInt32Number));
return TRUE;
}
static
cmsBool WriteCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, const char* Section)
{
cmsUInt32Number TextSize;
char* Text;
TextSize = cmsMLUgetASCII(mlu, "PS", Section, NULL, 0);
Text = (char*) _cmsMalloc(self ->ContextID, TextSize);
if (!_cmsWriteUInt32Number(io, TextSize)) return FALSE;
if (cmsMLUgetASCII(mlu, "PS", Section, Text, TextSize) == 0) return FALSE;
if (!io ->Write(io, TextSize, Text)) return FALSE;
_cmsFree(self ->ContextID, Text);
return TRUE;
}
static
void *Type_CrdInfo_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsMLU* mlu = cmsMLUalloc(self ->ContextID, 5);
*nItems = 0;
if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "nm")) goto Error;
if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "#0")) goto Error;
if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "#1")) goto Error;
if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "#2")) goto Error;
if (!ReadCountAndSting(self, io, mlu, &SizeOfTag, "#3")) goto Error;
*nItems = 1;
return (void*) mlu;
Error:
cmsMLUfree(mlu);
return NULL;
}
static
cmsBool Type_CrdInfo_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsMLU* mlu = (cmsMLU*) Ptr;
if (!WriteCountAndSting(self, io, mlu, "nm")) goto Error;
if (!WriteCountAndSting(self, io, mlu, "#0")) goto Error;
if (!WriteCountAndSting(self, io, mlu, "#1")) goto Error;
if (!WriteCountAndSting(self, io, mlu, "#2")) goto Error;
if (!WriteCountAndSting(self, io, mlu, "#3")) goto Error;
return TRUE;
Error:
return FALSE;
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_CrdInfo_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return (void*) cmsMLUdup((cmsMLU*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_CrdInfo_Free(struct _cms_typehandler_struct* self, void *Ptr)
{
cmsMLUfree((cmsMLU*) Ptr);
return;
cmsUNUSED_PARAMETER(self);
}
static
void *Type_Screening_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsScreening* sc = NULL;
cmsUInt32Number i;
sc = (cmsScreening*) _cmsMallocZero(self ->ContextID, sizeof(cmsScreening));
if (sc == NULL) return NULL;
*nItems = 0;
if (!_cmsReadUInt32Number(io, &sc ->Flag)) goto Error;
if (!_cmsReadUInt32Number(io, &sc ->nChannels)) goto Error;
if (sc ->nChannels > cmsMAXCHANNELS - 1)
sc ->nChannels = cmsMAXCHANNELS - 1;
for (i=0; i < sc ->nChannels; i++) {
if (!_cmsRead15Fixed16Number(io, &sc ->Channels[i].Frequency)) goto Error;
if (!_cmsRead15Fixed16Number(io, &sc ->Channels[i].ScreenAngle)) goto Error;
if (!_cmsReadUInt32Number(io, &sc ->Channels[i].SpotShape)) goto Error;
}
*nItems = 1;
return (void*) sc;
Error:
if (sc != NULL)
_cmsFree(self ->ContextID, sc);
return NULL;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_Screening_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsScreening* sc = (cmsScreening* ) Ptr;
cmsUInt32Number i;
if (!_cmsWriteUInt32Number(io, sc ->Flag)) return FALSE;
if (!_cmsWriteUInt32Number(io, sc ->nChannels)) return FALSE;
for (i=0; i < sc ->nChannels; i++) {
if (!_cmsWrite15Fixed16Number(io, sc ->Channels[i].Frequency)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, sc ->Channels[i].ScreenAngle)) return FALSE;
if (!_cmsWriteUInt32Number(io, sc ->Channels[i].SpotShape)) return FALSE;
}
return TRUE;
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void* Type_Screening_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsScreening));
cmsUNUSED_PARAMETER(n);
}
static
void Type_Screening_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
_cmsFree(self ->ContextID, Ptr);
}
static
void *Type_ViewingConditions_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsICCViewingConditions* vc = NULL;
vc = (cmsICCViewingConditions*) _cmsMallocZero(self ->ContextID, sizeof(cmsICCViewingConditions));
if (vc == NULL) return NULL;
*nItems = 0;
if (!_cmsReadXYZNumber(io, &vc ->IlluminantXYZ)) goto Error;
if (!_cmsReadXYZNumber(io, &vc ->SurroundXYZ)) goto Error;
if (!_cmsReadUInt32Number(io, &vc ->IlluminantType)) goto Error;
*nItems = 1;
return (void*) vc;
Error:
if (vc != NULL)
_cmsFree(self ->ContextID, vc);
return NULL;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_ViewingConditions_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsICCViewingConditions* sc = (cmsICCViewingConditions* ) Ptr;
if (!_cmsWriteXYZNumber(io, &sc ->IlluminantXYZ)) return FALSE;
if (!_cmsWriteXYZNumber(io, &sc ->SurroundXYZ)) return FALSE;
if (!_cmsWriteUInt32Number(io, sc ->IlluminantType)) return FALSE;
return TRUE;
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void* Type_ViewingConditions_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsScreening));
cmsUNUSED_PARAMETER(n);
}
static
void Type_ViewingConditions_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
_cmsFree(self ->ContextID, Ptr);
}
static
void* GenericMPEdup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return (void*) cmsStageDup((cmsStage*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void GenericMPEfree(struct _cms_typehandler_struct* self, void *Ptr)
{
cmsStageFree((cmsStage*) Ptr);
return;
cmsUNUSED_PARAMETER(self);
}
static
cmsToneCurve* ReadSegmentedCurve(struct _cms_typehandler_struct* self, cmsIOHANDLER* io)
{
cmsCurveSegSignature ElementSig;
cmsUInt32Number i, j;
cmsUInt16Number nSegments;
cmsCurveSegment* Segments;
cmsToneCurve* Curve;
cmsFloat32Number PrevBreak = -1E22F;
if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return NULL;
if (ElementSig != cmsSigSegmentedCurve) return NULL;
if (!_cmsReadUInt32Number(io, NULL)) return NULL;
if (!_cmsReadUInt16Number(io, &nSegments)) return NULL;
if (!_cmsReadUInt16Number(io, NULL)) return NULL;
if (nSegments < 1) return NULL;
Segments = (cmsCurveSegment*) _cmsCalloc(self ->ContextID, nSegments, sizeof(cmsCurveSegment));
if (Segments == NULL) return NULL;
for (i=0; i < (cmsUInt32Number) nSegments - 1; i++) {
Segments[i].x0 = PrevBreak;
if (!_cmsReadFloat32Number(io, &Segments[i].x1)) goto Error;
PrevBreak = Segments[i].x1;
}
Segments[nSegments-1].x0 = PrevBreak;
Segments[nSegments-1].x1 = 1E22F;
for (i=0; i < nSegments; i++) {
if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) goto Error;
if (!_cmsReadUInt32Number(io, NULL)) goto Error;
switch (ElementSig) {
case cmsSigFormulaCurveSeg: {
cmsUInt16Number Type;
cmsUInt32Number ParamsByType[] = {4, 5, 5 };
if (!_cmsReadUInt16Number(io, &Type)) goto Error;
if (!_cmsReadUInt16Number(io, NULL)) goto Error;
Segments[i].Type = Type + 6;
if (Type > 2) goto Error;
for (j=0; j < ParamsByType[Type]; j++) {
cmsFloat32Number f;
if (!_cmsReadFloat32Number(io, &f)) goto Error;
Segments[i].Params[j] = f;
}
}
break;
case cmsSigSampledCurveSeg: {
cmsUInt32Number Count;
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
Segments[i].nGridPoints = Count;
Segments[i].SampledPoints = (cmsFloat32Number*) _cmsCalloc(self ->ContextID, Count, sizeof(cmsFloat32Number));
if (Segments[i].SampledPoints == NULL) goto Error;
for (j=0; j < Count; j++) {
if (!_cmsReadFloat32Number(io, &Segments[i].SampledPoints[j])) goto Error;
}
}
break;
default:
{
char String[5];
_cmsTagSignature2String(String, (cmsTagSignature) ElementSig);
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve element type '%s' found.", String);
}
return NULL;
}
}
Curve = cmsBuildSegmentedToneCurve(self ->ContextID, nSegments, Segments);
for (i=0; i < nSegments; i++) {
if (Segments[i].SampledPoints) _cmsFree(self ->ContextID, Segments[i].SampledPoints);
}
_cmsFree(self ->ContextID, Segments);
return Curve;
Error:
if (Segments) _cmsFree(self ->ContextID, Segments);
return NULL;
}
static
cmsBool ReadMPECurve(struct _cms_typehandler_struct* self,
cmsIOHANDLER* io,
void* Cargo,
cmsUInt32Number n,
cmsUInt32Number SizeOfTag)
{
cmsToneCurve** GammaTables = ( cmsToneCurve**) Cargo;
GammaTables[n] = ReadSegmentedCurve(self, io);
return (GammaTables[n] != NULL);
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
void *Type_MPEcurve_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsStage* mpe = NULL;
cmsUInt16Number InputChans, OutputChans;
cmsUInt32Number i, BaseOffset;
cmsToneCurve** GammaTables;
*nItems = 0;
BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
if (!_cmsReadUInt16Number(io, &InputChans)) return NULL;
if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL;
if (InputChans != OutputChans) return NULL;
GammaTables = (cmsToneCurve**) _cmsCalloc(self ->ContextID, InputChans, sizeof(cmsToneCurve*));
if (GammaTables == NULL) return NULL;
if (ReadPositionTable(self, io, InputChans, BaseOffset, GammaTables, ReadMPECurve)) {
mpe = cmsStageAllocToneCurves(self ->ContextID, InputChans, GammaTables);
}
else {
mpe = NULL;
}
for (i=0; i < InputChans; i++) {
if (GammaTables[i]) cmsFreeToneCurve(GammaTables[i]);
}
_cmsFree(self ->ContextID, GammaTables);
*nItems = (mpe != NULL) ? 1 : 0;
return mpe;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool WriteSegmentedCurve(cmsIOHANDLER* io, cmsToneCurve* g)
{
cmsUInt32Number i, j;
cmsCurveSegment* Segments = g ->Segments;
cmsUInt32Number nSegments = g ->nSegments;
if (!_cmsWriteUInt32Number(io, cmsSigSegmentedCurve)) goto Error;
if (!_cmsWriteUInt32Number(io, 0)) goto Error;
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) nSegments)) goto Error;
if (!_cmsWriteUInt16Number(io, 0)) goto Error;
for (i=0; i < nSegments - 1; i++) {
if (!_cmsWriteFloat32Number(io, Segments[i].x1)) goto Error;
}
for (i=0; i < g ->nSegments; i++) {
cmsCurveSegment* ActualSeg = Segments + i;
if (ActualSeg -> Type == 0) {
if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) cmsSigSampledCurveSeg)) goto Error;
if (!_cmsWriteUInt32Number(io, 0)) goto Error;
if (!_cmsWriteUInt32Number(io, ActualSeg -> nGridPoints)) goto Error;
for (j=0; j < g ->Segments[i].nGridPoints; j++) {
if (!_cmsWriteFloat32Number(io, ActualSeg -> SampledPoints[j])) goto Error;
}
}
else {
int Type;
cmsUInt32Number ParamsByType[] = { 4, 5, 5 };
if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) cmsSigFormulaCurveSeg)) goto Error;
if (!_cmsWriteUInt32Number(io, 0)) goto Error;
Type = ActualSeg ->Type - 6;
if (Type > 2 || Type < 0) goto Error;
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) Type)) goto Error;
if (!_cmsWriteUInt16Number(io, 0)) goto Error;
for (j=0; j < ParamsByType[Type]; j++) {
if (!_cmsWriteFloat32Number(io, (cmsFloat32Number) ActualSeg ->Params[j])) goto Error;
}
}
}
return TRUE;
Error:
return FALSE;
}
static
cmsBool WriteMPECurve(struct _cms_typehandler_struct* self,
cmsIOHANDLER* io,
void* Cargo,
cmsUInt32Number n,
cmsUInt32Number SizeOfTag)
{
_cmsStageToneCurvesData* Curves = (_cmsStageToneCurvesData*) Cargo;
return WriteSegmentedCurve(io, Curves ->TheCurves[n]);
cmsUNUSED_PARAMETER(SizeOfTag);
cmsUNUSED_PARAMETER(self);
}
static
cmsBool Type_MPEcurve_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsUInt32Number BaseOffset;
cmsStage* mpe = (cmsStage*) Ptr;
_cmsStageToneCurvesData* Curves = (_cmsStageToneCurvesData*) mpe ->Data;
BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE;
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE;
if (!WritePositionTable(self, io, 0,
mpe ->InputChannels, BaseOffset, Curves, WriteMPECurve)) return FALSE;
return TRUE;
cmsUNUSED_PARAMETER(nItems);
}
static
void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsStage* mpe;
cmsUInt16Number InputChans, OutputChans;
cmsUInt32Number nElems, i;
cmsFloat64Number* Matrix;
cmsFloat64Number* Offsets;
if (!_cmsReadUInt16Number(io, &InputChans)) return NULL;
if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL;
nElems = InputChans * OutputChans;
Matrix = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, nElems, sizeof(cmsFloat64Number));
if (Matrix == NULL) return NULL;
Offsets = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, OutputChans, sizeof(cmsFloat64Number));
if (Offsets == NULL) {
_cmsFree(self ->ContextID, Matrix);
return NULL;
}
for (i=0; i < nElems; i++) {
cmsFloat32Number v;
if (!_cmsReadFloat32Number(io, &v)) return NULL;
Matrix[i] = v;
}
for (i=0; i < OutputChans; i++) {
cmsFloat32Number v;
if (!_cmsReadFloat32Number(io, &v)) return NULL;
Offsets[i] = v;
}
mpe = cmsStageAllocMatrix(self ->ContextID, OutputChans, InputChans, Matrix, Offsets);
_cmsFree(self ->ContextID, Matrix);
_cmsFree(self ->ContextID, Offsets);
*nItems = 1;
return mpe;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_MPEmatrix_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsUInt32Number i, nElems;
cmsStage* mpe = (cmsStage*) Ptr;
_cmsStageMatrixData* Matrix = (_cmsStageMatrixData*) mpe ->Data;
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE;
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->OutputChannels)) return FALSE;
nElems = mpe ->InputChannels * mpe ->OutputChannels;
for (i=0; i < nElems; i++) {
if (!_cmsWriteFloat32Number(io, (cmsFloat32Number) Matrix->Double[i])) return FALSE;
}
for (i=0; i < mpe ->OutputChannels; i++) {
if (Matrix ->Offset == NULL) {
if (!_cmsWriteFloat32Number(io, 0)) return FALSE;
}
else {
if (!_cmsWriteFloat32Number(io, (cmsFloat32Number) Matrix->Offset[i])) return FALSE;
}
}
return TRUE;
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static
void *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsStage* mpe = NULL;
cmsUInt16Number InputChans, OutputChans;
cmsUInt8Number Dimensions8[16];
cmsUInt32Number i, nMaxGrids, GridPoints[MAX_INPUT_DIMENSIONS];
_cmsStageCLutData* clut;
if (!_cmsReadUInt16Number(io, &InputChans)) return NULL;
if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL;
if (InputChans == 0) goto Error;
if (OutputChans == 0) goto Error;
if (io ->Read(io, Dimensions8, sizeof(cmsUInt8Number), 16) != 16)
goto Error;
nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? MAX_INPUT_DIMENSIONS : InputChans;
for (i=0; i < nMaxGrids; i++) GridPoints[i] = (cmsUInt32Number) Dimensions8[i];
mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL);
if (mpe == NULL) goto Error;
clut = (_cmsStageCLutData*) mpe ->Data;
for (i=0; i < clut ->nEntries; i++) {
if (!_cmsReadFloat32Number(io, &clut ->Tab.TFloat[i])) goto Error;
}
*nItems = 1;
return mpe;
Error:
*nItems = 0;
if (mpe != NULL) cmsStageFree(mpe);
return NULL;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_MPEclut_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsUInt8Number Dimensions8[16];
cmsUInt32Number i;
cmsStage* mpe = (cmsStage*) Ptr;
_cmsStageCLutData* clut = (_cmsStageCLutData*) mpe ->Data;
if (mpe -> InputChannels > 15) return FALSE;
if (clut ->HasFloatValues == FALSE) return FALSE;
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->InputChannels)) return FALSE;
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) mpe ->OutputChannels)) return FALSE;
memset(Dimensions8, 0, sizeof(Dimensions8));
for (i=0; i < mpe ->InputChannels; i++)
Dimensions8[i] = (cmsUInt8Number) clut ->Params ->nSamples[i];
if (!io ->Write(io, 16, Dimensions8)) return FALSE;
for (i=0; i < clut ->nEntries; i++) {
if (!_cmsWriteFloat32Number(io, clut ->Tab.TFloat[i])) return FALSE;
}
return TRUE;
cmsUNUSED_PARAMETER(nItems);
cmsUNUSED_PARAMETER(self);
}
static _cmsTagTypeLinkedList SupportedMPEtypes[] = {
{{ (cmsTagTypeSignature) cmsSigBAcsElemType, NULL, NULL, NULL, NULL, NULL, 0 }, &SupportedMPEtypes[1] },
{{ (cmsTagTypeSignature) cmsSigEAcsElemType, NULL, NULL, NULL, NULL, NULL, 0 }, &SupportedMPEtypes[2] },
{TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigCurveSetElemType, MPEcurve), &SupportedMPEtypes[3] },
{TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigMatrixElemType, MPEmatrix), &SupportedMPEtypes[4] },
{TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigCLutElemType, MPEclut), NULL },
};
_cmsTagTypePluginChunkType _cmsMPETypePluginChunk = { NULL };
static
cmsBool ReadMPEElem(struct _cms_typehandler_struct* self,
cmsIOHANDLER* io,
void* Cargo,
cmsUInt32Number n,
cmsUInt32Number SizeOfTag)
{
cmsStageSignature ElementSig;
cmsTagTypeHandler* TypeHandler;
cmsUInt32Number nItems;
cmsPipeline *NewLUT = (cmsPipeline *) Cargo;
_cmsTagTypePluginChunkType* MPETypePluginChunk = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(self->ContextID, MPEPlugin);
if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return FALSE;
if (!_cmsReadUInt32Number(io, NULL)) return FALSE;
TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, MPETypePluginChunk ->TagTypes, SupportedMPEtypes);
if (TypeHandler == NULL) {
char String[5];
_cmsTagSignature2String(String, (cmsTagSignature) ElementSig);
cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown MPE type '%s' found.", String);
return FALSE;
}
if (TypeHandler ->ReadPtr != NULL) {
if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, (cmsStage*) TypeHandler ->ReadPtr(self, io, &nItems, SizeOfTag)))
return FALSE;
}
return TRUE;
cmsUNUSED_PARAMETER(SizeOfTag);
cmsUNUSED_PARAMETER(n);
}
static
void *Type_MPE_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsUInt16Number InputChans, OutputChans;
cmsUInt32Number ElementCount;
cmsPipeline *NewLUT = NULL;
cmsUInt32Number BaseOffset;
BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
if (!_cmsReadUInt16Number(io, &InputChans)) return NULL;
if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL;
NewLUT = cmsPipelineAlloc(self ->ContextID, InputChans, OutputChans);
if (NewLUT == NULL) return NULL;
if (!_cmsReadUInt32Number(io, &ElementCount)) return NULL;
if (!ReadPositionTable(self, io, ElementCount, BaseOffset, NewLUT, ReadMPEElem)) {
if (NewLUT != NULL) cmsPipelineFree(NewLUT);
*nItems = 0;
return NULL;
}
*nItems = 1;
return NewLUT;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_MPE_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsUInt32Number i, BaseOffset, DirectoryPos, CurrentPos;
int inputChan, outputChan;
cmsUInt32Number ElemCount;
cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL, Before;
cmsStageSignature ElementSig;
cmsPipeline* Lut = (cmsPipeline*) Ptr;
cmsStage* Elem = Lut ->Elements;
cmsTagTypeHandler* TypeHandler;
_cmsTagTypePluginChunkType* MPETypePluginChunk = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(self->ContextID, MPEPlugin);
BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
inputChan = cmsPipelineInputChannels(Lut);
outputChan = cmsPipelineOutputChannels(Lut);
ElemCount = cmsPipelineStageCount(Lut);
ElementOffsets = (cmsUInt32Number *) _cmsCalloc(self ->ContextID, ElemCount, sizeof(cmsUInt32Number));
if (ElementOffsets == NULL) goto Error;
ElementSizes = (cmsUInt32Number *) _cmsCalloc(self ->ContextID, ElemCount, sizeof(cmsUInt32Number));
if (ElementSizes == NULL) goto Error;
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) inputChan)) goto Error;
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) outputChan)) goto Error;
if (!_cmsWriteUInt32Number(io, (cmsUInt16Number) ElemCount)) goto Error;
DirectoryPos = io ->Tell(io);
for (i=0; i < ElemCount; i++) {
if (!_cmsWriteUInt32Number(io, 0)) goto Error;
if (!_cmsWriteUInt32Number(io, 0)) goto Error;
}
for (i=0; i < ElemCount; i++) {
ElementOffsets[i] = io ->Tell(io) - BaseOffset;
ElementSig = Elem ->Type;
TypeHandler = GetHandler((cmsTagTypeSignature) ElementSig, MPETypePluginChunk->TagTypes, SupportedMPEtypes);
if (TypeHandler == NULL) {
char String[5];
_cmsTagSignature2String(String, (cmsTagSignature) ElementSig);
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Found unknown MPE type '%s'", String);
goto Error;
}
if (!_cmsWriteUInt32Number(io, ElementSig)) goto Error;
if (!_cmsWriteUInt32Number(io, 0)) goto Error;
Before = io ->Tell(io);
if (!TypeHandler ->WritePtr(self, io, Elem, 1)) goto Error;
if (!_cmsWriteAlignment(io)) goto Error;
ElementSizes[i] = io ->Tell(io) - Before;
Elem = Elem ->Next;
}
CurrentPos = io ->Tell(io);
if (!io ->Seek(io, DirectoryPos)) goto Error;
for (i=0; i < ElemCount; i++) {
if (!_cmsWriteUInt32Number(io, ElementOffsets[i])) goto Error;
if (!_cmsWriteUInt32Number(io, ElementSizes[i])) goto Error;
}
if (!io ->Seek(io, CurrentPos)) goto Error;
if (ElementOffsets != NULL) _cmsFree(self ->ContextID, ElementOffsets);
if (ElementSizes != NULL) _cmsFree(self ->ContextID, ElementSizes);
return TRUE;
Error:
if (ElementOffsets != NULL) _cmsFree(self ->ContextID, ElementOffsets);
if (ElementSizes != NULL) _cmsFree(self ->ContextID, ElementSizes);
return FALSE;
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_MPE_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return (void*) cmsPipelineDup((cmsPipeline*) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_MPE_Free(struct _cms_typehandler_struct* self, void *Ptr)
{
cmsPipelineFree((cmsPipeline*) Ptr);
return;
cmsUNUSED_PARAMETER(self);
}
#define cmsVideoCardGammaTableType 0
#define cmsVideoCardGammaFormulaType 1
typedef struct {
double Gamma;
double Min;
double Max;
} _cmsVCGTGAMMA;
static
void *Type_vcgt_Read(struct _cms_typehandler_struct* self,
cmsIOHANDLER* io,
cmsUInt32Number* nItems,
cmsUInt32Number SizeOfTag)
{
cmsUInt32Number TagType, n, i;
cmsToneCurve** Curves;
*nItems = 0;
if (!_cmsReadUInt32Number(io, &TagType)) return NULL;
Curves = ( cmsToneCurve**) _cmsCalloc(self ->ContextID, 3, sizeof(cmsToneCurve*));
if (Curves == NULL) return NULL;
switch (TagType) {
case cmsVideoCardGammaTableType:
{
cmsUInt16Number nChannels, nElems, nBytes;
if (!_cmsReadUInt16Number(io, &nChannels)) goto Error;
if (nChannels != 3) {
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported number of channels for VCGT '%d'", nChannels);
goto Error;
}
if (!_cmsReadUInt16Number(io, &nElems)) goto Error;
if (!_cmsReadUInt16Number(io, &nBytes)) goto Error;
if (nElems == 256 && nBytes == 1 && SizeOfTag == 1576)
nBytes = 2;
for (n=0; n < 3; n++) {
Curves[n] = cmsBuildTabulatedToneCurve16(self ->ContextID, nElems, NULL);
if (Curves[n] == NULL) goto Error;
switch (nBytes) {
case 1:
for (i=0; i < nElems; i++) {
cmsUInt8Number v;
if (!_cmsReadUInt8Number(io, &v)) goto Error;
Curves[n] ->Table16[i] = FROM_8_TO_16(v);
}
break;
case 2:
if (!_cmsReadUInt16Array(io, nElems, Curves[n]->Table16)) goto Error;
break;
default:
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported bit depth for VCGT '%d'", nBytes * 8);
goto Error;
}
}
}
break;
case cmsVideoCardGammaFormulaType:
{
_cmsVCGTGAMMA Colorant[3];
for (n=0; n < 3; n++) {
double Params[10];
if (!_cmsRead15Fixed16Number(io, &Colorant[n].Gamma)) goto Error;
if (!_cmsRead15Fixed16Number(io, &Colorant[n].Min)) goto Error;
if (!_cmsRead15Fixed16Number(io, &Colorant[n].Max)) goto Error;
Params[0] = Colorant[n].Gamma;
Params[1] = pow((Colorant[n].Max - Colorant[n].Min), (1.0 / Colorant[n].Gamma));
Params[2] = 0;
Params[3] = 0;
Params[4] = 0;
Params[5] = Colorant[n].Min;
Params[6] = 0;
Curves[n] = cmsBuildParametricToneCurve(self ->ContextID, 5, Params);
if (Curves[n] == NULL) goto Error;
}
}
break;
default:
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported tag type for VCGT '%d'", TagType);
goto Error;
}
*nItems = 1;
return (void*) Curves;
Error:
cmsFreeToneCurveTriple(Curves);
_cmsFree(self ->ContextID, Curves);
return NULL;
cmsUNUSED_PARAMETER(SizeOfTag);
}
static
cmsBool Type_vcgt_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsToneCurve** Curves = (cmsToneCurve**) Ptr;
cmsUInt32Number i, j;
if (cmsGetToneCurveParametricType(Curves[0]) == 5 &&
cmsGetToneCurveParametricType(Curves[1]) == 5 &&
cmsGetToneCurveParametricType(Curves[2]) == 5) {
if (!_cmsWriteUInt32Number(io, cmsVideoCardGammaFormulaType)) return FALSE;
for (i=0; i < 3; i++) {
_cmsVCGTGAMMA v;
v.Gamma = Curves[i] ->Segments[0].Params[0];
v.Min = Curves[i] ->Segments[0].Params[5];
v.Max = pow(Curves[i] ->Segments[0].Params[1], v.Gamma) + v.Min;
if (!_cmsWrite15Fixed16Number(io, v.Gamma)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, v.Min)) return FALSE;
if (!_cmsWrite15Fixed16Number(io, v.Max)) return FALSE;
}
}
else {
if (!_cmsWriteUInt32Number(io, cmsVideoCardGammaTableType)) return FALSE;
if (!_cmsWriteUInt16Number(io, 3)) return FALSE;
if (!_cmsWriteUInt16Number(io, 256)) return FALSE;
if (!_cmsWriteUInt16Number(io, 2)) return FALSE;
for (i=0; i < 3; i++) {
for (j=0; j < 256; j++) {
cmsFloat32Number v = cmsEvalToneCurveFloat(Curves[i], (cmsFloat32Number) (j / 255.0));
cmsUInt16Number n = _cmsQuickSaturateWord(v * 65535.0);
if (!_cmsWriteUInt16Number(io, n)) return FALSE;
}
}
}
return TRUE;
cmsUNUSED_PARAMETER(self);
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_vcgt_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
cmsToneCurve** OldCurves = (cmsToneCurve**) Ptr;
cmsToneCurve** NewCurves;
NewCurves = ( cmsToneCurve**) _cmsCalloc(self ->ContextID, 3, sizeof(cmsToneCurve*));
if (NewCurves == NULL) return NULL;
NewCurves[0] = cmsDupToneCurve(OldCurves[0]);
NewCurves[1] = cmsDupToneCurve(OldCurves[1]);
NewCurves[2] = cmsDupToneCurve(OldCurves[2]);
return (void*) NewCurves;
cmsUNUSED_PARAMETER(n);
}
static
void Type_vcgt_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsFreeToneCurveTriple((cmsToneCurve**) Ptr);
_cmsFree(self ->ContextID, Ptr);
}
typedef struct {
cmsContext ContextID;
cmsUInt32Number *Offsets;
cmsUInt32Number *Sizes;
} _cmsDICelem;
typedef struct {
_cmsDICelem Name, Value, DisplayName, DisplayValue;
} _cmsDICarray;
static
cmsBool AllocElem(cmsContext ContextID, _cmsDICelem* e, cmsUInt32Number Count)
{
e->Offsets = (cmsUInt32Number *) _cmsCalloc(ContextID, Count, sizeof(cmsUInt32Number));
if (e->Offsets == NULL) return FALSE;
e->Sizes = (cmsUInt32Number *) _cmsCalloc(ContextID, Count, sizeof(cmsUInt32Number));
if (e->Sizes == NULL) {
_cmsFree(ContextID, e -> Offsets);
return FALSE;
}
e ->ContextID = ContextID;
return TRUE;
}
static
void FreeElem(_cmsDICelem* e)
{
if (e ->Offsets != NULL) _cmsFree(e -> ContextID, e -> Offsets);
if (e ->Sizes != NULL) _cmsFree(e -> ContextID, e -> Sizes);
e->Offsets = e ->Sizes = NULL;
}
static
void FreeArray( _cmsDICarray* a)
{
if (a ->Name.Offsets != NULL) FreeElem(&a->Name);
if (a ->Value.Offsets != NULL) FreeElem(&a ->Value);
if (a ->DisplayName.Offsets != NULL) FreeElem(&a->DisplayName);
if (a ->DisplayValue.Offsets != NULL) FreeElem(&a ->DisplayValue);
}
static
cmsBool AllocArray(cmsContext ContextID, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length)
{
memset(a, 0, sizeof(_cmsDICarray));
if (!AllocElem(ContextID, &a ->Name, Count)) goto Error;
if (!AllocElem(ContextID, &a ->Value, Count)) goto Error;
if (Length > 16) {
if (!AllocElem(ContextID, &a -> DisplayName, Count)) goto Error;
}
if (Length > 24) {
if (!AllocElem(ContextID, &a ->DisplayValue, Count)) goto Error;
}
return TRUE;
Error:
FreeArray(a);
return FALSE;
}
static
cmsBool ReadOneElem(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, cmsUInt32Number BaseOffset)
{
if (!_cmsReadUInt32Number(io, &e->Offsets[i])) return FALSE;
if (!_cmsReadUInt32Number(io, &e ->Sizes[i])) return FALSE;
if (e ->Offsets[i] > 0)
e ->Offsets[i] += BaseOffset;
return TRUE;
}
static
cmsBool ReadOffsetArray(cmsIOHANDLER* io, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length, cmsUInt32Number BaseOffset)
{
cmsUInt32Number i;
for (i=0; i < Count; i++) {
if (!ReadOneElem(io, &a -> Name, i, BaseOffset)) return FALSE;
if (!ReadOneElem(io, &a -> Value, i, BaseOffset)) return FALSE;
if (Length > 16) {
if (!ReadOneElem(io, &a ->DisplayName, i, BaseOffset)) return FALSE;
}
if (Length > 24) {
if (!ReadOneElem(io, & a -> DisplayValue, i, BaseOffset)) return FALSE;
}
}
return TRUE;
}
static
cmsBool WriteOneElem(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i)
{
if (!_cmsWriteUInt32Number(io, e->Offsets[i])) return FALSE;
if (!_cmsWriteUInt32Number(io, e ->Sizes[i])) return FALSE;
return TRUE;
}
static
cmsBool WriteOffsetArray(cmsIOHANDLER* io, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length)
{
cmsUInt32Number i;
for (i=0; i < Count; i++) {
if (!WriteOneElem(io, &a -> Name, i)) return FALSE;
if (!WriteOneElem(io, &a -> Value, i)) return FALSE;
if (Length > 16) {
if (!WriteOneElem(io, &a -> DisplayName, i)) return FALSE;
}
if (Length > 24) {
if (!WriteOneElem(io, &a -> DisplayValue, i)) return FALSE;
}
}
return TRUE;
}
static
cmsBool ReadOneWChar(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, wchar_t ** wcstr)
{
cmsUInt32Number nChars;
if (e -> Offsets[i] == 0) {
*wcstr = NULL;
return TRUE;
}
if (!io -> Seek(io, e -> Offsets[i])) return FALSE;
nChars = e ->Sizes[i] / sizeof(cmsUInt16Number);
*wcstr = (wchar_t*) _cmsMallocZero(e ->ContextID, (nChars + 1) * sizeof(wchar_t));
if (*wcstr == NULL) return FALSE;
if (!_cmsReadWCharArray(io, nChars, *wcstr)) {
_cmsFree(e ->ContextID, *wcstr);
return FALSE;
}
(*wcstr)[nChars] = 0;
return TRUE;
}
static
cmsUInt32Number mywcslen(const wchar_t *s)
{
const wchar_t *p;
p = s;
while (*p)
p++;
return (cmsUInt32Number)(p - s);
}
static
cmsBool WriteOneWChar(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, const wchar_t * wcstr, cmsUInt32Number BaseOffset)
{
cmsUInt32Number Before = io ->Tell(io);
cmsUInt32Number n;
e ->Offsets[i] = Before - BaseOffset;
if (wcstr == NULL) {
e ->Sizes[i] = 0;
e ->Offsets[i] = 0;
return TRUE;
}
n = mywcslen(wcstr);
if (!_cmsWriteWCharArray(io, n, wcstr)) return FALSE;
e ->Sizes[i] = io ->Tell(io) - Before;
return TRUE;
}
static
cmsBool ReadOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, cmsMLU** mlu)
{
cmsUInt32Number nItems = 0;
if (e -> Offsets[i] == 0 || e ->Sizes[i] == 0) {
*mlu = NULL;
return TRUE;
}
if (!io -> Seek(io, e -> Offsets[i])) return FALSE;
*mlu = (cmsMLU*) Type_MLU_Read(self, io, &nItems, e ->Sizes[i]);
return *mlu != NULL;
}
static
cmsBool WriteOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, const cmsMLU* mlu, cmsUInt32Number BaseOffset)
{
cmsUInt32Number Before;
if (mlu == NULL) {
e ->Sizes[i] = 0;
e ->Offsets[i] = 0;
return TRUE;
}
Before = io ->Tell(io);
e ->Offsets[i] = Before - BaseOffset;
if (!Type_MLU_Write(self, io, (void*) mlu, 1)) return FALSE;
e ->Sizes[i] = io ->Tell(io) - Before;
return TRUE;
}
static
void *Type_Dictionary_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
cmsHANDLE hDict;
cmsUInt32Number i, Count, Length;
cmsUInt32Number BaseOffset;
_cmsDICarray a;
wchar_t *NameWCS = NULL, *ValueWCS = NULL;
cmsMLU *DisplayNameMLU = NULL, *DisplayValueMLU=NULL;
cmsBool rc;
*nItems = 0;
BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
if (!_cmsReadUInt32Number(io, &Length)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
if (Length != 16 && Length != 24 && Length != 32) {
cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown record length in dictionary '%d'", Length);
return NULL;
}
hDict = cmsDictAlloc(self -> ContextID);
if (hDict == NULL) return NULL;
if (!AllocArray(self -> ContextID, &a, Count, Length)) goto Error;
if (!ReadOffsetArray(io, &a, Count, Length, BaseOffset)) goto Error;
for (i=0; i < Count; i++) {
if (!ReadOneWChar(io, &a.Name, i, &NameWCS)) goto Error;
if (!ReadOneWChar(io, &a.Value, i, &ValueWCS)) goto Error;
if (Length > 16) {
if (!ReadOneMLUC(self, io, &a.DisplayName, i, &DisplayNameMLU)) goto Error;
}
if (Length > 24) {
if (!ReadOneMLUC(self, io, &a.DisplayValue, i, &DisplayValueMLU)) goto Error;
}
if (NameWCS == NULL || ValueWCS == NULL) {
cmsSignalError(self->ContextID, cmsERROR_CORRUPTION_DETECTED, "Bad dictionary Name/Value");
rc = FALSE;
}
else {
rc = cmsDictAddEntry(hDict, NameWCS, ValueWCS, DisplayNameMLU, DisplayValueMLU);
}
if (NameWCS != NULL) _cmsFree(self ->ContextID, NameWCS);
if (ValueWCS != NULL) _cmsFree(self ->ContextID, ValueWCS);
if (DisplayNameMLU != NULL) cmsMLUfree(DisplayNameMLU);
if (DisplayValueMLU != NULL) cmsMLUfree(DisplayValueMLU);
if (!rc) goto Error;
}
FreeArray(&a);
*nItems = 1;
return (void*) hDict;
Error:
FreeArray(&a);
cmsDictFree(hDict);
return NULL;
}
static
cmsBool Type_Dictionary_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsHANDLE hDict = (cmsHANDLE) Ptr;
const cmsDICTentry* p;
cmsBool AnyName, AnyValue;
cmsUInt32Number i, Count, Length;
cmsUInt32Number DirectoryPos, CurrentPos, BaseOffset;
_cmsDICarray a;
if (hDict == NULL) return FALSE;
BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
Count = 0; AnyName = FALSE; AnyValue = FALSE;
for (p = cmsDictGetEntryList(hDict); p != NULL; p = cmsDictNextEntry(p)) {
if (p ->DisplayName != NULL) AnyName = TRUE;
if (p ->DisplayValue != NULL) AnyValue = TRUE;
Count++;
}
Length = 16;
if (AnyName) Length += 8;
if (AnyValue) Length += 8;
if (!_cmsWriteUInt32Number(io, Count)) return FALSE;
if (!_cmsWriteUInt32Number(io, Length)) return FALSE;
DirectoryPos = io ->Tell(io);
if (!AllocArray(self ->ContextID, &a, Count, Length)) goto Error;
if (!WriteOffsetArray(io, &a, Count, Length)) goto Error;
p = cmsDictGetEntryList(hDict);
for (i=0; i < Count; i++) {
if (!WriteOneWChar(io, &a.Name, i, p ->Name, BaseOffset)) goto Error;
if (!WriteOneWChar(io, &a.Value, i, p ->Value, BaseOffset)) goto Error;
if (p ->DisplayName != NULL) {
if (!WriteOneMLUC(self, io, &a.DisplayName, i, p ->DisplayName, BaseOffset)) goto Error;
}
if (p ->DisplayValue != NULL) {
if (!WriteOneMLUC(self, io, &a.DisplayValue, i, p ->DisplayValue, BaseOffset)) goto Error;
}
p = cmsDictNextEntry(p);
}
CurrentPos = io ->Tell(io);
if (!io ->Seek(io, DirectoryPos)) goto Error;
if (!WriteOffsetArray(io, &a, Count, Length)) goto Error;
if (!io ->Seek(io, CurrentPos)) goto Error;
FreeArray(&a);
return TRUE;
Error:
FreeArray(&a);
return FALSE;
cmsUNUSED_PARAMETER(nItems);
}
static
void* Type_Dictionary_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
{
return (void*) cmsDictDup((cmsHANDLE) Ptr);
cmsUNUSED_PARAMETER(n);
cmsUNUSED_PARAMETER(self);
}
static
void Type_Dictionary_Free(struct _cms_typehandler_struct* self, void* Ptr)
{
cmsDictFree((cmsHANDLE) Ptr);
cmsUNUSED_PARAMETER(self);
}
static _cmsTagTypeLinkedList SupportedTagTypes[] = {
{TYPE_HANDLER(cmsSigChromaticityType, Chromaticity), &SupportedTagTypes[1] },
{TYPE_HANDLER(cmsSigColorantOrderType, ColorantOrderType), &SupportedTagTypes[2] },
{TYPE_HANDLER(cmsSigS15Fixed16ArrayType, S15Fixed16), &SupportedTagTypes[3] },
{TYPE_HANDLER(cmsSigU16Fixed16ArrayType, U16Fixed16), &SupportedTagTypes[4] },
{TYPE_HANDLER(cmsSigTextType, Text), &SupportedTagTypes[5] },
{TYPE_HANDLER(cmsSigTextDescriptionType, Text_Description), &SupportedTagTypes[6] },
{TYPE_HANDLER(cmsSigCurveType, Curve), &SupportedTagTypes[7] },
{TYPE_HANDLER(cmsSigParametricCurveType, ParametricCurve), &SupportedTagTypes[8] },
{TYPE_HANDLER(cmsSigDateTimeType, DateTime), &SupportedTagTypes[9] },
{TYPE_HANDLER(cmsSigLut8Type, LUT8), &SupportedTagTypes[10] },
{TYPE_HANDLER(cmsSigLut16Type, LUT16), &SupportedTagTypes[11] },
{TYPE_HANDLER(cmsSigColorantTableType, ColorantTable), &SupportedTagTypes[12] },
{TYPE_HANDLER(cmsSigNamedColor2Type, NamedColor), &SupportedTagTypes[13] },
{TYPE_HANDLER(cmsSigMultiLocalizedUnicodeType, MLU), &SupportedTagTypes[14] },
{TYPE_HANDLER(cmsSigProfileSequenceDescType, ProfileSequenceDesc), &SupportedTagTypes[15] },
{TYPE_HANDLER(cmsSigSignatureType, Signature), &SupportedTagTypes[16] },
{TYPE_HANDLER(cmsSigMeasurementType, Measurement), &SupportedTagTypes[17] },
{TYPE_HANDLER(cmsSigDataType, Data), &SupportedTagTypes[18] },
{TYPE_HANDLER(cmsSigLutAtoBType, LUTA2B), &SupportedTagTypes[19] },
{TYPE_HANDLER(cmsSigLutBtoAType, LUTB2A), &SupportedTagTypes[20] },
{TYPE_HANDLER(cmsSigUcrBgType, UcrBg), &SupportedTagTypes[21] },
{TYPE_HANDLER(cmsSigCrdInfoType, CrdInfo), &SupportedTagTypes[22] },
{TYPE_HANDLER(cmsSigMultiProcessElementType, MPE), &SupportedTagTypes[23] },
{TYPE_HANDLER(cmsSigScreeningType, Screening), &SupportedTagTypes[24] },
{TYPE_HANDLER(cmsSigViewingConditionsType, ViewingConditions), &SupportedTagTypes[25] },
{TYPE_HANDLER(cmsSigXYZType, XYZ), &SupportedTagTypes[26] },
{TYPE_HANDLER(cmsCorbisBrokenXYZtype, XYZ), &SupportedTagTypes[27] },
{TYPE_HANDLER(cmsMonacoBrokenCurveType, Curve), &SupportedTagTypes[28] },
{TYPE_HANDLER(cmsSigProfileSequenceIdType, ProfileSequenceId), &SupportedTagTypes[29] },
{TYPE_HANDLER(cmsSigDictType, Dictionary), &SupportedTagTypes[30] },
{TYPE_HANDLER(cmsSigVcgtType, vcgt), NULL }
};
_cmsTagTypePluginChunkType _cmsTagTypePluginChunk = { NULL };
static
void DupTagTypeList(struct _cmsContext_struct* ctx,
const struct _cmsContext_struct* src,
int loc)
{
_cmsTagTypePluginChunkType newHead = { NULL };
_cmsTagTypeLinkedList* entry;
_cmsTagTypeLinkedList* Anterior = NULL;
_cmsTagTypePluginChunkType* head = (_cmsTagTypePluginChunkType*) src->chunks[loc];
for (entry = head->TagTypes;
entry != NULL;
entry = entry ->Next) {
_cmsTagTypeLinkedList *newEntry = ( _cmsTagTypeLinkedList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTagTypeLinkedList));
if (newEntry == NULL)
return;
newEntry -> Next = NULL;
if (Anterior)
Anterior -> Next = newEntry;
Anterior = newEntry;
if (newHead.TagTypes == NULL)
newHead.TagTypes = newEntry;
}
ctx ->chunks[loc] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTagTypePluginChunkType));
}
void _cmsAllocTagTypePluginChunk(struct _cmsContext_struct* ctx,
const struct _cmsContext_struct* src)
{
if (src != NULL) {
DupTagTypeList(ctx, src, TagTypePlugin);
}
else {
static _cmsTagTypePluginChunkType TagTypePluginChunk = { NULL };
ctx ->chunks[TagTypePlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagTypePluginChunk, sizeof(_cmsTagTypePluginChunkType));
}
}
void _cmsAllocMPETypePluginChunk(struct _cmsContext_struct* ctx,
const struct _cmsContext_struct* src)
{
if (src != NULL) {
DupTagTypeList(ctx, src, MPEPlugin);
}
else {
static _cmsTagTypePluginChunkType TagTypePluginChunk = { NULL };
ctx ->chunks[MPEPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagTypePluginChunk, sizeof(_cmsTagTypePluginChunkType));
}
}
cmsBool _cmsRegisterTagTypePlugin(cmsContext id, cmsPluginBase* Data)
{
return RegisterTypesPlugin(id, Data, TagTypePlugin);
}
cmsBool _cmsRegisterMultiProcessElementPlugin(cmsContext id, cmsPluginBase* Data)
{
return RegisterTypesPlugin(id, Data,MPEPlugin);
}
cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig)
{
_cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(ContextID, TagTypePlugin);
return GetHandler(sig, ctx->TagTypes, SupportedTagTypes);
}
typedef struct _cmsTagLinkedList_st {
cmsTagSignature Signature;
cmsTagDescriptor Descriptor;
struct _cmsTagLinkedList_st* Next;
} _cmsTagLinkedList;
static _cmsTagLinkedList SupportedTags[] = {
{ cmsSigAToB0Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutAtoBType, cmsSigLut8Type}, DecideLUTtypeA2B}, &SupportedTags[1]},
{ cmsSigAToB1Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutAtoBType, cmsSigLut8Type}, DecideLUTtypeA2B}, &SupportedTags[2]},
{ cmsSigAToB2Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutAtoBType, cmsSigLut8Type}, DecideLUTtypeA2B}, &SupportedTags[3]},
{ cmsSigBToA0Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type}, DecideLUTtypeB2A}, &SupportedTags[4]},
{ cmsSigBToA1Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type}, DecideLUTtypeB2A}, &SupportedTags[5]},
{ cmsSigBToA2Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type}, DecideLUTtypeB2A}, &SupportedTags[6]},
{ cmsSigRedColorantTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, DecideXYZtype}, &SupportedTags[7]},
{ cmsSigGreenColorantTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, DecideXYZtype}, &SupportedTags[8]},
{ cmsSigBlueColorantTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, DecideXYZtype}, &SupportedTags[9]},
{ cmsSigRedTRCTag, { 1, 3, { cmsSigCurveType, cmsSigParametricCurveType, cmsMonacoBrokenCurveType }, DecideCurveType}, &SupportedTags[10]},
{ cmsSigGreenTRCTag, { 1, 3, { cmsSigCurveType, cmsSigParametricCurveType, cmsMonacoBrokenCurveType }, DecideCurveType}, &SupportedTags[11]},
{ cmsSigBlueTRCTag, { 1, 3, { cmsSigCurveType, cmsSigParametricCurveType, cmsMonacoBrokenCurveType }, DecideCurveType}, &SupportedTags[12]},
{ cmsSigCalibrationDateTimeTag, { 1, 1, { cmsSigDateTimeType }, NULL}, &SupportedTags[13]},
{ cmsSigCharTargetTag, { 1, 1, { cmsSigTextType }, NULL}, &SupportedTags[14]},
{ cmsSigChromaticAdaptationTag, { 9, 1, { cmsSigS15Fixed16ArrayType }, NULL}, &SupportedTags[15]},
{ cmsSigChromaticityTag, { 1, 1, { cmsSigChromaticityType }, NULL}, &SupportedTags[16]},
{ cmsSigColorantOrderTag, { 1, 1, { cmsSigColorantOrderType }, NULL}, &SupportedTags[17]},
{ cmsSigColorantTableTag, { 1, 1, { cmsSigColorantTableType }, NULL}, &SupportedTags[18]},
{ cmsSigColorantTableOutTag, { 1, 1, { cmsSigColorantTableType }, NULL}, &SupportedTags[19]},
{ cmsSigCopyrightTag, { 1, 3, { cmsSigTextType, cmsSigMultiLocalizedUnicodeType, cmsSigTextDescriptionType}, DecideTextType}, &SupportedTags[20]},
{ cmsSigDateTimeTag, { 1, 1, { cmsSigDateTimeType }, NULL}, &SupportedTags[21]},
{ cmsSigDeviceMfgDescTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[22]},
{ cmsSigDeviceModelDescTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[23]},
{ cmsSigGamutTag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[24]},
{ cmsSigGrayTRCTag, { 1, 2, { cmsSigCurveType, cmsSigParametricCurveType }, DecideCurveType}, &SupportedTags[25]},
{ cmsSigLuminanceTag, { 1, 1, { cmsSigXYZType }, NULL}, &SupportedTags[26]},
{ cmsSigMediaBlackPointTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, NULL}, &SupportedTags[27]},
{ cmsSigMediaWhitePointTag, { 1, 2, { cmsSigXYZType, cmsCorbisBrokenXYZtype }, NULL}, &SupportedTags[28]},
{ cmsSigNamedColor2Tag, { 1, 1, { cmsSigNamedColor2Type }, NULL}, &SupportedTags[29]},
{ cmsSigPreview0Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[30]},
{ cmsSigPreview1Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[31]},
{ cmsSigPreview2Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[32]},
{ cmsSigProfileDescriptionTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[33]},
{ cmsSigProfileSequenceDescTag, { 1, 1, { cmsSigProfileSequenceDescType }, NULL}, &SupportedTags[34]},
{ cmsSigTechnologyTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[35]},
{ cmsSigColorimetricIntentImageStateTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[36]},
{ cmsSigPerceptualRenderingIntentGamutTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[37]},
{ cmsSigSaturationRenderingIntentGamutTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[38]},
{ cmsSigMeasurementTag, { 1, 1, { cmsSigMeasurementType }, NULL}, &SupportedTags[39]},
{ cmsSigPs2CRD0Tag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[40]},
{ cmsSigPs2CRD1Tag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[41]},
{ cmsSigPs2CRD2Tag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[42]},
{ cmsSigPs2CRD3Tag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[43]},
{ cmsSigPs2CSATag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[44]},
{ cmsSigPs2RenderingIntentTag, { 1, 1, { cmsSigDataType }, NULL}, &SupportedTags[45]},
{ cmsSigViewingCondDescTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[46]},
{ cmsSigUcrBgTag, { 1, 1, { cmsSigUcrBgType}, NULL}, &SupportedTags[47]},
{ cmsSigCrdInfoTag, { 1, 1, { cmsSigCrdInfoType}, NULL}, &SupportedTags[48]},
{ cmsSigDToB0Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[49]},
{ cmsSigDToB1Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[50]},
{ cmsSigDToB2Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[51]},
{ cmsSigDToB3Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[52]},
{ cmsSigBToD0Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[53]},
{ cmsSigBToD1Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[54]},
{ cmsSigBToD2Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[55]},
{ cmsSigBToD3Tag, { 1, 1, { cmsSigMultiProcessElementType}, NULL}, &SupportedTags[56]},
{ cmsSigScreeningDescTag, { 1, 1, { cmsSigTextDescriptionType }, NULL}, &SupportedTags[57]},
{ cmsSigViewingConditionsTag, { 1, 1, { cmsSigViewingConditionsType }, NULL}, &SupportedTags[58]},
{ cmsSigScreeningTag, { 1, 1, { cmsSigScreeningType}, NULL }, &SupportedTags[59]},
{ cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]},
{ cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]},
{ cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]},
{ cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, NULL}
};
_cmsTagPluginChunkType _cmsTagPluginChunk = { NULL };
static
void DupTagList(struct _cmsContext_struct* ctx,
const struct _cmsContext_struct* src)
{
_cmsTagPluginChunkType newHead = { NULL };
_cmsTagLinkedList* entry;
_cmsTagLinkedList* Anterior = NULL;
_cmsTagPluginChunkType* head = (_cmsTagPluginChunkType*) src->chunks[TagPlugin];
for (entry = head->Tag;
entry != NULL;
entry = entry ->Next) {
_cmsTagLinkedList *newEntry = ( _cmsTagLinkedList *) _cmsSubAllocDup(ctx ->MemPool, entry, sizeof(_cmsTagLinkedList));
if (newEntry == NULL)
return;
newEntry -> Next = NULL;
if (Anterior)
Anterior -> Next = newEntry;
Anterior = newEntry;
if (newHead.Tag == NULL)
newHead.Tag = newEntry;
}
ctx ->chunks[TagPlugin] = _cmsSubAllocDup(ctx->MemPool, &newHead, sizeof(_cmsTagPluginChunkType));
}
void _cmsAllocTagPluginChunk(struct _cmsContext_struct* ctx,
const struct _cmsContext_struct* src)
{
if (src != NULL) {
DupTagList(ctx, src);
}
else {
static _cmsTagPluginChunkType TagPluginChunk = { NULL };
ctx ->chunks[TagPlugin] = _cmsSubAllocDup(ctx ->MemPool, &TagPluginChunk, sizeof(_cmsTagPluginChunkType));
}
}
cmsBool _cmsRegisterTagPlugin(cmsContext id, cmsPluginBase* Data)
{
cmsPluginTag* Plugin = (cmsPluginTag*) Data;
_cmsTagLinkedList *pt;
_cmsTagPluginChunkType* TagPluginChunk = ( _cmsTagPluginChunkType*) _cmsContextGetClientChunk(id, TagPlugin);
if (Data == NULL) {
TagPluginChunk->Tag = NULL;
return TRUE;
}
pt = (_cmsTagLinkedList*) _cmsPluginMalloc(id, sizeof(_cmsTagLinkedList));
if (pt == NULL) return FALSE;
pt ->Signature = Plugin ->Signature;
pt ->Descriptor = Plugin ->Descriptor;
pt ->Next = TagPluginChunk ->Tag;
TagPluginChunk ->Tag = pt;
return TRUE;
}
cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig)
{
_cmsTagLinkedList* pt;
_cmsTagPluginChunkType* TagPluginChunk = ( _cmsTagPluginChunkType*) _cmsContextGetClientChunk(ContextID, TagPlugin);
for (pt = TagPluginChunk->Tag;
pt != NULL;
pt = pt ->Next) {
if (sig == pt -> Signature) return &pt ->Descriptor;
}
for (pt = SupportedTags;
pt != NULL;
pt = pt ->Next) {
if (sig == pt -> Signature) return &pt ->Descriptor;
}
return NULL;
}