< prev index next >

src/share/native/sun/java2d/cmm/lcms/cmsnamed.c

Print this page




  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 // This file is available under and governed by the GNU General Public
  26 // License version 2 only, as published by the Free Software Foundation.
  27 // However, the following notice accompanied the original version of this
  28 // file:
  29 //
  30 //---------------------------------------------------------------------------------
  31 //
  32 //  Little Color Management System
  33 //  Copyright (c) 1998-2012 Marti Maria Saguer
  34 //
  35 // Permission is hereby granted, free of charge, to any person obtaining
  36 // a copy of this software and associated documentation files (the "Software"),
  37 // to deal in the Software without restriction, including without limitation
  38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  39 // and/or sell copies of the Software, and to permit persons to whom the Software
  40 // is furnished to do so, subject to the following conditions:
  41 //
  42 // The above copyright notice and this permission notice shall be included in
  43 // all copies or substantial portions of the Software.
  44 //
  45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  52 //
  53 //---------------------------------------------------------------------------------


 104 
 105     // Check for overflow
 106     if (size < mlu ->PoolSize) return FALSE;
 107 
 108     // Reallocate the pool
 109     NewPtr = _cmsRealloc(mlu ->ContextID, mlu ->MemPool, size);
 110     if (NewPtr == NULL) return FALSE;
 111 
 112 
 113     mlu ->MemPool  = NewPtr;
 114     mlu ->PoolSize = size;
 115 
 116     return TRUE;
 117 }
 118 
 119 
 120 // Grows a entry table for a MLU. Each time this function is called, table size is multiplied times two.
 121 static
 122 cmsBool GrowMLUtable(cmsMLU* mlu)
 123 {
 124     int AllocatedEntries;
 125     _cmsMLUentry *NewPtr;
 126 
 127     // Sanity check
 128     if (mlu == NULL) return FALSE;
 129 
 130     AllocatedEntries = mlu ->AllocatedEntries * 2;
 131 
 132     // Check for overflow
 133     if (AllocatedEntries / 2 != mlu ->AllocatedEntries) return FALSE;
 134 
 135     // Reallocate the memory
 136     NewPtr = (_cmsMLUentry*)_cmsRealloc(mlu ->ContextID, mlu ->Entries, AllocatedEntries*sizeof(_cmsMLUentry));
 137     if (NewPtr == NULL) return FALSE;
 138 
 139     mlu ->Entries          = NewPtr;
 140     mlu ->AllocatedEntries = AllocatedEntries;
 141 
 142     return TRUE;
 143 }
 144 
 145 
 146 // Search for a specific entry in the structure. Language and Country are used.
 147 static
 148 int SearchMLUEntry(cmsMLU* mlu, cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode)
 149 {
 150     int i;
 151 
 152     // Sanity check
 153     if (mlu == NULL) return -1;
 154 
 155     // Iterate whole table
 156     for (i=0; i < mlu ->UsedEntries; i++) {
 157 
 158         if (mlu ->Entries[i].Country  == CountryCode &&
 159             mlu ->Entries[i].Language == LanguageCode) return i;
 160     }
 161 
 162     // Not found
 163     return -1;
 164 }
 165 
 166 // Add a block of characters to the intended MLU. Language and country are specified.
 167 // Only one entry for Language/country pair is allowed.
 168 static
 169 cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block,
 170                      cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode)


 190     }
 191 
 192     Offset = mlu ->PoolUsed;
 193 
 194     Ptr = (cmsUInt8Number*) mlu ->MemPool;
 195     if (Ptr == NULL) return FALSE;
 196 
 197     // Set the entry
 198     memmove(Ptr + Offset, Block, size);
 199     mlu ->PoolUsed += size;
 200 
 201     mlu ->Entries[mlu ->UsedEntries].StrW     = Offset;
 202     mlu ->Entries[mlu ->UsedEntries].Len      = size;
 203     mlu ->Entries[mlu ->UsedEntries].Country  = CountryCode;
 204     mlu ->Entries[mlu ->UsedEntries].Language = LanguageCode;
 205     mlu ->UsedEntries++;
 206 
 207     return TRUE;
 208 }
 209 


 210 
 211 // Add an ASCII entry.

























 212 cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString)
 213 {
 214     cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString)+1;
 215     wchar_t* WStr;
 216     cmsBool  rc;
 217     cmsUInt16Number Lang  = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
 218     cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
 219 
 220     if (mlu == NULL) return FALSE;
 221 
 222     WStr = (wchar_t*) _cmsCalloc(mlu ->ContextID, len,  sizeof(wchar_t));
 223     if (WStr == NULL) return FALSE;
 224 
 225     for (i=0; i < len; i++)
 226         WStr[i] = (wchar_t) ASCIIString[i];
 227 
 228     rc = AddMLUBlock(mlu, len  * sizeof(wchar_t), WStr, Lang, Cntry);
 229 
 230     _cmsFree(mlu ->ContextID, WStr);
 231     return rc;
 232 
 233 }
 234 
 235 // We don't need any wcs support library
 236 static
 237 cmsUInt32Number mywcslen(const wchar_t *s)
 238 {
 239     const wchar_t *p;
 240 
 241     p = s;
 242     while (*p)
 243         p++;
 244 
 245     return (cmsUInt32Number)(p - s);
 246 }
 247 
 248 
 249 // Add a wide entry
 250 cmsBool  CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char Country[3], const wchar_t* WideString)
 251 {
 252     cmsUInt16Number Lang  = _cmsAdjustEndianess16(*(cmsUInt16Number*) Language);
 253     cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) Country);
 254     cmsUInt32Number len;
 255 
 256     if (mlu == NULL) return FALSE;
 257     if (WideString == NULL) return FALSE;
 258 
 259     len = (cmsUInt32Number) (mywcslen(WideString) + 1) * sizeof(wchar_t);
 260     return AddMLUBlock(mlu, len, WideString, Lang, Cntry);
 261 }
 262 
 263 // Duplicating a MLU is as easy as copying all members
 264 cmsMLU* CMSEXPORT cmsMLUdup(const cmsMLU* mlu)
 265 {
 266     cmsMLU* NewMlu = NULL;
 267 
 268     // Duplicating a NULL obtains a NULL
 269     if (mlu == NULL) return NULL;
 270 
 271     NewMlu = cmsMLUalloc(mlu ->ContextID, mlu ->UsedEntries);
 272     if (NewMlu == NULL) return NULL;
 273 
 274     // Should never happen
 275     if (NewMlu ->AllocatedEntries < mlu ->UsedEntries)
 276         goto Error;
 277 
 278     // Sanitize...
 279     if (NewMlu ->Entries == NULL || mlu ->Entries == NULL)  goto Error;


 310 void CMSEXPORT cmsMLUfree(cmsMLU* mlu)
 311 {
 312     if (mlu) {
 313 
 314         if (mlu -> Entries) _cmsFree(mlu ->ContextID, mlu->Entries);
 315         if (mlu -> MemPool) _cmsFree(mlu ->ContextID, mlu->MemPool);
 316 
 317         _cmsFree(mlu ->ContextID, mlu);
 318     }
 319 }
 320 
 321 
 322 // The algorithm first searches for an exact match of country and language, if not found it uses
 323 // the Language. If none is found, first entry is used instead.
 324 static
 325 const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
 326                               cmsUInt32Number *len,
 327                               cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode,
 328                               cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode)
 329 {
 330     int i;
 331     int Best = -1;
 332     _cmsMLUentry* v;
 333 
 334     if (mlu == NULL) return NULL;
 335 
 336     if (mlu -> AllocatedEntries <= 0) return NULL;
 337 
 338     for (i=0; i < mlu ->UsedEntries; i++) {
 339 
 340         v = mlu ->Entries + i;
 341 
 342         if (v -> Language == LanguageCode) {
 343 
 344             if (Best == -1) Best = i;
 345 
 346             if (v -> Country == CountryCode) {
 347 
 348                 if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language;
 349                 if (UsedCountryCode  != NULL) *UsedCountryCode = v ->Country;
 350 
 351                 if (len != NULL) *len = v ->Len;


 362     v = mlu ->Entries + Best;
 363 
 364     if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language;
 365     if (UsedCountryCode  != NULL) *UsedCountryCode = v ->Country;
 366 
 367     if (len != NULL) *len   = v ->Len;
 368 
 369     return(wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v ->StrW);
 370 }
 371 
 372 
 373 // Obtain an ASCII representation of the wide string. Setting buffer to NULL returns the len
 374 cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
 375                                        const char LanguageCode[3], const char CountryCode[3],
 376                                        char* Buffer, cmsUInt32Number BufferSize)
 377 {
 378     const wchar_t *Wide;
 379     cmsUInt32Number  StrLen = 0;
 380     cmsUInt32Number ASCIIlen, i;
 381 
 382     cmsUInt16Number Lang  = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
 383     cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
 384 
 385     // Sanitize
 386     if (mlu == NULL) return 0;
 387 
 388     // Get WideChar
 389     Wide = _cmsMLUgetWide(mlu, &StrLen, Lang, Cntry, NULL, NULL);
 390     if (Wide == NULL) return 0;
 391 
 392     ASCIIlen = StrLen / sizeof(wchar_t);
 393 
 394     // Maybe we want only to know the len?
 395     if (Buffer == NULL) return ASCIIlen + 1; // Note the zero at the end
 396 
 397     // No buffer size means no data
 398     if (BufferSize <= 0) return 0;
 399 
 400     // Some clipping may be required
 401     if (BufferSize < ASCIIlen + 1)
 402         ASCIIlen = BufferSize - 1;
 403 


 406 
 407         if (Wide[i] == 0)
 408             Buffer[i] = 0;
 409         else
 410             Buffer[i] = (char) Wide[i];
 411     }
 412 
 413     // We put a termination "\0"
 414     Buffer[ASCIIlen] = 0;
 415     return ASCIIlen + 1;
 416 }
 417 
 418 // Obtain a wide representation of the MLU, on depending on current locale settings
 419 cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu,
 420                                       const char LanguageCode[3], const char CountryCode[3],
 421                                       wchar_t* Buffer, cmsUInt32Number BufferSize)
 422 {
 423     const wchar_t *Wide;
 424     cmsUInt32Number  StrLen = 0;
 425 
 426     cmsUInt16Number Lang  = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
 427     cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
 428 
 429     // Sanitize
 430     if (mlu == NULL) return 0;
 431 
 432     Wide = _cmsMLUgetWide(mlu, &StrLen, Lang, Cntry, NULL, NULL);
 433     if (Wide == NULL) return 0;
 434 
 435     // Maybe we want only to know the len?
 436     if (Buffer == NULL) return StrLen + sizeof(wchar_t);
 437 
 438   // No buffer size means no data
 439     if (BufferSize <= 0) return 0;
 440 
 441     // Some clipping may be required
 442     if (BufferSize < StrLen + sizeof(wchar_t))
 443         StrLen = BufferSize - + sizeof(wchar_t);
 444 
 445     memmove(Buffer, Wide, StrLen);
 446     Buffer[StrLen / sizeof(wchar_t)] = 0;
 447 
 448     return StrLen + sizeof(wchar_t);
 449 }
 450 
 451 
 452 // Get also the language and country
 453 CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu,
 454                                               const char LanguageCode[3], const char CountryCode[3],
 455                                               char ObtainedLanguage[3], char ObtainedCountry[3])
 456 {
 457     const wchar_t *Wide;
 458 
 459     cmsUInt16Number Lang  = _cmsAdjustEndianess16(*(cmsUInt16Number*) LanguageCode);
 460     cmsUInt16Number Cntry = _cmsAdjustEndianess16(*(cmsUInt16Number*) CountryCode);
 461     cmsUInt16Number ObtLang, ObtCode;
 462 
 463     // Sanitize
 464     if (mlu == NULL) return FALSE;
 465 
 466     Wide = _cmsMLUgetWide(mlu, NULL, Lang, Cntry, &ObtLang, &ObtCode);
 467     if (Wide == NULL) return FALSE;
 468 
 469     // Get used language and code
 470     *(cmsUInt16Number *)ObtainedLanguage = _cmsAdjustEndianess16(ObtLang);
 471     *(cmsUInt16Number *)ObtainedCountry  = _cmsAdjustEndianess16(ObtCode);
 472 
 473     ObtainedLanguage[2] = ObtainedCountry[2] = 0;
 474     return TRUE;
 475 }
 476 
 477 
 478 
 479 // Get the number of translations in the MLU object
 480 cmsUInt32Number CMSEXPORT cmsMLUtranslationsCount(const cmsMLU* mlu)
 481 {
 482     if (mlu == NULL) return 0;
 483     return mlu->UsedEntries;
 484 }
 485 
 486 // Get the language and country codes for a specific MLU index
 487 cmsBool CMSEXPORT cmsMLUtranslationsCodes(const cmsMLU* mlu,
 488                                           cmsUInt32Number idx,
 489                                           char LanguageCode[3],
 490                                           char CountryCode[3])
 491 {
 492     _cmsMLUentry *entry;
 493 
 494     if (mlu == NULL) return FALSE;
 495 
 496     if (idx >= (cmsUInt32Number) mlu->UsedEntries) return FALSE;
 497 
 498     entry = &mlu->Entries[idx];
 499 
 500     *(cmsUInt16Number *)LanguageCode = _cmsAdjustEndianess16(entry->Language);
 501     *(cmsUInt16Number *)CountryCode  = _cmsAdjustEndianess16(entry->Country);
 502 
 503     return TRUE;
 504 }
 505 
 506 
 507 // Named color lists --------------------------------------------------------------------------------------------
 508 
 509 // Grow the list to keep at least NumElements
 510 static
 511 cmsBool  GrowNamedColorList(cmsNAMEDCOLORLIST* v)
 512 {
 513     cmsUInt32Number size;
 514     _cmsNAMEDCOLOR * NewPtr;
 515 
 516     if (v == NULL) return FALSE;
 517 
 518     if (v ->Allocated == 0)
 519         size = 64;   // Initial guess
 520     else
 521         size = v ->Allocated * 2;




  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 // This file is available under and governed by the GNU General Public
  26 // License version 2 only, as published by the Free Software Foundation.
  27 // However, the following notice accompanied the original version of this
  28 // file:
  29 //
  30 //---------------------------------------------------------------------------------
  31 //
  32 //  Little Color Management System
  33 //  Copyright (c) 1998-2016 Marti Maria Saguer
  34 //
  35 // Permission is hereby granted, free of charge, to any person obtaining
  36 // a copy of this software and associated documentation files (the "Software"),
  37 // to deal in the Software without restriction, including without limitation
  38 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  39 // and/or sell copies of the Software, and to permit persons to whom the Software
  40 // is furnished to do so, subject to the following conditions:
  41 //
  42 // The above copyright notice and this permission notice shall be included in
  43 // all copies or substantial portions of the Software.
  44 //
  45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  46 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  47 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  48 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  49 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  50 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  51 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  52 //
  53 //---------------------------------------------------------------------------------


 104 
 105     // Check for overflow
 106     if (size < mlu ->PoolSize) return FALSE;
 107 
 108     // Reallocate the pool
 109     NewPtr = _cmsRealloc(mlu ->ContextID, mlu ->MemPool, size);
 110     if (NewPtr == NULL) return FALSE;
 111 
 112 
 113     mlu ->MemPool  = NewPtr;
 114     mlu ->PoolSize = size;
 115 
 116     return TRUE;
 117 }
 118 
 119 
 120 // Grows a entry table for a MLU. Each time this function is called, table size is multiplied times two.
 121 static
 122 cmsBool GrowMLUtable(cmsMLU* mlu)
 123 {
 124     cmsUInt32Number AllocatedEntries;
 125     _cmsMLUentry *NewPtr;
 126 
 127     // Sanity check
 128     if (mlu == NULL) return FALSE;
 129 
 130     AllocatedEntries = mlu ->AllocatedEntries * 2;
 131 
 132     // Check for overflow
 133     if (AllocatedEntries / 2 != mlu ->AllocatedEntries) return FALSE;
 134 
 135     // Reallocate the memory
 136     NewPtr = (_cmsMLUentry*)_cmsRealloc(mlu ->ContextID, mlu ->Entries, AllocatedEntries*sizeof(_cmsMLUentry));
 137     if (NewPtr == NULL) return FALSE;
 138 
 139     mlu ->Entries          = NewPtr;
 140     mlu ->AllocatedEntries = AllocatedEntries;
 141 
 142     return TRUE;
 143 }
 144 
 145 
 146 // Search for a specific entry in the structure. Language and Country are used.
 147 static
 148 int SearchMLUEntry(cmsMLU* mlu, cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode)
 149 {
 150     cmsUInt32Number i;
 151 
 152     // Sanity check
 153     if (mlu == NULL) return -1;
 154 
 155     // Iterate whole table
 156     for (i=0; i < mlu ->UsedEntries; i++) {
 157 
 158         if (mlu ->Entries[i].Country  == CountryCode &&
 159             mlu ->Entries[i].Language == LanguageCode) return i;
 160     }
 161 
 162     // Not found
 163     return -1;
 164 }
 165 
 166 // Add a block of characters to the intended MLU. Language and country are specified.
 167 // Only one entry for Language/country pair is allowed.
 168 static
 169 cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block,
 170                      cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode)


 190     }
 191 
 192     Offset = mlu ->PoolUsed;
 193 
 194     Ptr = (cmsUInt8Number*) mlu ->MemPool;
 195     if (Ptr == NULL) return FALSE;
 196 
 197     // Set the entry
 198     memmove(Ptr + Offset, Block, size);
 199     mlu ->PoolUsed += size;
 200 
 201     mlu ->Entries[mlu ->UsedEntries].StrW     = Offset;
 202     mlu ->Entries[mlu ->UsedEntries].Len      = size;
 203     mlu ->Entries[mlu ->UsedEntries].Country  = CountryCode;
 204     mlu ->Entries[mlu ->UsedEntries].Language = LanguageCode;
 205     mlu ->UsedEntries++;
 206 
 207     return TRUE;
 208 }
 209 
 210 // Convert from a 3-char code to a cmsUInt16Number. It is done inthis way because some
 211 // compilers don't properly align beginning of strings
 212 
 213 static
 214 cmsUInt16Number strTo16(const char str[3])
 215 {
 216     cmsUInt16Number n = ((cmsUInt16Number) str[0] << 8) | str[1];
 217 
 218     return n;  // Always big endian in this case
 219 }
 220 
 221 static
 222 void strFrom16(char str[3], cmsUInt16Number n)
 223 {
 224     // Assiming this would be aligned
 225     union {
 226 
 227        cmsUInt16Number n;
 228        char str[2];
 229 
 230     } c;
 231 
 232     c.n = n;  // Always big endian in this case
 233 
 234     str[0] = c.str[0]; str[1] = c.str[1]; str[2] = 0;
 235 
 236 }
 237 
 238 // Add an ASCII entry. Do not add any \0 termination (ICC1v43_2010-12.pdf page 61)
 239 cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString)
 240 {
 241     cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString);
 242     wchar_t* WStr;
 243     cmsBool  rc;
 244     cmsUInt16Number Lang  = strTo16(LanguageCode);
 245     cmsUInt16Number Cntry = strTo16(CountryCode);
 246 
 247     if (mlu == NULL) return FALSE;
 248 
 249     WStr = (wchar_t*) _cmsCalloc(mlu ->ContextID, len,  sizeof(wchar_t));
 250     if (WStr == NULL) return FALSE;
 251 
 252     for (i=0; i < len; i++)
 253         WStr[i] = (wchar_t) ASCIIString[i];
 254 
 255     rc = AddMLUBlock(mlu, len  * sizeof(wchar_t), WStr, Lang, Cntry);
 256 
 257     _cmsFree(mlu ->ContextID, WStr);
 258     return rc;
 259 
 260 }
 261 
 262 // We don't need any wcs support library
 263 static
 264 cmsUInt32Number mywcslen(const wchar_t *s)
 265 {
 266     const wchar_t *p;
 267 
 268     p = s;
 269     while (*p)
 270         p++;
 271 
 272     return (cmsUInt32Number)(p - s);
 273 }
 274 
 275 // Add a wide entry. Do not add any \0 terminator (ICC1v43_2010-12.pdf page 61)

 276 cmsBool  CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char Country[3], const wchar_t* WideString)
 277 {
 278     cmsUInt16Number Lang  = strTo16(Language);
 279     cmsUInt16Number Cntry = strTo16(Country);
 280     cmsUInt32Number len;
 281 
 282     if (mlu == NULL) return FALSE;
 283     if (WideString == NULL) return FALSE;
 284 
 285     len = (cmsUInt32Number) (mywcslen(WideString)) * sizeof(wchar_t);
 286     return AddMLUBlock(mlu, len, WideString, Lang, Cntry);
 287 }
 288 
 289 // Duplicating a MLU is as easy as copying all members
 290 cmsMLU* CMSEXPORT cmsMLUdup(const cmsMLU* mlu)
 291 {
 292     cmsMLU* NewMlu = NULL;
 293 
 294     // Duplicating a NULL obtains a NULL
 295     if (mlu == NULL) return NULL;
 296 
 297     NewMlu = cmsMLUalloc(mlu ->ContextID, mlu ->UsedEntries);
 298     if (NewMlu == NULL) return NULL;
 299 
 300     // Should never happen
 301     if (NewMlu ->AllocatedEntries < mlu ->UsedEntries)
 302         goto Error;
 303 
 304     // Sanitize...
 305     if (NewMlu ->Entries == NULL || mlu ->Entries == NULL)  goto Error;


 336 void CMSEXPORT cmsMLUfree(cmsMLU* mlu)
 337 {
 338     if (mlu) {
 339 
 340         if (mlu -> Entries) _cmsFree(mlu ->ContextID, mlu->Entries);
 341         if (mlu -> MemPool) _cmsFree(mlu ->ContextID, mlu->MemPool);
 342 
 343         _cmsFree(mlu ->ContextID, mlu);
 344     }
 345 }
 346 
 347 
 348 // The algorithm first searches for an exact match of country and language, if not found it uses
 349 // the Language. If none is found, first entry is used instead.
 350 static
 351 const wchar_t* _cmsMLUgetWide(const cmsMLU* mlu,
 352                               cmsUInt32Number *len,
 353                               cmsUInt16Number LanguageCode, cmsUInt16Number CountryCode,
 354                               cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode)
 355 {
 356     cmsUInt32Number i;
 357     cmsInt32Number Best = -1;
 358     _cmsMLUentry* v;
 359 
 360     if (mlu == NULL) return NULL;
 361 
 362     if (mlu -> AllocatedEntries <= 0) return NULL;
 363 
 364     for (i=0; i < mlu ->UsedEntries; i++) {
 365 
 366         v = mlu ->Entries + i;
 367 
 368         if (v -> Language == LanguageCode) {
 369 
 370             if (Best == -1) Best = i;
 371 
 372             if (v -> Country == CountryCode) {
 373 
 374                 if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language;
 375                 if (UsedCountryCode  != NULL) *UsedCountryCode = v ->Country;
 376 
 377                 if (len != NULL) *len = v ->Len;


 388     v = mlu ->Entries + Best;
 389 
 390     if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language;
 391     if (UsedCountryCode  != NULL) *UsedCountryCode = v ->Country;
 392 
 393     if (len != NULL) *len   = v ->Len;
 394 
 395     return(wchar_t*) ((cmsUInt8Number*) mlu ->MemPool + v ->StrW);
 396 }
 397 
 398 
 399 // Obtain an ASCII representation of the wide string. Setting buffer to NULL returns the len
 400 cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
 401                                        const char LanguageCode[3], const char CountryCode[3],
 402                                        char* Buffer, cmsUInt32Number BufferSize)
 403 {
 404     const wchar_t *Wide;
 405     cmsUInt32Number  StrLen = 0;
 406     cmsUInt32Number ASCIIlen, i;
 407 
 408     cmsUInt16Number Lang  = strTo16(LanguageCode);
 409     cmsUInt16Number Cntry = strTo16(CountryCode);
 410 
 411     // Sanitize
 412     if (mlu == NULL) return 0;
 413 
 414     // Get WideChar
 415     Wide = _cmsMLUgetWide(mlu, &StrLen, Lang, Cntry, NULL, NULL);
 416     if (Wide == NULL) return 0;
 417 
 418     ASCIIlen = StrLen / sizeof(wchar_t);
 419 
 420     // Maybe we want only to know the len?
 421     if (Buffer == NULL) return ASCIIlen + 1; // Note the zero at the end
 422 
 423     // No buffer size means no data
 424     if (BufferSize <= 0) return 0;
 425 
 426     // Some clipping may be required
 427     if (BufferSize < ASCIIlen + 1)
 428         ASCIIlen = BufferSize - 1;
 429 


 432 
 433         if (Wide[i] == 0)
 434             Buffer[i] = 0;
 435         else
 436             Buffer[i] = (char) Wide[i];
 437     }
 438 
 439     // We put a termination "\0"
 440     Buffer[ASCIIlen] = 0;
 441     return ASCIIlen + 1;
 442 }
 443 
 444 // Obtain a wide representation of the MLU, on depending on current locale settings
 445 cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu,
 446                                       const char LanguageCode[3], const char CountryCode[3],
 447                                       wchar_t* Buffer, cmsUInt32Number BufferSize)
 448 {
 449     const wchar_t *Wide;
 450     cmsUInt32Number  StrLen = 0;
 451 
 452     cmsUInt16Number Lang  = strTo16(LanguageCode);
 453     cmsUInt16Number Cntry = strTo16(CountryCode);
 454 
 455     // Sanitize
 456     if (mlu == NULL) return 0;
 457 
 458     Wide = _cmsMLUgetWide(mlu, &StrLen, Lang, Cntry, NULL, NULL);
 459     if (Wide == NULL) return 0;
 460 
 461     // Maybe we want only to know the len?
 462     if (Buffer == NULL) return StrLen + sizeof(wchar_t);
 463 
 464   // No buffer size means no data
 465     if (BufferSize <= 0) return 0;
 466 
 467     // Some clipping may be required
 468     if (BufferSize < StrLen + sizeof(wchar_t))
 469         StrLen = BufferSize - + sizeof(wchar_t);
 470 
 471     memmove(Buffer, Wide, StrLen);
 472     Buffer[StrLen / sizeof(wchar_t)] = 0;
 473 
 474     return StrLen + sizeof(wchar_t);
 475 }
 476 
 477 
 478 // Get also the language and country
 479 CMSAPI cmsBool CMSEXPORT cmsMLUgetTranslation(const cmsMLU* mlu,
 480                                               const char LanguageCode[3], const char CountryCode[3],
 481                                               char ObtainedLanguage[3], char ObtainedCountry[3])
 482 {
 483     const wchar_t *Wide;
 484 
 485     cmsUInt16Number Lang  = strTo16(LanguageCode);
 486     cmsUInt16Number Cntry = strTo16(CountryCode);
 487     cmsUInt16Number ObtLang, ObtCode;
 488 
 489     // Sanitize
 490     if (mlu == NULL) return FALSE;
 491 
 492     Wide = _cmsMLUgetWide(mlu, NULL, Lang, Cntry, &ObtLang, &ObtCode);
 493     if (Wide == NULL) return FALSE;
 494 
 495     // Get used language and code
 496     strFrom16(ObtainedLanguage, ObtLang);
 497     strFrom16(ObtainedCountry, ObtCode);
 498 

 499     return TRUE;
 500 }
 501 
 502 
 503 
 504 // Get the number of translations in the MLU object
 505 cmsUInt32Number CMSEXPORT cmsMLUtranslationsCount(const cmsMLU* mlu)
 506 {
 507     if (mlu == NULL) return 0;
 508     return mlu->UsedEntries;
 509 }
 510 
 511 // Get the language and country codes for a specific MLU index
 512 cmsBool CMSEXPORT cmsMLUtranslationsCodes(const cmsMLU* mlu,
 513                                           cmsUInt32Number idx,
 514                                           char LanguageCode[3],
 515                                           char CountryCode[3])
 516 {
 517     _cmsMLUentry *entry;
 518 
 519     if (mlu == NULL) return FALSE;
 520 
 521     if (idx >= mlu->UsedEntries) return FALSE;
 522 
 523     entry = &mlu->Entries[idx];
 524 
 525     strFrom16(LanguageCode, entry->Language);
 526     strFrom16(CountryCode, entry->Country);
 527 
 528     return TRUE;
 529 }
 530 
 531 
 532 // Named color lists --------------------------------------------------------------------------------------------
 533 
 534 // Grow the list to keep at least NumElements
 535 static
 536 cmsBool  GrowNamedColorList(cmsNAMEDCOLORLIST* v)
 537 {
 538     cmsUInt32Number size;
 539     _cmsNAMEDCOLOR * NewPtr;
 540 
 541     if (v == NULL) return FALSE;
 542 
 543     if (v ->Allocated == 0)
 544         size = 64;   // Initial guess
 545     else
 546         size = v ->Allocated * 2;


< prev index next >