diff options
Diffstat (limited to 'third_party/lcms/src/cmstypes.c')
-rw-r--r-- | third_party/lcms/src/cmstypes.c | 90 |
1 files changed, 48 insertions, 42 deletions
diff --git a/third_party/lcms/src/cmstypes.c b/third_party/lcms/src/cmstypes.c index 29806fb194..8b02f86ca5 100644 --- a/third_party/lcms/src/cmstypes.c +++ b/third_party/lcms/src/cmstypes.c @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2014 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"), @@ -30,7 +30,7 @@ // This file implements every single tag and tag type as described in the ICC spec. Some types // have been deprecated, like ncl and Data. There is no implementation for those types as there // are no profiles holding them. The programmer can also extend this list by defining his own types -// by using the appropiate plug-in. There are three types of plug ins regarding that. First type +// by using the appropriate plug-in. There are three types of plug ins regarding that. First type // allows to define new tags using any existing type. Next plug-in type allows to define new types // and the third one is very specific: allows to extend the number of elements in the multiprocessing // elements special type. @@ -113,7 +113,7 @@ cmsTagTypeHandler* GetHandler(cmsTagTypeSignature sig, _cmsTagTypeLinkedList* Pl } -// Auxiliar to convert UTF-32 to UTF-16 in some cases +// Auxiliary to convert UTF-32 to UTF-16 in some cases static cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t* Array) { @@ -129,7 +129,7 @@ cmsBool _cmsWriteWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, const wchar_t* return TRUE; } -// Auxiliar to read an array of wchar_t +// Auxiliary to read an array of wchar_t static cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array) { @@ -160,7 +160,7 @@ typedef cmsBool (* PositionTableEntryFn)(struct _cms_typehandler_struct* self, cmsUInt32Number n, cmsUInt32Number SizeOfTag); -// Helper function to deal with position tables as decribed in ICC spec 4.3 +// Helper function to deal with position tables as described in ICC spec 4.3 // A table of n elements is readed, where first comes n records containing offsets and sizes and // then a block containing the data itself. This allows to reuse same data in more than one entry static @@ -957,7 +957,7 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO cmsMLU* mlu = (cmsMLU*) Ptr; char *Text = NULL; wchar_t *Wide = NULL; - cmsUInt32Number len, len_aligned, len_filler_alignment; + cmsUInt32Number len, len_text, len_tag_requirement, len_aligned; cmsBool rc = FALSE; char Filler[68]; @@ -967,17 +967,18 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO // Get the len of string len = cmsMLUgetASCII(mlu, cmsNoLanguage, cmsNoCountry, NULL, 0); - // From ICC3.4: It has been found that textDescriptionType can contain misaligned data + // Specification ICC.1:2001-04 (v2.4.0): It has been found that textDescriptionType can contain misaligned data //(see clause 4.1 for the definition of 'aligned'. Because the Unicode language // code and Unicode count immediately follow the ASCII description, their // alignment is not correct if the ASCII count is not a multiple of four. The // ScriptCode code is misaligned when the ASCII count is odd. Profile reading and // writing software must be written carefully in order to handle these alignment // problems. - - // Compute an aligned size - len_aligned = _cmsALIGNLONG(len); - len_filler_alignment = len_aligned - len; + // + // The above last sentence suggest to handle alignment issues in the + // parser. The provided example (Table 69 on Page 60) makes this clear. + // The padding only in the ASCII count is not sufficient for a aligned tag + // size, with the same text size in ASCII and Unicode. // Null strings if (len <= 0) { @@ -998,6 +999,12 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO cmsMLUgetWide(mlu, cmsNoLanguage, cmsNoCountry, Wide, len * sizeof(wchar_t)); } + // Tell the real text len including the null terminator and padding + len_text = (cmsUInt32Number) strlen(Text) + 1; + // Compute an total tag size requirement + len_tag_requirement = (8+4+len_text+4+4+2*len_text+2+1+67); + len_aligned = _cmsALIGNLONG(len_tag_requirement); + // * cmsUInt32Number count; * Description length // * cmsInt8Number desc[count] * NULL terminated ascii string // * cmsUInt32Number ucLangCode; * UniCode language code @@ -1007,20 +1014,14 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO // * cmsUInt8Number scCount; * ScriptCode count // * cmsInt8Number scDesc[67]; * ScriptCode Description - if (!_cmsWriteUInt32Number(io, len_aligned)) goto Error; - if (!io ->Write(io, len, Text)) goto Error; - if (!io ->Write(io, len_filler_alignment, Filler)) goto Error; + if (!_cmsWriteUInt32Number(io, len_text)) goto Error; + if (!io ->Write(io, len_text, Text)) goto Error; if (!_cmsWriteUInt32Number(io, 0)) goto Error; // ucLanguageCode - // This part is tricky: we need an aligned tag size, and the ScriptCode part - // takes 70 bytes, so we need 2 extra bytes to do the alignment - - if (!_cmsWriteUInt32Number(io, len_aligned+1)) goto Error; - + if (!_cmsWriteUInt32Number(io, len_text)) goto Error; // Note that in some compilers sizeof(cmsUInt16Number) != sizeof(wchar_t) - if (!_cmsWriteWCharArray(io, len, Wide)) goto Error; - if (!_cmsWriteUInt16Array(io, len_filler_alignment+1, (cmsUInt16Number*) Filler)) goto Error; + if (!_cmsWriteWCharArray(io, len_text, Wide)) goto Error; // ScriptCode Code & count (unused) if (!_cmsWriteUInt16Number(io, 0)) goto Error; @@ -1028,6 +1029,10 @@ cmsBool Type_Text_Description_Write(struct _cms_typehandler_struct* self, cmsIO if (!io ->Write(io, 67, Filler)) goto Error; + // possibly add pad at the end of tag + if(len_aligned - len_tag_requirement > 0) + if (!io ->Write(io, len_aligned - len_tag_requirement, Filler)) goto Error; + rc = TRUE; Error: @@ -1478,7 +1483,7 @@ void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU LargestPosition = EndOfThisString; } - // Now read the remaining of tag and fill all strings. Substract the directory + // Now read the remaining of tag and fill all strings. Subtract the directory SizeOfTag = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number); if (SizeOfTag == 0) { @@ -1512,7 +1517,7 @@ cmsBool Type_MLU_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu =(cmsMLU*) Ptr; cmsUInt32Number HeaderSize; cmsUInt32Number Len, Offset; - int i; + cmsUInt32Number i; if (Ptr == NULL) { @@ -1698,10 +1703,7 @@ cmsBool Write8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsUInt32Number else for (j=0; j < 256; j++) { - if (Tables != NULL) - val = (cmsUInt8Number) FROM_16_TO_8(Tables->TheCurves[i]->Table16[j]); - else - val = (cmsUInt8Number) j; + val = (cmsUInt8Number) FROM_16_TO_8(Tables->TheCurves[i]->Table16[j]); if (!_cmsWriteUInt8Number(io, val)) return FALSE; } @@ -3125,7 +3127,8 @@ void *Type_NamedColor_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* i memset(Colorant, 0, sizeof(Colorant)); if (io -> Read(io, Root, 32, 1) != 1) goto Error; - Root[32] = 0; + Root[32] = 0; // To prevent exploits + if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error; if (!_cmsReadUInt16Array(io, nDeviceCoords, Colorant)) goto Error; @@ -3148,8 +3151,8 @@ static cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) { cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr; - char prefix[32]; // Prefix for each color name - char suffix[32]; // Suffix for each color name + char prefix[33]; // Prefix for each color name + char suffix[33]; // Suffix for each color name int i, nColors; nColors = cmsNamedColorCount(NamedColorList); @@ -3161,7 +3164,7 @@ cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER strncpy(prefix, (const char*) NamedColorList->Prefix, 32); strncpy(suffix, (const char*) NamedColorList->Suffix, 32); - suffix[31] = prefix[31] = 0; + suffix[32] = prefix[32] = 0; if (!io ->Write(io, 32, prefix)) return FALSE; if (!io ->Write(io, 32, suffix)) return FALSE; @@ -3173,6 +3176,7 @@ cmsBool Type_NamedColor_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER char Root[33]; if (!cmsNamedColorInfo(NamedColorList, i, Root, NULL, NULL, PCS, Colorant)) return 0; + Root[32] = 0; if (!io ->Write(io, 32 , Root)) return FALSE; if (!_cmsWriteUInt16Array(io, 3, PCS)) return FALSE; if (!_cmsWriteUInt16Array(io, NamedColorList ->ColorantCount, Colorant)) return FALSE; @@ -3623,7 +3627,7 @@ country varies for each element: -// Auxiliar, read an string specified as count + string +// Auxiliary, read an string specified as count + string static cmsBool ReadCountAndSting(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* mlu, cmsUInt32Number* SizeOfTag, const char* Section) { @@ -3872,7 +3876,7 @@ cmsBool Type_ViewingConditions_Write(struct _cms_typehandler_struct* self, cmsIO static void* Type_ViewingConditions_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n) { - return _cmsDupMem(self ->ContextID, Ptr, sizeof(cmsScreening)); + return _cmsDupMem(self->ContextID, Ptr, sizeof(cmsICCViewingConditions)); cmsUNUSED_PARAMETER(n); } @@ -4190,7 +4194,7 @@ cmsBool Type_MPEcurve_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* // The matrix is organized as an array of PxQ+Q elements, where P is the number of input channels to the // matrix, and Q is the number of output channels. The matrix elements are each float32Numbers. The array // is organized as follows: -// array = [e11, e12, ? e1P, e21, e22, ? e2P, ? eQ1, eQ2, ? eQP, e1, e2, ? eQ] +// array = [e11, e12, ..., e1P, e21, e22, ..., e2P, ..., eQ1, eQ2, ..., eQP, e1, e2, ..., eQ] static void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag) @@ -4320,7 +4324,7 @@ void *Type_MPEclut_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, if (Dimensions8[i] == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least GridPoints[i] = (cmsUInt32Number)Dimensions8[i]; } - + // Allocate the true CLUT mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL); if (mpe == NULL) goto Error; @@ -4347,13 +4351,13 @@ Error: static cmsBool Type_MPEclut_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) { - cmsUInt8Number Dimensions8[16]; + cmsUInt8Number Dimensions8[16]; // 16 because the spec says 16 and not max number of channels cmsUInt32Number i; cmsStage* mpe = (cmsStage*) Ptr; _cmsStageCLutData* clut = (_cmsStageCLutData*) mpe ->Data; - // Check for maximum number of channels - if (mpe -> InputChannels > 15) return FALSE; + // Check for maximum number of channels supported by lcms + if (mpe -> InputChannels > MAX_INPUT_DIMENSIONS) return FALSE; // Only floats are supported in MPE if (clut ->HasFloatValues == FALSE) return FALSE; @@ -4709,10 +4713,10 @@ void *Type_vcgt_Read(struct _cms_typehandler_struct* self, // Y = cX + f | X < d // vcgt formula is: - // Y = (Max ?Min) * (X ^ Gamma) + Min + // Y = (Max - Min) * (X ^ Gamma) + Min // So, the translation is - // a = (Max ?Min) ^ ( 1 / Gamma) + // a = (Max - Min) ^ ( 1 / Gamma) // e = Min // b=c=d=f=0 @@ -5495,8 +5499,9 @@ static _cmsTagLinkedList SupportedTags[] = { { cmsSigScreeningTag, { 1, 1, { cmsSigScreeningType}, NULL }, &SupportedTags[59]}, { cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]}, { cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]}, - { cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]}, - { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, NULL} + { cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]}, + { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]}, + { cmsSigArgyllArtsTag, { 9, 1, { cmsSigS15Fixed16ArrayType}, NULL}, NULL} }; @@ -5608,3 +5613,4 @@ cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig return NULL; } + |