< prev index next >

src/java.desktop/share/native/liblcms/cmsplugin.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-2017 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


 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     _cmsAssert(Result != NULL);
 129 
 130 #  ifdef CMS_DONT_USE_INT64
 131     (*Result)[0] = QWord[0];
 132     (*Result)[1] = QWord[1];
 133 #  else
 134     *Result = *QWord;
 135 #  endif
 136 #endif
 137 }
 138 
 139 // Auxiliary -- read 8, 16 and 32-bit numbers
 140 cmsBool CMSEXPORT  _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n)
 141 {
 142     cmsUInt8Number tmp;
 143 
 144     _cmsAssert(io != NULL);
 145 
 146     if (io -> Read(io, &tmp, sizeof(cmsUInt8Number), 1) != 1)
 147             return FALSE;
 148 
 149     if (n != NULL) *n = tmp;
 150     return TRUE;
 151 }
 152 


 199 {
 200     cmsUInt32Number tmp;
 201 
 202     _cmsAssert(io != NULL);
 203 
 204     if (io->Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
 205         return FALSE;
 206 
 207     if (n != NULL) {
 208 
 209         tmp = _cmsAdjustEndianess32(tmp);
 210         *n = *(cmsFloat32Number*)(void*)&tmp;
 211 
 212         // Safeguard which covers against absurd values
 213         if (*n > 1E+20 || *n < -1E+20) return FALSE;
 214 
 215         #if defined(_MSC_VER) && _MSC_VER < 1800
 216            return TRUE;
 217         #elif defined (__BORLANDC__)
 218            return TRUE;


 219         #else
 220 
 221            // fpclassify() required by C99 (only provided by MSVC >= 1800, VS2013 onwards)
 222            return ((fpclassify(*n) == FP_ZERO) || (fpclassify(*n) == FP_NORMAL));
 223         #endif
 224     }
 225 
 226     return TRUE;
 227 }
 228 
 229 
 230 cmsBool CMSEXPORT   _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
 231 {
 232     cmsUInt64Number tmp;
 233 
 234     _cmsAssert(io != NULL);
 235 
 236     if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1)
 237             return FALSE;
 238 


 685     { NULL, NULL, NULL, NULL, NULL, NULL } // The default memory allocator is not used for context 0
 686 };
 687 
 688 
 689 // The context pool (linked list head)
 690 static _cmsMutex _cmsContextPoolHeadMutex = CMS_MUTEX_INITIALIZER;
 691 static struct _cmsContext_struct* _cmsContextPoolHead = NULL;
 692 
 693 // Internal, get associated pointer, with guessing. Never returns NULL.
 694 struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID)
 695 {
 696     struct _cmsContext_struct* id = (struct _cmsContext_struct*) ContextID;
 697     struct _cmsContext_struct* ctx;
 698 
 699 
 700     // On 0, use global settings
 701     if (id == NULL)
 702         return &globalContext;
 703 
 704     // Search


 705     for (ctx = _cmsContextPoolHead;
 706          ctx != NULL;
 707          ctx = ctx ->Next) {
 708 
 709             // Found it?
 710             if (id == ctx)
 711                 return ctx; // New-style context,



 712     }
 713 

 714     return &globalContext;
 715 }
 716 
 717 
 718 // Internal: get the memory area associanted with each context client
 719 // Returns the block assigned to the specific zone. Never return NULL.
 720 void* _cmsContextGetClientChunk(cmsContext ContextID, _cmsMemoryClient mc)
 721 {
 722     struct _cmsContext_struct* ctx;
 723     void *ptr;
 724 
 725     if ((int) mc < 0 || mc >= MemoryClientMax) {
 726 
 727            cmsSignalError(ContextID, cmsERROR_INTERNAL, "Bad context client -- possible corruption");
 728 
 729            // This is catastrophic. Should never reach here
 730            _cmsAssert(0);
 731 
 732            // Reverts to global context
 733            return globalContext.chunks[UserPtr];


 782 
 783                     // Found!
 784                     return (cmsPluginMemHandler*) Plugin;
 785             }
 786     }
 787 
 788     // Nope, revert to defaults
 789     return NULL;
 790 }
 791 
 792 
 793 // Creates a new context with optional associated plug-ins. Caller may also specify an optional pointer to user-defined
 794 // data that will be forwarded to plug-ins and logger.
 795 cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData)
 796 {
 797     struct _cmsContext_struct* ctx;
 798     struct _cmsContext_struct  fakeContext;
 799 
 800     // See the comments regarding locking in lcms2_internal.h
 801     // for an explanation of why we need the following code.

 802 #ifdef CMS_IS_WINDOWS_
 803 #ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
 804     {
 805         static HANDLE _cmsWindowsInitMutex = NULL;
 806         static volatile HANDLE* mutex = &_cmsWindowsInitMutex;
 807 
 808         if (*mutex == NULL)
 809         {
 810             HANDLE p = CreateMutex(NULL, FALSE, NULL);
 811             if (p && InterlockedCompareExchangePointer((void **)mutex, (void*)p, NULL) != NULL)
 812                 CloseHandle(p);
 813         }
 814         if (*mutex == NULL || WaitForSingleObject(*mutex, INFINITE) == WAIT_FAILED)
 815             return NULL;
 816         if (((void **)&_cmsContextPoolHeadMutex)[0] == NULL)
 817             InitializeCriticalSection(&_cmsContextPoolHeadMutex);
 818         if (*mutex == NULL || !ReleaseMutex(*mutex))
 819             return NULL;
 820     }
 821 #endif
 822 #endif

 823 
 824     _cmsInstallAllocFunctions(_cmsFindMemoryPlugin(Plugin), &fakeContext.DefaultMemoryManager);
 825 
 826     fakeContext.chunks[UserPtr]     = UserData;
 827     fakeContext.chunks[MemPlugin]   = &fakeContext.DefaultMemoryManager;
 828 
 829     // Create the context structure.
 830     ctx = (struct _cmsContext_struct*) _cmsMalloc(&fakeContext, sizeof(struct _cmsContext_struct));
 831     if (ctx == NULL)
 832         return NULL;     // Something very wrong happened!
 833 
 834     // Init the structure and the memory manager
 835     memset(ctx, 0, sizeof(struct _cmsContext_struct));
 836 
 837     // Keep memory manager
 838     memcpy(&ctx->DefaultMemoryManager, &fakeContext.DefaultMemoryManager, sizeof(_cmsMemPluginChunk));
 839 
 840     // Maintain the linked list (with proper locking)
 841     _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
 842        ctx ->Next = _cmsContextPoolHead;


 925     _cmsAllocTagTypePluginChunk(ctx, src);
 926     _cmsAllocMPETypePluginChunk(ctx, src);
 927     _cmsAllocTagPluginChunk(ctx, src);
 928     _cmsAllocIntentsPluginChunk(ctx, src);
 929     _cmsAllocOptimizationPluginChunk(ctx, src);
 930     _cmsAllocTransformPluginChunk(ctx, src);
 931     _cmsAllocMutexPluginChunk(ctx, src);
 932 
 933     // Make sure no one failed
 934     for (i=Logger; i < MemoryClientMax; i++) {
 935 
 936         if (src ->chunks[i] == NULL) {
 937             cmsDeleteContext((cmsContext) ctx);
 938             return NULL;
 939         }
 940     }
 941 
 942     return (cmsContext) ctx;
 943 }
 944 
 945 
 946 /*
 947 static
 948 struct _cmsContext_struct* FindPrev(struct _cmsContext_struct* id)
 949 {
 950     struct _cmsContext_struct* prev;
 951 
 952     // Search for previous
 953     for (prev = _cmsContextPoolHead;
 954              prev != NULL;
 955              prev = prev ->Next)
 956     {
 957         if (prev ->Next == id)
 958             return prev;
 959     }
 960 
 961     return NULL;  // List is empty or only one element!
 962 }
 963 */
 964 
 965 // Frees any resources associated with the given context,
 966 // and destroys the context placeholder.
 967 // The ContextID can no longer be used in any THR operation.
 968 void CMSEXPORT cmsDeleteContext(cmsContext ContextID)
 969 {
 970     if (ContextID != NULL) {
 971 
 972         struct _cmsContext_struct* ctx = (struct _cmsContext_struct*) ContextID;
 973         struct _cmsContext_struct  fakeContext;
 974         struct _cmsContext_struct* prev;
 975 
 976         memcpy(&fakeContext.DefaultMemoryManager, &ctx->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
 977 
 978         fakeContext.chunks[UserPtr]     = ctx ->chunks[UserPtr];
 979         fakeContext.chunks[MemPlugin]   = &fakeContext.DefaultMemoryManager;
 980 
 981         // Get rid of plugins
 982         cmsUnregisterPluginsTHR(ContextID);
 983 




  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-2020 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 read/ 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


 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     _cmsAssert(Result != NULL);
 129 
 130 #  ifdef CMS_DONT_USE_INT64
 131     (*Result)[0] = (*QWord)[0];
 132     (*Result)[1] = (*QWord)[1];
 133 #  else
 134     *Result = *QWord;
 135 #  endif
 136 #endif
 137 }
 138 
 139 // Auxiliary -- read 8, 16 and 32-bit numbers
 140 cmsBool CMSEXPORT  _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n)
 141 {
 142     cmsUInt8Number tmp;
 143 
 144     _cmsAssert(io != NULL);
 145 
 146     if (io -> Read(io, &tmp, sizeof(cmsUInt8Number), 1) != 1)
 147             return FALSE;
 148 
 149     if (n != NULL) *n = tmp;
 150     return TRUE;
 151 }
 152 


 199 {
 200     cmsUInt32Number tmp;
 201 
 202     _cmsAssert(io != NULL);
 203 
 204     if (io->Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
 205         return FALSE;
 206 
 207     if (n != NULL) {
 208 
 209         tmp = _cmsAdjustEndianess32(tmp);
 210         *n = *(cmsFloat32Number*)(void*)&tmp;
 211 
 212         // Safeguard which covers against absurd values
 213         if (*n > 1E+20 || *n < -1E+20) return FALSE;
 214 
 215         #if defined(_MSC_VER) && _MSC_VER < 1800
 216            return TRUE;
 217         #elif defined (__BORLANDC__)
 218            return TRUE;
 219         #elif !defined(_MSC_VER) && (defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L)
 220            return TRUE;
 221         #else
 222 
 223            // fpclassify() required by C99 (only provided by MSVC >= 1800, VS2013 onwards)
 224            return ((fpclassify(*n) == FP_ZERO) || (fpclassify(*n) == FP_NORMAL));
 225         #endif
 226     }
 227 
 228     return TRUE;
 229 }
 230 
 231 
 232 cmsBool CMSEXPORT   _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
 233 {
 234     cmsUInt64Number tmp;
 235 
 236     _cmsAssert(io != NULL);
 237 
 238     if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1)
 239             return FALSE;
 240 


 687     { NULL, NULL, NULL, NULL, NULL, NULL } // The default memory allocator is not used for context 0
 688 };
 689 
 690 
 691 // The context pool (linked list head)
 692 static _cmsMutex _cmsContextPoolHeadMutex = CMS_MUTEX_INITIALIZER;
 693 static struct _cmsContext_struct* _cmsContextPoolHead = NULL;
 694 
 695 // Internal, get associated pointer, with guessing. Never returns NULL.
 696 struct _cmsContext_struct* _cmsGetContext(cmsContext ContextID)
 697 {
 698     struct _cmsContext_struct* id = (struct _cmsContext_struct*) ContextID;
 699     struct _cmsContext_struct* ctx;
 700 
 701 
 702     // On 0, use global settings
 703     if (id == NULL)
 704         return &globalContext;
 705 
 706     // Search
 707     _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
 708 
 709     for (ctx = _cmsContextPoolHead;
 710          ctx != NULL;
 711          ctx = ctx ->Next) {
 712 
 713             // Found it?
 714         if (id == ctx)
 715         {
 716             _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
 717             return ctx; // New-style context
 718         }
 719     }
 720 
 721     _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
 722     return &globalContext;
 723 }
 724 
 725 
 726 // Internal: get the memory area associanted with each context client
 727 // Returns the block assigned to the specific zone. Never return NULL.
 728 void* _cmsContextGetClientChunk(cmsContext ContextID, _cmsMemoryClient mc)
 729 {
 730     struct _cmsContext_struct* ctx;
 731     void *ptr;
 732 
 733     if ((int) mc < 0 || mc >= MemoryClientMax) {
 734 
 735            cmsSignalError(ContextID, cmsERROR_INTERNAL, "Bad context client -- possible corruption");
 736 
 737            // This is catastrophic. Should never reach here
 738            _cmsAssert(0);
 739 
 740            // Reverts to global context
 741            return globalContext.chunks[UserPtr];


 790 
 791                     // Found!
 792                     return (cmsPluginMemHandler*) Plugin;
 793             }
 794     }
 795 
 796     // Nope, revert to defaults
 797     return NULL;
 798 }
 799 
 800 
 801 // Creates a new context with optional associated plug-ins. Caller may also specify an optional pointer to user-defined
 802 // data that will be forwarded to plug-ins and logger.
 803 cmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData)
 804 {
 805     struct _cmsContext_struct* ctx;
 806     struct _cmsContext_struct  fakeContext;
 807 
 808     // See the comments regarding locking in lcms2_internal.h
 809     // for an explanation of why we need the following code.
 810 #ifndef CMS_NO_PTHREADS
 811 #ifdef CMS_IS_WINDOWS_
 812 #ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT
 813     {
 814         static HANDLE _cmsWindowsInitMutex = NULL;
 815         static volatile HANDLE* mutex = &_cmsWindowsInitMutex;
 816 
 817         if (*mutex == NULL)
 818         {
 819             HANDLE p = CreateMutex(NULL, FALSE, NULL);
 820             if (p && InterlockedCompareExchangePointer((void **)mutex, (void*)p, NULL) != NULL)
 821                 CloseHandle(p);
 822         }
 823         if (*mutex == NULL || WaitForSingleObject(*mutex, INFINITE) == WAIT_FAILED)
 824             return NULL;
 825         if (((void **)&_cmsContextPoolHeadMutex)[0] == NULL)
 826             InitializeCriticalSection(&_cmsContextPoolHeadMutex);
 827         if (*mutex == NULL || !ReleaseMutex(*mutex))
 828             return NULL;
 829     }
 830 #endif
 831 #endif
 832 #endif
 833 
 834     _cmsInstallAllocFunctions(_cmsFindMemoryPlugin(Plugin), &fakeContext.DefaultMemoryManager);
 835 
 836     fakeContext.chunks[UserPtr]     = UserData;
 837     fakeContext.chunks[MemPlugin]   = &fakeContext.DefaultMemoryManager;
 838 
 839     // Create the context structure.
 840     ctx = (struct _cmsContext_struct*) _cmsMalloc(&fakeContext, sizeof(struct _cmsContext_struct));
 841     if (ctx == NULL)
 842         return NULL;     // Something very wrong happened!
 843 
 844     // Init the structure and the memory manager
 845     memset(ctx, 0, sizeof(struct _cmsContext_struct));
 846 
 847     // Keep memory manager
 848     memcpy(&ctx->DefaultMemoryManager, &fakeContext.DefaultMemoryManager, sizeof(_cmsMemPluginChunk));
 849 
 850     // Maintain the linked list (with proper locking)
 851     _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
 852        ctx ->Next = _cmsContextPoolHead;


 935     _cmsAllocTagTypePluginChunk(ctx, src);
 936     _cmsAllocMPETypePluginChunk(ctx, src);
 937     _cmsAllocTagPluginChunk(ctx, src);
 938     _cmsAllocIntentsPluginChunk(ctx, src);
 939     _cmsAllocOptimizationPluginChunk(ctx, src);
 940     _cmsAllocTransformPluginChunk(ctx, src);
 941     _cmsAllocMutexPluginChunk(ctx, src);
 942 
 943     // Make sure no one failed
 944     for (i=Logger; i < MemoryClientMax; i++) {
 945 
 946         if (src ->chunks[i] == NULL) {
 947             cmsDeleteContext((cmsContext) ctx);
 948             return NULL;
 949         }
 950     }
 951 
 952     return (cmsContext) ctx;
 953 }
 954 



















 955 
 956 // Frees any resources associated with the given context,
 957 // and destroys the context placeholder.
 958 // The ContextID can no longer be used in any THR operation.
 959 void CMSEXPORT cmsDeleteContext(cmsContext ContextID)
 960 {
 961     if (ContextID != NULL) {
 962 
 963         struct _cmsContext_struct* ctx = (struct _cmsContext_struct*) ContextID;
 964         struct _cmsContext_struct  fakeContext;
 965         struct _cmsContext_struct* prev;
 966 
 967         memcpy(&fakeContext.DefaultMemoryManager, &ctx->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
 968 
 969         fakeContext.chunks[UserPtr]     = ctx ->chunks[UserPtr];
 970         fakeContext.chunks[MemPlugin]   = &fakeContext.DefaultMemoryManager;
 971 
 972         // Get rid of plugins
 973         cmsUnregisterPluginsTHR(ContextID);
 974 


< prev index next >