mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-16 08:29:34 +00:00
8383354: Update LCMS to 2.19.1
Reviewed-by: prr, azvegint
This commit is contained in:
parent
42d6307030
commit
bcbf5cf730
@ -1,4 +1,4 @@
|
||||
## Little Color Management System (LCMS) v2.18
|
||||
## Little Color Management System (LCMS) v2.19.1
|
||||
|
||||
### LCMS License
|
||||
<pre>
|
||||
@ -86,6 +86,7 @@ Amyspark
|
||||
Lovell Fuller
|
||||
Eli Schwartz
|
||||
Diogo Teles Sant'Anna
|
||||
Vlad Erium
|
||||
|
||||
Special Thanks
|
||||
--------------
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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, " >>");
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 ---------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user