diff options
author | Marti Maria <info@littlecms.com> | 2011-05-23 14:25:35 +0200 |
---|---|---|
committer | Marti Maria <info@littlecms.com> | 2011-05-23 14:25:35 +0200 |
commit | b972648a0e5ad083a2b7c345b24b3bb08480cbef (patch) | |
tree | 8aa513277b89e5ee88b28520e026749d99a56898 | |
parent | dd1c51f91dabf54cb38708530c2ab1510f4ef428 (diff) | |
download | lcms2-b972648a0e5ad083a2b7c345b24b3bb08480cbef.tar.gz |
Dicctionary tag implementation. 2.2 version bump
-rw-r--r-- | Projects/BorlandC_5.5/lcms2.rc | 6 | ||||
-rw-r--r-- | Projects/VC2008/lcms2.rc | 10 | ||||
-rw-r--r-- | Projects/VC2010/lcms2.rc | 10 | ||||
-rw-r--r-- | Projects/VC2010/resource.h | 2 | ||||
-rw-r--r-- | include/lcms2.h | 32 | ||||
-rw-r--r-- | src/cmsio1.c | 3 | ||||
-rw-r--r-- | src/cmsnamed.c | 369 | ||||
-rw-r--r-- | src/cmstypes.c | 379 | ||||
-rw-r--r-- | testbed/testcms2.c | 139 |
9 files changed, 792 insertions, 158 deletions
diff --git a/Projects/BorlandC_5.5/lcms2.rc b/Projects/BorlandC_5.5/lcms2.rc index 960d4ee..4ce60b7 100644 --- a/Projects/BorlandC_5.5/lcms2.rc +++ b/Projects/BorlandC_5.5/lcms2.rc @@ -1,8 +1,8 @@ 1 VERSIONINFO -FILEVERSION 2, 1, 0, 0 -PRODUCTVERSION 2, 1, 0, 0 +FILEVERSION 2, 2, 0, 0 +PRODUCTVERSION 2, 2, 0, 0 FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_DLL { @@ -14,7 +14,7 @@ FILETYPE VFT_DLL VALUE "FileDescription", "lcms color engine\000" VALUE "FileVersion", "2.01\000\000" VALUE "InternalName", "lcms\000" - VALUE "LegalCopyright", "Copyright © Marti Maria 2010\000\000" + VALUE "LegalCopyright", "Copyright © Marti Maria 2011\000\000" VALUE "OriginalFilename", "lcms.dll\000" } diff --git a/Projects/VC2008/lcms2.rc b/Projects/VC2008/lcms2.rc index fa98520..3593fed 100644 --- a/Projects/VC2008/lcms2.rc +++ b/Projects/VC2008/lcms2.rc @@ -30,8 +30,8 @@ LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_MODERN // 1 VERSIONINFO - FILEVERSION 2,1,0,0 - PRODUCTVERSION 2,1,0,0 + FILEVERSION 2,2,0,0 + PRODUCTVERSION 2,2,0,0 FILEFLAGSMASK 0x0L #ifdef _DEBUG FILEFLAGS 0x1L @@ -49,14 +49,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Marti Maria\0" VALUE "FileDescription", "lcms color engine\0" - VALUE "FileVersion", "2.0\0" + VALUE "FileVersion", "2.2\0" VALUE "InternalName", "lcms\0" - VALUE "LegalCopyright", "Copyright © Marti Maria 2010\0" + VALUE "LegalCopyright", "Copyright © Marti Maria 2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "lcms2.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "LittleCMS color engine\0" - VALUE "ProductVersion", "2, 0, 0, 0\0" + VALUE "ProductVersion", "2, 0, 2, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/Projects/VC2010/lcms2.rc b/Projects/VC2010/lcms2.rc index fa98520..3593fed 100644 --- a/Projects/VC2010/lcms2.rc +++ b/Projects/VC2010/lcms2.rc @@ -30,8 +30,8 @@ LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_MODERN // 1 VERSIONINFO - FILEVERSION 2,1,0,0 - PRODUCTVERSION 2,1,0,0 + FILEVERSION 2,2,0,0 + PRODUCTVERSION 2,2,0,0 FILEFLAGSMASK 0x0L #ifdef _DEBUG FILEFLAGS 0x1L @@ -49,14 +49,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Marti Maria\0" VALUE "FileDescription", "lcms color engine\0" - VALUE "FileVersion", "2.0\0" + VALUE "FileVersion", "2.2\0" VALUE "InternalName", "lcms\0" - VALUE "LegalCopyright", "Copyright © Marti Maria 2010\0" + VALUE "LegalCopyright", "Copyright © Marti Maria 2011\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "lcms2.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "LittleCMS color engine\0" - VALUE "ProductVersion", "2, 0, 0, 0\0" + VALUE "ProductVersion", "2, 0, 2, 0\0" VALUE "SpecialBuild", "\0" END END diff --git a/Projects/VC2010/resource.h b/Projects/VC2010/resource.h index a989cba..7655978 100644 --- a/Projects/VC2010/resource.h +++ b/Projects/VC2010/resource.h @@ -1,5 +1,5 @@ //{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. +// Microsoft Visual C++ generated include file. // Used by lcms2.rc // diff --git a/include/lcms2.h b/include/lcms2.h index acdc6b5..d5a77ae 100644 --- a/include/lcms2.h +++ b/include/lcms2.h @@ -248,6 +248,7 @@ typedef enum { cmsSigCrdInfoType = 0x63726469, // 'crdi' cmsSigCurveType = 0x63757276, // 'curv' cmsSigDataType = 0x64617461, // 'data' + cmsSigDictType = 0x64696374, // 'dict' cmsSigDateTimeType = 0x6474696D, // 'dtim' cmsSigDeviceSettingsType = 0x64657673, // 'devs' cmsSigLut16Type = 0x6d667432, // 'mft2' @@ -273,10 +274,11 @@ typedef enum { cmsSigUInt16ArrayType = 0x75693136, // 'ui16' cmsSigUInt32ArrayType = 0x75693332, // 'ui32' cmsSigUInt64ArrayType = 0x75693634, // 'ui64' - cmsSigUInt8ArrayType = 0x75693038, // 'ui08' + cmsSigUInt8ArrayType = 0x75693038, // 'ui08' + cmsSigVcgtType = 0x76636774, // 'vcgt' cmsSigViewingConditionsType = 0x76696577, // 'view' - cmsSigXYZType = 0x58595A20, // 'XYZ ' - cmsSigVcgtType = 0x76636774 // 'vcgt' + cmsSigXYZType = 0x58595A20 // 'XYZ ' + } cmsTagTypeSignature; @@ -349,7 +351,8 @@ typedef enum { cmsSigUcrBgTag = 0x62666420, // 'bfd ' cmsSigViewingCondDescTag = 0x76756564, // 'vued' cmsSigViewingConditionsTag = 0x76696577, // 'view' - cmsSigVcgtTag = 0x76636774 // 'vcgt' + cmsSigVcgtTag = 0x76636774, // 'vcgt' + cmsSigMetaTag = 0x6D657461 // 'meta' } cmsTagSignature; @@ -1299,6 +1302,27 @@ CMSAPI cmsSEQ* CMSEXPORT cmsAllocProfileSequenceDescription(cmsContext CMSAPI cmsSEQ* CMSEXPORT cmsDupProfileSequenceDescription(const cmsSEQ* pseq); CMSAPI void CMSEXPORT cmsFreeProfileSequenceDescription(cmsSEQ* pseq); +// Dictionaries -------------------------------------------------------------------------------------------------------- + +typedef struct _cmsDICTentry_struct { + + struct _cmsDICTentry_struct* Next; + + cmsMLU *DisplayName; + cmsMLU *DisplayValue; + wchar_t* Name; + wchar_t* Value; + +} cmsDICTentry; + +CMSAPI cmsHANDLE CMSEXPORT cmsDictAlloc(cmsContext ContextID); +CMSAPI void CMSEXPORT cmsDictFree(cmsHANDLE hDict); +CMSAPI cmsHANDLE CMSEXPORT cmsDictDup(cmsHANDLE hDict); + +CMSAPI cmsBool CMSEXPORT cmsDictAddEntry(cmsHANDLE hDict, const wchar_t* Name, const wchar_t* Value, const cmsMLU *DisplayName, const cmsMLU *DisplayValue); +CMSAPI const cmsDICTentry* CMSEXPORT cmsDictGetEntryList(cmsHANDLE hDict); +CMSAPI const cmsDICTentry* CMSEXPORT cmsDictNextEntry(const cmsDICTentry* e); + // Access to Profile data ---------------------------------------------------------------------------------------------- CMSAPI cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext ContextID); diff --git a/src/cmsio1.c b/src/cmsio1.c index f746d81..9c7d245 100644 --- a/src/cmsio1.c +++ b/src/cmsio1.c @@ -512,8 +512,7 @@ cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent) // On named color, take the appropiate tag if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) { - - cmsPipeline* Lut; + cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) cmsReadTag(hProfile, cmsSigNamedColor2Tag); if (nc == NULL) return NULL; diff --git a/src/cmsnamed.c b/src/cmsnamed.c index f4f423d..a36abf8 100644 --- a/src/cmsnamed.c +++ b/src/cmsnamed.c @@ -32,29 +32,29 @@ // Allocates an empty multi localizad unicode object cmsMLU* CMSEXPORT cmsMLUalloc(cmsContext ContextID, cmsUInt32Number nItems) { - cmsMLU* mlu; + cmsMLU* mlu; - // nItems should be positive if given - if (nItems <= 0) nItems = 2; + // nItems should be positive if given + if (nItems <= 0) nItems = 2; - // Create the container - mlu = (cmsMLU*) _cmsMallocZero(ContextID, sizeof(cmsMLU)); - if (mlu == NULL) return NULL; + // Create the container + mlu = (cmsMLU*) _cmsMallocZero(ContextID, sizeof(cmsMLU)); + if (mlu == NULL) return NULL; - mlu ->ContextID = ContextID; + mlu ->ContextID = ContextID; - // Create entry array - mlu ->Entries = (_cmsMLUentry*) _cmsCalloc(ContextID, nItems, sizeof(_cmsMLUentry)); - if (mlu ->Entries == NULL) { - _cmsFree(ContextID, mlu); - return NULL; - } + // Create entry array + mlu ->Entries = (_cmsMLUentry*) _cmsCalloc(ContextID, nItems, sizeof(_cmsMLUentry)); + if (mlu ->Entries == NULL) { + _cmsFree(ContextID, mlu); + return NULL; + } - // Ok, keep indexes up to date - mlu ->AllocatedEntries = nItems; - mlu ->UsedEntries = 0; + // Ok, keep indexes up to date + mlu ->AllocatedEntries = nItems; + mlu ->UsedEntries = 0; - return mlu; + return mlu; } @@ -62,29 +62,29 @@ cmsMLU* CMSEXPORT cmsMLUalloc(cmsContext ContextID, cmsUInt32Number nItems) static cmsBool GrowMLUpool(cmsMLU* mlu) { - cmsUInt32Number size; - void *NewPtr; + cmsUInt32Number size; + void *NewPtr; - // Sanity check - if (mlu == NULL) return FALSE; + // Sanity check + if (mlu == NULL) return FALSE; - if (mlu ->PoolSize == 0) - size = 256; - else - size = mlu ->PoolSize * 2; + if (mlu ->PoolSize == 0) + size = 256; + else + size = mlu ->PoolSize * 2; - // Check for overflow - if (size < mlu ->PoolSize) return FALSE; + // Check for overflow + if (size < mlu ->PoolSize) return FALSE; - // Reallocate the pool - NewPtr = _cmsRealloc(mlu ->ContextID, mlu ->MemPool, size); - if (NewPtr == NULL) return FALSE; + // Reallocate the pool + NewPtr = _cmsRealloc(mlu ->ContextID, mlu ->MemPool, size); + if (NewPtr == NULL) return FALSE; - mlu ->MemPool = NewPtr; - mlu ->PoolSize = size; + mlu ->MemPool = NewPtr; + mlu ->PoolSize = size; - return TRUE; + return TRUE; } @@ -94,16 +94,16 @@ cmsBool GrowMLUtable(cmsMLU* mlu) { int AllocatedEntries; _cmsMLUentry *NewPtr; - - // Sanity check - if (mlu == NULL) return FALSE; + + // Sanity check + if (mlu == NULL) return FALSE; AllocatedEntries = mlu ->AllocatedEntries * 2; - // Check for overflow - if (AllocatedEntries / 2 != mlu ->AllocatedEntries) return FALSE; + // Check for overflow + if (AllocatedEntries / 2 != mlu ->AllocatedEntries) return FALSE; - // Reallocate the memory + // Reallocate the memory NewPtr = (_cmsMLUentry*)_cmsRealloc(mlu ->ContextID, mlu ->Entries, AllocatedEntries*sizeof(_cmsMLUentry)); if (NewPtr == NULL) return FALSE; @@ -119,18 +119,18 @@ static int SearchMLUEntry(cmsMLU* mlu, cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode) { int i; - - // Sanity check - if (mlu == NULL) return -1; + + // Sanity check + if (mlu == NULL) return -1; - // Iterate whole table + // Iterate whole table for (i=0; i < mlu ->UsedEntries; i++) { if (mlu ->Entries[i].Country == CountryCode && mlu ->Entries[i].Language == LanguageCode) return i; } - // Not found + // Not found return -1; } @@ -143,8 +143,8 @@ cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block, cmsUInt32Number Offset; cmsUInt8Number* Ptr; - // Sanity check - if (mlu == NULL) return FALSE; + // Sanity check + if (mlu == NULL) return FALSE; // Is there any room available? if (mlu ->UsedEntries >= mlu ->AllocatedEntries) { @@ -155,17 +155,17 @@ cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block, if (SearchMLUEntry(mlu, LanguageCode, CountryCode) >= 0) return FALSE; // Only one is allowed! // Check for size - while ((mlu ->PoolSize - mlu ->PoolUsed) < size) { + while ((mlu ->PoolSize - mlu ->PoolUsed) < size) { if (!GrowMLUpool(mlu)) return FALSE; - } + } Offset = mlu ->PoolUsed; - Ptr = (cmsUInt8Number*) mlu ->MemPool; - if (Ptr == NULL) return FALSE; + Ptr = (cmsUInt8Number*) mlu ->MemPool; + if (Ptr == NULL) return FALSE; - // Set the entry + // Set the entry memmove(Ptr + Offset, Block, size); mlu ->PoolUsed += size; @@ -209,7 +209,7 @@ cmsUInt32Number mywcslen(const wchar_t *s) { const wchar_t *p; - p = s; + p = s; while (*p) p++; @@ -225,7 +225,7 @@ cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char cmsUInt32Number len; if (mlu == NULL) return FALSE; - if (WideString == NULL) return FALSE; + if (WideString == NULL) return FALSE; len = (cmsUInt32Number) (mywcslen(WideString) + 1) * sizeof(wchar_t); return AddMLUBlock(mlu, len, WideString, Lang, Cntry); @@ -234,59 +234,59 @@ cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char // Duplicating a MLU is as easy as copying all members cmsMLU* CMSEXPORT cmsMLUdup(const cmsMLU* mlu) { - cmsMLU* NewMlu = NULL; + cmsMLU* NewMlu = NULL; - // Duplicating a NULL obtains a NULL - if (mlu == NULL) return NULL; + // Duplicating a NULL obtains a NULL + if (mlu == NULL) return NULL; - NewMlu = cmsMLUalloc(mlu ->ContextID, mlu ->UsedEntries); - if (NewMlu == NULL) return NULL; + NewMlu = cmsMLUalloc(mlu ->ContextID, mlu ->UsedEntries); + if (NewMlu == NULL) return NULL; - // Should never happen - if (NewMlu ->AllocatedEntries < mlu ->UsedEntries) - goto Error; + // Should never happen + if (NewMlu ->AllocatedEntries < mlu ->UsedEntries) + goto Error; - // Sanitize... - if (NewMlu ->Entries == NULL || mlu ->Entries == NULL) goto Error; + // Sanitize... + if (NewMlu ->Entries == NULL || mlu ->Entries == NULL) goto Error; - memmove(NewMlu ->Entries, mlu ->Entries, mlu ->UsedEntries * sizeof(_cmsMLUentry)); - NewMlu ->UsedEntries = mlu ->UsedEntries; + memmove(NewMlu ->Entries, mlu ->Entries, mlu ->UsedEntries * sizeof(_cmsMLUentry)); + NewMlu ->UsedEntries = mlu ->UsedEntries; - // The MLU may be empty - if (mlu ->PoolUsed == 0) { - NewMlu ->MemPool = NULL; - } - else { - // It is not empty - NewMlu ->MemPool = _cmsMalloc(mlu ->ContextID, mlu ->PoolUsed); - if (NewMlu ->MemPool == NULL) goto Error; - } + // The MLU may be empty + if (mlu ->PoolUsed == 0) { + NewMlu ->MemPool = NULL; + } + else { + // It is not empty + NewMlu ->MemPool = _cmsMalloc(mlu ->ContextID, mlu ->PoolUsed); + if (NewMlu ->MemPool == NULL) goto Error; + } - NewMlu ->PoolSize = mlu ->PoolUsed; + NewMlu ->PoolSize = mlu ->PoolUsed; - if (NewMlu ->MemPool == NULL || mlu ->MemPool == NULL) goto Error; + if (NewMlu ->MemPool == NULL || mlu ->MemPool == NULL) goto Error; - memmove(NewMlu ->MemPool, mlu->MemPool, mlu ->PoolUsed); - NewMlu ->PoolUsed = mlu ->PoolUsed; + memmove(NewMlu ->MemPool, mlu->MemPool, mlu ->PoolUsed); + NewMlu ->PoolUsed = mlu ->PoolUsed; - return NewMlu; + return NewMlu; Error: - if (NewMlu != NULL) cmsMLUfree(NewMlu); - return NULL; + if (NewMlu != NULL) cmsMLUfree(NewMlu); + return NULL; } // Free any used memory void CMSEXPORT cmsMLUfree(cmsMLU* mlu) { - if (mlu) { + if (mlu) { - if (mlu -> Entries) _cmsFree(mlu ->ContextID, mlu->Entries); - if (mlu -> MemPool) _cmsFree(mlu ->ContextID, mlu->MemPool); + if (mlu -> Entries) _cmsFree(mlu ->ContextID, mlu->Entries); + if (mlu -> MemPool) _cmsFree(mlu ->ContextID, mlu->MemPool); - _cmsFree(mlu ->ContextID, mlu); - } + _cmsFree(mlu ->ContextID, mlu); + } } @@ -294,13 +294,13 @@ void CMSEXPORT cmsMLUfree(cmsMLU* mlu) // the Language. If none is found, first entry is used instead. static const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu, - cmsUInt32Number *len, - cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode, - cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode) + cmsUInt32Number *len, + cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode, + cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode) { int i; int Best = -1; - _cmsMLUentry* v; + _cmsMLUentry* v; if (mlu == NULL) return NULL; @@ -316,8 +316,8 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu, if (v -> Country == CountryCode) { - if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language; - if (UsedCountryCode != NULL) *UsedCountryCode = v ->Country; + if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language; + if (UsedCountryCode != NULL) *UsedCountryCode = v ->Country; if (len != NULL) *len = v ->Len; @@ -330,30 +330,30 @@ const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu, if (Best == -1) Best = 0; - v = mlu ->Entries + Best; + v = mlu ->Entries + Best; - if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language; - if (UsedCountryCode != NULL) *UsedCountryCode = v ->Country; + if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language; + if (UsedCountryCode != NULL) *UsedCountryCode = v ->Country; if (len != NULL) *len = v ->Len; - return(wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v ->StrW); + return(wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v ->StrW); } // Obtain an ASCII representation of the wide string. Setting buffer to NULL returns the len cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu, - const char LanguageCode[3], const char CountryCode[3], - char* Buffer, cmsUInt32Number BufferSize) + const char LanguageCode[3], const char CountryCode[3], + char* Buffer, cmsUInt32Number BufferSize) { const wchar_t *Wide; cmsUInt32Number StrLen = 0; cmsUInt32Number ASCIIlen, i; - cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode); + cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode); cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode); - // Sanitize + // Sanitize if (mlu == NULL) return 0; // Get WideChar @@ -381,23 +381,23 @@ cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu, Buffer[i] = (char) Wide[i]; } - // We put a termination "\0" + // We put a termination "\0" Buffer[ASCIIlen] = 0; return ASCIIlen + 1; } // Obtain a wide representation of the MLU, on depending on current locale settings cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu, - const char LanguageCode[3], const char CountryCode[3], - wchar_t* Buffer, cmsUInt32Number BufferSize) + const char LanguageCode[3], const char CountryCode[3], + wchar_t* Buffer, cmsUInt32Number BufferSize) { const wchar_t *Wide; cmsUInt32Number StrLen = 0; - cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode); + cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode); cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode); - // Sanitize + // Sanitize if (mlu == NULL) return 0; Wide = _cmsMLUgetWide(mlu, &StrLen, Lang, Cntry, NULL, NULL); @@ -414,7 +414,7 @@ cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu, StrLen = BufferSize - + sizeof(wchar_t); memmove(Buffer, Wide, StrLen); - Buffer[StrLen / sizeof(wchar_t)] = 0; + Buffer[StrLen / sizeof(wchar_t)] = 0; return StrLen + sizeof(wchar_t); } @@ -422,27 +422,27 @@ cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu, // Get also the language and country CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu, - const char LanguageCode[3], const char CountryCode[3], - char ObtainedLanguage[3], char ObtainedCountry[3]) + const char LanguageCode[3], const char CountryCode[3], + char ObtainedLanguage[3], char ObtainedCountry[3]) { - const wchar_t *Wide; + const wchar_t *Wide; - cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode); + cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode); cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode); cmsUInt16Number ObtLang, ObtCode; - // Sanitize + // Sanitize if (mlu == NULL) return FALSE; Wide = _cmsMLUgetWide(mlu, NULL, Lang, Cntry, &ObtLang, &ObtCode); - if (Wide == NULL) return FALSE; + if (Wide == NULL) return FALSE; - // Get used language and code + // Get used language and code *(cmsUInt16Number *)ObtainedLanguage = _cmsAdjustEndianess16(ObtLang); - *(cmsUInt16Number *)ObtainedCountry = _cmsAdjustEndianess16(ObtCode); + *(cmsUInt16Number *)ObtainedCountry = _cmsAdjustEndianess16(ObtCode); - ObtainedLanguage[2] = ObtainedCountry[2] = 0; - return TRUE; + ObtainedLanguage[2] = ObtainedCountry[2] = 0; + return TRUE; } @@ -657,12 +657,12 @@ void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const c cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS) { return _cmsStageAllocPlaceholder(NamedColorList ->ContextID, - cmsSigNamedColorElemType, + cmsSigNamedColorElemType, 1, UsePCS ? 3 : NamedColorList ->ColorantCount, - UsePCS ? EvalNamedColorPCS : EvalNamedColor, - DupNamedColorList, - FreeNamedColorList, - cmsDupNamedColorList(NamedColorList)); + UsePCS ? EvalNamedColorPCS : EvalNamedColor, + DupNamedColorList, + FreeNamedColorList, + cmsDupNamedColorList(NamedColorList)); } @@ -763,6 +763,133 @@ Error: return NULL; } +// Dictionaries -------------------------------------------------------------------------------------------------------- + +// Dictionaries are just very simple linked lists + + +typedef struct _cmsDICT_struct { + cmsDICTentry* head; + cmsContext ContextID; +} _cmsDICT; + + +// Allocate an empty dictionary +cmsHANDLE CMSEXPORT cmsDictAlloc(cmsContext ContextID) +{ + _cmsDICT* dict = (_cmsDICT*) _cmsMallocZero(ContextID, sizeof(_cmsDICT)); + if (dict == NULL) return NULL; + dict ->ContextID = ContextID; + return (cmsHANDLE) dict; +} + +// Dispose resources +void CMSEXPORT cmsDictFree(cmsHANDLE hDict) +{ + _cmsDICT* dict = (_cmsDICT*) hDict; + cmsDICTentry *entry, *next; + + _cmsAssert(dict != NULL); + + // Walk the list freeing all nodes + entry = dict ->head; + while (entry != NULL) { + + if (entry ->DisplayName != NULL) cmsMLUfree(entry ->DisplayName); + if (entry ->DisplayValue != NULL) cmsMLUfree(entry ->DisplayValue); + if (entry ->Name != NULL) _cmsFree(dict ->ContextID, entry -> Name); + if (entry ->Value != NULL) _cmsFree(dict ->ContextID, entry -> Value); + + // Don't fall in the habitual trap... + next = entry ->Next; + _cmsFree(dict ->ContextID, entry); + + entry = next; + } + _cmsFree(dict ->ContextID, dict); +} + + +// Duplicate a wide char string +static +wchar_t* DupWcs(cmsContext ContextID, const wchar_t* ptr) +{ + _cmsAssert(ptr != NULL); + + return (wchar_t*) _cmsDupMem(ContextID, ptr, (mywcslen(ptr) + 1) * sizeof(wchar_t)); +} + +// Add a new entry to the linked list +cmsBool CMSEXPORT cmsDictAddEntry(cmsHANDLE hDict, const wchar_t* Name, const wchar_t* Value, const cmsMLU *DisplayName, const cmsMLU *DisplayValue) +{ + _cmsDICT* dict = (_cmsDICT*) hDict; + cmsDICTentry *entry; + + _cmsAssert(dict != NULL); + _cmsAssert(Name != NULL); + _cmsAssert(Value != NULL); + + entry = (cmsDICTentry*) _cmsMallocZero(dict ->ContextID, sizeof(cmsDICTentry)); + if (entry == NULL) return FALSE; + + entry ->DisplayName = cmsMLUdup(DisplayName); + entry ->DisplayValue = cmsMLUdup(DisplayValue); + entry ->Name = DupWcs(dict ->ContextID, Name); + entry ->Value = DupWcs(dict ->ContextID, Value); + + entry ->Next = dict ->head; + dict ->head = entry; + + return TRUE; +} + + +// Duplicates an existing dictionary +cmsHANDLE CMSEXPORT cmsDictDup(cmsHANDLE hDict) +{ + _cmsDICT* old_dict = (_cmsDICT*) hDict; + cmsHANDLE hNew; + _cmsDICT* new_dict; + cmsDICTentry *entry; + + _cmsAssert(old_dict != NULL); + + hNew = cmsDictAlloc(old_dict ->ContextID); + if (hNew == NULL) return NULL; + + new_dict = (_cmsDICT*) hNew; + + // Walk the list freeing all nodes + entry = old_dict ->head; + while (entry != NULL) { + + if (!cmsDictAddEntry(hNew, entry ->Name, entry ->Value, entry ->DisplayName, entry ->DisplayValue)) { + + cmsDictFree(hNew); + return NULL; + } + + entry = entry -> Next; + } + + return hNew; +} + +// Get a pointer to the linked list +const cmsDICTentry* CMSEXPORT cmsDictGetEntryList(cmsHANDLE hDict) +{ + _cmsDICT* dict = (_cmsDICT*) hDict; + + if (dict == NULL) return NULL; + return dict ->head; +} + +// Helper For external languages +const cmsDICTentry* CMSEXPORT cmsDictNextEntry(const cmsDICTentry* e) +{ + if (e == NULL) return NULL; + return e ->Next; +} diff --git a/src/cmstypes.c b/src/cmstypes.c index ad5e0bc..462e85c 100644 --- a/src/cmstypes.c +++ b/src/cmstypes.c @@ -4734,46 +4734,399 @@ void Type_vcgt_Free(struct _cms_typehandler_struct* self, void* Ptr) } - - // ******************************************************************************** // Type cmsSigDictType // ******************************************************************************** +// Single column of the table can point to wchar or MLUC elements. Holds arrays of data +typedef struct { + cmsContext ContextID; + cmsUInt32Number *Offsets; + cmsUInt32Number *Sizes; +} _cmsDICelem; + +typedef struct { + _cmsDICelem Name, Value, DisplayName, DisplayValue; + +} _cmsDICarray; + +// Allocate an empty array element +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; +} + +// Free an array element +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; +} + +// Get rid of whole array +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); +} + + +// Allocate whole array +static +cmsBool AllocArray(cmsContext ContextID, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length) +{ + // Empty values + memset(a, 0, sizeof(_cmsDICarray)); + + // On depending on record size, create column arrays + 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; +} + +// Read one element +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; + + e ->Offsets[i] += BaseOffset; + return TRUE; +} + + +static +cmsBool ReadOffsetArray(cmsIOHANDLER* io, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length, cmsUInt32Number BaseOffset) +{ + cmsUInt32Number i; + + // Read column arrays + 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; +} + + +// Write one element +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 (!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; + } + + // End of string marker + (*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 = mywcslen(wcstr); + + e ->Offsets[i] = Before - BaseOffset; + + 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 (!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 = 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; + + // Get actual position as a basis for element offsets + BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase); + + // Get name-value record count + if (!_cmsReadUInt32Number(io, &Count)) return NULL; + SizeOfTag -= sizeof(cmsUInt32Number); + + // Get rec lenghth + if (!_cmsReadUInt32Number(io, &Length)) return NULL; + SizeOfTag -= sizeof(cmsUInt32Number); + + // Check for valid lengths + if (Length != 16 && Length != 24 && Length != 32) { + cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown record length in dictionary '%d'", Length); + return NULL; + } + + // Creates an empty dictionary + hDict = cmsDictAlloc(self -> ContextID); + if (hDict == NULL) return NULL; + + // On depending on record size, create column arrays + if (!AllocArray(self -> ContextID, &a, Count, Length)) goto Error; + + // Read column arrays + if (!ReadOffsetArray(io, &a, Count, Length, BaseOffset)) goto Error; + + // Seek to each element and read it + 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; + } + + 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) return FALSE; + } + + 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); + + // Let's inspect the dictionary + 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; + + // Keep starting position of offsets table + DirectoryPos = io ->Tell(io); + + // Allocate offsets array + if (!AllocArray(self ->ContextID, &a, Count, Length)) goto Error; + + // Write a fake directory to be filled latter on + if (!WriteOffsetArray(io, &a, Count, Length)) goto Error; + + // Write each element. Keep track of the size as well. + 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); + } + + // Write the directory + 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); } -/* -cmsHANDLE cmsDictAlloc(); -cmsHANDLE cmsDictFree(cmsHANDLE hDict); -cmsUInt32Number cmsDictPut(cmsHANDLE hDict, const char LanguageCode[3], const char CountryCode[3], - wchar_t* DisplayName, wchar_t* DisplayValue, const wchar_t* Name, const wchar_t* Value); -cmsUInt32Number cmsDictCount(cmsHANDLE hDict); -cmsBool cmsDictGetData(cmsHANDLE hDict, cmsUInt32Number n, wchar_t* Name, wchar_t* Value); -cmsBool cmsDictGetDisplayData(cmsHANDLE hDict, cmsUInt32Number n, const char LanguageCode[3], const char CountryCode[3], - wchar_t* DisplayName, wchar_t* DisplayValue); -*/ // ******************************************************************************** // Type support main routines diff --git a/testbed/testcms2.c b/testbed/testcms2.c index 6536c61..2d108d7 100644 --- a/testbed/testcms2.c +++ b/testbed/testcms2.c @@ -2008,6 +2008,37 @@ cmsInt32Number Check7DinterpGranular(void) return 1; } + + +static +cmsInt32Number Check8DinterpGranular(void) +{ + cmsPipeline* lut; + cmsStage* mpe; + cmsUInt32Number Dimensions[] = { 4, 3, 3, 2, 2, 2, 2, 2 }; + + lut = cmsPipelineAlloc(DbgThread(), 8, 3); + mpe = cmsStageAllocCLut16bitGranular(DbgThread(), Dimensions, 8, 3, NULL); + cmsStageSampleCLut16bit(mpe, Sampler8D, NULL, 0); + cmsPipelineInsertStage(lut, cmsAT_BEGIN, mpe); + + // Check accuracy + + if (!CheckOne8D(lut, 0, 0, 0, 0, 0, 0, 0, 0)) return 0; + if (!CheckOne8D(lut, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff)) return 0; + + if (!CheckOne8D(lut, 0x8080, 0x8080, 0x8080, 0x8080, 0x1234, 0x1122, 0x0056, 0x0011)) return 0; + if (!CheckOne8D(lut, 0x0000, 0xFE00, 0x80FF, 0x8888, 0x8078, 0x2233, 0x0088, 0x2020)) return 0; + if (!CheckOne8D(lut, 0x1111, 0x2222, 0x3333, 0x4444, 0x1455, 0x3344, 0x1987, 0x4532)) return 0; + if (!CheckOne8D(lut, 0x0000, 0x0012, 0x0013, 0x0014, 0x2333, 0x4455, 0x9988, 0x1200)) return 0; + if (!CheckOne8D(lut, 0x3141, 0x1415, 0x1592, 0x9261, 0x4567, 0x5566, 0xfe56, 0x6666)) return 0; + if (!CheckOne8D(lut, 0xFF00, 0xFF01, 0xFF12, 0xFF13, 0xF344, 0x6677, 0xbabe, 0xface)) return 0; + + cmsPipelineFree(lut); + + return 1; +} + // Colorimetric conversions ------------------------------------------------------------------------------------------------- // Lab to LCh and back should be performed at 1E-12 accuracy at least @@ -4795,6 +4826,42 @@ cmsInt32Number CheckVCGT(cmsInt32Number Pass, cmsHPROFILE hProfile) return 0; } +static +cmsInt32Number CheckDictionary16(cmsInt32Number Pass, cmsHPROFILE hProfile) +{ + cmsHANDLE hDict; + const cmsDICTentry* e; + switch (Pass) { + + case 1: + hDict = cmsDictAlloc(DbgThread()); + + cmsDictAddEntry(hDict, L"Name", L"String", NULL, NULL); + cmsDictAddEntry(hDict, L"Name2", L"12", NULL, NULL); + if (!cmsWriteTag(hProfile, cmsSigMetaTag, hDict)) return 0; + cmsDictFree(hDict); + return 1; + + + case 2: + + hDict = cmsReadTag(hProfile, cmsSigMetaTag); + if (hDict == NULL) return 0; + + e = cmsDictGetEntryList(hDict); + if (memcmp(e ->Name, L"Name2", sizeof(wchar_t) * 5) != 0) return 0; + if (memcmp(e ->Value, L"12", sizeof(wchar_t) * 2) != 0) return 0; + e = cmsDictNextEntry(e); + if (memcmp(e ->Name, L"Name", sizeof(wchar_t) * 4) != 0) return 0; + if (memcmp(e ->Value, L"String", sizeof(wchar_t) * 5) != 0) return 0; + return 1; + + default:; + } + + return 0; +} + static cmsInt32Number CheckRAWtags(cmsInt32Number Pass, cmsHPROFILE hProfile) @@ -4957,6 +5024,8 @@ cmsInt32Number CheckProfileCreation(void) SubTest("RAW tags"); if (!CheckRAWtags(Pass, h)) return 0; + SubTest("Dictionary meta tags"); + if (!CheckDictionary16(Pass, h)) return 0; if (Pass == 1) { cmsSaveProfileToFile(h, "alltags.icc"); @@ -6726,6 +6795,33 @@ cmsInt32Number CheckGBD(void) } +static +int CheckMD5(void) +{ + _cmsICCPROFILE* h; + cmsHPROFILE pProfile = cmsOpenProfileFromFile("sRGBlcms2.icc", "r"); + cmsProfileID ProfileID1, ProfileID2, ProfileID3, ProfileID4; + + h =(_cmsICCPROFILE*) pProfile; + if (cmsMD5computeID(pProfile)) cmsGetHeaderProfileID(pProfile, ProfileID1.ID8); + if (cmsMD5computeID(pProfile)) cmsGetHeaderProfileID(pProfile,ProfileID2.ID8); + + cmsCloseProfile(pProfile); + + + pProfile = cmsOpenProfileFromFile("sRGBlcms2.icc", "r"); + + h =(_cmsICCPROFILE*) pProfile; + if (cmsMD5computeID(pProfile)) cmsGetHeaderProfileID(pProfile, ProfileID3.ID8); + if (cmsMD5computeID(pProfile)) cmsGetHeaderProfileID(pProfile,ProfileID4.ID8); + + cmsCloseProfile(pProfile); + + return ((memcmp(ProfileID1.ID8, ProfileID3.ID8, sizeof(ProfileID1)) == 0) && + (memcmp(ProfileID2.ID8, ProfileID4.ID8, sizeof(ProfileID2)) == 0)); +} + + // -------------------------------------------------------------------------------------------------- // P E R F O R M A N C E C H E C K S // -------------------------------------------------------------------------------------------------- @@ -7342,6 +7438,39 @@ void CheckProfileZOO(void) #endif + + +#define TYPE_709 709 +static double Rec709Math(int Type, const double Params[], double R) +{ double Fun; + +switch (Type) +{ +case 709: + +if (R <= (Params[3]*Params[4])) Fun = R / Params[3]; +else Fun = pow(((R - Params[2])/Params[1]), Params[0]); +break; + +case -709: + +if (R <= Params[4]) Fun = R * Params[3]; +else Fun = Params[1] * pow(R, (1/Params[0])) + Params[2]; +break; +} +return Fun; +} + + +// Add nonstandard TRC curves -> Rec709 +cmsPluginParametricCurves NewCurvePlugin = { +{ cmsPluginMagicNumber, 2000, cmsPluginParametricCurveSig, NULL }, +1, {TYPE_709}, {5}, Rec709Math}; + + + + + // --------------------------------------------------------------------------------------- int main(int argc, char* argv[]) @@ -7349,6 +7478,7 @@ int main(int argc, char* argv[]) cmsInt32Number Exhaustive = 0; cmsInt32Number DoSpeedTests = 1; + #ifdef _MSC_VER _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif @@ -7430,7 +7560,7 @@ int main(int argc, char* argv[]) Check("5D interpolation with granularity", Check5DinterpGranular); Check("6D interpolation with granularity", Check6DinterpGranular); Check("7D interpolation with granularity", Check7DinterpGranular); - + Check("8D interpolation with granularity", Check8DinterpGranular); // Encoding of colorspaces Check("Lab to LCh and back (float only) ", CheckLab2LCh); @@ -7547,6 +7677,7 @@ int main(int argc, char* argv[]) Check("CGATS parser", CheckCGATS); Check("PostScript generator", CheckPostScript); Check("Segment maxima GBD", CheckGBD); + Check("MD5 digest", CheckMD5); if (DoSpeedTests) @@ -7557,9 +7688,9 @@ int main(int argc, char* argv[]) cmsUnregisterPlugins(); // Cleanup - RemoveTestProfiles(); - - return TotalFail; + RemoveTestProfiles(); + + return TotalFail; } |