summaryrefslogtreecommitdiff
path: root/thirdparty/liblcms2/src/cmsio0.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/liblcms2/src/cmsio0.c')
-rw-r--r--thirdparty/liblcms2/src/cmsio0.c66
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;
}