- Disable single-column listviews when double-clicked, and provide a
[AROS.git] / workbench / libs / lcms2 / src / cmsplugin.c
blobc049aab734d9d1ebb87eefb94a64ee682b08f733
1 //---------------------------------------------------------------------------------
2 //
3 // Little Color Management System
4 // Copyright (c) 1998-2010 Marti Maria Saguer
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining
7 // a copy of this software and associated documentation files (the "Software"),
8 // to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 // and/or sell copies of the Software, and to permit persons to whom the Software
11 // is furnished to do so, subject to the following conditions:
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
18 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 //---------------------------------------------------------------------------------
27 #include "lcms2_internal.h"
30 // ----------------------------------------------------------------------------------
31 // Encoding & Decoding support functions
32 // ----------------------------------------------------------------------------------
34 // Little-Endian to Big-Endian
36 // Adjust a word value after being readed/ before being written from/to an ICC profile
37 cmsUInt16Number CMSEXPORT _cmsAdjustEndianess16(cmsUInt16Number Word)
39 #ifndef CMS_USE_BIG_ENDIAN
41 cmsUInt8Number* pByte = (cmsUInt8Number*) &Word;
42 cmsUInt8Number tmp;
44 tmp = pByte[0];
45 pByte[0] = pByte[1];
46 pByte[1] = tmp;
47 #endif
49 return Word;
53 // Transports to properly encoded values - note that icc profiles does use big endian notation.
55 // 1 2 3 4
56 // 4 3 2 1
58 cmsUInt32Number CMSEXPORT _cmsAdjustEndianess32(cmsUInt32Number DWord)
60 #ifndef CMS_USE_BIG_ENDIAN
62 cmsUInt8Number* pByte = (cmsUInt8Number*) &DWord;
63 cmsUInt8Number temp1;
64 cmsUInt8Number temp2;
66 temp1 = *pByte++;
67 temp2 = *pByte++;
68 *(pByte-1) = *pByte;
69 *pByte++ = temp2;
70 *(pByte-3) = *pByte;
71 *pByte = temp1;
72 #endif
73 return DWord;
76 // 1 2 3 4 5 6 7 8
77 // 8 7 6 5 4 3 2 1
79 void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord)
82 #ifndef CMS_USE_BIG_ENDIAN
84 cmsUInt8Number* pIn = (cmsUInt8Number*) QWord;
85 cmsUInt8Number* pOut = (cmsUInt8Number*) Result;
87 _cmsAssert(Result != NULL);
89 pOut[7] = pIn[0];
90 pOut[6] = pIn[1];
91 pOut[5] = pIn[2];
92 pOut[4] = pIn[3];
93 pOut[3] = pIn[4];
94 pOut[2] = pIn[5];
95 pOut[1] = pIn[6];
96 pOut[0] = pIn[7];
98 #else
99 _cmsAssert(Result != NULL);
101 # ifdef CMS_DONT_USE_INT64
102 (*Result)[0] = QWord[0];
103 (*Result)[1] = QWord[1];
104 # else
105 *Result = *QWord;
106 # endif
107 #endif
110 // Auxiliar -- read 8, 16 and 32-bit numbers
111 cmsBool CMSEXPORT _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n)
113 cmsUInt8Number tmp;
115 _cmsAssert(io != NULL);
117 if (io -> Read(io, &tmp, sizeof(cmsUInt8Number), 1) != 1)
118 return FALSE;
120 if (n != NULL) *n = tmp;
121 return TRUE;
124 cmsBool CMSEXPORT _cmsReadUInt16Number(cmsIOHANDLER* io, cmsUInt16Number* n)
126 cmsUInt16Number tmp;
128 _cmsAssert(io != NULL);
130 if (io -> Read(io, &tmp, sizeof(cmsUInt16Number), 1) != 1)
131 return FALSE;
133 if (n != NULL) *n = _cmsAdjustEndianess16(tmp);
134 return TRUE;
137 cmsBool CMSEXPORT _cmsReadUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, cmsUInt16Number* Array)
139 cmsUInt32Number i;
141 _cmsAssert(io != NULL);
143 for (i=0; i < n; i++) {
145 if (Array != NULL) {
146 if (!_cmsReadUInt16Number(io, Array + i)) return FALSE;
148 else {
149 if (!_cmsReadUInt16Number(io, NULL)) return FALSE;
153 return TRUE;
156 cmsBool CMSEXPORT _cmsReadUInt32Number(cmsIOHANDLER* io, cmsUInt32Number* n)
158 cmsUInt32Number tmp;
160 _cmsAssert(io != NULL);
162 if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
163 return FALSE;
165 if (n != NULL) *n = _cmsAdjustEndianess32(tmp);
166 return TRUE;
169 cmsBool CMSEXPORT _cmsReadFloat32Number(cmsIOHANDLER* io, cmsFloat32Number* n)
171 cmsUInt32Number tmp;
173 _cmsAssert(io != NULL);
175 if (io -> Read(io, &tmp, sizeof(cmsFloat32Number), 1) != 1)
176 return FALSE;
178 if (n != NULL) {
179 char *cp = (char *)&tmp;
180 tmp = _cmsAdjustEndianess32(tmp);
181 *n = *(cmsFloat32Number*)cp;
183 return TRUE;
187 cmsBool CMSEXPORT _cmsReadUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
189 cmsUInt64Number tmp;
191 _cmsAssert(io != NULL);
193 if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1)
194 return FALSE;
196 if (n != NULL) _cmsAdjustEndianess64(n, &tmp);
197 return TRUE;
201 cmsBool CMSEXPORT _cmsRead15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number* n)
203 cmsUInt32Number tmp;
205 _cmsAssert(io != NULL);
207 if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1)
208 return FALSE;
210 if (n != NULL) {
211 *n = _cms15Fixed16toDouble(_cmsAdjustEndianess32(tmp));
214 return TRUE;
218 // Jun-21-2000: Some profiles (those that comes with W2K) comes
219 // with the media white (media black?) x 100. Add a sanity check
221 static
222 void NormalizeXYZ(cmsCIEXYZ* Dest)
224 while (Dest -> X > 2. &&
225 Dest -> Y > 2. &&
226 Dest -> Z > 2.) {
228 Dest -> X /= 10.;
229 Dest -> Y /= 10.;
230 Dest -> Z /= 10.;
234 cmsBool CMSEXPORT _cmsReadXYZNumber(cmsIOHANDLER* io, cmsCIEXYZ* XYZ)
236 cmsEncodedXYZNumber xyz;
238 _cmsAssert(io != NULL);
240 if (io ->Read(io, &xyz, sizeof(cmsEncodedXYZNumber), 1) != 1) return FALSE;
242 if (XYZ != NULL) {
244 XYZ->X = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.X));
245 XYZ->Y = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Y));
246 XYZ->Z = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Z));
248 NormalizeXYZ(XYZ);
250 return TRUE;
253 cmsBool CMSEXPORT _cmsWriteUInt8Number(cmsIOHANDLER* io, cmsUInt8Number n)
255 _cmsAssert(io != NULL);
257 if (io -> Write(io, sizeof(cmsUInt8Number), &n) != 1)
258 return FALSE;
260 return TRUE;
263 cmsBool CMSEXPORT _cmsWriteUInt16Number(cmsIOHANDLER* io, cmsUInt16Number n)
265 cmsUInt16Number tmp;
267 _cmsAssert(io != NULL);
269 tmp = _cmsAdjustEndianess16(n);
270 if (io -> Write(io, sizeof(cmsUInt16Number), &tmp) != 1)
271 return FALSE;
273 return TRUE;
276 cmsBool CMSEXPORT _cmsWriteUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, const cmsUInt16Number* Array)
278 cmsUInt32Number i;
280 _cmsAssert(io != NULL);
281 _cmsAssert(Array != NULL);
283 for (i=0; i < n; i++) {
284 if (!_cmsWriteUInt16Number(io, Array[i])) return FALSE;
287 return TRUE;
290 cmsBool CMSEXPORT _cmsWriteUInt32Number(cmsIOHANDLER* io, cmsUInt32Number n)
292 cmsUInt32Number tmp;
294 _cmsAssert(io != NULL);
296 tmp = _cmsAdjustEndianess32(n);
297 if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
298 return FALSE;
300 return TRUE;
304 cmsBool CMSEXPORT _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n)
306 cmsUInt32Number tmp;
307 char *cp = (char *)&n;
309 _cmsAssert(io != NULL);
311 tmp = *(cmsUInt32Number*)cp;
312 tmp = _cmsAdjustEndianess32(tmp);
313 if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
314 return FALSE;
316 return TRUE;
319 cmsBool CMSEXPORT _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
321 cmsUInt64Number tmp;
323 _cmsAssert(io != NULL);
325 _cmsAdjustEndianess64(&tmp, n);
326 if (io -> Write(io, sizeof(cmsUInt64Number), &tmp) != 1)
327 return FALSE;
329 return TRUE;
332 cmsBool CMSEXPORT _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n)
334 cmsUInt32Number tmp;
336 _cmsAssert(io != NULL);
338 tmp = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(n));
339 if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1)
340 return FALSE;
342 return TRUE;
345 cmsBool CMSEXPORT _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ)
347 cmsEncodedXYZNumber xyz;
349 _cmsAssert(io != NULL);
350 _cmsAssert(XYZ != NULL);
352 xyz.X = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->X));
353 xyz.Y = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Y));
354 xyz.Z = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Z));
356 return io -> Write(io, sizeof(cmsEncodedXYZNumber), &xyz);
359 // from Fixed point 8.8 to double
360 cmsFloat64Number CMSEXPORT _cms8Fixed8toDouble(cmsUInt16Number fixed8)
362 cmsUInt8Number msb, lsb;
364 lsb = (cmsUInt8Number) (fixed8 & 0xff);
365 msb = (cmsUInt8Number) (((cmsUInt16Number) fixed8 >> 8) & 0xff);
367 return (cmsFloat64Number) ((cmsFloat64Number) msb + ((cmsFloat64Number) lsb / 256.0));
370 cmsUInt16Number CMSEXPORT _cmsDoubleTo8Fixed8(cmsFloat64Number val)
372 cmsS15Fixed16Number GammaFixed32 = _cmsDoubleTo15Fixed16(val);
373 return (cmsUInt16Number) ((GammaFixed32 >> 8) & 0xFFFF);
376 // from Fixed point 15.16 to double
377 cmsFloat64Number CMSEXPORT _cms15Fixed16toDouble(cmsS15Fixed16Number fix32)
379 cmsFloat64Number floater, sign, mid;
380 int Whole, FracPart;
382 sign = (fix32 < 0 ? -1 : 1);
383 fix32 = abs(fix32);
385 Whole = (cmsUInt16Number)(fix32 >> 16) & 0xffff;
386 FracPart = (cmsUInt16Number)(fix32 & 0xffff);
388 mid = (cmsFloat64Number) FracPart / 65536.0;
389 floater = (cmsFloat64Number) Whole + mid;
391 return sign * floater;
394 // from double to Fixed point 15.16
395 cmsS15Fixed16Number CMSEXPORT _cmsDoubleTo15Fixed16(cmsFloat64Number v)
397 return ((cmsS15Fixed16Number) floor((v)*65536.0 + 0.5));
400 // Date/Time functions
402 void CMSEXPORT _cmsDecodeDateTimeNumber(const cmsDateTimeNumber *Source, struct tm *Dest)
405 _cmsAssert(Dest != NULL);
406 _cmsAssert(Source != NULL);
408 Dest->tm_sec = _cmsAdjustEndianess16(Source->seconds);
409 Dest->tm_min = _cmsAdjustEndianess16(Source->minutes);
410 Dest->tm_hour = _cmsAdjustEndianess16(Source->hours);
411 Dest->tm_mday = _cmsAdjustEndianess16(Source->day);
412 Dest->tm_mon = _cmsAdjustEndianess16(Source->month) - 1;
413 Dest->tm_year = _cmsAdjustEndianess16(Source->year) - 1900;
414 Dest->tm_wday = -1;
415 Dest->tm_yday = -1;
416 Dest->tm_isdst = 0;
419 void CMSEXPORT _cmsEncodeDateTimeNumber(cmsDateTimeNumber *Dest, const struct tm *Source)
421 _cmsAssert(Dest != NULL);
422 _cmsAssert(Source != NULL);
424 Dest->seconds = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_sec);
425 Dest->minutes = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_min);
426 Dest->hours = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_hour);
427 Dest->day = _cmsAdjustEndianess16((cmsUInt16Number) Source->tm_mday);
428 Dest->month = _cmsAdjustEndianess16((cmsUInt16Number) (Source->tm_mon + 1));
429 Dest->year = _cmsAdjustEndianess16((cmsUInt16Number) (Source->tm_year + 1900));
432 // Read base and return type base
433 cmsTagTypeSignature CMSEXPORT _cmsReadTypeBase(cmsIOHANDLER* io)
435 _cmsTagBase Base;
437 _cmsAssert(io != NULL);
439 if (io -> Read(io, &Base, sizeof(_cmsTagBase), 1) != 1)
440 return (cmsTagTypeSignature) 0;
442 return (cmsTagTypeSignature) _cmsAdjustEndianess32(Base.sig);
445 // Setup base marker
446 cmsBool CMSEXPORT _cmsWriteTypeBase(cmsIOHANDLER* io, cmsTagTypeSignature sig)
448 _cmsTagBase Base;
450 _cmsAssert(io != NULL);
452 Base.sig = (cmsTagTypeSignature) _cmsAdjustEndianess32(sig);
453 memset(&Base.reserved, 0, sizeof(Base.reserved));
454 return io -> Write(io, sizeof(_cmsTagBase), &Base);
457 cmsBool CMSEXPORT _cmsReadAlignment(cmsIOHANDLER* io)
459 cmsUInt8Number Buffer[4];
460 cmsUInt32Number NextAligned, At;
461 cmsUInt32Number BytesToNextAlignedPos;
463 _cmsAssert(io != NULL);
465 At = io -> Tell(io);
466 NextAligned = _cmsALIGNLONG(At);
467 BytesToNextAlignedPos = NextAligned - At;
468 if (BytesToNextAlignedPos == 0) return TRUE;
469 if (BytesToNextAlignedPos > 4) return FALSE;
471 return (io ->Read(io, Buffer, BytesToNextAlignedPos, 1) == 1);
474 cmsBool CMSEXPORT _cmsWriteAlignment(cmsIOHANDLER* io)
476 cmsUInt8Number Buffer[4];
477 cmsUInt32Number NextAligned, At;
478 cmsUInt32Number BytesToNextAlignedPos;
480 _cmsAssert(io != NULL);
482 At = io -> Tell(io);
483 NextAligned = _cmsALIGNLONG(At);
484 BytesToNextAlignedPos = NextAligned - At;
485 if (BytesToNextAlignedPos == 0) return TRUE;
486 if (BytesToNextAlignedPos > 4) return FALSE;
488 memset(Buffer, 0, BytesToNextAlignedPos);
489 return io -> Write(io, BytesToNextAlignedPos, Buffer);
493 // To deal with text streams. 2K at most
494 cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
496 va_list args;
497 int len;
498 cmsUInt8Number Buffer[2048];
499 cmsBool rc;
501 _cmsAssert(io != NULL);
502 _cmsAssert(frm != NULL);
504 va_start(args, frm);
506 len = vsnprintf((char*) Buffer, 2047, frm, args);
507 if (len < 0) return FALSE; // Truncated, which is a fatal error for us
509 rc = io ->Write(io, len, Buffer);
511 va_end(args);
513 return rc;
517 // Plugin memory management -------------------------------------------------------------------------------------------------
519 static _cmsSubAllocator* PluginPool = NULL;
521 // Specialized malloc for plug-ins, that is freed upon exit.
522 void* _cmsPluginMalloc(cmsContext id, cmsUInt32Number size)
524 if (PluginPool == NULL)
525 PluginPool = _cmsCreateSubAlloc(id, 4*1024);
527 return _cmsSubAlloc(PluginPool, size);
531 // Main plug-in dispatcher
532 cmsBool CMSEXPORT cmsPlugin(void* Plug_in)
534 return cmsPluginTHR(NULL, Plug_in);
537 cmsBool CMSEXPORT cmsPluginTHR(cmsContext id, void* Plug_in)
539 cmsPluginBase* Plugin;
541 for (Plugin = (cmsPluginBase*) Plug_in;
542 Plugin != NULL;
543 Plugin = Plugin -> Next) {
545 if (Plugin -> Magic != cmsPluginMagicNumber) {
546 cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin");
547 return FALSE;
550 if (Plugin ->ExpectedVersion > LCMS_VERSION) {
551 cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current version is %d",
552 Plugin ->ExpectedVersion, LCMS_VERSION);
553 return FALSE;
556 switch (Plugin -> Type) {
558 case cmsPluginMemHandlerSig:
559 if (!_cmsRegisterMemHandlerPlugin(Plugin)) return FALSE;
560 break;
562 case cmsPluginInterpolationSig:
563 if (!_cmsRegisterInterpPlugin(Plugin)) return FALSE;
564 break;
566 case cmsPluginTagTypeSig:
567 if (!_cmsRegisterTagTypePlugin(id, Plugin)) return FALSE;
568 break;
570 case cmsPluginTagSig:
571 if (!_cmsRegisterTagPlugin(id, Plugin)) return FALSE;
572 break;
574 case cmsPluginFormattersSig:
575 if (!_cmsRegisterFormattersPlugin(id, Plugin)) return FALSE;
576 break;
578 case cmsPluginRenderingIntentSig:
579 if (!_cmsRegisterRenderingIntentPlugin(id, Plugin)) return FALSE;
580 break;
582 case cmsPluginParametricCurveSig:
583 if (!_cmsRegisterParametricCurvesPlugin(id, Plugin)) return FALSE;
584 break;
586 case cmsPluginMultiProcessElementSig:
587 if (!_cmsRegisterMultiProcessElementPlugin(id, Plugin)) return FALSE;
588 break;
590 case cmsPluginOptimizationSig:
591 if (!_cmsRegisterOptimizationPlugin(id, Plugin)) return FALSE;
592 break;
594 case cmsPluginTransformSig:
595 if (!_cmsRegisterTransformPlugin(id, Plugin)) return FALSE;
596 break;
598 default:
599 cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
600 return FALSE;
604 // Keep a reference to the plug-in
605 return TRUE;
609 // Revert all plug-ins to default
610 void CMSEXPORT cmsUnregisterPlugins(void)
612 _cmsRegisterMemHandlerPlugin(NULL);
613 _cmsRegisterInterpPlugin(NULL);
614 _cmsRegisterTagTypePlugin(NULL, NULL);
615 _cmsRegisterTagPlugin(NULL, NULL);
616 _cmsRegisterFormattersPlugin(NULL, NULL);
617 _cmsRegisterRenderingIntentPlugin(NULL, NULL);
618 _cmsRegisterParametricCurvesPlugin(NULL, NULL);
619 _cmsRegisterMultiProcessElementPlugin(NULL, NULL);
620 _cmsRegisterOptimizationPlugin(NULL, NULL);
621 _cmsRegisterTransformPlugin(NULL, NULL);
623 if (PluginPool != NULL)
624 _cmsSubAllocDestroy(PluginPool);
626 PluginPool = NULL;