Skip to content
Permalink
Browse files
8260380: Upgrade to LittleCMS 2.12
Reviewed-by: jdv, serb
  • Loading branch information
Phil Race committed Feb 10, 2021
1 parent a772639 commit 4caeb39f01b13b5472d8dacb268262fd418fd0c4
@@ -1,4 +1,4 @@
## Little Color Management System (LCMS) v2.11
## Little Color Management System (LCMS) v2.12

### LCMS License
<pre>
@@ -104,7 +104,7 @@ static
void from8to16(void* dst, const void* src)
{
cmsUInt8Number n = *(cmsUInt8Number*)src;
*(cmsUInt16Number*) dst = FROM_8_TO_16(n);
*(cmsUInt16Number*) dst = (cmsUInt16Number) FROM_8_TO_16(n);
}

static
@@ -117,13 +117,13 @@ void from8to16SE(void* dst, const void* src)
static
void from8toFLT(void* dst, const void* src)
{
*(cmsFloat32Number*)dst = (*(cmsUInt8Number*)src) / 255.0f;
*(cmsFloat32Number*)dst = (cmsFloat32Number) (*(cmsUInt8Number*)src) / 255.0f;
}

static
void from8toDBL(void* dst, const void* src)
{
*(cmsFloat64Number*)dst = (*(cmsUInt8Number*)src) / 255.0;
*(cmsFloat64Number*)dst = (cmsFloat64Number) (*(cmsUInt8Number*)src) / 255.0;
}

static
@@ -182,13 +182,13 @@ void from16SEtoFLT(void* dst, const void* src)
static
void from16toDBL(void* dst, const void* src)
{
*(cmsFloat64Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
*(cmsFloat64Number*)dst = (cmsFloat64Number) (*(cmsUInt16Number*)src) / 65535.0;
}

static
void from16SEtoDBL(void* dst, const void* src)
{
*(cmsFloat64Number*)dst = (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0f;
*(cmsFloat64Number*)dst = (cmsFloat64Number) (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0;
}

static
@@ -1525,21 +1525,30 @@ cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE h, int n, const char *Sample)
return SetDataFormat(it8, n, Sample);
}

// A safe atoi that returns 0 when NULL input is given
static
cmsInt32Number satoi(const char* b)
{
if (b == NULL) return 0;
return atoi(b);
}

static
void AllocateDataSet(cmsIT8* it8)
{
TABLE* t = GetTable(it8);

if (t -> Data) return; // Already allocated

t-> nSamples = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
t-> nPatches = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
t-> nSamples = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
t-> nPatches = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));

if (t -> nSamples < 0 || t->nSamples > 0x7ffe || t->nPatches < 0 || t->nPatches > 0x7ffe)
{
SynError(it8, "AllocateDataSet: too much data");
}
else {
// Some dumb analizers warns of possible overflow here, just take a look couple of lines above.
t->Data = (char**)AllocChunk(it8, ((cmsUInt32Number)t->nSamples + 1) * ((cmsUInt32Number)t->nPatches + 1) * sizeof(char*));
if (t->Data == NULL) {

@@ -1705,11 +1714,11 @@ void WriteHeader(cmsIT8* it8, SAVESTREAM* fp)
break;

case WRITE_HEXADECIMAL:
Writef(fp, "\t0x%X", atoi(p ->Value));
Writef(fp, "\t0x%X", satoi(p ->Value));
break;

case WRITE_BINARY:
Writef(fp, "\t0x%B", atoi(p ->Value));
Writef(fp, "\t0x%B", satoi(p ->Value));
break;

case WRITE_PAIR:
@@ -1738,7 +1747,7 @@ void WriteDataFormat(SAVESTREAM* fp, cmsIT8* it8)

WriteStr(fp, "BEGIN_DATA_FORMAT\n");
WriteStr(fp, " ");
nSamples = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
nSamples = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));

for (i = 0; i < nSamples; i++) {

@@ -1761,7 +1770,7 @@ void WriteData(SAVESTREAM* fp, cmsIT8* it8)

WriteStr (fp, "BEGIN_DATA\n");

t->nPatches = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
t->nPatches = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));

for (i = 0; i < t-> nPatches; i++) {

@@ -759,6 +759,9 @@ cmsPipeline* BlackPreservingKOnlyIntents(cmsContext ContextID,
cmsUInt32Number ICCIntents[256];
cmsStage* CLUT;
cmsUInt32Number i, nGridPoints;
cmsUInt32Number lastProfilePos;
cmsUInt32Number preservationProfilesCount;
cmsHPROFILE hLastProfile;


// Sanity check
@@ -768,20 +771,36 @@ cmsPipeline* BlackPreservingKOnlyIntents(cmsContext ContextID,
for (i=0; i < nProfiles; i++)
ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]);


// Trim all CMYK devicelinks at the end
lastProfilePos = nProfiles - 1;
hLastProfile = hProfiles[lastProfilePos];

while (lastProfilePos > 1)
{
hLastProfile = hProfiles[--lastProfilePos];
if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData ||
cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass)
break;
}

preservationProfilesCount = lastProfilePos + 1;

// Check for non-cmyk profiles
if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData ||
cmsGetColorSpace(hProfiles[nProfiles-1]) != cmsSigCmykData)
!(cmsGetColorSpace(hLastProfile) == cmsSigCmykData ||
cmsGetDeviceClass(hLastProfile) == cmsSigOutputClass))
return DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags);

memset(&bp, 0, sizeof(bp));

// Allocate an empty LUT for holding the result
Result = cmsPipelineAlloc(ContextID, 4, 4);
if (Result == NULL) return NULL;

memset(&bp, 0, sizeof(bp));

// Create a LUT holding normal ICC transform
bp.cmyk2cmyk = DefaultICCintents(ContextID,
nProfiles,
preservationProfilesCount,
ICCIntents,
hProfiles,
BPC,
@@ -793,7 +812,7 @@ cmsPipeline* BlackPreservingKOnlyIntents(cmsContext ContextID,
// Now, compute the tone curve
bp.KTone = _cmsBuildKToneCurve(ContextID,
4096,
nProfiles,
preservationProfilesCount,
ICCIntents,
hProfiles,
BPC,
@@ -818,6 +837,19 @@ cmsPipeline* BlackPreservingKOnlyIntents(cmsContext ContextID,
if (!cmsStageSampleCLut16bit(CLUT, BlackPreservingGrayOnlySampler, (void*) &bp, 0))
goto Error;


// Insert possible devicelinks at the end
for (i = lastProfilePos + 1; i < nProfiles; i++)
{
cmsPipeline* devlink = _cmsReadDevicelinkLUT(hProfiles[i], ICCIntents[i]);
if (devlink == NULL)
goto Error;

if (!cmsPipelineCat(Result, devlink))
goto Error;
}


// Get rid of xform and tone curve
cmsPipelineFree(bp.cmyk2cmyk);
cmsFreeToneCurve(bp.KTone);
@@ -936,6 +968,8 @@ int BlackPreservingSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER c
return TRUE;
}



// This is the entry for black-plane preserving, which are non-ICC
static
cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,
@@ -947,10 +981,14 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,
cmsUInt32Number dwFlags)
{
PreserveKPlaneParams bp;

cmsPipeline* Result = NULL;
cmsUInt32Number ICCIntents[256];
cmsStage* CLUT;
cmsUInt32Number i, nGridPoints;
cmsUInt32Number lastProfilePos;
cmsUInt32Number preservationProfilesCount;
cmsHPROFILE hLastProfile;
cmsHPROFILE hLab;

// Sanity check
@@ -960,32 +998,45 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,
for (i=0; i < nProfiles; i++)
ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]);

// Trim all CMYK devicelinks at the end
lastProfilePos = nProfiles - 1;
hLastProfile = hProfiles[lastProfilePos];

while (lastProfilePos > 1)
{
hLastProfile = hProfiles[--lastProfilePos];
if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData ||
cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass)
break;
}

preservationProfilesCount = lastProfilePos + 1;

// Check for non-cmyk profiles
if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData ||
!(cmsGetColorSpace(hProfiles[nProfiles-1]) == cmsSigCmykData ||
cmsGetDeviceClass(hProfiles[nProfiles-1]) == cmsSigOutputClass))
!(cmsGetColorSpace(hLastProfile) == cmsSigCmykData ||
cmsGetDeviceClass(hLastProfile) == cmsSigOutputClass))
return DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags);

// Allocate an empty LUT for holding the result
Result = cmsPipelineAlloc(ContextID, 4, 4);
if (Result == NULL) return NULL;


memset(&bp, 0, sizeof(bp));

// We need the input LUT of the last profile, assuming this one is responsible of
// black generation. This LUT will be searched in inverse order.
bp.LabK2cmyk = _cmsReadInputLUT(hProfiles[nProfiles-1], INTENT_RELATIVE_COLORIMETRIC);
bp.LabK2cmyk = _cmsReadInputLUT(hLastProfile, INTENT_RELATIVE_COLORIMETRIC);
if (bp.LabK2cmyk == NULL) goto Cleanup;

// Get total area coverage (in 0..1 domain)
bp.MaxTAC = cmsDetectTAC(hProfiles[nProfiles-1]) / 100.0;
bp.MaxTAC = cmsDetectTAC(hLastProfile) / 100.0;
if (bp.MaxTAC <= 0) goto Cleanup;


// Create a LUT holding normal ICC transform
bp.cmyk2cmyk = DefaultICCintents(ContextID,
nProfiles,
preservationProfilesCount,
ICCIntents,
hProfiles,
BPC,
@@ -994,7 +1045,7 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,
if (bp.cmyk2cmyk == NULL) goto Cleanup;

// Now the tone curve
bp.KTone = _cmsBuildKToneCurve(ContextID, 4096, nProfiles,
bp.KTone = _cmsBuildKToneCurve(ContextID, 4096, preservationProfilesCount,
ICCIntents,
hProfiles,
BPC,
@@ -1004,14 +1055,14 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,

// To measure the output, Last profile to Lab
hLab = cmsCreateLab4ProfileTHR(ContextID, NULL);
bp.hProofOutput = cmsCreateTransformTHR(ContextID, hProfiles[nProfiles-1],
bp.hProofOutput = cmsCreateTransformTHR(ContextID, hLastProfile,
CHANNELS_SH(4)|BYTES_SH(2), hLab, TYPE_Lab_DBL,
INTENT_RELATIVE_COLORIMETRIC,
cmsFLAGS_NOCACHE|cmsFLAGS_NOOPTIMIZE);
if ( bp.hProofOutput == NULL) goto Cleanup;

// Same as anterior, but lab in the 0..1 range
bp.cmyk2Lab = cmsCreateTransformTHR(ContextID, hProfiles[nProfiles-1],
bp.cmyk2Lab = cmsCreateTransformTHR(ContextID, hLastProfile,
FLOAT_SH(1)|CHANNELS_SH(4)|BYTES_SH(4), hLab,
FLOAT_SH(1)|CHANNELS_SH(3)|BYTES_SH(4),
INTENT_RELATIVE_COLORIMETRIC,
@@ -1034,6 +1085,18 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,

cmsStageSampleCLut16bit(CLUT, BlackPreservingSampler, (void*) &bp, 0);

// Insert possible devicelinks at the end
for (i = lastProfilePos + 1; i < nProfiles; i++)
{
cmsPipeline* devlink = _cmsReadDevicelinkLUT(hProfiles[i], ICCIntents[i]);
if (devlink == NULL)
goto Cleanup;

if (!cmsPipelineCat(Result, devlink))
goto Cleanup;
}


Cleanup:

if (bp.cmyk2cmyk) cmsPipelineFree(bp.cmyk2cmyk);
@@ -1046,6 +1109,8 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext ContextID,
return Result;
}



// Link routines ------------------------------------------------------------------------------------------------------

// Chain several profiles into a single LUT. It just checks the parameters and then calls the handler

1 comment on commit 4caeb39

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on 4caeb39 Feb 10, 2021

Please sign in to comment.