diff options
Diffstat (limited to 'thirdparty/liblcms2/src/cmsio0.c')
| -rw-r--r-- | thirdparty/liblcms2/src/cmsio0.c | 66 |
1 files changed, 57 insertions, 9 deletions
diff --git a/thirdparty/liblcms2/src/cmsio0.c b/thirdparty/liblcms2/src/cmsio0.c index 4449acd4..2084c7c4 100644 --- a/thirdparty/liblcms2/src/cmsio0.c +++ b/thirdparty/liblcms2/src/cmsio0.c @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2012 Marti Maria Saguer +// Copyright (c) 1998-2016 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -453,6 +453,14 @@ cmsBool CMSEXPORT cmsCloseIOhandler(cmsIOHANDLER* io) // ------------------------------------------------------------------------------------------------------- +cmsIOHANDLER* CMSEXPORT cmsGetProfileIOhandler(cmsHPROFILE hProfile) +{ + _cmsICCPROFILE* Icc = (_cmsICCPROFILE*)hProfile; + + if (Icc == NULL) return NULL; + return Icc->IOhandler; +} + // Creates an empty structure holding all required parameters cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext ContextID) { @@ -623,6 +631,32 @@ cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig) } + +// Enforces that the profile version is per. spec. +// Operates on the big endian bytes from the profile. +// Called before converting to platform endianness. +// Byte 0 is BCD major version, so max 9. +// Byte 1 is 2 BCD digits, one per nibble. +// Reserved bytes 2 & 3 must be 0. +static +cmsUInt32Number _validatedVersion(cmsUInt32Number DWord) +{ + cmsUInt8Number* pByte = (cmsUInt8Number*) &DWord; + cmsUInt8Number temp1; + cmsUInt8Number temp2; + + if (*pByte > 0x09) *pByte = (cmsUInt8Number) 0x09; + temp1 = *(pByte+1) & 0xf0; + temp2 = *(pByte+1) & 0x0f; + if (temp1 > 0x90) temp1 = 0x90; + if (temp2 > 0x09) temp2 = 0x09; + *(pByte+1) = (cmsUInt8Number)(temp1 | temp2); + *(pByte+2) = (cmsUInt8Number)0; + *(pByte+3) = (cmsUInt8Number)0; + + return DWord; +} + // Read profile header and validate it cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc) { @@ -657,7 +691,7 @@ cmsBool _cmsReadHeader(_cmsICCPROFILE* Icc) Icc -> creator = _cmsAdjustEndianess32(Header.creator); _cmsAdjustEndianess64(&Icc -> attributes, &Header.attributes); - Icc -> Version = _cmsAdjustEndianess32(Header.version); + Icc -> Version = _cmsAdjustEndianess32(_validatedVersion(Header.version)); // Get size as reported in header HeaderSize = _cmsAdjustEndianess32(Header.size); @@ -773,7 +807,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace) // Get true count for (i=0; i < Icc -> TagCount; i++) { - if (Icc ->TagNames[i] != 0) + if (Icc ->TagNames[i] != (cmsTagSignature) 0) Count++; } @@ -782,7 +816,7 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace) for (i=0; i < Icc -> TagCount; i++) { - if (Icc ->TagNames[i] == 0) continue; // It is just a placeholder + if (Icc ->TagNames[i] == (cmsTagSignature) 0) continue; // It is just a placeholder Tag.sig = (cmsTagSignature) _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagNames[i]); Tag.offset = _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagOffsets[i]); @@ -1132,7 +1166,7 @@ cmsBool SaveTags(_cmsICCPROFILE* Icc, _cmsICCPROFILE* FileOrig) for (i=0; i < Icc -> TagCount; i++) { - if (Icc ->TagNames[i] == 0) continue; + if (Icc ->TagNames[i] == (cmsTagSignature) 0) continue; // Linked tags are not written if (Icc ->TagLinked[i] != (cmsTagSignature) 0) continue; @@ -1265,12 +1299,16 @@ cmsUInt32Number CMSEXPORT cmsSaveProfileToIOhandler(cmsHPROFILE hProfile, cmsIOH cmsContext ContextID; _cmsAssert(hProfile != NULL); - + + if (!_cmsLockMutex(Icc->ContextID, Icc->UsrMutex)) return 0; memmove(&Keep, Icc, sizeof(_cmsICCPROFILE)); ContextID = cmsGetProfileContextID(hProfile); PrevIO = Icc ->IOhandler = cmsOpenIOhandlerFromNULL(ContextID); - if (PrevIO == NULL) return 0; + if (PrevIO == NULL) { + _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex); + return 0; + } // Pass #1 does compute offsets @@ -1290,7 +1328,10 @@ cmsUInt32Number CMSEXPORT cmsSaveProfileToIOhandler(cmsHPROFILE hProfile, cmsIOH } memmove(Icc, &Keep, sizeof(_cmsICCPROFILE)); - if (!cmsCloseIOhandler(PrevIO)) return 0; + if (!cmsCloseIOhandler(PrevIO)) + UsedSpace = 0; // As a error marker + + _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex); return UsedSpace; @@ -1298,6 +1339,8 @@ cmsUInt32Number CMSEXPORT cmsSaveProfileToIOhandler(cmsHPROFILE hProfile, cmsIOH Error: cmsCloseIOhandler(PrevIO); memmove(Icc, &Keep, sizeof(_cmsICCPROFILE)); + _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex); + return 0; } @@ -1794,7 +1837,7 @@ Error: // Similar to the anterior. This function allows to write directly to the ICC profile any data, without // checking anything. As a rule, mixing Raw with cooked doesn't work, so writting a tag as raw and then reading -// it as cooked without serializing does result into an error. If that is wha you want, you will need to dump +// it as cooked without serializing does result into an error. If that is what you want, you will need to dump // the profile to memry or disk and then reopen it. cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size) { @@ -1818,6 +1861,11 @@ cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, cons Icc ->TagSizes[i] = Size; _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex); + + if (Icc->TagPtrs[i] == NULL) { + Icc->TagNames[i] = (cmsTagSignature) 0; + return FALSE; + } return TRUE; } |
