1 /*
   2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  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-2010 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 //---------------------------------------------------------------------------------
  54 //
  55 
  56 #include "lcms2_internal.h"
  57 
  58 
  59 // ----------------------------------------------------------------------------------
  60 // Encoding & Decoding support functions
  61 // ----------------------------------------------------------------------------------
  62 
  63 //      Little-Endian to Big-Endian
  64 
  65 // Adjust a word value after being readed/ before being written from/to an ICC profile
  66 cmsUInt16Number CMSEXPORT  _cmsAdjustEndianess16(cmsUInt16Number Word)
  67 {
  68 #ifndef CMS_USE_BIG_ENDIAN
  69 
  70     cmsUInt8Number* pByte = (cmsUInt8Number*) &Word;
  71     cmsUInt8Number tmp;
  72 
  73     tmp = pByte[0];
  74     pByte[0] = pByte[1];
  75     pByte[1] = tmp;
  76 #endif
  77 
  78     return Word;
  79 }
  80 
  81 
  82 // Transports to properly encoded values - note that icc profiles does use big endian notation.
  83 
  84 // 1 2 3 4
  85 // 4 3 2 1
  86 
  87 cmsUInt32Number CMSEXPORT  _cmsAdjustEndianess32(cmsUInt32Number DWord)
  88 {
  89 #ifndef CMS_USE_BIG_ENDIAN
  90 
  91     cmsUInt8Number* pByte = (cmsUInt8Number*) &DWord;
  92     cmsUInt8Number temp1;
  93     cmsUInt8Number temp2;
  94 
  95     temp1 = *pByte++;
  96     temp2 = *pByte++;
  97     *(pByte-1) = *pByte;
  98     *pByte++ = temp2;
  99     *(pByte-3) = *pByte;
 100     *pByte = temp1;
 101 #endif
 102     return DWord;
 103 }
 104 
 105 // 1 2 3 4 5 6 7 8
 106 // 8 7 6 5 4 3 2 1
 107 
 108 void CMSEXPORT  _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord)
 109 {
 110 
 111 #ifndef CMS_USE_BIG_ENDIAN
 112 
 113     cmsUInt8Number* pIn  = (cmsUInt8Number*) QWord;
 114     cmsUInt8Number* pOut = (cmsUInt8Number*) Result;
 115 
 116     _cmsAssert(Result != NULL);
 117 
 118     pOut[7] = pIn[0];
 119     pOut[6] = pIn[1];
 120     pOut[5] = pIn[2];
 121     pOut[4] = pIn[3];
 122     pOut[3] = pIn[4];
 123     pOut[2] = pIn[5];
 124     pOut[1] = pIn[6];
 125     pOut[0] = pIn[7];
 126 
 127 #else
 128 
 129     _cmsAssert(Result != NULL);
 130 
 131     *Result = *QWord;
 132 #endif
 133 }
 134 
 135 // Auxiliar -- read 8, 16 and 32-bit numbers
 136 cmsBool CMSEXPORT  _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n)
 137 {
 138     cmsUInt8Number tmp;
 139 
 140     _cmsAssert(io != NULL);
 141 
 142     if (io -> Read(io, &tmp, sizeof(cmsUInt8Number), 1) != 1)
 143             return FALSE;
 144 
 145     if (n != NULL) *n = tmp;
 146     return TRUE;
 147 }
 148 
 149 cmsBool CMSEXPORT  _cmsReadUInt16Number(cmsIOHANDLER* io, cmsUInt16Number* n)
 150 {
 151     cmsUInt16Number tmp;
 152 
 153     _cmsAssert(io != NULL);
 154 
 155     if (io -> Read(io, &tmp, sizeof(cmsUInt16Number), 1) != 1)
 156             return FALSE;
 157 
 158     if (n != NULL) *n = _cmsAdjustEndianess16(tmp);
 159     return TRUE;
 160 }
 161 
 162 cmsBool CMSEXPORT  _cmsReadUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, cmsUInt16Number* Array)
 163 {
 164     cmsUInt32Number i;
 165 
 166     _cmsAssert(io != NULL);
 167 
 168     for (i=0; i < n; i++) {
 169 
 170         if (Array != NULL) {
 171             if (!_cmsReadUInt16Number(io, Array + i)) return FALSE;
 172         }
 173         else {
 174             if (!_cmsReadUInt16Number(io, NULL)) return FALSE;
 175         }
 176 
 177     }
 178     return TRUE;
 179 }
 180 
 181 cmsBool CMSEXPORT  _cmsReadUInt32Number(cmsIOHANDLER* io, cmsUInt32Number* n)
 182 {
 183     cmsUInt32Number tmp;
 184 
 185     _cmsAssert(io != NULL);
 186 
 187     if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
 188             return FALSE;
 189 
 190     if (n != NULL) *n = _cmsAdjustEndianess32(tmp);
 191     return TRUE;
 192 }
 193 
 194 cmsBool CMSEXPORT  _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n)
 195 {
 196     cmsUInt32Number tmp;
 197 
 198     _cmsAssert(io != NULL);
 199 
 200     if (io -> Read(io, &tmp, sizeof(cmsFloat32Number), 1) != 1)
 201             return FALSE;
 202 
 203     if (n != NULL) {
 204 
 205         tmp = _cmsAdjustEndianess32(tmp);
 206         *n = *(cmsFloat32Number*) &tmp;
 207     }
 208     return TRUE;
 209 }
 210 
 211 
 212 cmsBool CMSEXPORT   _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
 213 {
 214     cmsUInt64Number tmp;
 215 
 216     _cmsAssert(io != NULL);
 217 
 218     if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1)
 219             return FALSE;
 220 
 221     if (n != NULL) _cmsAdjustEndianess64(n, &tmp);
 222     return TRUE;
 223 }
 224 
 225 
 226 cmsBool CMSEXPORT  _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n)
 227 {
 228     cmsUInt32Number tmp;
 229 
 230     _cmsAssert(io != NULL);
 231 
 232     if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
 233             return FALSE;
 234 
 235     if (n != NULL) {
 236         *n = _cms15Fixed16toDouble(_cmsAdjustEndianess32(tmp));
 237     }
 238 
 239     return TRUE;
 240 }
 241 
 242 
 243 // Jun-21-2000: Some profiles (those that comes with W2K) comes
 244 // with the media white (media black?) x 100. Add a sanity check
 245 
 246 static
 247 void NormalizeXYZ(cmsCIEXYZ* Dest)
 248 {
 249     while (Dest -> X > 2. &&
 250            Dest -> Y > 2. &&
 251            Dest -> Z > 2.) {
 252 
 253                Dest -> X /= 10.;
 254                Dest -> Y /= 10.;
 255                Dest -> Z /= 10.;
 256        }
 257 }
 258 
 259 cmsBool CMSEXPORT  _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ)
 260 {
 261     cmsEncodedXYZNumber xyz;
 262 
 263     _cmsAssert(io != NULL);
 264 
 265     if (io ->Read(io, &xyz, sizeof(cmsEncodedXYZNumber), 1) != 1) return FALSE;
 266 
 267     if (XYZ != NULL) {
 268 
 269         XYZ->X = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.X));
 270         XYZ->Y = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Y));
 271         XYZ->Z = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Z));
 272 
 273         NormalizeXYZ(XYZ);
 274     }
 275     return TRUE;
 276 }
 277 
 278 cmsBool CMSEXPORT  _cmsWriteUInt8Number(cmsIOHANDLER* io, cmsUInt8Number n)
 279 {
 280     _cmsAssert(io != NULL);
 281 
 282     if (io -> Write(io, sizeof(cmsUInt8Number), &n) != 1)
 283             return FALSE;
 284 
 285     return TRUE;
 286 }
 287 
 288 cmsBool CMSEXPORT  _cmsWriteUInt16Number(cmsIOHANDLER* io, cmsUInt16Number n)
 289 {
 290     cmsUInt16Number tmp;
 291 
 292     _cmsAssert(io != NULL);
 293 
 294     tmp = _cmsAdjustEndianess16(n);
 295     if (io -> Write(io, sizeof(cmsUInt16Number), &tmp) != 1)
 296             return FALSE;
 297 
 298     return TRUE;
 299 }
 300 
 301 cmsBool CMSEXPORT  _cmsWriteUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, const cmsUInt16Number* Array)
 302 {
 303     cmsUInt32Number i;
 304 
 305     _cmsAssert(io != NULL);
 306     _cmsAssert(Array != NULL);
 307 
 308     for (i=0; i < n; i++) {
 309         if (!_cmsWriteUInt16Number(io, Array[i])) return FALSE;
 310     }
 311 
 312     return TRUE;
 313 }
 314 
 315 cmsBool CMSEXPORT  _cmsWriteUInt32Number(cmsIOHANDLER* io, cmsUInt32Number n)
 316 {
 317     cmsUInt32Number tmp;
 318 
 319     _cmsAssert(io != NULL);
 320 
 321     tmp = _cmsAdjustEndianess32(n);
 322     if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
 323             return FALSE;
 324 
 325     return TRUE;
 326 }
 327 
 328 
 329 cmsBool CMSEXPORT  _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n)
 330 {
 331     cmsUInt32Number tmp;
 332 
 333     _cmsAssert(io != NULL);
 334 
 335     tmp = *(cmsUInt32Number*) &n;
 336     tmp = _cmsAdjustEndianess32(tmp);
 337     if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
 338             return FALSE;
 339 
 340     return TRUE;
 341 }
 342 
 343 cmsBool CMSEXPORT  _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
 344 {
 345     cmsUInt64Number tmp;
 346 
 347     _cmsAssert(io != NULL);
 348 
 349     _cmsAdjustEndianess64(&tmp, n);
 350     if (io -> Write(io, sizeof(cmsUInt64Number), &tmp) != 1)
 351             return FALSE;
 352 
 353     return TRUE;
 354 }
 355 
 356 cmsBool CMSEXPORT  _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n)
 357 {
 358     cmsUInt32Number tmp;
 359 
 360     _cmsAssert(io != NULL);
 361 
 362     tmp = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(n));
 363     if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
 364             return FALSE;
 365 
 366     return TRUE;
 367 }
 368 
 369 cmsBool CMSEXPORT  _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ)
 370 {
 371     cmsEncodedXYZNumber xyz;
 372 
 373     _cmsAssert(io != NULL);
 374     _cmsAssert(XYZ != NULL);
 375 
 376     xyz.X = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->X));
 377     xyz.Y = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Y));
 378     xyz.Z = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Z));
 379 
 380     return io -> Write(io,  sizeof(cmsEncodedXYZNumber), &xyz);
 381 }
 382 
 383 // from Fixed point 8.8 to double
 384 cmsFloat64Number CMSEXPORT _cms8Fixed8toDouble(cmsUInt16Number fixed8)
 385 {
 386        cmsUInt8Number  msb, lsb;
 387 
 388        lsb = (cmsUInt8Number) (fixed8 & 0xff);
 389        msb = (cmsUInt8Number) (((cmsUInt16Number) fixed8 >> 8) & 0xff);
 390 
 391        return (cmsFloat64Number) ((cmsFloat64Number) msb + ((cmsFloat64Number) lsb / 256.0));
 392 }
 393 
 394 cmsUInt16Number CMSEXPORT _cmsDoubleTo8Fixed8(cmsFloat64Number val)
 395 {
 396     cmsS15Fixed16Number GammaFixed32 = _cmsDoubleTo15Fixed16(val);
 397     return  (cmsUInt16Number) ((GammaFixed32 >> 8) & 0xFFFF);
 398 }
 399 
 400 // from Fixed point 15.16 to double
 401 cmsFloat64Number CMSEXPORT _cms15Fixed16toDouble(cmsS15Fixed16Number fix32)
 402 {
 403     cmsFloat64Number floater, sign, mid;
 404     int Whole, FracPart;
 405 
 406     sign  = (fix32 < 0 ? -1 : 1);
 407     fix32 = abs(fix32);
 408 
 409     Whole     = (cmsUInt16Number)(fix32 >> 16) & 0xffff;
 410     FracPart  = (cmsUInt16Number)(fix32 & 0xffff);
 411 
 412     mid     = (cmsFloat64Number) FracPart / 65536.0;
 413     floater = (cmsFloat64Number) Whole + mid;
 414 
 415     return sign * floater;
 416 }
 417 
 418 // from double to Fixed point 15.16
 419 cmsS15Fixed16Number CMSEXPORT _cmsDoubleTo15Fixed16(cmsFloat64Number v)
 420 {
 421     return ((cmsS15Fixed16Number) floor((v)*65536.0 + 0.5));
 422 }
 423 
 424 // Date/Time functions
 425 
 426 void CMSEXPORT _cmsDecodeDateTimeNumber(const cmsDateTimeNumber *Source, struct tm *Dest)
 427 {
 428 
 429     _cmsAssert(Dest != NULL);
 430     _cmsAssert(Source != NULL);
 431 
 432     Dest->tm_sec   = _cmsAdjustEndianess16(Source->seconds);
 433     Dest->tm_min   = _cmsAdjustEndianess16(Source->minutes);
 434     Dest->tm_hour  = _cmsAdjustEndianess16(Source->hours);
 435     Dest->tm_mday  = _cmsAdjustEndianess16(Source->day);
 436     Dest->tm_mon   = _cmsAdjustEndianess16(Source->month) - 1;
 437     Dest->tm_year  = _cmsAdjustEndianess16(Source->year) - 1900;
 438     Dest->tm_wday  = -1;
 439     Dest->tm_yday  = -1;
 440     Dest->tm_isdst = 0;
 441 }
 442 
 443 void CMSEXPORT _cmsEncodeDateTimeNumber(cmsDateTimeNumber *Dest, const struct tm *Source)
 444 {
 445     _cmsAssert(Dest != NULL);
 446     _cmsAssert(Source != NULL);
 447 
 448     Dest->seconds = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_sec);
 449     Dest->minutes = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_min);
 450     Dest->hours   = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_hour);
 451     Dest->day     = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_mday);
 452     Dest->month   = _cmsAdjustEndianess16((cmsUInt16Number) (Source->tm_mon + 1));
 453     Dest->year    = _cmsAdjustEndianess16((cmsUInt16Number) (Source->tm_year + 1900));
 454 }
 455 
 456 // Read base and return type base
 457 cmsTagTypeSignature CMSEXPORT _cmsReadTypeBase(cmsIOHANDLER* io)
 458 {
 459     _cmsTagBase Base;
 460 
 461     _cmsAssert(io != NULL);
 462 
 463     if (io -> Read(io, &Base, sizeof(_cmsTagBase), 1) != 1)
 464         return (cmsTagTypeSignature) 0;
 465 
 466     return (cmsTagTypeSignature) _cmsAdjustEndianess32(Base.sig);
 467 }
 468 
 469 // Setup base marker
 470 cmsBool  CMSEXPORT _cmsWriteTypeBase(cmsIOHANDLER* io, cmsTagTypeSignature sig)
 471 {
 472     _cmsTagBase  Base;
 473 
 474     _cmsAssert(io != NULL);
 475 
 476     Base.sig = (cmsTagTypeSignature) _cmsAdjustEndianess32(sig);
 477     memset(&Base.reserved, 0, sizeof(Base.reserved));
 478     return io -> Write(io, sizeof(_cmsTagBase), &Base);
 479 }
 480 
 481 cmsBool CMSEXPORT _cmsReadAlignment(cmsIOHANDLER* io)
 482 {
 483     cmsUInt8Number  Buffer[4];
 484     cmsUInt32Number NextAligned, At;
 485     cmsUInt32Number BytesToNextAlignedPos;
 486 
 487     _cmsAssert(io != NULL);
 488 
 489     At = io -> Tell(io);
 490     NextAligned = _cmsALIGNLONG(At);
 491     BytesToNextAlignedPos = NextAligned - At;
 492     if (BytesToNextAlignedPos == 0) return TRUE;
 493     if (BytesToNextAlignedPos > 4)  return FALSE;
 494 
 495     return (io ->Read(io, Buffer, BytesToNextAlignedPos, 1) == 1);
 496 }
 497 
 498 cmsBool CMSEXPORT _cmsWriteAlignment(cmsIOHANDLER* io)
 499 {
 500     cmsUInt8Number  Buffer[4];
 501     cmsUInt32Number NextAligned, At;
 502     cmsUInt32Number BytesToNextAlignedPos;
 503 
 504     _cmsAssert(io != NULL);
 505 
 506     At = io -> Tell(io);
 507     NextAligned = _cmsALIGNLONG(At);
 508     BytesToNextAlignedPos = NextAligned - At;
 509     if (BytesToNextAlignedPos == 0) return TRUE;
 510     if (BytesToNextAlignedPos > 4)  return FALSE;
 511 
 512     memset(Buffer, 0, BytesToNextAlignedPos);
 513     return io -> Write(io, BytesToNextAlignedPos, Buffer);
 514 }
 515 
 516 
 517 // To deal with text streams. 2K at most
 518 cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
 519 {
 520     va_list args;
 521     int len;
 522     cmsUInt8Number Buffer[2048];
 523     cmsBool rc;
 524 
 525     _cmsAssert(io != NULL);
 526     _cmsAssert(frm != NULL);
 527 
 528     va_start(args, frm);
 529 
 530     len = vsnprintf((char*) Buffer, 2047, frm, args);
 531     if (len < 0) return FALSE;   // Truncated, which is a fatal error for us
 532 
 533     rc = io ->Write(io, len, Buffer);
 534 
 535     va_end(args);
 536 
 537     return rc;
 538 }
 539 
 540 
 541 // Plugin memory management -------------------------------------------------------------------------------------------------
 542 
 543 static _cmsSubAllocator* PluginPool = NULL;
 544 
 545 // Specialized malloc for plug-ins, that is freed upon exit.
 546 void* _cmsPluginMalloc(cmsUInt32Number size)
 547 {
 548     if (PluginPool == NULL)
 549         PluginPool = _cmsCreateSubAlloc(0, 4*1024);
 550 
 551     return _cmsSubAlloc(PluginPool, size);
 552 }
 553 
 554 
 555 // Main plug-in dispatcher
 556 cmsBool CMSEXPORT cmsPlugin(void* Plug_in)
 557 {
 558     cmsPluginBase* Plugin;
 559 
 560     for (Plugin = (cmsPluginBase*) Plug_in;
 561          Plugin != NULL;
 562          Plugin = Plugin -> Next) {
 563 
 564             if (Plugin -> Magic != cmsPluginMagicNumber) {
 565                 cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin");
 566                 return FALSE;
 567             }
 568 
 569             if (Plugin ->ExpectedVersion > LCMS_VERSION) {
 570                 cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current  version is %d",
 571                     Plugin ->ExpectedVersion, LCMS_VERSION);
 572                 return FALSE;
 573             }
 574 
 575             switch (Plugin -> Type) {
 576 
 577                 case cmsPluginMemHandlerSig:
 578                     if (!_cmsRegisterMemHandlerPlugin(Plugin)) return FALSE;
 579                     break;
 580 
 581                 case cmsPluginInterpolationSig:
 582                     if (!_cmsRegisterInterpPlugin(Plugin)) return FALSE;
 583                     break;
 584 
 585                 case cmsPluginTagTypeSig:
 586                     if (!_cmsRegisterTagTypePlugin(Plugin)) return FALSE;
 587                     break;
 588 
 589                 case cmsPluginTagSig:
 590                     if (!_cmsRegisterTagPlugin(Plugin)) return FALSE;
 591                     break;
 592 
 593                 case cmsPluginFormattersSig:
 594                     if (!_cmsRegisterFormattersPlugin(Plugin)) return FALSE;
 595                     break;
 596 
 597                 case cmsPluginRenderingIntentSig:
 598                     if (!_cmsRegisterRenderingIntentPlugin(Plugin)) return FALSE;
 599                     break;
 600 
 601                 case cmsPluginParametricCurveSig:
 602                     if (!_cmsRegisterParametricCurvesPlugin(Plugin)) return FALSE;
 603                     break;
 604 
 605                 case cmsPluginMultiProcessElementSig:
 606                     if (!_cmsRegisterMultiProcessElementPlugin(Plugin)) return FALSE;
 607                     break;
 608 
 609                 case cmsPluginOptimizationSig:
 610                     if (!_cmsRegisterOptimizationPlugin(Plugin)) return FALSE;
 611                     break;
 612 
 613                 case cmsPluginTransformSig:
 614                     if (!_cmsRegisterTransformPlugin(Plugin)) return FALSE;
 615                     break;
 616 
 617                 default:
 618                     cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
 619                     return FALSE;
 620             }
 621     }
 622 
 623     // Keep a reference to the plug-in
 624     return TRUE;
 625 }
 626 
 627 
 628 // Revert all plug-ins to default
 629 void CMSEXPORT cmsUnregisterPlugins(void)
 630 {
 631     _cmsRegisterMemHandlerPlugin(NULL);
 632     _cmsRegisterInterpPlugin(NULL);
 633     _cmsRegisterTagTypePlugin(NULL);
 634     _cmsRegisterTagPlugin(NULL);
 635     _cmsRegisterFormattersPlugin(NULL);
 636     _cmsRegisterRenderingIntentPlugin(NULL);
 637     _cmsRegisterParametricCurvesPlugin(NULL);
 638     _cmsRegisterMultiProcessElementPlugin(NULL);
 639     _cmsRegisterOptimizationPlugin(NULL);
 640     _cmsRegisterTransformPlugin(NULL);
 641 
 642     if (PluginPool != NULL)
 643         _cmsSubAllocDestroy(PluginPool);
 644 
 645     PluginPool = NULL;
 646 }