diff --git a/src/java.desktop/share/legal/lcms.md b/src/java.desktop/share/legal/lcms.md index 20a22ea4db5..b2ea686eee0 100644 --- a/src/java.desktop/share/legal/lcms.md +++ b/src/java.desktop/share/legal/lcms.md @@ -1,4 +1,4 @@ -## Little Color Management System (LCMS) v2.18 +## Little Color Management System (LCMS) v2.19.1 ### LCMS License
@@ -86,6 +86,7 @@ Amyspark
Lovell Fuller
Eli Schwartz
Diogo Teles Sant'Anna
+Vlad Erium
Special Thanks
--------------
diff --git a/src/java.desktop/share/native/liblcms/cmscgats.c b/src/java.desktop/share/native/liblcms/cmscgats.c
index e8a75c7355f..d1585443816 100644
--- a/src/java.desktop/share/native/liblcms/cmscgats.c
+++ b/src/java.desktop/share/native/liblcms/cmscgats.c
@@ -1274,19 +1274,26 @@ void* AllocChunk(cmsIT8* it8, cmsUInt32Number size)
it8 ->Allocator.Used = 0;
new_block = (cmsUInt8Number*)AllocBigBlock(it8, it8->Allocator.BlockSize);
- if (new_block == NULL)
- return NULL;
+ if (new_block == NULL) goto Error;
it8->Allocator.Block = new_block;
}
if (it8->Allocator.Block == NULL)
- return NULL;
+ goto Error;
ptr = it8 ->Allocator.Block + it8 ->Allocator.Used;
it8 ->Allocator.Used += size;
return (void*) ptr;
+
+Error:
+
+ SynError(it8, "Allocation error");
+ it8->Allocator.BlockSize = 0;
+ it8->Allocator.Used = 0;
+ it8->Allocator.Block = NULL;
+ return NULL;
}
@@ -1706,8 +1713,8 @@ cmsBool SetDataFormat(cmsIT8* it8, int n, const char *label)
return FALSE;
}
- if (n >= t -> nSamples) {
- SynError(it8, "More than NUMBER_OF_FIELDS fields.");
+ if (n < 0 || n >= t -> nSamples) {
+ SynError(it8, "Invalid or more than NUMBER_OF_FIELDS fields.");
return FALSE;
}
@@ -1720,9 +1727,11 @@ cmsBool SetDataFormat(cmsIT8* it8, int n, const char *label)
}
-cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE h, int n, const char *Sample)
+cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE h, int n, const char *Sample)
{
cmsIT8* it8 = (cmsIT8*)h;
+
+ _cmsAssert(n >= 0);
return SetDataFormat(it8, n, Sample);
}
@@ -3144,6 +3153,8 @@ cmsBool ParseCube(cmsIT8* cube, cmsStage** Shaper, cmsStage** CLUT, char title[]
InSymbol(cube);
if (!Check(cube, SINUM, "Shaper size expected")) return FALSE;
shaper_size = cube->inum;
+ if (shaper_size < 2 || shaper_size > 65536)
+ return SynError(cube, "LUT_1D_SIZE '%d' is out of bounds", shaper_size);
InSymbol(cube);
break;
@@ -3209,7 +3220,16 @@ cmsBool ParseCube(cmsIT8* cube, cmsStage** Shaper, cmsStage** CLUT, char title[]
if (lut_size > 0) {
- int nodes = lut_size * lut_size * lut_size;
+ int nodes;
+
+ /**
+ * Professional LUT generation tools (e.g., Nobe LutBake) list 65×65×65 as their highest supported size.
+ */
+ if (lut_size < 2 || lut_size > 65)
+ return SynError(cube, "LUT size '%d' is not allowed", lut_size);
+
+ nodes = lut_size * lut_size * lut_size;
+
cmsFloat32Number* lut_table = (cmsFloat32Number*) _cmsMalloc(cube->ContextID, nodes * 3 * sizeof(cmsFloat32Number));
if (lut_table == NULL) return FALSE;
@@ -3280,13 +3300,17 @@ cmsHPROFILE CMSEXPORT cmsCreateDeviceLinkFromCubeFileTHR(cmsContext ContextID, c
// Populates the pipeline
if (Shaper != NULL) {
- if (!cmsPipelineInsertStage(Pipeline, cmsAT_BEGIN, Shaper))
+ if (!cmsPipelineInsertStage(Pipeline, cmsAT_BEGIN, Shaper)) {
+ cmsStageFree(Shaper);
goto Done;
+ }
}
if (CLUT != NULL) {
- if (!cmsPipelineInsertStage(Pipeline, cmsAT_END, CLUT))
+ if (!cmsPipelineInsertStage(Pipeline, cmsAT_END, CLUT)) {
+ cmsStageFree(CLUT);
goto Done;
+ }
}
// Propagate the description. We put no copyright because we know
diff --git a/src/java.desktop/share/native/liblcms/cmserr.c b/src/java.desktop/share/native/liblcms/cmserr.c
index 877beb9ca6a..220602d4a36 100644
--- a/src/java.desktop/share/native/liblcms/cmserr.c
+++ b/src/java.desktop/share/native/liblcms/cmserr.c
@@ -77,25 +77,64 @@ int CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2)
return (toupper(*us1) - toupper(*--us2));
}
-// long int because C99 specifies ftell in such way (7.19.9.2)
-long int CMSEXPORT cmsfilelength(FILE* f)
+#ifdef CMS_LARGE_FILE_SUPPORT
+
+long long int CMSEXPORT cmsfilelength(FILE* f)
{
- long int p , n;
+ long long int p, n;
- p = ftell(f); // register current file position
- if (p == -1L)
- return -1L;
+#ifdef CMS_IS_WINDOWS_
+ p = _ftelli64(f);
+ if (p == -1LL)
+ return -1LL;
- if (fseek(f, 0, SEEK_END) != 0) {
- return -1L;
- }
+ if (_fseeki64(f, 0, SEEK_END) != 0)
+ return -1LL;
- n = ftell(f);
- fseek(f, p, SEEK_SET); // file position restored
+ n = _ftelli64(f);
+
+ if (_fseeki64(f, p, SEEK_SET) != 0)
+ return -1LL;
+#else
+ p = (long long int) ftello(f);
+ if (p < 0)
+ return -1LL;
+
+ if (fseeko(f, 0, SEEK_END) != 0)
+ return -1LL;
+
+ n = (long long int) ftello(f);
+
+ if (fseeko(f, (off_t) p, SEEK_SET) != 0)
+ return -1LL;
+#endif
return n;
}
+#else
+
+// long int because C99 specifies ftell in such way (7.19.9.2)
+long int CMSEXPORT cmsfilelength(FILE* f)
+{
+ long int p, n;
+
+ p = ftell(f);
+ if (p == -1L)
+ return -1L;
+
+ if (fseek(f, 0, SEEK_END) != 0)
+ return -1L;
+
+ n = ftell(f);
+
+ if (fseek(f, p, SEEK_SET) != 0)
+ return -1L;
+
+ return n;
+}
+
+#endif
// Memory handling ------------------------------------------------------------------
//
@@ -104,7 +143,11 @@ long int CMSEXPORT cmsfilelength(FILE* f)
// amount of memory that can be reclaimed. This is mostly as a safety feature to prevent
// bogus or evil code to allocate huge blocks that otherwise lcms would never need.
-#define MAX_MEMORY_FOR_ALLOC ((cmsUInt32Number)(1024U*1024U*512U))
+#ifdef CMS_LARGE_FILE_SUPPORT
+# define MAX_MEMORY_FOR_ALLOC ((cmsUInt32Number)(1024U*1024U*2048U))
+#else
+# define MAX_MEMORY_FOR_ALLOC ((cmsUInt32Number)(1024U*1024U*512U))
+#endif
// User may override this behaviour by using a memory plug-in, which basically replaces
// the default memory management functions. In this case, no check is performed and it
diff --git a/src/java.desktop/share/native/liblcms/cmsio0.c b/src/java.desktop/share/native/liblcms/cmsio0.c
index 5a4f09af5bc..6e2a856b4b8 100644
--- a/src/java.desktop/share/native/liblcms/cmsio0.c
+++ b/src/java.desktop/share/native/liblcms/cmsio0.c
@@ -106,6 +106,9 @@ cmsBool NULLWrite(cmsIOHANDLER* iohandler, cmsUInt32Number size, const void *Pt
{
FILENULL* ResData = (FILENULL*) iohandler ->stream;
+ if (size > (cmsUInt32Number)(0xFFFFFFFFU - ResData->Pointer))
+ return FALSE;
+
ResData ->Pointer += size;
if (ResData ->Pointer > iohandler->UsedSpace)
iohandler->UsedSpace = ResData ->Pointer;
@@ -159,7 +162,6 @@ Error:
}
-
// Memory-based stream --------------------------------------------------------------
// Those functions implements an iohandler which takes a block of memory as storage medium.
@@ -179,12 +181,20 @@ cmsUInt32Number MemoryRead(struct _cms_io_handler* iohandler, void *Buffer, cmsU
cmsUInt8Number* Ptr;
cmsUInt32Number len = size * count;
- if (ResData -> Pointer + len > ResData -> Size){
-
- len = (ResData -> Size - ResData -> Pointer);
- cmsSignalError(iohandler ->ContextID, cmsERROR_READ, "Read from memory error. Got %d bytes, block should be of %d bytes", len, count * size);
+ if (size == 0 || count == 0)
return 0;
- }
+
+ if ((len / count) != size)
+ goto ReadError;
+
+ if (Buffer == NULL)
+ goto ReadError;
+
+ if (len > ResData->Size)
+ goto ReadError;
+
+ if (ResData -> Pointer > ResData -> Size - len)
+ goto ReadError;
Ptr = ResData -> Block;
Ptr += ResData -> Pointer;
@@ -192,18 +202,21 @@ cmsUInt32Number MemoryRead(struct _cms_io_handler* iohandler, void *Buffer, cmsU
ResData -> Pointer += len;
return count;
+
+ReadError:
+ cmsSignalError(iohandler->ContextID, cmsERROR_READ, "Read from memory error");
+ return 0;
+
}
// SEEK_CUR is assumed
static
-cmsBool MemorySeek(struct _cms_io_handler* iohandler, cmsUInt32Number offset)
+cmsBool MemorySeek(struct _cms_io_handler* iohandler, cmsUInt32Number offset)
{
FILEMEM* ResData = (FILEMEM*) iohandler ->stream;
- if (offset > ResData ->Size) {
- cmsSignalError(iohandler ->ContextID, cmsERROR_SEEK, "Too few data; probably corrupted profile");
+ if (offset > ResData ->Size)
return FALSE;
- }
ResData ->Pointer = offset;
return TRUE;
@@ -226,15 +239,17 @@ cmsBool MemoryWrite(struct _cms_io_handler* iohandler, cmsUInt32Number size, con
{
FILEMEM* ResData = (FILEMEM*) iohandler ->stream;
- if (ResData == NULL) return FALSE; // Housekeeping
-
- // Check for available space. Clip.
- if (ResData->Pointer + size > ResData->Size) {
- size = ResData ->Size - ResData->Pointer;
- }
+ if (ResData == NULL || Ptr == NULL) goto WriteError;
if (size == 0) return TRUE; // Write zero bytes is ok, but does nothing
+ // Check for available space. Truncate the output in case the space
+ // is not enough instead of erroring out. See
+ // https://github.com/hughsie/colord/issues/147.
+
+ if (size > ResData->Size - ResData->Pointer)
+ size = ResData->Size - ResData->Pointer;
+
memmove(ResData ->Block + ResData ->Pointer, Ptr, size);
ResData ->Pointer += size;
@@ -242,6 +257,10 @@ cmsBool MemoryWrite(struct _cms_io_handler* iohandler, cmsUInt32Number size, con
iohandler->UsedSpace = ResData ->Pointer;
return TRUE;
+
+WriteError:
+ cmsSignalError(iohandler->ContextID, cmsERROR_WRITE, "Write to memory error");
+ return FALSE;
}
@@ -362,8 +381,15 @@ cmsUInt32Number FileRead(cmsIOHANDLER* iohandler, void *Buffer, cmsUInt32Number
static
cmsBool FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset)
{
+#ifdef CMS_LARGE_FILE_SUPPORT
+# ifdef CMS_IS_WINDOWS_
+ if (_fseeki64((FILE*) iohandler->stream, (long long int) offset, SEEK_SET) != 0) {
+# else
+ if (fseeko((FILE*) iohandler->stream, (off_t) offset, SEEK_SET) != 0) {
+# endif
+#else
if (fseek((FILE*) iohandler ->stream, (long) offset, SEEK_SET) != 0) {
-
+#endif
cmsSignalError(iohandler ->ContextID, cmsERROR_FILE, "Seek error; probably corrupted file");
return FALSE;
}
@@ -375,13 +401,24 @@ cmsBool FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset)
static
cmsUInt32Number FileTell(cmsIOHANDLER* iohandler)
{
+#ifdef CMS_LARGE_FILE_SUPPORT
+# ifdef CMS_IS_WINDOWS_
+ long long int t = _ftelli64((FILE*) iohandler->stream);
+# else
+ long long int t = (long long int) ftello((FILE*) iohandler->stream);
+# endif
+ if (t < 0) {
+ cmsSignalError(iohandler->ContextID, cmsERROR_FILE, "Tell error; probably corrupted file");
+ return 0;
+ }
+#else
long t = ftell((FILE*)iohandler ->stream);
if (t == -1L) {
cmsSignalError(iohandler->ContextID, cmsERROR_FILE, "Tell error; probably corrupted file");
return 0;
}
-
- return (cmsUInt32Number)t;
+#endif
+ return (cmsUInt32Number) t;
}
// Writes data to stream, also keeps used space for further reference. Returns TRUE on success, FALSE on error
@@ -408,7 +445,11 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
{
cmsIOHANDLER* iohandler = NULL;
FILE* fm = NULL;
- cmsInt32Number fileLen;
+#ifdef CMS_LARGE_FILE_SUPPORT
+ long long int fileLen;
+#else
+ long int fileLen;
+#endif
char mode[4] = { 0,0,0,0 };
_cmsAssert(FileName != NULL);
@@ -459,7 +500,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' not found", FileName);
return NULL;
}
- fileLen = (cmsInt32Number)cmsfilelength(fm);
+ fileLen = cmsfilelength(fm);
if (fileLen < 0)
{
fclose(fm);
@@ -467,6 +508,15 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of file '%s'", FileName);
return NULL;
}
+#ifdef CMS_LARGE_FILE_SUPPORT
+ if (fileLen > (long long int) 0xFFFFFFFFLL)
+ {
+ fclose(fm);
+ _cmsFree(ContextID, iohandler);
+ cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' is too large", FileName);
+ return NULL;
+ }
+#endif
iohandler -> ReportedSize = (cmsUInt32Number) fileLen;
break;
@@ -506,14 +556,25 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* Stream)
{
cmsIOHANDLER* iohandler = NULL;
- cmsInt32Number fileSize;
+#ifdef CMS_LARGE_FILE_SUPPORT
+ long long int fileSize;
+#else
+ long int fileSize;
+#endif
- fileSize = (cmsInt32Number)cmsfilelength(Stream);
+ fileSize = cmsfilelength(Stream);
if (fileSize < 0)
{
cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of stream");
return NULL;
}
+#ifdef CMS_LARGE_FILE_SUPPORT
+ if (fileSize > (long long int) 0xFFFFFFFFLL)
+ {
+ cmsSignalError(ContextID, cmsERROR_FILE, "Stream is too large");
+ return NULL;
+ }
+#endif
iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER));
if (iohandler == NULL) return NULL;
@@ -626,6 +687,18 @@ cmsTagSignature CMSEXPORT cmsGetTagSignature(cmsHPROFILE hProfile, cmsUInt32Numb
return Icc ->TagNames[n];
}
+// Return location of the tag
+cmsBool CMSEXPORT cmsGetTagOffsetAndSize(cmsHPROFILE hProfile, cmsUInt32Number n, cmsUInt32Number* offset, cmsUInt32Number* size)
+{
+ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*)hProfile;
+
+ if (n > Icc->TagCount) return FALSE;
+ if (n >= MAX_TABLE_TAG) return FALSE;
+
+ if (offset != NULL) *offset = Icc->TagOffsets[n];
+ if (size != NULL) *size = Icc->TagSizes[n];
+ return TRUE;
+}
static
int SearchOneTag(_cmsICCPROFILE* Profile, cmsTagSignature sig)
@@ -791,7 +864,8 @@ cmsUInt32Number _validatedVersion(cmsUInt32Number DWord)
static
cmsBool validDeviceClass(cmsProfileClassSignature cl)
{
- if ((int)cl == 0) return TRUE; // We allow zero because older lcms versions defaulted to that.
+ if (cl == (cmsProfileClassSignature)0)
+ return TRUE; // We allow zero because older lcms versions defaulted to that.
switch (cl)
{
@@ -802,6 +876,10 @@ cmsBool validDeviceClass(cmsProfileClassSignature cl)
case cmsSigAbstractClass:
case cmsSigColorSpaceClass:
case cmsSigNamedColorClass:
+ case cmsSigColorEncodingSpaceClass:
+ case cmsSigMultiplexIdentificationClass:
+ case cmsSigMultiplexLinkClass:
+ case cmsSigMultiplexVisualizationClass:
return TRUE;
default:
@@ -1010,6 +1088,17 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
// ----------------------------------------------------------------------- Set/Get several struct members
+cmsUInt32Number CMSEXPORT cmsGetHeaderCMM(cmsHPROFILE hProfile)
+{
+ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*)hProfile;
+ return Icc->CMM;
+}
+
+void CMSEXPORT _cmsSetHeaderCMM(cmsHPROFILE hProfile, cmsUInt32Number CMM)
+{
+ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*)hProfile;
+ Icc->CMM = CMM;
+}
cmsUInt32Number CMSEXPORT cmsGetHeaderRenderingIntent(cmsHPROFILE hProfile)
{
@@ -1228,7 +1317,6 @@ Error:
return NULL;
}
-
// Create profile from disk file
cmsHPROFILE CMSEXPORT cmsOpenProfileFromFileTHR(cmsContext ContextID, const char *lpFileName, const char *sAccess)
{
@@ -1296,7 +1384,6 @@ cmsHPROFILE CMSEXPORT cmsOpenProfileFromStream(FILE* ICCProfile, const char *sA
return cmsOpenProfileFromStreamTHR(NULL, ICCProfile, sAccess);
}
-
// Open from memory block
cmsHPROFILE CMSEXPORT cmsOpenProfileFromMemTHR(cmsContext ContextID, const void* MemPtr, cmsUInt32Number dwSize)
{
@@ -1445,7 +1532,6 @@ cmsBool SaveTags(_cmsICCPROFILE* Icc, _cmsICCPROFILE* FileOrig)
return TRUE;
}
-
// Fill the offset and size fields for all linked tags
static
cmsBool SetLinks( _cmsICCPROFILE* Icc)
@@ -1527,7 +1613,6 @@ Error:
return 0;
}
-
// Low-level save to disk.
cmsBool CMSEXPORT cmsSaveProfileToFile(cmsHPROFILE hProfile, const char* FileName)
{
@@ -1663,21 +1748,23 @@ cmsBool IsTypeSupported(cmsTagDescriptor* TagDescriptor, cmsTagTypeSignature Typ
return FALSE;
}
-
// That's the main read function
void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
{
- _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
+ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*)hProfile;
+ cmsBool avoidCheck;
cmsIOHANDLER* io;
cmsTagTypeHandler* TypeHandler;
cmsTagTypeHandler LocalTypeHandler;
- cmsTagDescriptor* TagDescriptor;
+ cmsTagDescriptor* TagDescriptor = NULL;
cmsTagTypeSignature BaseType;
cmsUInt32Number Offset, TagSize;
cmsUInt32Number ElemCount;
int n;
- if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return NULL;
+ if (!_cmsLockMutex(Icc->ContextID, Icc->UsrMutex)) return NULL;
+
+ avoidCheck = _cmsAvoidTypeCheckOnTags(Icc->ContextID);
n = _cmsSearchTag(Icc, sig, TRUE);
if (n < 0)
@@ -1688,7 +1775,7 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
}
// If the element is already in memory, return the pointer
- if (Icc -> TagPtrs[n]) {
+ if (Icc->TagPtrs[n]) {
if (Icc->TagTypeHandlers[n] == NULL) goto Error;
@@ -1696,24 +1783,26 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
BaseType = Icc->TagTypeHandlers[n]->Signature;
if (BaseType == 0) goto Error;
- TagDescriptor = _cmsGetTagDescriptor(Icc->ContextID, sig);
- if (TagDescriptor == NULL) goto Error;
+ if (!avoidCheck) {
- if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
+ TagDescriptor = _cmsGetTagDescriptor(Icc->ContextID, sig);
+ if (TagDescriptor == NULL) goto Error;
+ if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
+ }
- if (Icc ->TagSaveAsRaw[n]) goto Error; // We don't support read raw tags as cooked
+ if (Icc->TagSaveAsRaw[n]) goto Error; // We don't support read raw tags as cooked
- _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
- return Icc -> TagPtrs[n];
+ _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
+ return Icc->TagPtrs[n];
}
// We need to read it. Get the offset and size to the file
- Offset = Icc -> TagOffsets[n];
- TagSize = Icc -> TagSizes[n];
+ Offset = Icc->TagOffsets[n];
+ TagSize = Icc->TagSizes[n];
if (TagSize < 8) goto Error;
- io = Icc ->IOhandler;
+ io = Icc->IOhandler;
if (io == NULL) { // This is a built-in profile that has been manipulated, abort early
@@ -1722,70 +1811,75 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
}
// Seek to its location
- if (!io -> Seek(io, Offset))
+ if (!io->Seek(io, Offset))
goto Error;
- // Search for support on this tag
- TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
- if (TagDescriptor == NULL) {
+ if (!avoidCheck) {
+ // Search for support on this tag
+ TagDescriptor = _cmsGetTagDescriptor(Icc->ContextID, sig);
+ if (TagDescriptor == NULL) {
- char String[5];
+ char String[5];
- _cmsTagSignature2String(String, sig);
+ _cmsTagSignature2String(String, sig);
- // An unknown element was found.
- cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown tag type '%s' found.", String);
- goto Error; // Unsupported.
+ // An unknown element was found.
+ cmsSignalError(Icc->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown tag type '%s' found.", String);
+ goto Error; // Unsupported.
+ }
}
// if supported, get type and check if in list
BaseType = _cmsReadTypeBase(io);
if (BaseType == 0) goto Error;
- if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
+ if (!avoidCheck) {
+ if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
+ }
- TagSize -= 8; // Already read by the type base logic
+ TagSize -= 8; // Already read by the type base logic
// Get type handler
- TypeHandler = _cmsGetTagTypeHandler(Icc ->ContextID, BaseType);
+ TypeHandler = _cmsGetTagTypeHandler(Icc->ContextID, BaseType);
if (TypeHandler == NULL) goto Error;
LocalTypeHandler = *TypeHandler;
// Read the tag
- Icc -> TagTypeHandlers[n] = TypeHandler;
+ Icc->TagTypeHandlers[n] = TypeHandler;
- LocalTypeHandler.ContextID = Icc ->ContextID;
- LocalTypeHandler.ICCVersion = Icc ->Version;
- Icc -> TagPtrs[n] = LocalTypeHandler.ReadPtr(&LocalTypeHandler, io, &ElemCount, TagSize);
+ LocalTypeHandler.ContextID = Icc->ContextID;
+ LocalTypeHandler.ICCVersion = Icc->Version;
+ Icc->TagPtrs[n] = LocalTypeHandler.ReadPtr(&LocalTypeHandler, io, &ElemCount, TagSize);
// The tag type is supported, but something wrong happened and we cannot read the tag.
// let know the user about this (although it is just a warning)
- if (Icc -> TagPtrs[n] == NULL) {
+ if (Icc->TagPtrs[n] == NULL) {
char String[5];
_cmsTagSignature2String(String, sig);
- cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Corrupted tag '%s'", String);
+ cmsSignalError(Icc->ContextID, cmsERROR_CORRUPTION_DETECTED, "Corrupted tag '%s'", String);
goto Error;
}
- // This is a weird error that may be a symptom of something more serious, the number of
- // stored item is actually less than the number of required elements.
- if (ElemCount < TagDescriptor ->ElemCount) {
+ if (!avoidCheck) {
+ // This is a weird error that may be a symptom of something more serious, the number of
+ // stored item is actually less than the number of required elements.
+ if (ElemCount < TagDescriptor->ElemCount) {
- char String[5];
+ char String[5];
- _cmsTagSignature2String(String, sig);
- cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "'%s' Inconsistent number of items: expected %d, got %d",
- String, TagDescriptor ->ElemCount, ElemCount);
- goto Error;
+ _cmsTagSignature2String(String, sig);
+ cmsSignalError(Icc->ContextID, cmsERROR_CORRUPTION_DETECTED, "'%s' Inconsistent number of items: expected %d, got %d",
+ String, TagDescriptor->ElemCount, ElemCount);
+ goto Error;
+ }
}
-
// Return the data
- _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
- return Icc -> TagPtrs[n];
+ _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
+ return Icc->TagPtrs[n];
// Return error and unlock the data
@@ -1794,7 +1888,7 @@ Error:
freeOneTag(Icc, n);
Icc->TagPtrs[n] = NULL;
- _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+ _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
return NULL;
}
@@ -1812,6 +1906,8 @@ cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig
// Get the handler. The true type is there
TypeHandler = Icc -> TagTypeHandlers[n];
+ if (TypeHandler == NULL) return (cmsTagTypeSignature) 0;
+
return TypeHandler ->Signature;
}
@@ -2122,7 +2218,6 @@ cmsBool CMSEXPORT cmsLinkTag(cmsHPROFILE hProfile, cmsTagSignature sig, cmsTagSi
return TRUE;
}
-
// Returns the tag linked to sig, in the case two tags are sharing same resource
cmsTagSignature CMSEXPORT cmsTagLinkedTo(cmsHPROFILE hProfile, cmsTagSignature sig)
{
diff --git a/src/java.desktop/share/native/liblcms/cmslut.c b/src/java.desktop/share/native/liblcms/cmslut.c
index 28220eae667..6ac5b63d2de 100644
--- a/src/java.desktop/share/native/liblcms/cmslut.c
+++ b/src/java.desktop/share/native/liblcms/cmslut.c
@@ -489,25 +489,26 @@ void EvaluateCLUTfloatIn16(const cmsFloat32Number In[], cmsFloat32Number Out[],
static
cmsUInt32Number CubeSize(const cmsUInt32Number Dims[], cmsUInt32Number b)
{
- cmsUInt32Number rv, dim;
+ cmsUInt32Number dim;
+ cmsUInt64Number rv;
_cmsAssert(Dims != NULL);
for (rv = 1; b > 0; b--) {
dim = Dims[b-1];
- if (dim <= 1) return 0; // Error
-
- rv *= dim;
+ if (dim <= 1) return 0;
// Check for overflow
if (rv > UINT_MAX / dim) return 0;
+
+ rv *= dim;
}
// Again, prevent overflow
if (rv > UINT_MAX / 15) return 0;
- return rv;
+ return (cmsUInt32Number) rv;
}
static
diff --git a/src/java.desktop/share/native/liblcms/cmsnamed.c b/src/java.desktop/share/native/liblcms/cmsnamed.c
index acdaabc3ec2..4338b7cb8f5 100644
--- a/src/java.desktop/share/native/liblcms/cmsnamed.c
+++ b/src/java.desktop/share/native/liblcms/cmsnamed.c
@@ -116,8 +116,11 @@ cmsBool GrowMLUpool(cmsMLU* mlu)
return TRUE;
}
-
// Grows a entry table for a MLU. Each time this function is called, table size is multiplied times two.
+// No need to check integer overflow since that is 2*16*count = 2^32-1 ; => count = 128 M entries,
+// That would be 2Gb, which is over MAX_MEMORY_FOR_ALLOC, even for large file size.
+// I added this check to silence the continuous spam reports of people using AI to catch what
+// they think are "vulnerabilities".
static
cmsBool GrowMLUtable(cmsMLU* mlu)
{
@@ -129,8 +132,12 @@ cmsBool GrowMLUtable(cmsMLU* mlu)
AllocatedEntries = mlu ->AllocatedEntries * 2;
- // Check for overflow
- if (AllocatedEntries / 2 != mlu ->AllocatedEntries) return FALSE;
+ // Check for overflow in count doubling: if wrapped, result < original
+ if (AllocatedEntries < mlu->AllocatedEntries) return FALSE;
+
+ // Check for overflow in byte-size multiplication:
+ // dividing back by sizeof must recover the original count
+ if ((AllocatedEntries * sizeof(_cmsMLUentry)) / sizeof(_cmsMLUentry) != AllocatedEntries) return FALSE;
// Reallocate the memory
NewPtr = (_cmsMLUentry*)_cmsRealloc(mlu ->ContextID, mlu ->Entries, AllocatedEntries*sizeof(_cmsMLUentry));
@@ -834,7 +841,8 @@ cmsNAMEDCOLORLIST* CMSEXPORT cmsDupNamedColorList(const cmsNAMEDCOLORLIST* v)
memmove(NewNC ->Prefix, v ->Prefix, sizeof(v ->Prefix));
memmove(NewNC ->Suffix, v ->Suffix, sizeof(v ->Suffix));
NewNC ->ColorantCount = v ->ColorantCount;
- memmove(NewNC->List, v ->List, v->nColors * sizeof(_cmsNAMEDCOLOR));
+ if (v->nColors > 0)
+ memmove(NewNC->List, v ->List, v->nColors * sizeof(_cmsNAMEDCOLOR));
NewNC ->nColors = v ->nColors;
return NewNC;
}
diff --git a/src/java.desktop/share/native/liblcms/cmsopt.c b/src/java.desktop/share/native/liblcms/cmsopt.c
index 9e71426a332..bba31722383 100644
--- a/src/java.desktop/share/native/liblcms/cmsopt.c
+++ b/src/java.desktop/share/native/liblcms/cmsopt.c
@@ -1221,10 +1221,13 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
if (Trans[t]) cmsFreeToneCurve(Trans[t]);
if (TransReverse[t]) cmsFreeToneCurve(TransReverse[t]);
+
+ Trans[t] = NULL;
+ TransReverse[t] = NULL;
}
cmsPipelineFree(LutPlusCurves);
-
+ LutPlusCurves = NULL;
OptimizedPrelinCurves = _cmsStageGetPtrToCurveSet(OptimizedPrelinMpe);
OptimizedPrelinCLUT = (_cmsStageCLutData*) OptimizedCLUTmpe ->Data;
@@ -1235,7 +1238,7 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
Prelin8Data* p8 = PrelinOpt8alloc(OptimizedLUT ->ContextID,
OptimizedPrelinCLUT ->Params,
OptimizedPrelinCurves);
- if (p8 == NULL) return FALSE;
+ if (p8 == NULL) goto Error;
_cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval8, (void*) p8, Prelin8free, Prelin8dup);
@@ -1245,7 +1248,8 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
Prelin16Data* p16 = PrelinOpt16alloc(OptimizedLUT ->ContextID,
OptimizedPrelinCLUT ->Params,
3, OptimizedPrelinCurves, 3, NULL);
- if (p16 == NULL) return FALSE;
+
+ if (p16 == NULL) goto Error;
_cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval16, (void*) p16, PrelinOpt16free, Prelin16dup);
@@ -1259,7 +1263,7 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
if (!FixWhiteMisalignment(OptimizedLUT, ColorSpace, OutputColorSpace)) {
- return FALSE;
+ goto Error;
}
}
diff --git a/src/java.desktop/share/native/liblcms/cmsps2.c b/src/java.desktop/share/native/liblcms/cmsps2.c
index 80f7c8084ae..3901f92d212 100644
--- a/src/java.desktop/share/native/liblcms/cmsps2.c
+++ b/src/java.desktop/share/native/liblcms/cmsps2.c
@@ -358,6 +358,32 @@ char* RemoveCR(const char* txt)
}
+// Writes the body of a PostScript string literal, escaping the metacharacters
+// '\\', '(' and ')' and emitting non-printable / high-bit bytes as octal
+// triples per PLRM 3.3.4.1. The caller is responsible for the surrounding
+// '(' and ')' delimiters.
+static
+void EmitPSEscaped(cmsIOHANDLER* m, const char* txt)
+{
+ const unsigned char* p;
+
+ if (txt == NULL) return;
+
+ for (p = (const unsigned char*)txt; *p != 0; p++) {
+ unsigned char c = *p;
+
+ if (c == '\\' || c == '(' || c == ')') {
+ _cmsIOPrintf(m, "\\%c", c);
+ }
+ else if (c < 0x20 || c >= 0x7F) {
+ _cmsIOPrintf(m, "\\%03o", c);
+ }
+ else {
+ _cmsIOPrintf(m, "%c", c);
+ }
+ }
+}
+
static
void EmitHeader(cmsIOHANDLER* m, const char* Title, cmsHPROFILE hProfile)
{
@@ -1048,7 +1074,10 @@ int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number
continue;
cmsDoTransform(xform, In, &Lab, 1);
- _cmsIOPrintf(m, " (%s) [ %.3f %.3f %.3f ]\n", ColorName, Lab.L, Lab.a, Lab.b);
+
+ _cmsIOPrintf(m, " (");
+ EmitPSEscaped(m, ColorName);
+ _cmsIOPrintf(m, ") [ %.3f %.3f %.3f ]\n", Lab.L, Lab.a, Lab.b);
}
_cmsIOPrintf(m, ">>\n");
@@ -1483,7 +1512,10 @@ int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number
cmsDoTransform(xform, In, Out, 1);
BuildColorantList(Colorant, nColorant, Out);
- _cmsIOPrintf(m, " (%s) [ %s ]\n", ColorName, Colorant);
+
+ _cmsIOPrintf(m, " (");
+ EmitPSEscaped(m, ColorName);
+ _cmsIOPrintf(m, ") [ %s ]\n", Colorant);
}
_cmsIOPrintf(m, " >>");
diff --git a/src/java.desktop/share/native/liblcms/cmssamp.c b/src/java.desktop/share/native/liblcms/cmssamp.c
index c54a0d4ea72..7c8c93d9d52 100644
--- a/src/java.desktop/share/native/liblcms/cmssamp.c
+++ b/src/java.desktop/share/native/liblcms/cmssamp.c
@@ -214,6 +214,50 @@ cmsBool BlackPointUsingPerceptualBlack(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfi
return TRUE;
}
+
+static
+cmsBool isInkColorspace(cmsColorSpaceSignature c)
+{
+ switch(c)
+ {
+ case cmsSigCmykData:
+ case cmsSigCmyData:
+ case cmsSigMCH1Data:
+ case cmsSigMCH2Data:
+ case cmsSigMCH3Data:
+ case cmsSigMCH4Data:
+ case cmsSigMCH5Data:
+ case cmsSigMCH6Data:
+ case cmsSigMCH7Data:
+ case cmsSigMCH8Data:
+ case cmsSigMCH9Data:
+ case cmsSigMCHAData:
+ case cmsSigMCHBData:
+ case cmsSigMCHCData:
+ case cmsSigMCHDData:
+ case cmsSigMCHEData:
+ case cmsSigMCHFData:
+ case cmsSig1colorData:
+ case cmsSig2colorData:
+ case cmsSig3colorData:
+ case cmsSig4colorData:
+ case cmsSig5colorData:
+ case cmsSig6colorData:
+ case cmsSig7colorData:
+ case cmsSig8colorData:
+ case cmsSig9colorData:
+ case cmsSig10colorData:
+ case cmsSig11colorData:
+ case cmsSig12colorData:
+ case cmsSig13colorData:
+ case cmsSig14colorData:
+ case cmsSig15colorData:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
// This function shouldn't exist at all -- there is such quantity of broken
// profiles on black point tag, that we must somehow fix chromaticity to
// avoid huge tint when doing Black point compensation. This function does
@@ -298,7 +342,7 @@ cmsBool CMSEXPORT cmsDetectBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfil
// If output profile, discount ink-limiting and that's all
if (Intent == INTENT_RELATIVE_COLORIMETRIC &&
(cmsGetDeviceClass(hProfile) == cmsSigOutputClass) &&
- (cmsGetColorSpace(hProfile) == cmsSigCmykData))
+ (isInkColorspace(cmsGetColorSpace(hProfile))))
return BlackPointUsingPerceptualBlack(BlackPoint, hProfile);
// Nope, compute BP using current intent.
@@ -435,7 +479,7 @@ cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROF
if (!cmsIsCLUT(hProfile, Intent, LCMS_USED_AS_OUTPUT ) ||
(ColorSpace != cmsSigGrayData &&
ColorSpace != cmsSigRgbData &&
- ColorSpace != cmsSigCmykData)) {
+ !isInkColorspace(ColorSpace))) {
// In this case, handle as input case
return cmsDetectBlackPoint(BlackPoint, hProfile, Intent, dwFlags);
diff --git a/src/java.desktop/share/native/liblcms/cmstypes.c b/src/java.desktop/share/native/liblcms/cmstypes.c
index eab74940cd0..6ef3031aee0 100644
--- a/src/java.desktop/share/native/liblcms/cmstypes.c
+++ b/src/java.desktop/share/native/liblcms/cmstypes.c
@@ -6265,3 +6265,17 @@ cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig
return NULL;
}
+cmsBool _cmsAvoidTypeCheckOnTags(cmsContext ContextID)
+{
+ _cmsTagLinkedList* pt;
+ _cmsTagPluginChunkType* TagPluginChunk = (_cmsTagPluginChunkType*)_cmsContextGetClientChunk(ContextID, TagPlugin);
+
+ for (pt = TagPluginChunk->Tag;
+ pt != NULL;
+ pt = pt->Next) {
+
+ if (pt->Signature == (cmsTagSignature)0) return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/src/java.desktop/share/native/liblcms/cmsvirt.c b/src/java.desktop/share/native/liblcms/cmsvirt.c
index 0dfc6e947a5..2b5cdf896f8 100644
--- a/src/java.desktop/share/native/liblcms/cmsvirt.c
+++ b/src/java.desktop/share/native/liblcms/cmsvirt.c
@@ -1348,12 +1348,23 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
if (!cmsWriteTag(hProfile, DestinationTag, LUT)) goto Error;
- if (xform -> InputColorant != NULL) {
+ // Colorant tables have special rules depening on deviceClass
+ if (xform -> InputColorant != NULL &&
+ (deviceClass == cmsSigLinkClass || deviceClass == cmsSigInputClass)) {
+
if (!cmsWriteTag(hProfile, cmsSigColorantTableTag, xform->InputColorant)) goto Error;
}
if (xform -> OutputColorant != NULL) {
- if (!cmsWriteTag(hProfile, cmsSigColorantTableOutTag, xform->OutputColorant)) goto Error;
+
+ if (deviceClass == cmsSigLinkClass) {
+
+ if (!cmsWriteTag(hProfile, cmsSigColorantTableOutTag, xform->OutputColorant)) goto Error;
+ }
+ else
+ {
+ if (!cmsWriteTag(hProfile, cmsSigColorantTableTag, xform->OutputColorant)) goto Error;
+ }
}
if ((deviceClass == cmsSigLinkClass) && (xform ->Sequence != NULL)) {
diff --git a/src/java.desktop/share/native/liblcms/cmsxform.c b/src/java.desktop/share/native/liblcms/cmsxform.c
index b5dd302b973..397266551b9 100644
--- a/src/java.desktop/share/native/liblcms/cmsxform.c
+++ b/src/java.desktop/share/native/liblcms/cmsxform.c
@@ -528,7 +528,6 @@ void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
}
}
-
// No gamut check, Cache, 16 bits,
static
void CachedXFORM(_cmsTRANSFORM* p,
@@ -1471,6 +1470,22 @@ cmsUInt32Number CMSEXPORT cmsGetTransformOutputFormat(cmsHTRANSFORM hTransform)
return xform->OutputFormat;
}
+// Returns the optimized pipeline (Lut) inside a transform. Read-only; do not free.
+cmsPipeline* CMSEXPORT cmsGetTransformPipeline(cmsHTRANSFORM hTransform)
+{
+ _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
+ if (xform == NULL) return NULL;
+ return xform->Lut;
+}
+
+// Returns the gamut-check pipeline inside a transform. Read-only; do not free.
+cmsPipeline* CMSEXPORT cmsGetTransformGamutCheckPipeline(cmsHTRANSFORM hTransform)
+{
+ _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
+ if (xform == NULL) return NULL;
+ return xform->GamutCheck;
+}
+
// For backwards compatibility
cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
cmsUInt32Number InputFormat,
@@ -1502,3 +1517,19 @@ cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
xform ->ToOutput = ToOutput;
return TRUE;
}
+
+cmsNAMEDCOLORLIST* CMSEXPORT cmsGetTransformInputColorants(cmsHTRANSFORM hTransform)
+{
+ _cmsTRANSFORM* xform = (_cmsTRANSFORM*)hTransform;
+
+ if (xform == NULL) return NULL;
+ return xform->InputColorant;
+}
+
+cmsNAMEDCOLORLIST* CMSEXPORT cmsGetTransformOutputColorants(cmsHTRANSFORM hTransform)
+{
+ _cmsTRANSFORM* xform = (_cmsTRANSFORM*)hTransform;
+
+ if (xform == NULL) return NULL;
+ return xform->OutputColorant;
+}
diff --git a/src/java.desktop/share/native/liblcms/lcms2.h b/src/java.desktop/share/native/liblcms/lcms2.h
index 17a52384721..f05378ad95e 100644
--- a/src/java.desktop/share/native/liblcms/lcms2.h
+++ b/src/java.desktop/share/native/liblcms/lcms2.h
@@ -52,7 +52,7 @@
//
//---------------------------------------------------------------------------------
//
-// Version 2.18
+// Version 2.19
//
#ifndef _lcms2_H
@@ -66,6 +66,13 @@
// "long long" type.
// #define CMS_DONT_USE_INT64 1
+// Uncomment this one to enable large file support on file/stream I/O.
+// LittleCMS is still limited by ICC 32-bit offsets and sizes, so the
+// practical maximum remains 4 GiB minus profile overhead. Be careful
+// because such huge profiles have to be loaded into memory and that's
+// usually a very bad idea.
+// #define CMS_LARGE_FILE_SUPPORT 1
+
// Uncomment this if your compiler doesn't work with fast floor function
// #define CMS_DONT_USE_FAST_FLOOR 1
@@ -116,7 +123,7 @@ extern "C" {
#endif
// Version/release
-#define LCMS_VERSION 2180
+#define LCMS_VERSION 2190
// I will give the chance of redefining basic types for compilers that are not fully C99 compliant
#ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
@@ -197,6 +204,9 @@ typedef double cmsFloat64Number;
#ifdef CMS_DONT_USE_INT64
typedef cmsUInt32Number cmsUInt64Number[2];
typedef cmsInt32Number cmsInt64Number[2];
+# if defined(CMS_LARGE_FILE_SUPPORT)
+# error "You need int64 for large file support"
+# endif
#endif
// Derivative types
@@ -533,7 +543,13 @@ typedef enum {
cmsSigLinkClass = 0x6C696E6B, // 'link'
cmsSigAbstractClass = 0x61627374, // 'abst'
cmsSigColorSpaceClass = 0x73706163, // 'spac'
- cmsSigNamedColorClass = 0x6e6d636c // 'nmcl'
+ cmsSigNamedColorClass = 0x6e6d636c, // 'nmcl'
+
+ // iccMAX only
+ cmsSigColorEncodingSpaceClass = 0x63656E63, // 'cenc'
+ cmsSigMultiplexIdentificationClass = 0x6D696420, // 'mid '
+ cmsSigMultiplexLinkClass = 0x6d6c6e6b, // 'mlnk'
+ cmsSigMultiplexVisualizationClass = 0x6d766973 // 'mvis'
} cmsProfileClassSignature;
@@ -1107,8 +1123,12 @@ CMSAPI int CMSEXPORT cmsGetEncodedCMMversion(void);
// Support of non-standard functions --------------------------------------------------------------------------------------
CMSAPI int CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2);
-CMSAPI long int CMSEXPORT cmsfilelength(FILE* f);
+#ifdef CMS_LARGE_FILE_SUPPORT
+CMSAPI long long int CMSEXPORT cmsfilelength(FILE* f);
+#else
+CMSAPI long int CMSEXPORT cmsfilelength(FILE* f);
+#endif
// Context handling --------------------------------------------------------------------------------------------------------
@@ -1531,6 +1551,7 @@ CMSAPI cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext Contex
CMSAPI cmsContext CMSEXPORT cmsGetProfileContextID(cmsHPROFILE hProfile);
CMSAPI cmsInt32Number CMSEXPORT cmsGetTagCount(cmsHPROFILE hProfile);
CMSAPI cmsTagSignature CMSEXPORT cmsGetTagSignature(cmsHPROFILE hProfile, cmsUInt32Number n);
+CMSAPI cmsBool CMSEXPORT cmsGetTagOffsetAndSize(cmsHPROFILE hProfile, cmsUInt32Number n, cmsUInt32Number* offset, cmsUInt32Number* size);
CMSAPI cmsBool CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig);
// Read and write pre-formatted data
@@ -1554,6 +1575,8 @@ CMSAPI void CMSEXPORT cmsGetHeaderAttributes(cmsHPROFILE hProfile,
CMSAPI void CMSEXPORT cmsGetHeaderProfileID(cmsHPROFILE hProfile, cmsUInt8Number* ProfileID);
CMSAPI cmsBool CMSEXPORT cmsGetHeaderCreationDateTime(cmsHPROFILE hProfile, struct tm *Dest);
CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderRenderingIntent(cmsHPROFILE hProfile);
+CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderCMM(cmsHPROFILE hProfile);
+
CMSAPI void CMSEXPORT cmsSetHeaderFlags(cmsHPROFILE hProfile, cmsUInt32Number Flags);
CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderManufacturer(cmsHPROFILE hProfile);
@@ -1896,6 +1919,13 @@ CMSAPI cmsContext CMSEXPORT cmsGetTransformContextID(cmsHTRANSFORM hTransf
CMSAPI cmsUInt32Number CMSEXPORT cmsGetTransformInputFormat(cmsHTRANSFORM hTransform);
CMSAPI cmsUInt32Number CMSEXPORT cmsGetTransformOutputFormat(cmsHTRANSFORM hTransform);
+// Access the optimized pipeline and gamut-check pipeline inside a transform.
+CMSAPI cmsPipeline* CMSEXPORT cmsGetTransformPipeline(cmsHTRANSFORM hTransform);
+CMSAPI cmsPipeline* CMSEXPORT cmsGetTransformGamutCheckPipeline(cmsHTRANSFORM hTransform);
+// Grab colorants
+CMSAPI cmsNAMEDCOLORLIST* CMSEXPORT cmsGetTransformInputColorants(cmsHTRANSFORM hTransform);
+CMSAPI cmsNAMEDCOLORLIST* CMSEXPORT cmsGetTransformOutputColorants(cmsHTRANSFORM hTransform);
+
// For backwards compatibility
CMSAPI cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
cmsUInt32Number InputFormat,
diff --git a/src/java.desktop/share/native/liblcms/lcms2_internal.h b/src/java.desktop/share/native/liblcms/lcms2_internal.h
index 6bfe67e5350..073e497b1b8 100644
--- a/src/java.desktop/share/native/liblcms/lcms2_internal.h
+++ b/src/java.desktop/share/native/liblcms/lcms2_internal.h
@@ -887,6 +887,7 @@ int _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cms
cmsTagTypeHandler* _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
+cmsBool _cmsAvoidTypeCheckOnTags(cmsContext ContextID);
// Error logging ---------------------------------------------------------------------------------------------------------