1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------------
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//  Little Color Management System
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//  Copyright (c) 1998-2010 Marti Maria Saguer
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Permission is hereby granted, free of charge, to any person obtaining
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// a copy of this software and associated documentation files (the "Software"),
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// to deal in the Software without restriction, including without limitation
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// the rights to use, copy, modify, merge, publish, distribute, sublicense,
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// and/or sell copies of the Software, and to permit persons to whom the Software
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// is furnished to do so, subject to the following conditions:
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The above copyright notice and this permission notice shall be included in
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// all copies or substantial portions of the Software.
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------------
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "lcms2_internal.h"
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ----------------------------------------------------------------------------------
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Encoding & Decoding support functions
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// ----------------------------------------------------------------------------------
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//      Little-Endian to Big-Endian
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Adjust a word value after being readed/ before being written from/to an ICC profile
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsUInt16Number CMSEXPORT  _cmsAdjustEndianess16(cmsUInt16Number Word)
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef CMS_USE_BIG_ENDIAN
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt8Number* pByte = (cmsUInt8Number*) &Word;
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt8Number tmp;
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    tmp = pByte[0];
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pByte[0] = pByte[1];
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pByte[1] = tmp;
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return Word;
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Transports to properly encoded values - note that icc profiles does use big endian notation.
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 1 2 3 4
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 4 3 2 1
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsUInt32Number CMSEXPORT  _cmsAdjustEndianess32(cmsUInt32Number DWord)
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef CMS_USE_BIG_ENDIAN
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt8Number* pByte = (cmsUInt8Number*) &DWord;
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt8Number temp1;
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt8Number temp2;
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    temp1 = *pByte++;
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    temp2 = *pByte++;
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *(pByte-1) = *pByte;
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *pByte++ = temp2;
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *(pByte-3) = *pByte;
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *pByte = temp1;
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return DWord;
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 1 2 3 4 5 6 7 8
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 8 7 6 5 4 3 2 1
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT  _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord)
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef CMS_USE_BIG_ENDIAN
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt8Number* pIn  = (cmsUInt8Number*) QWord;
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt8Number* pOut = (cmsUInt8Number*) Result;
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(Result != NULL);
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pOut[7] = pIn[0];
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pOut[6] = pIn[1];
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pOut[5] = pIn[2];
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pOut[4] = pIn[3];
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pOut[3] = pIn[4];
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pOut[2] = pIn[5];
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pOut[1] = pIn[6];
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pOut[0] = pIn[7];
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(Result != NULL);
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#  ifdef CMS_DONT_USE_INT64
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (*Result)[0] = QWord[0];
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (*Result)[1] = QWord[1];
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#  else
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *Result = *QWord;
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#  endif
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Auxiliar -- read 8, 16 and 32-bit numbers
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n)
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt8Number tmp;
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io -> Read(io, &tmp, sizeof(cmsUInt8Number), 1) != 1)
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (n != NULL) *n = tmp;
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsReadUInt16Number(cmsIOHANDLER* io, cmsUInt16Number* n)
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt16Number tmp;
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io -> Read(io, &tmp, sizeof(cmsUInt16Number), 1) != 1)
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (n != NULL) *n = _cmsAdjustEndianess16(tmp);
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsReadUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, cmsUInt16Number* Array)
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number i;
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i=0; i < n; i++) {
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (Array != NULL) {
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!_cmsReadUInt16Number(io, Array + i)) return FALSE;
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else {
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!_cmsReadUInt16Number(io, NULL)) return FALSE;
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsReadUInt32Number(cmsIOHANDLER* io, cmsUInt32Number* n)
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number tmp;
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (n != NULL) *n = _cmsAdjustEndianess32(tmp);
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n)
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number tmp;
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io -> Read(io, &tmp, sizeof(cmsFloat32Number), 1) != 1)
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (n != NULL) {
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        tmp = _cmsAdjustEndianess32(tmp);
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *n = *(cmsFloat32Number*) &tmp;
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT   _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt64Number tmp;
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1)
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (n != NULL) _cmsAdjustEndianess64(n, &tmp);
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n)
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number tmp;
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (n != NULL) {
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *n = _cms15Fixed16toDouble(_cmsAdjustEndianess32(tmp));
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Jun-21-2000: Some profiles (those that comes with W2K) comes
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// with the media white (media black?) x 100. Add a sanity check
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid NormalizeXYZ(cmsCIEXYZ* Dest)
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (Dest -> X > 2. &&
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov           Dest -> Y > 2. &&
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov           Dest -> Z > 2.) {
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               Dest -> X /= 10.;
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               Dest -> Y /= 10.;
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               Dest -> Z /= 10.;
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       }
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ)
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsEncodedXYZNumber xyz;
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io ->Read(io, &xyz, sizeof(cmsEncodedXYZNumber), 1) != 1) return FALSE;
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (XYZ != NULL) {
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        XYZ->X = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.X));
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        XYZ->Y = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Y));
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        XYZ->Z = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Z));
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        NormalizeXYZ(XYZ);
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsWriteUInt8Number(cmsIOHANDLER* io, cmsUInt8Number n)
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io -> Write(io, sizeof(cmsUInt8Number), &n) != 1)
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsWriteUInt16Number(cmsIOHANDLER* io, cmsUInt16Number n)
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt16Number tmp;
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    tmp = _cmsAdjustEndianess16(n);
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io -> Write(io, sizeof(cmsUInt16Number), &tmp) != 1)
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsWriteUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, const cmsUInt16Number* Array)
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number i;
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(Array != NULL);
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i=0; i < n; i++) {
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!_cmsWriteUInt16Number(io, Array[i])) return FALSE;
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsWriteUInt32Number(cmsIOHANDLER* io, cmsUInt32Number n)
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number tmp;
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    tmp = _cmsAdjustEndianess32(n);
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n)
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number tmp;
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    tmp = *(cmsUInt32Number*) &n;
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    tmp = _cmsAdjustEndianess32(tmp);
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt64Number tmp;
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAdjustEndianess64(&tmp, n);
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io -> Write(io, sizeof(cmsUInt64Number), &tmp) != 1)
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n)
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number tmp;
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    tmp = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(n));
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT  _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ)
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsEncodedXYZNumber xyz;
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(XYZ != NULL);
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    xyz.X = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->X));
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    xyz.Y = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Y));
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    xyz.Z = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Z));
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return io -> Write(io,  sizeof(cmsEncodedXYZNumber), &xyz);
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// from Fixed point 8.8 to double
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsFloat64Number CMSEXPORT _cms8Fixed8toDouble(cmsUInt16Number fixed8)
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       cmsUInt8Number  msb, lsb;
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       lsb = (cmsUInt8Number) (fixed8 & 0xff);
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       msb = (cmsUInt8Number) (((cmsUInt16Number) fixed8 >> 8) & 0xff);
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       return (cmsFloat64Number) ((cmsFloat64Number) msb + ((cmsFloat64Number) lsb / 256.0));
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsUInt16Number CMSEXPORT _cmsDoubleTo8Fixed8(cmsFloat64Number val)
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsS15Fixed16Number GammaFixed32 = _cmsDoubleTo15Fixed16(val);
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return  (cmsUInt16Number) ((GammaFixed32 >> 8) & 0xFFFF);
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// from Fixed point 15.16 to double
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsFloat64Number CMSEXPORT _cms15Fixed16toDouble(cmsS15Fixed16Number fix32)
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsFloat64Number floater, sign, mid;
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int Whole, FracPart;
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    sign  = (fix32 < 0 ? -1 : 1);
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    fix32 = abs(fix32);
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Whole     = (cmsUInt16Number)(fix32 >> 16) & 0xffff;
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FracPart  = (cmsUInt16Number)(fix32 & 0xffff);
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    mid     = (cmsFloat64Number) FracPart / 65536.0;
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    floater = (cmsFloat64Number) Whole + mid;
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return sign * floater;
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// from double to Fixed point 15.16
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsS15Fixed16Number CMSEXPORT _cmsDoubleTo15Fixed16(cmsFloat64Number v)
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ((cmsS15Fixed16Number) floor((v)*65536.0 + 0.5));
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Date/Time functions
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT _cmsDecodeDateTimeNumber(const cmsDateTimeNumber *Source, struct tm *Dest)
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(Dest != NULL);
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(Source != NULL);
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->tm_sec   = _cmsAdjustEndianess16(Source->seconds);
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->tm_min   = _cmsAdjustEndianess16(Source->minutes);
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->tm_hour  = _cmsAdjustEndianess16(Source->hours);
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->tm_mday  = _cmsAdjustEndianess16(Source->day);
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->tm_mon   = _cmsAdjustEndianess16(Source->month) - 1;
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->tm_year  = _cmsAdjustEndianess16(Source->year) - 1900;
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->tm_wday  = -1;
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->tm_yday  = -1;
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->tm_isdst = 0;
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT _cmsEncodeDateTimeNumber(cmsDateTimeNumber *Dest, const struct tm *Source)
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(Dest != NULL);
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(Source != NULL);
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->seconds = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_sec);
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->minutes = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_min);
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->hours   = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_hour);
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->day     = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_mday);
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->month   = _cmsAdjustEndianess16((cmsUInt16Number) (Source->tm_mon + 1));
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Dest->year    = _cmsAdjustEndianess16((cmsUInt16Number) (Source->tm_year + 1900));
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Read base and return type base
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsTagTypeSignature CMSEXPORT _cmsReadTypeBase(cmsIOHANDLER* io)
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsTagBase Base;
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (io -> Read(io, &Base, sizeof(_cmsTagBase), 1) != 1)
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return (cmsTagTypeSignature) 0;
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (cmsTagTypeSignature) _cmsAdjustEndianess32(Base.sig);
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Setup base marker
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool  CMSEXPORT _cmsWriteTypeBase(cmsIOHANDLER* io, cmsTagTypeSignature sig)
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsTagBase  Base;
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Base.sig = (cmsTagTypeSignature) _cmsAdjustEndianess32(sig);
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    memset(&Base.reserved, 0, sizeof(Base.reserved));
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return io -> Write(io, sizeof(_cmsTagBase), &Base);
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT _cmsReadAlignment(cmsIOHANDLER* io)
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt8Number  Buffer[4];
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number NextAligned, At;
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number BytesToNextAlignedPos;
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    At = io -> Tell(io);
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    NextAligned = _cmsALIGNLONG(At);
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    BytesToNextAlignedPos = NextAligned - At;
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (BytesToNextAlignedPos == 0) return TRUE;
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (BytesToNextAlignedPos > 4)  return FALSE;
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (io ->Read(io, Buffer, BytesToNextAlignedPos, 1) == 1);
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT _cmsWriteAlignment(cmsIOHANDLER* io)
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt8Number  Buffer[4];
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number NextAligned, At;
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt32Number BytesToNextAlignedPos;
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    At = io -> Tell(io);
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    NextAligned = _cmsALIGNLONG(At);
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    BytesToNextAlignedPos = NextAligned - At;
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (BytesToNextAlignedPos == 0) return TRUE;
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (BytesToNextAlignedPos > 4)  return FALSE;
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    memset(Buffer, 0, BytesToNextAlignedPos);
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return io -> Write(io, BytesToNextAlignedPos, Buffer);
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// To deal with text streams. 2K at most
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    va_list args;
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int len;
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUInt8Number Buffer[2048];
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsBool rc;
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(io != NULL);
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAssert(frm != NULL);
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    va_start(args, frm);
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    len = vsnprintf((char*) Buffer, 2047, frm, args);
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (len < 0) return FALSE;   // Truncated, which is a fatal error for us
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rc = io ->Write(io, len, Buffer);
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    va_end(args);
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return rc;
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Plugin memory management -------------------------------------------------------------------------------------------------
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Specialized malloc for plug-ins, that is freed upon exit.
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* _cmsPluginMalloc(cmsContext ContextID, cmsUInt32Number size)
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct _cmsContext_struct* ctx = _cmsGetContext(ContextID);
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ctx ->MemPool == NULL) {
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (ContextID == NULL) {
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ctx->MemPool = _cmsCreateSubAlloc(0, 2*1024);
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else {
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            cmsSignalError(ContextID, cmsERROR_CORRUPTION_DETECTED, "NULL memory pool on context");
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return NULL;
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return _cmsSubAlloc(ctx->MemPool, size);
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Main plug-in dispatcher
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsPlugin(void* Plug_in)
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return cmsPluginTHR(NULL, Plug_in);
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsBool CMSEXPORT cmsPluginTHR(cmsContext id, void* Plug_in)
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsPluginBase* Plugin;
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (Plugin = (cmsPluginBase*) Plug_in;
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         Plugin != NULL;
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         Plugin = Plugin -> Next) {
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (Plugin -> Magic != cmsPluginMagicNumber) {
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin");
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (Plugin ->ExpectedVersion > LCMS_VERSION) {
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current version is %d",
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    Plugin ->ExpectedVersion, LCMS_VERSION);
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            switch (Plugin -> Type) {
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case cmsPluginMemHandlerSig:
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!_cmsRegisterMemHandlerPlugin(id, Plugin)) return FALSE;
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case cmsPluginInterpolationSig:
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!_cmsRegisterInterpPlugin(id, Plugin)) return FALSE;
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case cmsPluginTagTypeSig:
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!_cmsRegisterTagTypePlugin(id, Plugin)) return FALSE;
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case cmsPluginTagSig:
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!_cmsRegisterTagPlugin(id, Plugin)) return FALSE;
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case cmsPluginFormattersSig:
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!_cmsRegisterFormattersPlugin(id, Plugin)) return FALSE;
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case cmsPluginRenderingIntentSig:
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!_cmsRegisterRenderingIntentPlugin(id, Plugin)) return FALSE;
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case cmsPluginParametricCurveSig:
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!_cmsRegisterParametricCurvesPlugin(id, Plugin)) return FALSE;
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case cmsPluginMultiProcessElementSig:
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!_cmsRegisterMultiProcessElementPlugin(id, Plugin)) return FALSE;
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case cmsPluginOptimizationSig:
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!_cmsRegisterOptimizationPlugin(id, Plugin)) return FALSE;
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case cmsPluginTransformSig:
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!_cmsRegisterTransformPlugin(id, Plugin)) return FALSE;
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                case cmsPluginMutexSig:
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!_cmsRegisterMutexPlugin(id, Plugin)) return FALSE;
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                default:
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    cmsSignalError(id, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return FALSE;
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Keep a reference to the plug-in
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Revert all plug-ins to default
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT cmsUnregisterPlugins(void)
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsUnregisterPluginsTHR(NULL);
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The Global storage for system context. This is the one and only global variable
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// pointers structure. All global vars are referenced here.
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic struct _cmsContext_struct globalContext = {
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    NULL,                              // Not in the linked list
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    NULL,                              // No suballocator
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        NULL,                          //  UserPtr,
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsLogErrorChunk,            //  Logger,
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsAlarmCodesChunk,          //  AlarmCodes,
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsAdaptationStateChunk,     //  AdaptationState,
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsMemPluginChunk,           //  MemPlugin,
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsInterpPluginChunk,        //  InterpPlugin,
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsCurvesPluginChunk,        //  CurvesPlugin,
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsFormattersPluginChunk,    //  FormattersPlugin,
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsTagTypePluginChunk,       //  TagTypePlugin,
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsTagPluginChunk,           //  TagPlugin,
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsIntentsPluginChunk,       //  IntentPlugin,
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsMPETypePluginChunk,       //  MPEPlugin,
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsOptimizationPluginChunk,  //  OptimizationPlugin,
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsTransformPluginChunk,     //  TransformPlugin,
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        &_cmsMutexPluginChunk          //  MutexPlugin
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    },
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { NULL, NULL, NULL, NULL, NULL, NULL } // The default memory allocator is not used for context 0
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The context pool (linked list head)
657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic _cmsMutex _cmsContextPoolHeadMutex = CMS_MUTEX_INITIALIZER;
658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic struct _cmsContext_struct* _cmsContextPoolHead = NULL;
659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Internal, get associated pointer, with guessing. Never returns NULL.
661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstruct _cmsContext_struct* _cmsGetContext(cmsContext ContextID)
662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct _cmsContext_struct* id = (struct _cmsContext_struct*) ContextID;
664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct _cmsContext_struct* ctx;
665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // On 0, use global settings
668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (id == NULL)
669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return &globalContext;
670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Search
672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (ctx = _cmsContextPoolHead;
673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         ctx != NULL;
674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         ctx = ctx ->Next) {
675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            // Found it?
677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (id == ctx)
678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return ctx; // New-style context,
679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return &globalContext;
682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Internal: get the memory area associanted with each context client
686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Returns the block assigned to the specific zone.
687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* _cmsContextGetClientChunk(cmsContext ContextID, _cmsMemoryClient mc)
688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct _cmsContext_struct* ctx;
690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void *ptr;
691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (mc >= MemoryClientMax) {
693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsSignalError(ContextID, cmsERROR_RANGE, "Bad context client");
694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ctx = _cmsGetContext(ContextID);
698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ptr = ctx ->chunks[mc];
699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ptr != NULL)
701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return ptr;
702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // A null ptr means no special settings for that context, and this
704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // reverts to Context0 globals
705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return globalContext.chunks[mc];
706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This function returns the given context its default pristine state,
710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// as no plug-ins were declared. There is no way to unregister a single
711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// plug-in, as a single call to cmsPluginTHR() function may register
712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// many different plug-ins simultaneously, then there is no way to
713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// identify which plug-in to unregister.
714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT cmsUnregisterPluginsTHR(cmsContext ContextID)
715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsRegisterMemHandlerPlugin(ContextID, NULL);
717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsRegisterInterpPlugin(ContextID, NULL);
718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsRegisterTagTypePlugin(ContextID, NULL);
719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsRegisterTagPlugin(ContextID, NULL);
720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsRegisterFormattersPlugin(ContextID, NULL);
721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsRegisterRenderingIntentPlugin(ContextID, NULL);
722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsRegisterParametricCurvesPlugin(ContextID, NULL);
723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsRegisterMultiProcessElementPlugin(ContextID, NULL);
724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsRegisterOptimizationPlugin(ContextID, NULL);
725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsRegisterTransformPlugin(ContextID, NULL);
726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsRegisterMutexPlugin(ContextID, NULL);
727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Returns the memory manager plug-in, if any, from the Plug-in bundle
731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
732ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsPluginMemHandler* _cmsFindMemoryPlugin(void* PluginBundle)
733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    cmsPluginBase* Plugin;
735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (Plugin = (cmsPluginBase*) PluginBundle;
737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Plugin != NULL;
738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Plugin = Plugin -> Next) {
739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (Plugin -> Magic == cmsPluginMagicNumber &&
741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                Plugin -> ExpectedVersion <= LCMS_VERSION &&
742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                Plugin -> Type == cmsPluginMemHandlerSig) {
743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    // Found!
745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return (cmsPluginMemHandler*) Plugin;
746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Nope, revert to defaults
750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return NULL;
751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Creates a new context with optional associated plug-ins. Caller may also specify an optional pointer to user-defined
755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// data that will be forwarded to plug-ins and logger.
756ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsContext CMSEXPORT cmsCreateContext(void* Plugin, void* UserData)
757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct _cmsContext_struct* ctx;
759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct _cmsContext_struct  fakeContext;
760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsInstallAllocFunctions(_cmsFindMemoryPlugin(Plugin), &fakeContext.DefaultMemoryManager);
762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    fakeContext.chunks[UserPtr]     = UserData;
764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    fakeContext.chunks[MemPlugin]   = &fakeContext.DefaultMemoryManager;
765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Create the context structure.
767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ctx = (struct _cmsContext_struct*) _cmsMalloc(&fakeContext, sizeof(struct _cmsContext_struct));
768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ctx == NULL)
769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;     // Something very wrong happened!
770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Init the structure and the memory manager
772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    memset(ctx, 0, sizeof(struct _cmsContext_struct));
773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Keep memory manager
775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    memcpy(&ctx->DefaultMemoryManager, &fakeContext.DefaultMemoryManager, sizeof(_cmsMemPluginChunk));
776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Maintain the linked list (with proper locking)
778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       ctx ->Next = _cmsContextPoolHead;
780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       _cmsContextPoolHead = ctx;
781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ctx ->chunks[UserPtr]     = UserData;
784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ctx ->chunks[MemPlugin]   = &ctx->DefaultMemoryManager;
785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Now we can allocate the pool by using default memory manager
787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*));  // default size about 32 pointers
788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ctx ->MemPool == NULL) {
789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         cmsDeleteContext(ctx);
791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocLogErrorChunk(ctx, NULL);
795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocAlarmCodesChunk(ctx, NULL);
796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocAdaptationStateChunk(ctx, NULL);
797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocMemPluginChunk(ctx, NULL);
798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocInterpPluginChunk(ctx, NULL);
799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocCurvesPluginChunk(ctx, NULL);
800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocFormattersPluginChunk(ctx, NULL);
801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocTagTypePluginChunk(ctx, NULL);
802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocMPETypePluginChunk(ctx, NULL);
803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocTagPluginChunk(ctx, NULL);
804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocIntentsPluginChunk(ctx, NULL);
805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocOptimizationPluginChunk(ctx, NULL);
806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocTransformPluginChunk(ctx, NULL);
807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocMutexPluginChunk(ctx, NULL);
808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Setup the plug-ins
810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!cmsPluginTHR(ctx, Plugin)) {
811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsDeleteContext(ctx);
813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (cmsContext) ctx;
817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Duplicates a context with all associated plug-ins.
820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Caller may specify an optional pointer to user-defined
821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// data that will be forwarded to plug-ins and logger.
822ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovcmsContext CMSEXPORT cmsDupContext(cmsContext ContextID, void* NewUserData)
823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct _cmsContext_struct* ctx;
826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const struct _cmsContext_struct* src = _cmsGetContext(ContextID);
827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void* userData = (NewUserData != NULL) ? NewUserData : src -> chunks[UserPtr];
829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ctx = (struct _cmsContext_struct*) _cmsMalloc(ContextID, sizeof(struct _cmsContext_struct));
832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ctx == NULL)
833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;     // Something very wrong happened
834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Setup default memory allocators
836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    memcpy(&ctx->DefaultMemoryManager, &src->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Maintain the linked list
839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       ctx ->Next = _cmsContextPoolHead;
841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       _cmsContextPoolHead = ctx;
842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ctx ->chunks[UserPtr]    = userData;
845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ctx ->chunks[MemPlugin]  = &ctx->DefaultMemoryManager;
846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*));
848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ctx ->MemPool == NULL) {
849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov         cmsDeleteContext(ctx);
851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Allocate all required chunks.
855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocLogErrorChunk(ctx, src);
856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocAlarmCodesChunk(ctx, src);
857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocAdaptationStateChunk(ctx, src);
858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocMemPluginChunk(ctx, src);
859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocInterpPluginChunk(ctx, src);
860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocCurvesPluginChunk(ctx, src);
861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocFormattersPluginChunk(ctx, src);
862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocTagTypePluginChunk(ctx, src);
863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocMPETypePluginChunk(ctx, src);
864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocTagPluginChunk(ctx, src);
865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocIntentsPluginChunk(ctx, src);
866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocOptimizationPluginChunk(ctx, src);
867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocTransformPluginChunk(ctx, src);
868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _cmsAllocMutexPluginChunk(ctx, src);
869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Make sure no one failed
871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i=Logger; i < MemoryClientMax; i++) {
872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (src ->chunks[i] == NULL) {
874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            cmsDeleteContext((cmsContext) ctx);
875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return NULL;
876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (cmsContext) ctx;
880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic
885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstruct _cmsContext_struct* FindPrev(struct _cmsContext_struct* id)
886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct _cmsContext_struct* prev;
888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Search for previous
890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (prev = _cmsContextPoolHead;
891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov             prev != NULL;
892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov             prev = prev ->Next)
893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (prev ->Next == id)
895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return prev;
896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return NULL;  // List is empty or only one element!
899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Frees any resources associated with the given context,
902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// and destroys the context placeholder.
903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// The ContextID can no longer be used in any THR operation.
904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CMSEXPORT cmsDeleteContext(cmsContext ContextID)
905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ContextID != NULL) {
907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        struct _cmsContext_struct* ctx = (struct _cmsContext_struct*) ContextID;
909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        struct _cmsContext_struct  fakeContext;
910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        struct _cmsContext_struct* prev;
911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        memcpy(&fakeContext.DefaultMemoryManager, &ctx->DefaultMemoryManager, sizeof(ctx->DefaultMemoryManager));
913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        fakeContext.chunks[UserPtr]     = ctx ->chunks[UserPtr];
915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        fakeContext.chunks[MemPlugin]   = &fakeContext.DefaultMemoryManager;
916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // Get rid of plugins
918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmsUnregisterPluginsTHR(ContextID);
919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // Since all memory is allocated in the private pool, all what we need to do is destroy the pool
921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (ctx -> MemPool != NULL)
922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov              _cmsSubAllocDestroy(ctx ->MemPool);
923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ctx -> MemPool = NULL;
924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // Maintain list
926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _cmsEnterCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (_cmsContextPoolHead == ctx) {
928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _cmsContextPoolHead = ctx->Next;
930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else {
932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            // Search for previous
934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (prev = _cmsContextPoolHead;
935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                prev != NULL;
936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                prev = prev ->Next)
937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            {
938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (prev -> Next == ctx) {
939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    prev -> Next = ctx ->Next;
940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _cmsLeaveCriticalSectionPrimitive(&_cmsContextPoolHeadMutex);
945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        // free the memory block itself
947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _cmsFree(&fakeContext, ctx);
948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Returns the user data associated to the given ContextID, or NULL if no user data was attached on context creation
952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* CMSEXPORT cmsGetContextUserData(cmsContext ContextID)
953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return _cmsContextGetClientChunk(ContextID, UserPtr);
955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
956