X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=thirdparty%2Fliblcms2%2Fsrc%2Fcmsnamed.c;h=acfd1c8cf93a1a8b4ca6bd20cda455b76a72a7c1;hb=2fc9d4956a5d2ca90d6c89106c373fbd711aaf5e;hp=d1a86b6efd7a748da1e7d3db3f6979882c222249;hpb=28c6f547987e8cbe5ccaef622da4cf6667068989;p=openjpeg.git diff --git a/thirdparty/liblcms2/src/cmsnamed.c b/thirdparty/liblcms2/src/cmsnamed.c index d1a86b6e..acfd1c8c 100644 --- a/thirdparty/liblcms2/src/cmsnamed.c +++ b/thirdparty/liblcms2/src/cmsnamed.c @@ -1,24 +1,24 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2010 Marti Maria Saguer +// Copyright (c) 1998-2012 Marti Maria Saguer // -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the Software +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software // is furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in +// The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO -// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // //--------------------------------------------------------------------------------- @@ -32,81 +32,81 @@ // 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; } -// Grows a mempool table for a MLU. Each time this function is called, mempool size is multiplied times two. +// Grows a mempool table for a MLU. Each time this function is called, mempool size is multiplied times two. 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; } -// Grows a ntry table for a MLU. Each time this function is called, table size is multiplied times two. +// Grows a entry table for a MLU. Each time this function is called, table size is multiplied times two. static 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; - + mlu ->Entries = NewPtr; mlu ->AllocatedEntries = AllocatedEntries; @@ -114,37 +114,37 @@ cmsBool GrowMLUtable(cmsMLU* mlu) } -// Search for a specific entry in the structure. Language and Country are used. +// Search for a specific entry in the structure. Language and Country are used. static int SearchMLUEntry(cmsMLU* mlu, cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode) { int i; - - // Sanity check - if (mlu == NULL) return -1; - // Iterate whole table + // Sanity check + if (mlu == NULL) return -1; + + // Iterate whole table for (i=0; i < mlu ->UsedEntries; i++) { - if (mlu ->Entries[i].Country == CountryCode && + if (mlu ->Entries[i].Country == CountryCode && mlu ->Entries[i].Language == LanguageCode) return i; } - // Not found + // Not found return -1; } -// Add a block of characters to the intended MLU. Language and country are specified. +// Add a block of characters to the intended MLU. Language and country are specified. // Only one entry for Language/country pair is allowed. static -cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block, +cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block, cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode) { 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,20 +155,20 @@ 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; - // Set the entry + Ptr = (cmsUInt8Number*) mlu ->MemPool; + if (Ptr == NULL) return FALSE; + + // Set the entry memmove(Ptr + Offset, Block, size); mlu ->PoolUsed += size; - + mlu ->Entries[mlu ->UsedEntries].StrW = Offset; mlu ->Entries[mlu ->UsedEntries].Len = size; mlu ->Entries[mlu ->UsedEntries].Country = CountryCode; @@ -179,7 +179,7 @@ cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block, } -// Add an ASCII entry. +// Add an ASCII entry. cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString) { cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString)+1; @@ -195,21 +195,21 @@ cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const for (i=0; i < len; i++) WStr[i] = (wchar_t) ASCIIString[i]; - + rc = AddMLUBlock(mlu, len * sizeof(wchar_t), WStr, Lang, Cntry); _cmsFree(mlu ->ContextID, WStr); return rc; - + } // We don't need any wcs support library -static +static cmsUInt32Number mywcslen(const wchar_t *s) { const wchar_t *p; - p = s; + p = s; while (*p) p++; @@ -223,9 +223,9 @@ cmsBool CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) Language); cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) Country); 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,73 +234,73 @@ 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); + } } -// The algorithm first searches for an exact match of country and language, if not found it uses +// The algorithm first searches for an exact match of country and language, if not found it uses // 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) +const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu, + 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,12 +316,12 @@ 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; - return (wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v -> StrW); // Found exact match + return (wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v -> StrW); // Found exact match } } } @@ -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) +cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu, + 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 @@ -373,7 +373,7 @@ cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu, ASCIIlen = BufferSize - 1; // Precess each character - for (i=0; i < ASCIIlen; i++) { + for (i=0; i < ASCIIlen; i++) { if (Wide[i] == 0) Buffer[i] = 0; @@ -381,28 +381,28 @@ 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) +// 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 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); if (Wide == NULL) return 0; - + // Maybe we want only to know the len? if (Buffer == NULL) return StrLen + sizeof(wchar_t); @@ -414,35 +414,64 @@ 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); } // 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]) +CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu, + const char LanguageCode[3], const char CountryCode[3], + char ObtainedLanguage[3], char ObtainedCountry[3]) { - const wchar_t *Wide; - - cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode); + const wchar_t *Wide; + + cmsUInt16Number Lang = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode); cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode); - cmsUInt16Number ObtLang, ObtCode; + cmsUInt16Number ObtLang, ObtCode; - // Sanitize + // Sanitize if (mlu == NULL) return FALSE; Wide = _cmsMLUgetWide(mlu, NULL, Lang, Cntry, &ObtLang, &ObtCode); - if (Wide == NULL) return FALSE; - - // Get used language and code + if (Wide == NULL) return FALSE; + + // Get used language and code *(cmsUInt16Number *)ObtainedLanguage = _cmsAdjustEndianess16(ObtLang); - *(cmsUInt16Number *)ObtainedCountry = _cmsAdjustEndianess16(ObtCode); + *(cmsUInt16Number *)ObtainedCountry = _cmsAdjustEndianess16(ObtCode); + + ObtainedLanguage[2] = ObtainedCountry[2] = 0; + return TRUE; +} + + + +// Get the number of translations in the MLU object +cmsUInt32Number CMSEXPORT cmsMLUtranslationsCount(const cmsMLU* mlu) +{ + if (mlu == NULL) return 0; + return mlu->UsedEntries; +} + +// Get the language and country codes for a specific MLU index +cmsBool CMSEXPORT cmsMLUtranslationsCodes(const cmsMLU* mlu, + cmsUInt32Number idx, + char LanguageCode[3], + char CountryCode[3]) +{ + _cmsMLUentry *entry; + + if (mlu == NULL) return FALSE; + + if (idx >= (cmsUInt32Number) mlu->UsedEntries) return FALSE; + + entry = &mlu->Entries[idx]; + + *(cmsUInt16Number *)LanguageCode = _cmsAdjustEndianess16(entry->Language); + *(cmsUInt16Number *)CountryCode = _cmsAdjustEndianess16(entry->Country); - ObtainedLanguage[2] = ObtainedCountry[2] = 0; - return TRUE; + return TRUE; } @@ -451,7 +480,7 @@ CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu, // Grow the list to keep at least NumElements static cmsBool GrowNamedColorList(cmsNAMEDCOLORLIST* v) -{ +{ cmsUInt32Number size; _cmsNAMEDCOLOR * NewPtr; @@ -466,9 +495,9 @@ cmsBool GrowNamedColorList(cmsNAMEDCOLORLIST* v) if (size > 1024*100) return FALSE; NewPtr = (_cmsNAMEDCOLOR*) _cmsRealloc(v ->ContextID, v ->List, size * sizeof(_cmsNAMEDCOLOR)); - if (NewPtr == NULL) + if (NewPtr == NULL) return FALSE; - + v ->List = NewPtr; v ->Allocated = size; return TRUE; @@ -478,9 +507,9 @@ cmsBool GrowNamedColorList(cmsNAMEDCOLORLIST* v) cmsNAMEDCOLORLIST* CMSEXPORT cmsAllocNamedColorList(cmsContext ContextID, cmsUInt32Number n, cmsUInt32Number ColorantCount, const char* Prefix, const char* Suffix) { cmsNAMEDCOLORLIST* v = (cmsNAMEDCOLORLIST*) _cmsMallocZero(ContextID, sizeof(cmsNAMEDCOLORLIST)); - + if (v == NULL) return NULL; - + v ->List = NULL; v ->nColors = 0; v ->ContextID = ContextID; @@ -488,8 +517,10 @@ cmsNAMEDCOLORLIST* CMSEXPORT cmsAllocNamedColorList(cmsContext ContextID, cmsUIn while (v -> Allocated < n) GrowNamedColorList(v); - strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix)); - strncpy(v ->Suffix, Suffix, sizeof(v ->Suffix)); + strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix)-1); + strncpy(v ->Suffix, Suffix, sizeof(v ->Suffix)-1); + v->Prefix[32] = v->Suffix[32] = 0; + v -> ColorantCount = ColorantCount; return v; @@ -497,15 +528,16 @@ cmsNAMEDCOLORLIST* CMSEXPORT cmsAllocNamedColorList(cmsContext ContextID, cmsUIn // Free a list void CMSEXPORT cmsFreeNamedColorList(cmsNAMEDCOLORLIST* v) -{ +{ + if (v == NULL) return; if (v ->List) _cmsFree(v ->ContextID, v ->List); - if (v) _cmsFree(v ->ContextID, v); -} + _cmsFree(v ->ContextID, v); +} cmsNAMEDCOLORLIST* CMSEXPORT cmsDupNamedColorList(const cmsNAMEDCOLORLIST* v) { cmsNAMEDCOLORLIST* NewNC; - + if (v == NULL) return NULL; NewNC= cmsAllocNamedColorList(v ->ContextID, v -> nColors, v ->ColorantCount, v ->Prefix, v ->Suffix); @@ -525,10 +557,10 @@ cmsNAMEDCOLORLIST* CMSEXPORT cmsDupNamedColorList(const cmsNAMEDCOLORLIST* v) // Append a color to a list. List pointer may change if reallocated -cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* NamedColorList, - const char* Name, +cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* NamedColorList, + const char* Name, cmsUInt16Number PCS[3], cmsUInt16Number Colorant[cmsMAXCHANNELS]) -{ +{ cmsUInt32Number i; if (NamedColorList == NULL) return FALSE; @@ -543,9 +575,12 @@ cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* NamedColorList, for (i=0; i < 3; i++) NamedColorList ->List[NamedColorList ->nColors].PCS[i] = PCS == NULL ? 0 : PCS[i]; - if (Name != NULL) - strncpy(NamedColorList ->List[NamedColorList ->nColors].Name, Name, - sizeof(NamedColorList ->List[NamedColorList ->nColors].Name)); + if (Name != NULL) { + + strncpy(NamedColorList ->List[NamedColorList ->nColors].Name, Name, cmsMAX_PATH-1); + NamedColorList ->List[NamedColorList ->nColors].Name[cmsMAX_PATH-1] = 0; + + } else NamedColorList ->List[NamedColorList ->nColors].Name[0] = 0; @@ -554,21 +589,21 @@ cmsBool CMSEXPORT cmsAppendNamedColor(cmsNAMEDCOLORLIST* NamedColorList, return TRUE; } -// Returns number of elements +// Returns number of elements cmsUInt32Number CMSEXPORT cmsNamedColorCount(const cmsNAMEDCOLORLIST* NamedColorList) -{ +{ if (NamedColorList == NULL) return 0; return NamedColorList ->nColors; } // Info aboout a given color -cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cmsUInt32Number nColor, - char* Name, - char* Prefix, +cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cmsUInt32Number nColor, + char* Name, + char* Prefix, char* Suffix, - cmsUInt16Number* PCS, + cmsUInt16Number* PCS, cmsUInt16Number* Colorant) -{ +{ if (NamedColorList == NULL) return FALSE; if (nColor >= cmsNamedColorCount(NamedColorList)) return FALSE; @@ -576,11 +611,11 @@ cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cm if (Name) strcpy(Name, NamedColorList->List[nColor].Name); if (Prefix) strcpy(Prefix, NamedColorList->Prefix); if (Suffix) strcpy(Suffix, NamedColorList->Suffix); - if (PCS) + if (PCS) memmove(PCS, NamedColorList ->List[nColor].PCS, 3*sizeof(cmsUInt16Number)); - if (Colorant) - memmove(Colorant, NamedColorList ->List[nColor].DeviceColorant, + if (Colorant) + memmove(Colorant, NamedColorList ->List[nColor].DeviceColorant, sizeof(cmsUInt16Number) * NamedColorList ->ColorantCount); @@ -589,7 +624,7 @@ cmsBool CMSEXPORT cmsNamedColorInfo(const cmsNAMEDCOLORLIST* NamedColorList, cm // Search for a given color name (no prefix or suffix) cmsInt32Number CMSEXPORT cmsNamedColorIndex(const cmsNAMEDCOLORLIST* NamedColorList, const char* Name) -{ +{ int i, n; if (NamedColorList == NULL) return -1; @@ -618,6 +653,24 @@ void* DupNamedColorList(cmsStage* mpe) return cmsDupNamedColorList(List); } +static +void EvalNamedColorPCS(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe) +{ + cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) mpe ->Data; + cmsUInt16Number index = (cmsUInt16Number) _cmsQuickSaturateWord(In[0] * 65535.0); + + if (index >= NamedColorList-> nColors) { + cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range; ignored", index); + } + else { + + // Named color always uses Lab + Out[0] = (cmsFloat32Number) (NamedColorList->List[index].PCS[0] / 65535.0); + Out[1] = (cmsFloat32Number) (NamedColorList->List[index].PCS[1] / 65535.0); + Out[2] = (cmsFloat32Number) (NamedColorList->List[index].PCS[2] / 65535.0); + } +} + static void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe) { @@ -629,23 +682,23 @@ void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const c cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range; ignored", index); } else { - for (j=0; j < NamedColorList ->ColorantCount; j++) - Out[j] = (cmsFloat32Number) (NamedColorList->List[index].DeviceColorant[j] / 65535.0); + for (j=0; j < NamedColorList ->ColorantCount; j++) + Out[j] = (cmsFloat32Number) (NamedColorList->List[index].DeviceColorant[j] / 65535.0); } } // Named color lookup element -cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList) +cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS) { - return _cmsStageAllocPlaceholder(NamedColorList ->ContextID, - cmsSigNamedColorElemType, - 1, 3, - EvalNamedColor, - DupNamedColorList, - FreeNamedColorList, - cmsDupNamedColorList(NamedColorList)); - + return _cmsStageAllocPlaceholder(NamedColorList ->ContextID, + cmsSigNamedColorElemType, + 1, UsePCS ? 3 : NamedColorList ->ColorantCount, + UsePCS ? EvalNamedColorPCS : EvalNamedColor, + DupNamedColorList, + FreeNamedColorList, + cmsDupNamedColorList(NamedColorList)); + } @@ -674,19 +727,23 @@ cmsSEQ* CMSEXPORT cmsAllocProfileSequenceDescription(cmsContext ContextID, cmsUI if (n > 255) return NULL; Seq = (cmsSEQ*) _cmsMallocZero(ContextID, sizeof(cmsSEQ)); - if (Seq == NULL) return NULL; - + if (Seq == NULL) return NULL; + Seq -> ContextID = ContextID; Seq -> seq = (cmsPSEQDESC*) _cmsCalloc(ContextID, n, sizeof(cmsPSEQDESC)); Seq -> n = n; - + if (Seq -> seq == NULL) { + _cmsFree(ContextID, Seq); + return NULL; + } + for (i=0; i < n; i++) { Seq -> seq[i].Manufacturer = NULL; Seq -> seq[i].Model = NULL; Seq -> seq[i].Description = NULL; } - + return Seq; } @@ -715,10 +772,10 @@ cmsSEQ* CMSEXPORT cmsDupProfileSequenceDescription(const cmsSEQ* pseq) NewSeq = (cmsSEQ*) _cmsMalloc(pseq -> ContextID, sizeof(cmsSEQ)); if (NewSeq == NULL) return NULL; - + NewSeq -> seq = (cmsPSEQDESC*) _cmsCalloc(pseq ->ContextID, pseq ->n, sizeof(cmsPSEQDESC)); if (NewSeq ->seq == NULL) goto Error; - + NewSeq -> ContextID = pseq ->ContextID; NewSeq -> n = pseq ->n; @@ -734,7 +791,7 @@ cmsSEQ* CMSEXPORT cmsDupProfileSequenceDescription(const cmsSEQ* pseq) NewSeq ->seq[i].Manufacturer = cmsMLUdup(pseq ->seq[i].Manufacturer); NewSeq ->seq[i].Model = cmsMLUdup(pseq ->seq[i].Model); NewSeq ->seq[i].Description = cmsMLUdup(pseq ->seq[i].Description); - + } return NewSeq; @@ -745,6 +802,128 @@ 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) +{ + if (ptr == NULL) return 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); + + 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; + cmsDICTentry *entry; + + _cmsAssert(old_dict != NULL); + + hNew = cmsDictAlloc(old_dict ->ContextID); + if (hNew == NULL) return NULL; + // 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; +}