--- a/jdk/make/sun/cmm/lcms/FILES_c_unix.gmk Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/make/sun/cmm/lcms/FILES_c_unix.gmk Fri Nov 02 17:32:30 2012 -0700
@@ -30,6 +30,7 @@
cmserr.c \
cmsgamma.c \
cmsgmt.c \
+ cmshalf.c \
cmsintrp.c \
cmsio0.c \
cmsio1.c \
--- a/jdk/make/sun/cmm/lcms/FILES_c_windows.gmk Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/make/sun/cmm/lcms/FILES_c_windows.gmk Fri Nov 02 17:32:30 2012 -0700
@@ -30,6 +30,7 @@
cmserr.c \
cmsgamma.c \
cmsgmt.c \
+ cmshalf.c \
cmsintrp.c \
cmsio0.c \
cmsio1.c \
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscam02.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -409,29 +409,29 @@
switch (lpMod -> surround) {
- case CUTSHEET_SURROUND:
- lpMod->F = 0.8;
- lpMod->c = 0.41;
- lpMod->Nc = 0.8;
- break;
+ case CUTSHEET_SURROUND:
+ lpMod->F = 0.8;
+ lpMod->c = 0.41;
+ lpMod->Nc = 0.8;
+ break;
- case DARK_SURROUND:
- lpMod -> F = 0.8;
- lpMod -> c = 0.525;
- lpMod -> Nc = 0.8;
- break;
+ case DARK_SURROUND:
+ lpMod -> F = 0.8;
+ lpMod -> c = 0.525;
+ lpMod -> Nc = 0.8;
+ break;
- case DIM_SURROUND:
- lpMod -> F = 0.9;
- lpMod -> c = 0.59;
- lpMod -> Nc = 0.95;
- break;
+ case DIM_SURROUND:
+ lpMod -> F = 0.9;
+ lpMod -> c = 0.59;
+ lpMod -> Nc = 0.95;
+ break;
- default:
- // Average surround
- lpMod -> F = 1.0;
- lpMod -> c = 0.69;
- lpMod -> Nc = 1.0;
+ default:
+ // Average surround
+ lpMod -> F = 1.0;
+ lpMod -> c = 0.69;
+ lpMod -> Nc = 1.0;
}
lpMod -> n = compute_n(lpMod);
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscgats.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -73,6 +73,7 @@
# define DIR_CHAR '/'
#endif
+
// Symbols
typedef enum {
@@ -143,6 +144,8 @@
// Table. Each individual table can hold properties and rows & cols
typedef struct _Table {
+ char SheetType[MAXSTR]; // The first row of the IT8 (the type)
+
int nSamples, nPatches; // Cols, Rows
int SampleID; // Pos of ID
@@ -162,7 +165,6 @@
// This struct hold all information about an open IT8 handler.
typedef struct {
- char SheetType[MAXSTR]; // The first row of the IT8 (the type)
cmsUInt32Number TablesCount; // How many tables in this stream
cmsUInt32Number nTable; // The actual table
@@ -433,6 +435,8 @@
return FALSE;
}
+
+
// Makes a file path based on a given reference path
// NOTE: this function doesn't check if the path exists or even if it's legal
static
@@ -574,7 +578,7 @@
if (it8->ch == '.') { // Decimal point
cmsFloat64Number frac = 0.0; // fraction
- int prec = 0; // precision
+ int prec = 0; // precision
NextCh(it8); // Eats dec. point
@@ -621,6 +625,81 @@
}
}
+// Parses a float number
+// This can not call directly atof because it uses locale dependant
+// parsing, while CCMX files always use . as decimal separator
+static
+cmsFloat64Number ParseFloatNumber(const char *Buffer)
+{
+ cmsFloat64Number dnum = 0.0;
+ int sign = 1;
+
+ if (*Buffer == '-' || *Buffer == '+') {
+
+ sign = (*Buffer == '-') ? -1 : 1;
+ Buffer++;
+ }
+
+
+ while (*Buffer && isdigit((int) *Buffer)) {
+
+ dnum = dnum * 10.0 + (*Buffer - '0');
+ if (*Buffer) Buffer++;
+ }
+
+ if (*Buffer == '.') {
+
+ cmsFloat64Number frac = 0.0; // fraction
+ int prec = 0; // precission
+
+ if (*Buffer) Buffer++;
+
+ while (*Buffer && isdigit((int) *Buffer)) {
+
+ frac = frac * 10.0 + (*Buffer - '0');
+ prec++;
+ if (*Buffer) Buffer++;
+ }
+
+ dnum = dnum + (frac / xpow10(prec));
+ }
+
+ // Exponent, example 34.00E+20
+ if (*Buffer && toupper(*Buffer) == 'E') {
+
+ int e;
+ int sgn;
+
+ if (*Buffer) Buffer++;
+ sgn = 1;
+
+ if (*Buffer == '-') {
+
+ sgn = -1;
+ if (*Buffer) Buffer++;
+ }
+ else
+ if (*Buffer == '+') {
+
+ sgn = +1;
+ if (*Buffer) Buffer++;
+ }
+
+ e = 0;
+ while (*Buffer && isdigit((int) *Buffer)) {
+
+ if ((cmsFloat64Number) e * 10L < INT_MAX)
+ e = e * 10 + (*Buffer - '0');
+
+ if (*Buffer) Buffer++;
+ }
+
+ e = sgn*e;
+ dnum = dnum * xpow10(e);
+ }
+
+ return sign * dnum;
+}
// Reads next symbol
@@ -1011,7 +1090,7 @@
cmsUInt32Number Free = it8 ->Allocator.BlockSize - it8 ->Allocator.Used;
cmsUInt8Number* ptr;
- size = _cmsALIGNLONG(size);
+ size = _cmsALIGNMEM(size);
if (size > Free) {
@@ -1212,7 +1291,7 @@
cmsHANDLE CMSEXPORT cmsIT8Alloc(cmsContext ContextID)
{
cmsIT8* it8;
- int i;
+ cmsUInt32Number i;
it8 = (cmsIT8*) _cmsMallocZero(ContextID, sizeof(cmsIT8));
if (it8 == NULL) return NULL;
@@ -1243,7 +1322,7 @@
it8 -> lineno = 1;
strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT);
- strcpy(it8->SheetType, "CGATS.17");
+ cmsIT8SetSheetType((cmsHANDLE) it8, "CGATS.17");
// Initialize predefined properties & data
@@ -1260,18 +1339,15 @@
const char* CMSEXPORT cmsIT8GetSheetType(cmsHANDLE hIT8)
{
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- return it8 ->SheetType;
-
+ return GetTable((cmsIT8*) hIT8)->SheetType;
}
cmsBool CMSEXPORT cmsIT8SetSheetType(cmsHANDLE hIT8, const char* Type)
{
- cmsIT8* it8 = (cmsIT8*) hIT8;
-
- strncpy(it8 ->SheetType, Type, MAXSTR-1);
- it8 ->SheetType[MAXSTR-1] = 0;
+ TABLE* t = GetTable((cmsIT8*) hIT8);
+
+ strncpy(t ->SheetType, Type, MAXSTR-1);
+ t ->SheetType[MAXSTR-1] = 0;
return TRUE;
}
@@ -1285,8 +1361,6 @@
return AddToList(it8, &GetTable(it8)->HeaderList, "# ", NULL, Val, WRITE_UNCOOKED) != NULL;
}
-
-
// Sets a property
cmsBool CMSEXPORT cmsIT8SetPropertyStr(cmsHANDLE hIT8, const char* Key, const char *Val)
{
@@ -1298,7 +1372,6 @@
return AddToList(it8, &GetTable(it8)->HeaderList, Key, NULL, Val, WRITE_STRINGIFY) != NULL;
}
-
cmsBool CMSEXPORT cmsIT8SetPropertyDbl(cmsHANDLE hIT8, const char* cProp, cmsFloat64Number Val)
{
cmsIT8* it8 = (cmsIT8*) hIT8;
@@ -1351,8 +1424,7 @@
{
const char *v = cmsIT8GetProperty(hIT8, cProp);
- if (v) return atof(v);
- else return 0.0;
+ return ParseFloatNumber(v);
}
const char* CMSEXPORT cmsIT8GetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char *SubKey)
@@ -1553,6 +1625,9 @@
KEYVALUE* p;
TABLE* t = GetTable(it8);
+ // Writes the type
+ WriteStr(fp, t->SheetType);
+ WriteStr(fp, "\n");
for (p = t->HeaderList; (p != NULL); p = p->Next)
{
@@ -1701,8 +1776,6 @@
sd.stream = fopen(cFileName, "wt");
if (!sd.stream) return FALSE;
- WriteStr(&sd, it8->SheetType);
- WriteStr(&sd, "\n");
for (i=0; i < it8 ->TablesCount; i++) {
cmsIT8SetTable(hIT8, i);
@@ -1737,20 +1810,18 @@
else
sd.Max = 0; // Just counting the needed bytes
- WriteStr(&sd, it8->SheetType);
- WriteStr(&sd, "\n");
for (i=0; i < it8 ->TablesCount; i++) {
- cmsIT8SetTable(hIT8, i);
- WriteHeader(it8, &sd);
- WriteDataFormat(&sd, it8);
- WriteData(&sd, it8);
+ cmsIT8SetTable(hIT8, i);
+ WriteHeader(it8, &sd);
+ WriteDataFormat(&sd, it8);
+ WriteData(&sd, it8);
}
sd.Used++; // The \0 at the very end
if (sd.Base)
- sd.Ptr = 0;
+ *sd.Ptr = 0;
*BytesNeeded = sd.Used;
@@ -1963,12 +2034,8 @@
static
-cmsBool ParseIT8(cmsIT8* it8, cmsBool nosheet)
+void ReadType(cmsIT8* it8, char* SheetTypePtr)
{
- char* SheetTypePtr = it8 ->SheetType;
-
- if (nosheet == 0) {
-
// First line is a very special case.
while (isseparator(it8->ch))
@@ -1979,9 +2046,20 @@
*SheetTypePtr++= (char) it8 ->ch;
NextCh(it8);
}
- }
*SheetTypePtr = 0;
+}
+
+
+static
+cmsBool ParseIT8(cmsIT8* it8, cmsBool nosheet)
+{
+ char* SheetTypePtr = it8 ->Tab[0].SheetType;
+
+ if (nosheet == 0) {
+ ReadType(it8, SheetTypePtr);
+ }
+
InSymbol(it8);
SkipEOLN(it8);
@@ -2003,6 +2081,39 @@
AllocTable(it8);
it8 ->nTable = it8 ->TablesCount - 1;
+
+ // Read sheet type if present. We only support identifier and string.
+ // <ident> <eoln> is a type string
+ // anything else, is not a type string
+ if (nosheet == 0) {
+
+ if (it8 ->sy == SIDENT) {
+
+ // May be a type sheet or may be a prop value statement. We cannot use insymbol in
+ // this special case...
+ while (isseparator(it8->ch))
+ NextCh(it8);
+
+ // If a newline is found, then this is a type string
+ if (it8 ->ch == '\n') {
+
+ cmsIT8SetSheetType(it8, it8 ->id);
+ InSymbol(it8);
+ }
+ else
+ {
+ // It is not. Just continue
+ cmsIT8SetSheetType(it8, "");
+ }
+ }
+ else
+ // Validate quoted strings
+ if (it8 ->sy == SSTRING) {
+ cmsIT8SetSheetType(it8, it8 ->str);
+ InSymbol(it8);
+ }
+ }
+
}
break;
@@ -2123,14 +2234,14 @@
// Try to infere if the file is a CGATS/IT8 file at all. Read first line
// that should be something like some printable characters plus a \n
-
+// returns 0 if this is not like a CGATS, or an integer otherwise. This integer is the number of words in first line?
static
int IsMyBlock(cmsUInt8Number* Buffer, int n)
{
- int cols = 1, space = 0, quot = 0;
+ int words = 1, space = 0, quot = 0;
int i;
- if (n < 10) return FALSE; // Too small
+ if (n < 10) return 0; // Too small
if (n > 132)
n = 132;
@@ -2141,7 +2252,7 @@
{
case '\n':
case '\r':
- return quot == 1 || cols > 2 ? 0 : cols;
+ return ((quot == 1) || (words > 2)) ? 0 : words;
case '\t':
case ' ':
if(!quot && !space)
@@ -2153,14 +2264,13 @@
default:
if (Buffer[i] < 32) return 0;
if (Buffer[i] > 127) return 0;
- cols += space;
+ words += space;
space = 0;
break;
}
}
- return FALSE;
-
+ return 0;
}
@@ -2271,7 +2381,7 @@
it8 ->nTable = 0;
if (fclose(it8 ->FileStack[0]->Stream)!= 0) {
- cmsIT8Free(hIT8);
+ cmsIT8Free(hIT8);
return NULL;
}
@@ -2454,13 +2564,7 @@
Buffer = cmsIT8GetDataRowCol(hIT8, row, col);
- if (Buffer) {
-
- return atof(Buffer);
-
- } else
- return 0;
-
+ return ParseFloatNumber(Buffer);
}
@@ -2515,14 +2619,7 @@
Buffer = cmsIT8GetData(it8, cPatch, cSample);
- if (Buffer) {
-
- return atof(Buffer);
-
- } else {
-
- return 0;
- }
+ return ParseFloatNumber(Buffer);
}
@@ -2680,5 +2777,7 @@
strcpy(it8->DoubleFormatter, DEFAULT_DBL_FORMAT);
else
strcpy(it8->DoubleFormatter, Formatter);
+
+ it8 ->DoubleFormatter[sizeof(it8 ->DoubleFormatter)-1] = 0;
}
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -193,17 +193,21 @@
static
cmsFloat64Number CHAD2Temp(const cmsMAT3* Chad)
{
- // Convert D50 across CHAD to get the absolute white point
- cmsVEC3 d, s;
- cmsCIEXYZ Dest;
- cmsCIExyY DestChromaticity;
- cmsFloat64Number TempK;
+ // Convert D50 across inverse CHAD to get the absolute white point
+ cmsVEC3 d, s;
+ cmsCIEXYZ Dest;
+ cmsCIExyY DestChromaticity;
+ cmsFloat64Number TempK;
+ cmsMAT3 m1, m2;
+
+ m1 = *Chad;
+ if (!_cmsMAT3inverse(&m1, &m2)) return FALSE;
s.n[VX] = cmsD50_XYZ() -> X;
s.n[VY] = cmsD50_XYZ() -> Y;
s.n[VZ] = cmsD50_XYZ() -> Z;
- _cmsMAT3eval(&d, Chad, &s);
+ _cmsMAT3eval(&d, &m2, &s);
Dest.X = d.n[VX];
Dest.Y = d.n[VY];
@@ -219,15 +223,14 @@
// Compute a CHAD based on a given temperature
static
-void Temp2CHAD(cmsMAT3* Chad, cmsFloat64Number Temp)
+ void Temp2CHAD(cmsMAT3* Chad, cmsFloat64Number Temp)
{
cmsCIEXYZ White;
cmsCIExyY ChromaticityOfWhite;
cmsWhitePointFromTemp(&ChromaticityOfWhite, Temp);
cmsxyY2XYZ(&White, &ChromaticityOfWhite);
- _cmsAdaptationMatrix(Chad, NULL, cmsD50_XYZ(), &White);
-
+ _cmsAdaptationMatrix(Chad, NULL, &White, cmsD50_XYZ());
}
// Join scalings to obtain relative input to absolute and then to relative output.
@@ -240,7 +243,7 @@
const cmsMAT3* ChromaticAdaptationMatrixOut,
cmsMAT3* m)
{
- cmsMAT3 Scale, m1, m2, m3;
+ cmsMAT3 Scale, m1, m2, m3, m4;
// Adaptation state
if (AdaptationState == 1.0) {
@@ -259,23 +262,32 @@
_cmsVEC3init(&Scale.v[1], 0, WhitePointIn->Y / WhitePointOut->Y, 0);
_cmsVEC3init(&Scale.v[2], 0, 0, WhitePointIn->Z / WhitePointOut->Z);
- m1 = *ChromaticAdaptationMatrixIn;
- if (!_cmsMAT3inverse(&m1, &m2)) return FALSE;
- _cmsMAT3per(&m3, &m2, &Scale);
+
+ if (AdaptationState == 0.0) {
- // m3 holds CHAD from input white to D50 times abs. col. scaling
- if (AdaptationState == 0.0) {
+ m1 = *ChromaticAdaptationMatrixOut;
+ _cmsMAT3per(&m2, &m1, &Scale);
+ // m2 holds CHAD from output white to D50 times abs. col. scaling
// Observer is not adapted, undo the chromatic adaptation
_cmsMAT3per(m, &m3, ChromaticAdaptationMatrixOut);
+ m3 = *ChromaticAdaptationMatrixIn;
+ if (!_cmsMAT3inverse(&m3, &m4)) return FALSE;
+ _cmsMAT3per(m, &m2, &m4);
+
} else {
cmsMAT3 MixedCHAD;
cmsFloat64Number TempSrc, TempDest, Temp;
- TempSrc = CHAD2Temp(ChromaticAdaptationMatrixIn); // K for source white
- TempDest = CHAD2Temp(ChromaticAdaptationMatrixOut); // K for dest white
+ m1 = *ChromaticAdaptationMatrixIn;
+ if (!_cmsMAT3inverse(&m1, &m2)) return FALSE;
+ _cmsMAT3per(&m3, &m2, &Scale);
+ // m3 holds CHAD from input white to D50 times abs. col. scaling
+
+ TempSrc = CHAD2Temp(ChromaticAdaptationMatrixIn);
+ TempDest = CHAD2Temp(ChromaticAdaptationMatrixOut);
if (TempSrc < 0.0 || TempDest < 0.0) return FALSE; // Something went wrong
@@ -285,9 +297,9 @@
return TRUE;
}
- Temp = AdaptationState * TempSrc + (1.0 - AdaptationState) * TempDest;
+ Temp = (1.0 - AdaptationState) * TempDest + AdaptationState * TempSrc;
- // Get a CHAD from D50 to whatever output temperature. This replaces output CHAD
+ // Get a CHAD from whatever output temperature to D50. This replaces output CHAD
Temp2CHAD(&MixedCHAD, Temp);
_cmsMAT3per(m, &m3, &MixedCHAD);
@@ -362,7 +374,7 @@
cmsCIEXYZ BlackPointIn, BlackPointOut;
cmsDetectBlackPoint(&BlackPointIn, hProfiles[i-1], Intent, 0);
- cmsDetectBlackPoint(&BlackPointOut, hProfiles[i], Intent, 0);
+ cmsDetectDestinationBlackPoint(&BlackPointOut, hProfiles[i], Intent, 0);
// If black points are equal, then do nothing
if (BlackPointIn.X != BlackPointOut.X ||
@@ -463,6 +475,10 @@
// If they are same, they are compatible.
if (a == b) return TRUE;
+ // Check for MCH4 substitution of CMYK
+ if ((a == cmsSig4colorData) && (b == cmsSigCmykData)) return TRUE;
+ if ((a == cmsSigCmykData) && (b == cmsSig4colorData)) return TRUE;
+
// Check for XYZ/Lab. Those spaces are interchangeable as they can be computed one from other.
if ((a == cmsSigXYZData) && (b == cmsSigLabData)) return TRUE;
if ((a == cmsSigLabData) && (b == cmsSigXYZData)) return TRUE;
@@ -511,7 +527,7 @@
lIsInput = TRUE;
}
else {
- // Else use profile in the input direction if current space is not PCS
+ // Else use profile in the input direction if current space is not PCS
lIsInput = (CurrentColorSpace != cmsSigXYZData) &&
(CurrentColorSpace != cmsSigLabData);
}
@@ -537,7 +553,7 @@
// If devicelink is found, then no custom intent is allowed and we can
// read the LUT to be applied. Settings don't apply here.
- if (lIsDeviceLink) {
+ if (lIsDeviceLink || ((ClassSig == cmsSigNamedColorClass) && (nProfiles == 1))) {
// Get the involved LUT from the profile
Lut = _cmsReadDevicelinkLUT(hProfile, Intent);
@@ -876,7 +892,8 @@
// Check for non-cmyk profiles
if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData ||
- cmsGetColorSpace(hProfiles[nProfiles-1]) != cmsSigCmykData)
+ !(cmsGetColorSpace(hProfiles[nProfiles-1]) == cmsSigCmykData ||
+ cmsGetDeviceClass(hProfiles[nProfiles-1]) == cmsSigOutputClass))
return DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags);
// Allocate an empty LUT for holding the result
@@ -893,6 +910,8 @@
// Get total area coverage (in 0..1 domain)
bp.MaxTAC = cmsDetectTAC(hProfiles[nProfiles-1]) / 100.0;
+ if (bp.MaxTAC <= 0) goto Cleanup;
+
// Create a LUT holding normal ICC transform
bp.cmyk2cmyk = DefaultICCintents(ContextID,
@@ -902,6 +921,7 @@
BPC,
AdaptationStates,
dwFlags);
+ if (bp.cmyk2cmyk == NULL) goto Cleanup;
// Now the tone curve
bp.KTone = _cmsBuildKToneCurve(ContextID, 4096, nProfiles,
@@ -910,7 +930,7 @@
BPC,
AdaptationStates,
dwFlags);
-
+ if (bp.KTone == NULL) goto Cleanup;
// To measure the output, Last profile to Lab
hLab = cmsCreateLab4ProfileTHR(ContextID, NULL);
@@ -918,6 +938,7 @@
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],
@@ -925,6 +946,7 @@
FLOAT_SH(1)|CHANNELS_SH(3)|BYTES_SH(4),
INTENT_RELATIVE_COLORIMETRIC,
cmsFLAGS_NOCACHE|cmsFLAGS_NOOPTIMIZE);
+ if (bp.cmyk2Lab == NULL) goto Cleanup;
cmsCloseProfile(hLab);
// Error estimation (for debug only)
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmserr.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -72,17 +72,21 @@
// long int because C99 specifies ftell in such way (7.19.9.2)
long int CMSEXPORT cmsfilelength(FILE* f)
{
- long int n;
+ long int p , n;
+
+ p = ftell(f); // register current file position
if (fseek(f, 0, SEEK_END) != 0) {
return -1;
}
+
n = ftell(f);
- fseek(f, 0, SEEK_SET);
+ fseek(f, p, SEEK_SET); // file position restored
return n;
}
+
// Memory handling ------------------------------------------------------------------
//
// This is the interface to low-level memory management routines. By default a simple
@@ -160,6 +164,12 @@
{
cmsUInt32Number Total = num * size;
+ // Preserve calloc behaviour
+ if (Total == 0) return NULL;
+
+ // Safe check for overflow.
+ if (num >= UINT_MAX / size) return NULL;
+
// Check for overflow
if (Total < num || Total < size) {
return NULL;
@@ -269,12 +279,16 @@
// Sub allocation takes care of many pointers of small size. The memory allocated in
// this way have be freed at once. Next function allocates a single chunk for linked list
// I prefer this method over realloc due to the big inpact on xput realloc may have if
-// memory is being swapped to disk. This approach is safer (although thats not true on any platform)
+// memory is being swapped to disk. This approach is safer (although that may not be true on all platforms)
static
_cmsSubAllocator_chunk* _cmsCreateSubAllocChunk(cmsContext ContextID, cmsUInt32Number Initial)
{
_cmsSubAllocator_chunk* chunk;
+ // 20K by default
+ if (Initial == 0)
+ Initial = 20*1024;
+
// Create the container
chunk = (_cmsSubAllocator_chunk*) _cmsMallocZero(ContextID, sizeof(_cmsSubAllocator_chunk));
if (chunk == NULL) return NULL;
@@ -288,9 +302,7 @@
return NULL;
}
- // 20K by default
- if (Initial == 0)
- Initial = 20*1024;
+
chunk ->BlockSize = Initial;
chunk ->Used = 0;
@@ -344,7 +356,7 @@
cmsUInt32Number Free = sub -> h ->BlockSize - sub -> h -> Used;
cmsUInt8Number* ptr;
- size = _cmsALIGNLONG(size);
+ size = _cmsALIGNMEM(size);
// Check for memory. If there is no room, allocate a new chunk of double memory size.
if (size > Free) {
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -277,18 +277,28 @@
switch (Type) {
- // X = Y ^ Gamma
+ // X = Y ^ Gamma
case 1:
- if (R < 0)
- Val = 0;
+ if (R < 0) {
+
+ if (fabs(Params[0] - 1.0) < MATRIX_DET_TOLERANCE)
+ Val = R;
+ else
+ Val = 0;
+ }
else
Val = pow(R, Params[0]);
break;
// Type 1 Reversed: X = Y ^1/gamma
case -1:
- if (R < 0)
- Val = 0;
+ if (R < 0) {
+
+ if (fabs(Params[0] - 1.0) < MATRIX_DET_TOLERANCE)
+ Val = R;
+ else
+ Val = 0;
+ }
else
Val = pow(R, 1/Params[0]);
break;
@@ -552,6 +562,19 @@
return MINUS_INF;
}
+// Access to estimated low-res table
+cmsUInt32Number CMSEXPORT cmsGetToneCurveEstimatedTableEntries(const cmsToneCurve* t)
+{
+ _cmsAssert(t != NULL);
+ return t ->nEntries;
+}
+
+const cmsUInt16Number* CMSEXPORT cmsGetToneCurveEstimatedTable(const cmsToneCurve* t)
+{
+ _cmsAssert(t != NULL);
+ return t ->Table16;
+}
+
// Create an empty gamma curve, by using tables. This specifies only the limited-precision part, and leaves the
// floating point description empty.
@@ -828,7 +851,7 @@
cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, const cmsToneCurve* InCurve)
{
cmsToneCurve *out;
- cmsFloat64Number a = 1, b = 0, y, x1, y1, x2, y2;
+ cmsFloat64Number a = 0, b = 0, y, x1, y1, x2, y2;
int i, j;
int Ascending;
@@ -859,6 +882,7 @@
j = GetInterval(y, InCurve->Table16, InCurve->InterpParams);
if (j >= 0) {
+
// Get limits of interval
x1 = InCurve ->Table16[j];
x2 = InCurve ->Table16[j+1];
@@ -883,6 +907,7 @@
out ->Table16[i] = _cmsQuickSaturateWord(a* y + b);
}
+
return out;
}
@@ -891,7 +916,7 @@
{
_cmsAssert(InGamma != NULL);
- return cmsReverseToneCurveEx(InGamma -> nEntries, InGamma);
+ return cmsReverseToneCurveEx(4096, InGamma);
}
// From: Eilers, P.H.C. (1994) Smoothing and interpolation with finite
@@ -1035,20 +1060,42 @@
{
int n;
int i, last;
+ cmsBool lDescending;
_cmsAssert(t != NULL);
- n = t ->nEntries;
- last = t ->Table16[n-1];
+ // Degenerated curves are monotonic? Ok, let's pass them
+ n = t ->nEntries;
+ if (n < 2) return TRUE;
- for (i = n-2; i >= 0; --i) {
+ // Curve direction
+ lDescending = cmsIsToneCurveDescending(t);
+
+ if (lDescending) {
+
+ last = t ->Table16[0];
+
+ for (i = 1; i < n; i++) {
- if (t ->Table16[i] > last)
+ if (t ->Table16[i] - last > 2) // We allow some ripple
+ return FALSE;
+ else
+ last = t ->Table16[i];
+
+ }
+ }
+ else {
- return FALSE;
- else
- last = t ->Table16[i];
+ last = t ->Table16[n-1];
+
+ for (i = n-2; i >= 0; --i) {
+ if (t ->Table16[i] - last > 2)
+ return FALSE;
+ else
+ last = t ->Table16[i];
+
+ }
}
return TRUE;
@@ -1163,4 +1210,3 @@
return (sum / n); // The mean
}
-
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -212,7 +212,6 @@
// Make sure it is monotonic
if (!cmsIsToneCurveMonotonic(KTone)) {
-
cmsFreeToneCurve(KTone);
return NULL;
}
@@ -246,7 +245,7 @@
GAMUTCHAIN* t = (GAMUTCHAIN* ) Cargo;
cmsCIELab LabIn1, LabOut1;
cmsCIELab LabIn2, LabOut2;
- cmsFloat32Number Proof[cmsMAXCHANNELS], Proof2[cmsMAXCHANNELS];
+ cmsUInt16Number Proof[cmsMAXCHANNELS], Proof2[cmsMAXCHANNELS];
cmsFloat64Number dE1, dE2, ErrorRatio;
// Assume in-gamut by default.
@@ -396,8 +395,8 @@
cmsFLAGS_NOCACHE);
- // Does create the forward step. Lab double to cmsFloat32Number
- dwFormat = (FLOAT_SH(1)|CHANNELS_SH(nChannels)|BYTES_SH(4));
+ // Does create the forward step. Lab double to device
+ dwFormat = (CHANNELS_SH(nChannels)|BYTES_SH(2));
Chain.hForward = cmsCreateTransformTHR(ContextID,
hLab, TYPE_Lab_DBL,
hGamut, dwFormat,
@@ -421,10 +420,10 @@
if (Gamut != NULL) {
- CLUT = cmsStageAllocCLut16bit(ContextID, nGridpoints, nChannels, 1, NULL);
- cmsPipelineInsertStage(Gamut, cmsAT_BEGIN, CLUT);
+ CLUT = cmsStageAllocCLut16bit(ContextID, nGridpoints, nChannels, 1, NULL);
+ cmsPipelineInsertStage(Gamut, cmsAT_BEGIN, CLUT);
- cmsStageSampleCLut16bit(CLUT, GamutSampler, (void*) &Chain, 0);
+ cmsStageSampleCLut16bit(CLUT, GamutSampler, (void*) &Chain, 0);
}
}
else
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmshalf.c Fri Nov 02 17:32:30 2012 -0700
@@ -0,0 +1,564 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// This file is available under and governed by the GNU General Public
+// License version 2 only, as published by the Free Software Foundation.
+// However, the following notice accompanied the original version of this
+// file:
+//
+//---------------------------------------------------------------------------------
+//
+// Little Color Management System
+// Copyright (c) 1998-2012 Marti Maria Saguer
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the Software
+// is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//---------------------------------------------------------------------------------
+//
+//
+#include "lcms2_internal.h"
+
+#ifndef CMS_NO_HALF_SUPPORT
+
+// This code is inspired in the paper "Fast Half Float Conversions"
+// by Jeroen van der Zijp
+
+static cmsUInt32Number Mantissa[2048] = {
+
+0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34a00000,
+0x34c00000, 0x34e00000, 0x35000000, 0x35100000, 0x35200000, 0x35300000,
+0x35400000, 0x35500000, 0x35600000, 0x35700000, 0x35800000, 0x35880000,
+0x35900000, 0x35980000, 0x35a00000, 0x35a80000, 0x35b00000, 0x35b80000,
+0x35c00000, 0x35c80000, 0x35d00000, 0x35d80000, 0x35e00000, 0x35e80000,
+0x35f00000, 0x35f80000, 0x36000000, 0x36040000, 0x36080000, 0x360c0000,
+0x36100000, 0x36140000, 0x36180000, 0x361c0000, 0x36200000, 0x36240000,
+0x36280000, 0x362c0000, 0x36300000, 0x36340000, 0x36380000, 0x363c0000,
+0x36400000, 0x36440000, 0x36480000, 0x364c0000, 0x36500000, 0x36540000,
+0x36580000, 0x365c0000, 0x36600000, 0x36640000, 0x36680000, 0x366c0000,
+0x36700000, 0x36740000, 0x36780000, 0x367c0000, 0x36800000, 0x36820000,
+0x36840000, 0x36860000, 0x36880000, 0x368a0000, 0x368c0000, 0x368e0000,
+0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369a0000,
+0x369c0000, 0x369e0000, 0x36a00000, 0x36a20000, 0x36a40000, 0x36a60000,
+0x36a80000, 0x36aa0000, 0x36ac0000, 0x36ae0000, 0x36b00000, 0x36b20000,
+0x36b40000, 0x36b60000, 0x36b80000, 0x36ba0000, 0x36bc0000, 0x36be0000,
+0x36c00000, 0x36c20000, 0x36c40000, 0x36c60000, 0x36c80000, 0x36ca0000,
+0x36cc0000, 0x36ce0000, 0x36d00000, 0x36d20000, 0x36d40000, 0x36d60000,
+0x36d80000, 0x36da0000, 0x36dc0000, 0x36de0000, 0x36e00000, 0x36e20000,
+0x36e40000, 0x36e60000, 0x36e80000, 0x36ea0000, 0x36ec0000, 0x36ee0000,
+0x36f00000, 0x36f20000, 0x36f40000, 0x36f60000, 0x36f80000, 0x36fa0000,
+0x36fc0000, 0x36fe0000, 0x37000000, 0x37010000, 0x37020000, 0x37030000,
+0x37040000, 0x37050000, 0x37060000, 0x37070000, 0x37080000, 0x37090000,
+0x370a0000, 0x370b0000, 0x370c0000, 0x370d0000, 0x370e0000, 0x370f0000,
+0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000,
+0x37160000, 0x37170000, 0x37180000, 0x37190000, 0x371a0000, 0x371b0000,
+0x371c0000, 0x371d0000, 0x371e0000, 0x371f0000, 0x37200000, 0x37210000,
+0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000,
+0x37280000, 0x37290000, 0x372a0000, 0x372b0000, 0x372c0000, 0x372d0000,
+0x372e0000, 0x372f0000, 0x37300000, 0x37310000, 0x37320000, 0x37330000,
+0x37340000, 0x37350000, 0x37360000, 0x37370000, 0x37380000, 0x37390000,
+0x373a0000, 0x373b0000, 0x373c0000, 0x373d0000, 0x373e0000, 0x373f0000,
+0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000,
+0x37460000, 0x37470000, 0x37480000, 0x37490000, 0x374a0000, 0x374b0000,
+0x374c0000, 0x374d0000, 0x374e0000, 0x374f0000, 0x37500000, 0x37510000,
+0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000,
+0x37580000, 0x37590000, 0x375a0000, 0x375b0000, 0x375c0000, 0x375d0000,
+0x375e0000, 0x375f0000, 0x37600000, 0x37610000, 0x37620000, 0x37630000,
+0x37640000, 0x37650000, 0x37660000, 0x37670000, 0x37680000, 0x37690000,
+0x376a0000, 0x376b0000, 0x376c0000, 0x376d0000, 0x376e0000, 0x376f0000,
+0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000,
+0x37760000, 0x37770000, 0x37780000, 0x37790000, 0x377a0000, 0x377b0000,
+0x377c0000, 0x377d0000, 0x377e0000, 0x377f0000, 0x37800000, 0x37808000,
+0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000,
+0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000,
+0x37870000, 0x37878000, 0x37880000, 0x37888000, 0x37890000, 0x37898000,
+0x378a0000, 0x378a8000, 0x378b0000, 0x378b8000, 0x378c0000, 0x378c8000,
+0x378d0000, 0x378d8000, 0x378e0000, 0x378e8000, 0x378f0000, 0x378f8000,
+0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000,
+0x37930000, 0x37938000, 0x37940000, 0x37948000, 0x37950000, 0x37958000,
+0x37960000, 0x37968000, 0x37970000, 0x37978000, 0x37980000, 0x37988000,
+0x37990000, 0x37998000, 0x379a0000, 0x379a8000, 0x379b0000, 0x379b8000,
+0x379c0000, 0x379c8000, 0x379d0000, 0x379d8000, 0x379e0000, 0x379e8000,
+0x379f0000, 0x379f8000, 0x37a00000, 0x37a08000, 0x37a10000, 0x37a18000,
+0x37a20000, 0x37a28000, 0x37a30000, 0x37a38000, 0x37a40000, 0x37a48000,
+0x37a50000, 0x37a58000, 0x37a60000, 0x37a68000, 0x37a70000, 0x37a78000,
+0x37a80000, 0x37a88000, 0x37a90000, 0x37a98000, 0x37aa0000, 0x37aa8000,
+0x37ab0000, 0x37ab8000, 0x37ac0000, 0x37ac8000, 0x37ad0000, 0x37ad8000,
+0x37ae0000, 0x37ae8000, 0x37af0000, 0x37af8000, 0x37b00000, 0x37b08000,
+0x37b10000, 0x37b18000, 0x37b20000, 0x37b28000, 0x37b30000, 0x37b38000,
+0x37b40000, 0x37b48000, 0x37b50000, 0x37b58000, 0x37b60000, 0x37b68000,
+0x37b70000, 0x37b78000, 0x37b80000, 0x37b88000, 0x37b90000, 0x37b98000,
+0x37ba0000, 0x37ba8000, 0x37bb0000, 0x37bb8000, 0x37bc0000, 0x37bc8000,
+0x37bd0000, 0x37bd8000, 0x37be0000, 0x37be8000, 0x37bf0000, 0x37bf8000,
+0x37c00000, 0x37c08000, 0x37c10000, 0x37c18000, 0x37c20000, 0x37c28000,
+0x37c30000, 0x37c38000, 0x37c40000, 0x37c48000, 0x37c50000, 0x37c58000,
+0x37c60000, 0x37c68000, 0x37c70000, 0x37c78000, 0x37c80000, 0x37c88000,
+0x37c90000, 0x37c98000, 0x37ca0000, 0x37ca8000, 0x37cb0000, 0x37cb8000,
+0x37cc0000, 0x37cc8000, 0x37cd0000, 0x37cd8000, 0x37ce0000, 0x37ce8000,
+0x37cf0000, 0x37cf8000, 0x37d00000, 0x37d08000, 0x37d10000, 0x37d18000,
+0x37d20000, 0x37d28000, 0x37d30000, 0x37d38000, 0x37d40000, 0x37d48000,
+0x37d50000, 0x37d58000, 0x37d60000, 0x37d68000, 0x37d70000, 0x37d78000,
+0x37d80000, 0x37d88000, 0x37d90000, 0x37d98000, 0x37da0000, 0x37da8000,
+0x37db0000, 0x37db8000, 0x37dc0000, 0x37dc8000, 0x37dd0000, 0x37dd8000,
+0x37de0000, 0x37de8000, 0x37df0000, 0x37df8000, 0x37e00000, 0x37e08000,
+0x37e10000, 0x37e18000, 0x37e20000, 0x37e28000, 0x37e30000, 0x37e38000,
+0x37e40000, 0x37e48000, 0x37e50000, 0x37e58000, 0x37e60000, 0x37e68000,
+0x37e70000, 0x37e78000, 0x37e80000, 0x37e88000, 0x37e90000, 0x37e98000,
+0x37ea0000, 0x37ea8000, 0x37eb0000, 0x37eb8000, 0x37ec0000, 0x37ec8000,
+0x37ed0000, 0x37ed8000, 0x37ee0000, 0x37ee8000, 0x37ef0000, 0x37ef8000,
+0x37f00000, 0x37f08000, 0x37f10000, 0x37f18000, 0x37f20000, 0x37f28000,
+0x37f30000, 0x37f38000, 0x37f40000, 0x37f48000, 0x37f50000, 0x37f58000,
+0x37f60000, 0x37f68000, 0x37f70000, 0x37f78000, 0x37f80000, 0x37f88000,
+0x37f90000, 0x37f98000, 0x37fa0000, 0x37fa8000, 0x37fb0000, 0x37fb8000,
+0x37fc0000, 0x37fc8000, 0x37fd0000, 0x37fd8000, 0x37fe0000, 0x37fe8000,
+0x37ff0000, 0x37ff8000, 0x38000000, 0x38004000, 0x38008000, 0x3800c000,
+0x38010000, 0x38014000, 0x38018000, 0x3801c000, 0x38020000, 0x38024000,
+0x38028000, 0x3802c000, 0x38030000, 0x38034000, 0x38038000, 0x3803c000,
+0x38040000, 0x38044000, 0x38048000, 0x3804c000, 0x38050000, 0x38054000,
+0x38058000, 0x3805c000, 0x38060000, 0x38064000, 0x38068000, 0x3806c000,
+0x38070000, 0x38074000, 0x38078000, 0x3807c000, 0x38080000, 0x38084000,
+0x38088000, 0x3808c000, 0x38090000, 0x38094000, 0x38098000, 0x3809c000,
+0x380a0000, 0x380a4000, 0x380a8000, 0x380ac000, 0x380b0000, 0x380b4000,
+0x380b8000, 0x380bc000, 0x380c0000, 0x380c4000, 0x380c8000, 0x380cc000,
+0x380d0000, 0x380d4000, 0x380d8000, 0x380dc000, 0x380e0000, 0x380e4000,
+0x380e8000, 0x380ec000, 0x380f0000, 0x380f4000, 0x380f8000, 0x380fc000,
+0x38100000, 0x38104000, 0x38108000, 0x3810c000, 0x38110000, 0x38114000,
+0x38118000, 0x3811c000, 0x38120000, 0x38124000, 0x38128000, 0x3812c000,
+0x38130000, 0x38134000, 0x38138000, 0x3813c000, 0x38140000, 0x38144000,
+0x38148000, 0x3814c000, 0x38150000, 0x38154000, 0x38158000, 0x3815c000,
+0x38160000, 0x38164000, 0x38168000, 0x3816c000, 0x38170000, 0x38174000,
+0x38178000, 0x3817c000, 0x38180000, 0x38184000, 0x38188000, 0x3818c000,
+0x38190000, 0x38194000, 0x38198000, 0x3819c000, 0x381a0000, 0x381a4000,
+0x381a8000, 0x381ac000, 0x381b0000, 0x381b4000, 0x381b8000, 0x381bc000,
+0x381c0000, 0x381c4000, 0x381c8000, 0x381cc000, 0x381d0000, 0x381d4000,
+0x381d8000, 0x381dc000, 0x381e0000, 0x381e4000, 0x381e8000, 0x381ec000,
+0x381f0000, 0x381f4000, 0x381f8000, 0x381fc000, 0x38200000, 0x38204000,
+0x38208000, 0x3820c000, 0x38210000, 0x38214000, 0x38218000, 0x3821c000,
+0x38220000, 0x38224000, 0x38228000, 0x3822c000, 0x38230000, 0x38234000,
+0x38238000, 0x3823c000, 0x38240000, 0x38244000, 0x38248000, 0x3824c000,
+0x38250000, 0x38254000, 0x38258000, 0x3825c000, 0x38260000, 0x38264000,
+0x38268000, 0x3826c000, 0x38270000, 0x38274000, 0x38278000, 0x3827c000,
+0x38280000, 0x38284000, 0x38288000, 0x3828c000, 0x38290000, 0x38294000,
+0x38298000, 0x3829c000, 0x382a0000, 0x382a4000, 0x382a8000, 0x382ac000,
+0x382b0000, 0x382b4000, 0x382b8000, 0x382bc000, 0x382c0000, 0x382c4000,
+0x382c8000, 0x382cc000, 0x382d0000, 0x382d4000, 0x382d8000, 0x382dc000,
+0x382e0000, 0x382e4000, 0x382e8000, 0x382ec000, 0x382f0000, 0x382f4000,
+0x382f8000, 0x382fc000, 0x38300000, 0x38304000, 0x38308000, 0x3830c000,
+0x38310000, 0x38314000, 0x38318000, 0x3831c000, 0x38320000, 0x38324000,
+0x38328000, 0x3832c000, 0x38330000, 0x38334000, 0x38338000, 0x3833c000,
+0x38340000, 0x38344000, 0x38348000, 0x3834c000, 0x38350000, 0x38354000,
+0x38358000, 0x3835c000, 0x38360000, 0x38364000, 0x38368000, 0x3836c000,
+0x38370000, 0x38374000, 0x38378000, 0x3837c000, 0x38380000, 0x38384000,
+0x38388000, 0x3838c000, 0x38390000, 0x38394000, 0x38398000, 0x3839c000,
+0x383a0000, 0x383a4000, 0x383a8000, 0x383ac000, 0x383b0000, 0x383b4000,
+0x383b8000, 0x383bc000, 0x383c0000, 0x383c4000, 0x383c8000, 0x383cc000,
+0x383d0000, 0x383d4000, 0x383d8000, 0x383dc000, 0x383e0000, 0x383e4000,
+0x383e8000, 0x383ec000, 0x383f0000, 0x383f4000, 0x383f8000, 0x383fc000,
+0x38400000, 0x38404000, 0x38408000, 0x3840c000, 0x38410000, 0x38414000,
+0x38418000, 0x3841c000, 0x38420000, 0x38424000, 0x38428000, 0x3842c000,
+0x38430000, 0x38434000, 0x38438000, 0x3843c000, 0x38440000, 0x38444000,
+0x38448000, 0x3844c000, 0x38450000, 0x38454000, 0x38458000, 0x3845c000,
+0x38460000, 0x38464000, 0x38468000, 0x3846c000, 0x38470000, 0x38474000,
+0x38478000, 0x3847c000, 0x38480000, 0x38484000, 0x38488000, 0x3848c000,
+0x38490000, 0x38494000, 0x38498000, 0x3849c000, 0x384a0000, 0x384a4000,
+0x384a8000, 0x384ac000, 0x384b0000, 0x384b4000, 0x384b8000, 0x384bc000,
+0x384c0000, 0x384c4000, 0x384c8000, 0x384cc000, 0x384d0000, 0x384d4000,
+0x384d8000, 0x384dc000, 0x384e0000, 0x384e4000, 0x384e8000, 0x384ec000,
+0x384f0000, 0x384f4000, 0x384f8000, 0x384fc000, 0x38500000, 0x38504000,
+0x38508000, 0x3850c000, 0x38510000, 0x38514000, 0x38518000, 0x3851c000,
+0x38520000, 0x38524000, 0x38528000, 0x3852c000, 0x38530000, 0x38534000,
+0x38538000, 0x3853c000, 0x38540000, 0x38544000, 0x38548000, 0x3854c000,
+0x38550000, 0x38554000, 0x38558000, 0x3855c000, 0x38560000, 0x38564000,
+0x38568000, 0x3856c000, 0x38570000, 0x38574000, 0x38578000, 0x3857c000,
+0x38580000, 0x38584000, 0x38588000, 0x3858c000, 0x38590000, 0x38594000,
+0x38598000, 0x3859c000, 0x385a0000, 0x385a4000, 0x385a8000, 0x385ac000,
+0x385b0000, 0x385b4000, 0x385b8000, 0x385bc000, 0x385c0000, 0x385c4000,
+0x385c8000, 0x385cc000, 0x385d0000, 0x385d4000, 0x385d8000, 0x385dc000,
+0x385e0000, 0x385e4000, 0x385e8000, 0x385ec000, 0x385f0000, 0x385f4000,
+0x385f8000, 0x385fc000, 0x38600000, 0x38604000, 0x38608000, 0x3860c000,
+0x38610000, 0x38614000, 0x38618000, 0x3861c000, 0x38620000, 0x38624000,
+0x38628000, 0x3862c000, 0x38630000, 0x38634000, 0x38638000, 0x3863c000,
+0x38640000, 0x38644000, 0x38648000, 0x3864c000, 0x38650000, 0x38654000,
+0x38658000, 0x3865c000, 0x38660000, 0x38664000, 0x38668000, 0x3866c000,
+0x38670000, 0x38674000, 0x38678000, 0x3867c000, 0x38680000, 0x38684000,
+0x38688000, 0x3868c000, 0x38690000, 0x38694000, 0x38698000, 0x3869c000,
+0x386a0000, 0x386a4000, 0x386a8000, 0x386ac000, 0x386b0000, 0x386b4000,
+0x386b8000, 0x386bc000, 0x386c0000, 0x386c4000, 0x386c8000, 0x386cc000,
+0x386d0000, 0x386d4000, 0x386d8000, 0x386dc000, 0x386e0000, 0x386e4000,
+0x386e8000, 0x386ec000, 0x386f0000, 0x386f4000, 0x386f8000, 0x386fc000,
+0x38700000, 0x38704000, 0x38708000, 0x3870c000, 0x38710000, 0x38714000,
+0x38718000, 0x3871c000, 0x38720000, 0x38724000, 0x38728000, 0x3872c000,
+0x38730000, 0x38734000, 0x38738000, 0x3873c000, 0x38740000, 0x38744000,
+0x38748000, 0x3874c000, 0x38750000, 0x38754000, 0x38758000, 0x3875c000,
+0x38760000, 0x38764000, 0x38768000, 0x3876c000, 0x38770000, 0x38774000,
+0x38778000, 0x3877c000, 0x38780000, 0x38784000, 0x38788000, 0x3878c000,
+0x38790000, 0x38794000, 0x38798000, 0x3879c000, 0x387a0000, 0x387a4000,
+0x387a8000, 0x387ac000, 0x387b0000, 0x387b4000, 0x387b8000, 0x387bc000,
+0x387c0000, 0x387c4000, 0x387c8000, 0x387cc000, 0x387d0000, 0x387d4000,
+0x387d8000, 0x387dc000, 0x387e0000, 0x387e4000, 0x387e8000, 0x387ec000,
+0x387f0000, 0x387f4000, 0x387f8000, 0x387fc000, 0x38000000, 0x38002000,
+0x38004000, 0x38006000, 0x38008000, 0x3800a000, 0x3800c000, 0x3800e000,
+0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801a000,
+0x3801c000, 0x3801e000, 0x38020000, 0x38022000, 0x38024000, 0x38026000,
+0x38028000, 0x3802a000, 0x3802c000, 0x3802e000, 0x38030000, 0x38032000,
+0x38034000, 0x38036000, 0x38038000, 0x3803a000, 0x3803c000, 0x3803e000,
+0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804a000,
+0x3804c000, 0x3804e000, 0x38050000, 0x38052000, 0x38054000, 0x38056000,
+0x38058000, 0x3805a000, 0x3805c000, 0x3805e000, 0x38060000, 0x38062000,
+0x38064000, 0x38066000, 0x38068000, 0x3806a000, 0x3806c000, 0x3806e000,
+0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807a000,
+0x3807c000, 0x3807e000, 0x38080000, 0x38082000, 0x38084000, 0x38086000,
+0x38088000, 0x3808a000, 0x3808c000, 0x3808e000, 0x38090000, 0x38092000,
+0x38094000, 0x38096000, 0x38098000, 0x3809a000, 0x3809c000, 0x3809e000,
+0x380a0000, 0x380a2000, 0x380a4000, 0x380a6000, 0x380a8000, 0x380aa000,
+0x380ac000, 0x380ae000, 0x380b0000, 0x380b2000, 0x380b4000, 0x380b6000,
+0x380b8000, 0x380ba000, 0x380bc000, 0x380be000, 0x380c0000, 0x380c2000,
+0x380c4000, 0x380c6000, 0x380c8000, 0x380ca000, 0x380cc000, 0x380ce000,
+0x380d0000, 0x380d2000, 0x380d4000, 0x380d6000, 0x380d8000, 0x380da000,
+0x380dc000, 0x380de000, 0x380e0000, 0x380e2000, 0x380e4000, 0x380e6000,
+0x380e8000, 0x380ea000, 0x380ec000, 0x380ee000, 0x380f0000, 0x380f2000,
+0x380f4000, 0x380f6000, 0x380f8000, 0x380fa000, 0x380fc000, 0x380fe000,
+0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810a000,
+0x3810c000, 0x3810e000, 0x38110000, 0x38112000, 0x38114000, 0x38116000,
+0x38118000, 0x3811a000, 0x3811c000, 0x3811e000, 0x38120000, 0x38122000,
+0x38124000, 0x38126000, 0x38128000, 0x3812a000, 0x3812c000, 0x3812e000,
+0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813a000,
+0x3813c000, 0x3813e000, 0x38140000, 0x38142000, 0x38144000, 0x38146000,
+0x38148000, 0x3814a000, 0x3814c000, 0x3814e000, 0x38150000, 0x38152000,
+0x38154000, 0x38156000, 0x38158000, 0x3815a000, 0x3815c000, 0x3815e000,
+0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816a000,
+0x3816c000, 0x3816e000, 0x38170000, 0x38172000, 0x38174000, 0x38176000,
+0x38178000, 0x3817a000, 0x3817c000, 0x3817e000, 0x38180000, 0x38182000,
+0x38184000, 0x38186000, 0x38188000, 0x3818a000, 0x3818c000, 0x3818e000,
+0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819a000,
+0x3819c000, 0x3819e000, 0x381a0000, 0x381a2000, 0x381a4000, 0x381a6000,
+0x381a8000, 0x381aa000, 0x381ac000, 0x381ae000, 0x381b0000, 0x381b2000,
+0x381b4000, 0x381b6000, 0x381b8000, 0x381ba000, 0x381bc000, 0x381be000,
+0x381c0000, 0x381c2000, 0x381c4000, 0x381c6000, 0x381c8000, 0x381ca000,
+0x381cc000, 0x381ce000, 0x381d0000, 0x381d2000, 0x381d4000, 0x381d6000,
+0x381d8000, 0x381da000, 0x381dc000, 0x381de000, 0x381e0000, 0x381e2000,
+0x381e4000, 0x381e6000, 0x381e8000, 0x381ea000, 0x381ec000, 0x381ee000,
+0x381f0000, 0x381f2000, 0x381f4000, 0x381f6000, 0x381f8000, 0x381fa000,
+0x381fc000, 0x381fe000, 0x38200000, 0x38202000, 0x38204000, 0x38206000,
+0x38208000, 0x3820a000, 0x3820c000, 0x3820e000, 0x38210000, 0x38212000,
+0x38214000, 0x38216000, 0x38218000, 0x3821a000, 0x3821c000, 0x3821e000,
+0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822a000,
+0x3822c000, 0x3822e000, 0x38230000, 0x38232000, 0x38234000, 0x38236000,
+0x38238000, 0x3823a000, 0x3823c000, 0x3823e000, 0x38240000, 0x38242000,
+0x38244000, 0x38246000, 0x38248000, 0x3824a000, 0x3824c000, 0x3824e000,
+0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825a000,
+0x3825c000, 0x3825e000, 0x38260000, 0x38262000, 0x38264000, 0x38266000,
+0x38268000, 0x3826a000, 0x3826c000, 0x3826e000, 0x38270000, 0x38272000,
+0x38274000, 0x38276000, 0x38278000, 0x3827a000, 0x3827c000, 0x3827e000,
+0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828a000,
+0x3828c000, 0x3828e000, 0x38290000, 0x38292000, 0x38294000, 0x38296000,
+0x38298000, 0x3829a000, 0x3829c000, 0x3829e000, 0x382a0000, 0x382a2000,
+0x382a4000, 0x382a6000, 0x382a8000, 0x382aa000, 0x382ac000, 0x382ae000,
+0x382b0000, 0x382b2000, 0x382b4000, 0x382b6000, 0x382b8000, 0x382ba000,
+0x382bc000, 0x382be000, 0x382c0000, 0x382c2000, 0x382c4000, 0x382c6000,
+0x382c8000, 0x382ca000, 0x382cc000, 0x382ce000, 0x382d0000, 0x382d2000,
+0x382d4000, 0x382d6000, 0x382d8000, 0x382da000, 0x382dc000, 0x382de000,
+0x382e0000, 0x382e2000, 0x382e4000, 0x382e6000, 0x382e8000, 0x382ea000,
+0x382ec000, 0x382ee000, 0x382f0000, 0x382f2000, 0x382f4000, 0x382f6000,
+0x382f8000, 0x382fa000, 0x382fc000, 0x382fe000, 0x38300000, 0x38302000,
+0x38304000, 0x38306000, 0x38308000, 0x3830a000, 0x3830c000, 0x3830e000,
+0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831a000,
+0x3831c000, 0x3831e000, 0x38320000, 0x38322000, 0x38324000, 0x38326000,
+0x38328000, 0x3832a000, 0x3832c000, 0x3832e000, 0x38330000, 0x38332000,
+0x38334000, 0x38336000, 0x38338000, 0x3833a000, 0x3833c000, 0x3833e000,
+0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834a000,
+0x3834c000, 0x3834e000, 0x38350000, 0x38352000, 0x38354000, 0x38356000,
+0x38358000, 0x3835a000, 0x3835c000, 0x3835e000, 0x38360000, 0x38362000,
+0x38364000, 0x38366000, 0x38368000, 0x3836a000, 0x3836c000, 0x3836e000,
+0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837a000,
+0x3837c000, 0x3837e000, 0x38380000, 0x38382000, 0x38384000, 0x38386000,
+0x38388000, 0x3838a000, 0x3838c000, 0x3838e000, 0x38390000, 0x38392000,
+0x38394000, 0x38396000, 0x38398000, 0x3839a000, 0x3839c000, 0x3839e000,
+0x383a0000, 0x383a2000, 0x383a4000, 0x383a6000, 0x383a8000, 0x383aa000,
+0x383ac000, 0x383ae000, 0x383b0000, 0x383b2000, 0x383b4000, 0x383b6000,
+0x383b8000, 0x383ba000, 0x383bc000, 0x383be000, 0x383c0000, 0x383c2000,
+0x383c4000, 0x383c6000, 0x383c8000, 0x383ca000, 0x383cc000, 0x383ce000,
+0x383d0000, 0x383d2000, 0x383d4000, 0x383d6000, 0x383d8000, 0x383da000,
+0x383dc000, 0x383de000, 0x383e0000, 0x383e2000, 0x383e4000, 0x383e6000,
+0x383e8000, 0x383ea000, 0x383ec000, 0x383ee000, 0x383f0000, 0x383f2000,
+0x383f4000, 0x383f6000, 0x383f8000, 0x383fa000, 0x383fc000, 0x383fe000,
+0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840a000,
+0x3840c000, 0x3840e000, 0x38410000, 0x38412000, 0x38414000, 0x38416000,
+0x38418000, 0x3841a000, 0x3841c000, 0x3841e000, 0x38420000, 0x38422000,
+0x38424000, 0x38426000, 0x38428000, 0x3842a000, 0x3842c000, 0x3842e000,
+0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843a000,
+0x3843c000, 0x3843e000, 0x38440000, 0x38442000, 0x38444000, 0x38446000,
+0x38448000, 0x3844a000, 0x3844c000, 0x3844e000, 0x38450000, 0x38452000,
+0x38454000, 0x38456000, 0x38458000, 0x3845a000, 0x3845c000, 0x3845e000,
+0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846a000,
+0x3846c000, 0x3846e000, 0x38470000, 0x38472000, 0x38474000, 0x38476000,
+0x38478000, 0x3847a000, 0x3847c000, 0x3847e000, 0x38480000, 0x38482000,
+0x38484000, 0x38486000, 0x38488000, 0x3848a000, 0x3848c000, 0x3848e000,
+0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849a000,
+0x3849c000, 0x3849e000, 0x384a0000, 0x384a2000, 0x384a4000, 0x384a6000,
+0x384a8000, 0x384aa000, 0x384ac000, 0x384ae000, 0x384b0000, 0x384b2000,
+0x384b4000, 0x384b6000, 0x384b8000, 0x384ba000, 0x384bc000, 0x384be000,
+0x384c0000, 0x384c2000, 0x384c4000, 0x384c6000, 0x384c8000, 0x384ca000,
+0x384cc000, 0x384ce000, 0x384d0000, 0x384d2000, 0x384d4000, 0x384d6000,
+0x384d8000, 0x384da000, 0x384dc000, 0x384de000, 0x384e0000, 0x384e2000,
+0x384e4000, 0x384e6000, 0x384e8000, 0x384ea000, 0x384ec000, 0x384ee000,
+0x384f0000, 0x384f2000, 0x384f4000, 0x384f6000, 0x384f8000, 0x384fa000,
+0x384fc000, 0x384fe000, 0x38500000, 0x38502000, 0x38504000, 0x38506000,
+0x38508000, 0x3850a000, 0x3850c000, 0x3850e000, 0x38510000, 0x38512000,
+0x38514000, 0x38516000, 0x38518000, 0x3851a000, 0x3851c000, 0x3851e000,
+0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852a000,
+0x3852c000, 0x3852e000, 0x38530000, 0x38532000, 0x38534000, 0x38536000,
+0x38538000, 0x3853a000, 0x3853c000, 0x3853e000, 0x38540000, 0x38542000,
+0x38544000, 0x38546000, 0x38548000, 0x3854a000, 0x3854c000, 0x3854e000,
+0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855a000,
+0x3855c000, 0x3855e000, 0x38560000, 0x38562000, 0x38564000, 0x38566000,
+0x38568000, 0x3856a000, 0x3856c000, 0x3856e000, 0x38570000, 0x38572000,
+0x38574000, 0x38576000, 0x38578000, 0x3857a000, 0x3857c000, 0x3857e000,
+0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858a000,
+0x3858c000, 0x3858e000, 0x38590000, 0x38592000, 0x38594000, 0x38596000,
+0x38598000, 0x3859a000, 0x3859c000, 0x3859e000, 0x385a0000, 0x385a2000,
+0x385a4000, 0x385a6000, 0x385a8000, 0x385aa000, 0x385ac000, 0x385ae000,
+0x385b0000, 0x385b2000, 0x385b4000, 0x385b6000, 0x385b8000, 0x385ba000,
+0x385bc000, 0x385be000, 0x385c0000, 0x385c2000, 0x385c4000, 0x385c6000,
+0x385c8000, 0x385ca000, 0x385cc000, 0x385ce000, 0x385d0000, 0x385d2000,
+0x385d4000, 0x385d6000, 0x385d8000, 0x385da000, 0x385dc000, 0x385de000,
+0x385e0000, 0x385e2000, 0x385e4000, 0x385e6000, 0x385e8000, 0x385ea000,
+0x385ec000, 0x385ee000, 0x385f0000, 0x385f2000, 0x385f4000, 0x385f6000,
+0x385f8000, 0x385fa000, 0x385fc000, 0x385fe000, 0x38600000, 0x38602000,
+0x38604000, 0x38606000, 0x38608000, 0x3860a000, 0x3860c000, 0x3860e000,
+0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861a000,
+0x3861c000, 0x3861e000, 0x38620000, 0x38622000, 0x38624000, 0x38626000,
+0x38628000, 0x3862a000, 0x3862c000, 0x3862e000, 0x38630000, 0x38632000,
+0x38634000, 0x38636000, 0x38638000, 0x3863a000, 0x3863c000, 0x3863e000,
+0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864a000,
+0x3864c000, 0x3864e000, 0x38650000, 0x38652000, 0x38654000, 0x38656000,
+0x38658000, 0x3865a000, 0x3865c000, 0x3865e000, 0x38660000, 0x38662000,
+0x38664000, 0x38666000, 0x38668000, 0x3866a000, 0x3866c000, 0x3866e000,
+0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867a000,
+0x3867c000, 0x3867e000, 0x38680000, 0x38682000, 0x38684000, 0x38686000,
+0x38688000, 0x3868a000, 0x3868c000, 0x3868e000, 0x38690000, 0x38692000,
+0x38694000, 0x38696000, 0x38698000, 0x3869a000, 0x3869c000, 0x3869e000,
+0x386a0000, 0x386a2000, 0x386a4000, 0x386a6000, 0x386a8000, 0x386aa000,
+0x386ac000, 0x386ae000, 0x386b0000, 0x386b2000, 0x386b4000, 0x386b6000,
+0x386b8000, 0x386ba000, 0x386bc000, 0x386be000, 0x386c0000, 0x386c2000,
+0x386c4000, 0x386c6000, 0x386c8000, 0x386ca000, 0x386cc000, 0x386ce000,
+0x386d0000, 0x386d2000, 0x386d4000, 0x386d6000, 0x386d8000, 0x386da000,
+0x386dc000, 0x386de000, 0x386e0000, 0x386e2000, 0x386e4000, 0x386e6000,
+0x386e8000, 0x386ea000, 0x386ec000, 0x386ee000, 0x386f0000, 0x386f2000,
+0x386f4000, 0x386f6000, 0x386f8000, 0x386fa000, 0x386fc000, 0x386fe000,
+0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870a000,
+0x3870c000, 0x3870e000, 0x38710000, 0x38712000, 0x38714000, 0x38716000,
+0x38718000, 0x3871a000, 0x3871c000, 0x3871e000, 0x38720000, 0x38722000,
+0x38724000, 0x38726000, 0x38728000, 0x3872a000, 0x3872c000, 0x3872e000,
+0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873a000,
+0x3873c000, 0x3873e000, 0x38740000, 0x38742000, 0x38744000, 0x38746000,
+0x38748000, 0x3874a000, 0x3874c000, 0x3874e000, 0x38750000, 0x38752000,
+0x38754000, 0x38756000, 0x38758000, 0x3875a000, 0x3875c000, 0x3875e000,
+0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876a000,
+0x3876c000, 0x3876e000, 0x38770000, 0x38772000, 0x38774000, 0x38776000,
+0x38778000, 0x3877a000, 0x3877c000, 0x3877e000, 0x38780000, 0x38782000,
+0x38784000, 0x38786000, 0x38788000, 0x3878a000, 0x3878c000, 0x3878e000,
+0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879a000,
+0x3879c000, 0x3879e000, 0x387a0000, 0x387a2000, 0x387a4000, 0x387a6000,
+0x387a8000, 0x387aa000, 0x387ac000, 0x387ae000, 0x387b0000, 0x387b2000,
+0x387b4000, 0x387b6000, 0x387b8000, 0x387ba000, 0x387bc000, 0x387be000,
+0x387c0000, 0x387c2000, 0x387c4000, 0x387c6000, 0x387c8000, 0x387ca000,
+0x387cc000, 0x387ce000, 0x387d0000, 0x387d2000, 0x387d4000, 0x387d6000,
+0x387d8000, 0x387da000, 0x387dc000, 0x387de000, 0x387e0000, 0x387e2000,
+0x387e4000, 0x387e6000, 0x387e8000, 0x387ea000, 0x387ec000, 0x387ee000,
+0x387f0000, 0x387f2000, 0x387f4000, 0x387f6000, 0x387f8000, 0x387fa000,
+0x387fc000, 0x387fe000
+};
+
+static cmsUInt16Number Offset[64] = {
+0x0000, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
+0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
+0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
+0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
+0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
+0x0400, 0x0400, 0x0000, 0x0400, 0x0400, 0x0400,
+0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
+0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
+0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
+0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400,
+0x0400, 0x0400, 0x0400, 0x0400
+};
+
+static cmsUInt32Number Exponent[64] = {
+0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000,
+0x03000000, 0x03800000, 0x04000000, 0x04800000, 0x05000000, 0x05800000,
+0x06000000, 0x06800000, 0x07000000, 0x07800000, 0x08000000, 0x08800000,
+0x09000000, 0x09800000, 0x0a000000, 0x0a800000, 0x0b000000, 0x0b800000,
+0x0c000000, 0x0c800000, 0x0d000000, 0x0d800000, 0x0e000000, 0x0e800000,
+0x0f000000, 0x47800000, 0x80000000, 0x80800000, 0x81000000, 0x81800000,
+0x82000000, 0x82800000, 0x83000000, 0x83800000, 0x84000000, 0x84800000,
+0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000,
+0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8a000000, 0x8a800000,
+0x8b000000, 0x8b800000, 0x8c000000, 0x8c800000, 0x8d000000, 0x8d800000,
+0x8e000000, 0x8e800000, 0x8f000000, 0xc7800000
+};
+
+static cmsUInt16Number Base[512] = {
+0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040,
+0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x0c00, 0x1000, 0x1400, 0x1800, 0x1c00,
+0x2000, 0x2400, 0x2800, 0x2c00, 0x3000, 0x3400, 0x3800, 0x3c00, 0x4000, 0x4400,
+0x4800, 0x4c00, 0x5000, 0x5400, 0x5800, 0x5c00, 0x6000, 0x6400, 0x6800, 0x6c00,
+0x7000, 0x7400, 0x7800, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
+0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
+0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
+0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
+0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
+0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
+0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
+0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
+0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
+0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
+0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00,
+0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x7c00, 0x8000, 0x8000, 0x8000, 0x8000,
+0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001,
+0x8002, 0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100, 0x8200, 0x8400,
+0x8800, 0x8c00, 0x9000, 0x9400, 0x9800, 0x9c00, 0xa000, 0xa400, 0xa800, 0xac00,
+0xb000, 0xb400, 0xb800, 0xbc00, 0xc000, 0xc400, 0xc800, 0xcc00, 0xd000, 0xd400,
+0xd800, 0xdc00, 0xe000, 0xe400, 0xe800, 0xec00, 0xf000, 0xf400, 0xf800, 0xfc00,
+0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
+0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
+0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
+0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
+0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
+0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
+0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
+0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
+0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
+0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
+0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00, 0xfc00,
+0xfc00, 0xfc00
+};
+
+static cmsUInt8Number Shift[512] = {
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17,
+0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d,
+0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
+0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0d, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13,
+0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
+0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
+0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x0d
+};
+
+cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h)
+{
+ union {
+ cmsFloat32Number flt;
+ cmsUInt32Number num;
+ } out;
+
+ int n = h >> 10;
+
+ out.num = Mantissa[ (h & 0x3ff) + Offset[ n ] ] + Exponent[ n ];
+ return out.flt;
+}
+
+cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt)
+{
+ union {
+ cmsFloat32Number flt;
+ cmsUInt32Number num;
+ } in;
+
+ cmsUInt32Number n, j;
+
+ in.flt = flt;
+ n = in.num;
+ j = (n >> 23) & 0x1ff;
+
+ return (cmsUInt16Number) ((cmsUInt32Number) Base[ j ] + (( n & 0x007fffff) >> Shift[ j ]));
+}
+
+#endif
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -55,7 +55,7 @@
#include "lcms2_internal.h"
-// This module incorporates several interpolation routines, for 1, 3, 4, 5, 6, 7 and 8 channels on input and
+// This module incorporates several interpolation routines, for 1 to 8 channels on input and
// up to 65535 channels on output. The user may change those by using the interpolation plug-in
// Interpolation routines by default
@@ -83,7 +83,7 @@
// Set the interpolation method
-static
+
cmsBool _cmsSetInterpolationRoutine(cmsInterpParams* p)
{
// Invoke factory, possibly in the Plug-in
@@ -318,6 +318,116 @@
}
}
+// Bilinear interpolation (16 bits) - cmsFloat32Number version
+static
+void BilinearInterpFloat(const cmsFloat32Number Input[],
+ cmsFloat32Number Output[],
+ const cmsInterpParams* p)
+
+{
+# define LERP(a,l,h) (cmsFloat32Number) ((l)+(((h)-(l))*(a)))
+# define DENS(i,j) (LutTable[(i)+(j)+OutChan])
+
+ const cmsFloat32Number* LutTable = (cmsFloat32Number*) p ->Table;
+ cmsFloat32Number px, py;
+ int x0, y0,
+ X0, Y0, X1, Y1;
+ int TotalOut, OutChan;
+ cmsFloat32Number fx, fy,
+ d00, d01, d10, d11,
+ dx0, dx1,
+ dxy;
+
+ TotalOut = p -> nOutputs;
+ px = Input[0] * p->Domain[0];
+ py = Input[1] * p->Domain[1];
+
+ x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0;
+ y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0;
+
+ X0 = p -> opta[1] * x0;
+ X1 = X0 + (Input[0] >= 1.0 ? 0 : p->opta[1]);
+
+ Y0 = p -> opta[0] * y0;
+ Y1 = Y0 + (Input[1] >= 1.0 ? 0 : p->opta[0]);
+
+ for (OutChan = 0; OutChan < TotalOut; OutChan++) {
+
+ d00 = DENS(X0, Y0);
+ d01 = DENS(X0, Y1);
+ d10 = DENS(X1, Y0);
+ d11 = DENS(X1, Y1);
+
+ dx0 = LERP(fx, d00, d10);
+ dx1 = LERP(fx, d01, d11);
+
+ dxy = LERP(fy, dx0, dx1);
+
+ Output[OutChan] = dxy;
+ }
+
+
+# undef LERP
+# undef DENS
+}
+
+// Bilinear interpolation (16 bits) - optimized version
+static
+void BilinearInterp16(register const cmsUInt16Number Input[],
+ register cmsUInt16Number Output[],
+ register const cmsInterpParams* p)
+
+{
+#define DENS(i,j) (LutTable[(i)+(j)+OutChan])
+#define LERP(a,l,h) (cmsUInt16Number) (l + ROUND_FIXED_TO_INT(((h-l)*a)))
+
+ const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
+ int OutChan, TotalOut;
+ cmsS15Fixed16Number fx, fy;
+ register int rx, ry;
+ int x0, y0;
+ register int X0, X1, Y0, Y1;
+ int d00, d01, d10, d11,
+ dx0, dx1,
+ dxy;
+
+ TotalOut = p -> nOutputs;
+
+ fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
+ x0 = FIXED_TO_INT(fx);
+ rx = FIXED_REST_TO_INT(fx); // Rest in 0..1.0 domain
+
+
+ fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
+ y0 = FIXED_TO_INT(fy);
+ ry = FIXED_REST_TO_INT(fy);
+
+
+ X0 = p -> opta[1] * x0;
+ X1 = X0 + (Input[0] == 0xFFFFU ? 0 : p->opta[1]);
+
+ Y0 = p -> opta[0] * y0;
+ Y1 = Y0 + (Input[1] == 0xFFFFU ? 0 : p->opta[0]);
+
+ for (OutChan = 0; OutChan < TotalOut; OutChan++) {
+
+ d00 = DENS(X0, Y0);
+ d01 = DENS(X0, Y1);
+ d10 = DENS(X1, Y0);
+ d11 = DENS(X1, Y1);
+
+ dx0 = LERP(rx, d00, d10);
+ dx1 = LERP(rx, d01, d11);
+
+ dxy = LERP(ry, dx0, dx1);
+
+ Output[OutChan] = (cmsUInt16Number) dxy;
+ }
+
+
+# undef LERP
+# undef DENS
+}
// Trilinear interpolation (16 bits) - cmsFloat32Number version
@@ -343,9 +453,21 @@
TotalOut = p -> nOutputs;
- px = Input[0] * p->Domain[0];
- py = Input[1] * p->Domain[1];
- pz = Input[2] * p->Domain[2];
+ // We need some clipping here
+ px = Input[0];
+ py = Input[1];
+ pz = Input[2];
+
+ if (px < 0) px = 0;
+ if (px > 1) px = 1;
+ if (py < 0) py = 0;
+ if (py > 1) py = 1;
+ if (pz < 0) pz = 0;
+ if (pz > 1) pz = 1;
+
+ px *= p->Domain[0];
+ py *= p->Domain[1];
+ pz *= p->Domain[2];
x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0;
y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0;
@@ -486,9 +608,21 @@
TotalOut = p -> nOutputs;
- px = Input[0] * p->Domain[0];
- py = Input[1] * p->Domain[1];
- pz = Input[2] * p->Domain[2];
+ // We need some clipping here
+ px = Input[0];
+ py = Input[1];
+ pz = Input[2];
+
+ if (px < 0) px = 0;
+ if (px > 1) px = 1;
+ if (py < 0) py = 0;
+ if (py > 1) py = 1;
+ if (pz < 0) pz = 0;
+ if (pz > 1) pz = 1;
+
+ px *= p->Domain[0];
+ py *= p->Domain[1];
+ pz *= p->Domain[2];
x0 = (int) _cmsQuickFloor(px); rx = (px - (cmsFloat32Number) x0);
y0 = (int) _cmsQuickFloor(py); ry = (py - (cmsFloat32Number) y0);
@@ -570,7 +704,6 @@
-#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
static
void TetrahedralInterp16(register const cmsUInt16Number Input[],
@@ -578,99 +711,131 @@
register const cmsInterpParams* p)
{
const cmsUInt16Number* LutTable = (cmsUInt16Number*) p -> Table;
- cmsS15Fixed16Number fx, fy, fz;
- cmsS15Fixed16Number rx, ry, rz;
- int x0, y0, z0;
- cmsS15Fixed16Number c0, c1, c2, c3, Rest;
- cmsUInt32Number OutChan;
- cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
- cmsUInt32Number TotalOut = p -> nOutputs;
-
+ cmsS15Fixed16Number fx, fy, fz;
+ cmsS15Fixed16Number rx, ry, rz;
+ int x0, y0, z0;
+ cmsS15Fixed16Number c0, c1, c2, c3, Rest;
+ cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
+ cmsUInt32Number TotalOut = p -> nOutputs;
- fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
- fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
- fz = _cmsToFixedDomain((int) Input[2] * p -> Domain[2]);
+ fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
+ fy = _cmsToFixedDomain((int) Input[1] * p -> Domain[1]);
+ fz = _cmsToFixedDomain((int) Input[2] * p -> Domain[2]);
- x0 = FIXED_TO_INT(fx);
- y0 = FIXED_TO_INT(fy);
- z0 = FIXED_TO_INT(fz);
+ x0 = FIXED_TO_INT(fx);
+ y0 = FIXED_TO_INT(fy);
+ z0 = FIXED_TO_INT(fz);
- rx = FIXED_REST_TO_INT(fx);
- ry = FIXED_REST_TO_INT(fy);
- rz = FIXED_REST_TO_INT(fz);
+ rx = FIXED_REST_TO_INT(fx);
+ ry = FIXED_REST_TO_INT(fy);
+ rz = FIXED_REST_TO_INT(fz);
X0 = p -> opta[2] * x0;
- X1 = X0 + (Input[0] == 0xFFFFU ? 0 : p->opta[2]);
+ X1 = (Input[0] == 0xFFFFU ? 0 : p->opta[2]);
Y0 = p -> opta[1] * y0;
- Y1 = Y0 + (Input[1] == 0xFFFFU ? 0 : p->opta[1]);
+ Y1 = (Input[1] == 0xFFFFU ? 0 : p->opta[1]);
Z0 = p -> opta[0] * z0;
- Z1 = Z0 + (Input[2] == 0xFFFFU ? 0 : p->opta[0]);
-
- // These are the 6 Tetrahedral
- for (OutChan=0; OutChan < TotalOut; OutChan++) {
+ Z1 = (Input[2] == 0xFFFFU ? 0 : p->opta[0]);
- c0 = DENS(X0, Y0, Z0);
-
- if (rx >= ry && ry >= rz) {
-
- c1 = DENS(X1, Y0, Z0) - c0;
- c2 = DENS(X1, Y1, Z0) - DENS(X1, Y0, Z0);
- c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0);
+ LutTable = &LutTable[X0+Y0+Z0];
- }
- else
- if (rx >= rz && rz >= ry) {
-
- c1 = DENS(X1, Y0, Z0) - c0;
- c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
- c3 = DENS(X1, Y0, Z1) - DENS(X1, Y0, Z0);
-
- }
- else
- if (rz >= rx && rx >= ry) {
-
- c1 = DENS(X1, Y0, Z1) - DENS(X0, Y0, Z1);
- c2 = DENS(X1, Y1, Z1) - DENS(X1, Y0, Z1);
- c3 = DENS(X0, Y0, Z1) - c0;
-
- }
- else
- if (ry >= rx && rx >= rz) {
+ // Output should be computed as x = ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest))
+ // which expands as: x = (Rest + ((Rest+0x7fff)/0xFFFF) + 0x8000)>>16
+ // This can be replaced by: t = Rest+0x8001, x = (t + (t>>16))>>16
+ // at the cost of being off by one at 7fff and 17ffe.
- c1 = DENS(X1, Y1, Z0) - DENS(X0, Y1, Z0);
- c2 = DENS(X0, Y1, Z0) - c0;
- c3 = DENS(X1, Y1, Z1) - DENS(X1, Y1, Z0);
-
- }
- else
- if (ry >= rz && rz >= rx) {
-
- c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
- c2 = DENS(X0, Y1, Z0) - c0;
- c3 = DENS(X0, Y1, Z1) - DENS(X0, Y1, Z0);
-
- }
- else
- if (rz >= ry && ry >= rx) {
-
- c1 = DENS(X1, Y1, Z1) - DENS(X0, Y1, Z1);
- c2 = DENS(X0, Y1, Z1) - DENS(X0, Y0, Z1);
- c3 = DENS(X0, Y0, Z1) - c0;
-
- }
- else {
- c1 = c2 = c3 = 0;
- }
-
- Rest = c1 * rx + c2 * ry + c3 * rz;
-
- Output[OutChan] = (cmsUInt16Number) c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest));
+ if (rx >= ry) {
+ if (ry >= rz) {
+ Y1 += X1;
+ Z1 += Y1;
+ for (; TotalOut; TotalOut--) {
+ c1 = LutTable[X1];
+ c2 = LutTable[Y1];
+ c3 = LutTable[Z1];
+ c0 = *LutTable++;
+ c3 -= c2;
+ c2 -= c1;
+ c1 -= c0;
+ Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
+ *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
+ }
+ } else if (rz >= rx) {
+ X1 += Z1;
+ Y1 += X1;
+ for (; TotalOut; TotalOut--) {
+ c1 = LutTable[X1];
+ c2 = LutTable[Y1];
+ c3 = LutTable[Z1];
+ c0 = *LutTable++;
+ c2 -= c1;
+ c1 -= c3;
+ c3 -= c0;
+ Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
+ *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
+ }
+ } else {
+ Z1 += X1;
+ Y1 += Z1;
+ for (; TotalOut; TotalOut--) {
+ c1 = LutTable[X1];
+ c2 = LutTable[Y1];
+ c3 = LutTable[Z1];
+ c0 = *LutTable++;
+ c2 -= c3;
+ c3 -= c1;
+ c1 -= c0;
+ Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
+ *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
+ }
+ }
+ } else {
+ if (rx >= rz) {
+ X1 += Y1;
+ Z1 += X1;
+ for (; TotalOut; TotalOut--) {
+ c1 = LutTable[X1];
+ c2 = LutTable[Y1];
+ c3 = LutTable[Z1];
+ c0 = *LutTable++;
+ c3 -= c1;
+ c1 -= c2;
+ c2 -= c0;
+ Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
+ *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
+ }
+ } else if (ry >= rz) {
+ Z1 += Y1;
+ X1 += Z1;
+ for (; TotalOut; TotalOut--) {
+ c1 = LutTable[X1];
+ c2 = LutTable[Y1];
+ c3 = LutTable[Z1];
+ c0 = *LutTable++;
+ c1 -= c3;
+ c3 -= c2;
+ c2 -= c0;
+ Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
+ *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
+ }
+ } else {
+ Y1 += Z1;
+ X1 += Y1;
+ for (; TotalOut; TotalOut--) {
+ c1 = LutTable[X1];
+ c2 = LutTable[Y1];
+ c3 = LutTable[Z1];
+ c0 = *LutTable++;
+ c1 -= c2;
+ c2 -= c3;
+ c3 -= c0;
+ Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
+ *Output++ = (cmsUInt16Number) c0 + ((Rest + (Rest>>16))>>16);
+ }
+ }
}
-
}
-#undef DENS
#define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
@@ -1102,7 +1267,7 @@
K1 = p16 -> opta[6] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
p1 = *p16;
- memmove(&p1.Domain[0], &p16 ->Domain[1], 5*sizeof(cmsUInt32Number));
+ memmove(&p1.Domain[0], &p16 ->Domain[1], 6*sizeof(cmsUInt32Number));
T = LutTable + K0;
p1.Table = T;
@@ -1285,6 +1450,12 @@
}
break;
+ case 2: // Duotone
+ if (IsFloat)
+ Interpolation.LerpFloat = BilinearInterpFloat;
+ else
+ Interpolation.Lerp16 = BilinearInterp16;
+ break;
case 3: // RGB et al
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio0.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -142,6 +142,7 @@
iohandler ->ContextID = ContextID;
iohandler ->stream = (void*) fm;
iohandler ->UsedSpace = 0;
+ iohandler ->ReportedSize = 0;
iohandler ->PhysicalFile[0] = 0;
iohandler ->Read = NULLRead;
@@ -232,13 +233,11 @@
memmove(ResData ->Block + ResData ->Pointer, Ptr, size);
ResData ->Pointer += size;
+ iohandler->UsedSpace += size;
if (ResData ->Pointer > iohandler->UsedSpace)
iohandler->UsedSpace = ResData ->Pointer;
-
- iohandler->UsedSpace += size;
-
return TRUE;
}
@@ -297,6 +296,7 @@
fm ->FreeBlockOnClose = TRUE;
fm ->Size = size;
fm ->Pointer = 0;
+ iohandler -> ReportedSize = size;
break;
case 'w':
@@ -307,10 +307,11 @@
fm ->FreeBlockOnClose = FALSE;
fm ->Size = size;
fm ->Pointer = 0;
+ iohandler -> ReportedSize = 0;
break;
default:
- cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknow access mode '%c'", *AccessMode);
+ cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown access mode '%c'", *AccessMode);
return NULL;
}
@@ -407,6 +408,7 @@
cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' not found", FileName);
return NULL;
}
+ iohandler -> ReportedSize = cmsfilelength(fm);
break;
case 'w':
@@ -416,11 +418,12 @@
cmsSignalError(ContextID, cmsERROR_FILE, "Couldn't create '%s'", FileName);
return NULL;
}
+ iohandler -> ReportedSize = 0;
break;
default:
_cmsFree(ContextID, iohandler);
- cmsSignalError(ContextID, cmsERROR_FILE, "Unknow access mode '%c'", *AccessMode);
+ cmsSignalError(ContextID, cmsERROR_FILE, "Unknown access mode '%c'", *AccessMode);
return NULL;
}
@@ -455,6 +458,7 @@
iohandler -> ContextID = ContextID;
iohandler -> stream = (void*) Stream;
iohandler -> UsedSpace = 0;
+ iohandler -> ReportedSize = cmsfilelength(Stream);
iohandler -> PhysicalFile[0] = 0;
iohandler ->Read = FileRead;
@@ -643,12 +647,17 @@
Icc -> flags = _cmsAdjustEndianess32(Header.flags);
Icc -> manufacturer = _cmsAdjustEndianess32(Header.manufacturer);
Icc -> model = _cmsAdjustEndianess32(Header.model);
- _cmsAdjustEndianess64(&Icc -> attributes, Header.attributes);
+ _cmsAdjustEndianess64(&Icc -> attributes, &Header.attributes);
Icc -> Version = _cmsAdjustEndianess32(Header.version);
// Get size as reported in header
HeaderSize = _cmsAdjustEndianess32(Header.size);
+ // Make sure HeaderSize is lower than profile size
+ if (HeaderSize >= Icc ->IOhandler ->ReportedSize)
+ HeaderSize = Icc ->IOhandler ->ReportedSize;
+
+
// Get creation date/time
_cmsDecodeDateTimeNumber(&Header.date, &Icc ->Created);
@@ -664,6 +673,7 @@
return FALSE;
}
+
// Read tag directory
Icc -> TagCount = 0;
for (i=0; i < TagCount; i++) {
@@ -673,7 +683,8 @@
if (!_cmsReadUInt32Number(io, &Tag.size)) return FALSE;
// Perform some sanity check. Offset + size should fall inside file.
- if (Tag.offset + Tag.size > HeaderSize)
+ if (Tag.offset + Tag.size > HeaderSize ||
+ Tag.offset + Tag.size < Tag.offset)
continue;
Icc -> TagNames[Icc ->TagCount] = Tag.sig;
@@ -728,7 +739,7 @@
Header.manufacturer = _cmsAdjustEndianess32(Icc -> manufacturer);
Header.model = _cmsAdjustEndianess32(Icc -> model);
- _cmsAdjustEndianess64(&Header.attributes, Icc -> attributes);
+ _cmsAdjustEndianess64(&Header.attributes, &Icc -> attributes);
// Rendering intent in the header (for embedded profiles)
Header.renderingIntent = _cmsAdjustEndianess32(Icc -> RenderingIntent);
@@ -822,7 +833,7 @@
void CMSEXPORT cmsSetHeaderModel(cmsHPROFILE hProfile, cmsUInt32Number model)
{
_cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
- Icc -> manufacturer = (cmsUInt32Number) model;
+ Icc -> model = (cmsUInt32Number) model;
}
@@ -1138,10 +1149,12 @@
continue;
}
- TypeBase = TypeHandler ->Signature;
+ TypeBase = TypeHandler ->Signature;
if (!_cmsWriteTypeBase(io, TypeBase))
return FALSE;
+ TypeHandler ->ContextID = Icc ->ContextID;
+ TypeHandler ->ICCVersion = Icc ->Version;
if (!TypeHandler ->WritePtr(TypeHandler, io, Data, TagDescriptor ->ElemCount)) {
char String[5];
@@ -1317,8 +1330,12 @@
cmsTagTypeHandler* TypeHandler = Icc ->TagTypeHandlers[i];
- if (TypeHandler != NULL)
+ if (TypeHandler != NULL) {
+
+ TypeHandler ->ContextID = Icc ->ContextID; // As an additional parameters
+ TypeHandler ->ICCVersion = Icc ->Version;
TypeHandler ->FreePtr(TypeHandler, Icc -> TagPtrs[i]);
+ }
else
_cmsFree(Icc ->ContextID, Icc ->TagPtrs[i]);
}
@@ -1371,7 +1388,6 @@
if (n < 0) return NULL; // Not found, return NULL
-
// If the element is already in memory, return the pointer
if (Icc -> TagPtrs[n]) {
@@ -1406,6 +1422,9 @@
// Read the tag
Icc -> TagTypeHandlers[n] = TypeHandler;
+
+ TypeHandler ->ContextID = Icc ->ContextID;
+ TypeHandler ->ICCVersion = Icc ->Version;
Icc -> TagPtrs[n] = TypeHandler ->ReadPtr(TypeHandler, io, &ElemCount, TagSize);
// The tag type is supported, but something wrong happend and we cannot read the tag.
@@ -1463,11 +1482,15 @@
cmsTagTypeSignature Type;
int i;
cmsFloat64Number Version;
+ char TypeString[5], SigString[5];
if (data == NULL) {
- cmsSignalError(cmsGetProfileContextID(hProfile), cmsERROR_NULL, "couldn't wite NULL to tag");
+ i = _cmsSearchTag(Icc, sig, FALSE);
+ if (i >= 0)
+ Icc ->TagNames[i] = (cmsTagSignature) 0;
+ // Unsupported by now, reserved for future ampliations (delete)
return FALSE;
}
@@ -1482,7 +1505,13 @@
}
else {
TypeHandler = Icc ->TagTypeHandlers[i];
- TypeHandler->FreePtr(TypeHandler, Icc -> TagPtrs[i]);
+
+ if (TypeHandler != NULL) {
+
+ TypeHandler ->ContextID = Icc ->ContextID; // As an additional parameter
+ TypeHandler ->ICCVersion = Icc ->Version;
+ TypeHandler->FreePtr(TypeHandler, Icc -> TagPtrs[i]);
+ }
}
}
}
@@ -1514,6 +1543,7 @@
// Now we need to know which type to use. It depends on the version.
Version = cmsGetProfileVersion(hProfile);
+
if (TagDescriptor ->DecideType != NULL) {
// Let the tag descriptor to decide the type base on depending on
@@ -1525,33 +1555,47 @@
}
else {
+
Type = TagDescriptor ->SupportedTypes[0];
}
// Does the tag support this type?
if (!IsTypeSupported(TagDescriptor, Type)) {
- cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported type '%x' for tag '%x'", Type, sig);
+
+ _cmsTagSignature2String(TypeString, (cmsTagSignature) Type);
+ _cmsTagSignature2String(SigString, sig);
+
+ cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported type '%s' for tag '%s'", TypeString, SigString);
return FALSE;
}
// Does we have a handler for this type?
TypeHandler = _cmsGetTagTypeHandler(Type);
if (TypeHandler == NULL) {
- cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported type '%x' for tag '%x'", Type, sig);
+
+ _cmsTagSignature2String(TypeString, (cmsTagSignature) Type);
+ _cmsTagSignature2String(SigString, sig);
+
+ cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported type '%s' for tag '%s'", TypeString, SigString);
return FALSE; // Should never happen
}
+
// Fill fields on icc structure
Icc ->TagTypeHandlers[i] = TypeHandler;
Icc ->TagNames[i] = sig;
Icc ->TagSizes[i] = 0;
Icc ->TagOffsets[i] = 0;
- Icc ->TagPtrs[i] = TypeHandler ->DupPtr(TypeHandler, data, TagDescriptor ->ElemCount);
+
+ TypeHandler ->ContextID = Icc ->ContextID;
+ TypeHandler ->ICCVersion = Icc ->Version;
+ Icc ->TagPtrs[i] = TypeHandler ->DupPtr(TypeHandler, data, TagDescriptor ->ElemCount);
if (Icc ->TagPtrs[i] == NULL) {
- TypeHandler ->DupPtr(TypeHandler, data, TagDescriptor ->ElemCount);
- cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Malformed struct in type '%x' for tag '%x'", Type, sig);
+ _cmsTagSignature2String(TypeString, (cmsTagSignature) Type);
+ _cmsTagSignature2String(SigString, sig);
+ cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Malformed struct in type '%s' for tag '%s'", TypeString, SigString);
return FALSE;
}
@@ -1627,21 +1671,31 @@
if (data == NULL) {
MemIO = cmsOpenIOhandlerFromNULL(cmsGetProfileContextID(hProfile));
} else{
- MemIO = cmsOpenIOhandlerFromMem(cmsGetProfileContextID(hProfile), data, BufferSize, "w");
+ MemIO = cmsOpenIOhandlerFromMem(cmsGetProfileContextID(hProfile), data, BufferSize, "w");
}
if (MemIO == NULL) return 0;
// Obtain type handling for the tag
TypeHandler = Icc ->TagTypeHandlers[i];
TagDescriptor = _cmsGetTagDescriptor(sig);
+ if (TagDescriptor == NULL) {
+ cmsCloseIOhandler(MemIO);
+ return 0;
+ }
// Serialize
+ TypeHandler ->ContextID = Icc ->ContextID;
+ TypeHandler ->ICCVersion = Icc ->Version;
+
if (!_cmsWriteTypeBase(MemIO, TypeHandler ->Signature)) {
cmsCloseIOhandler(MemIO);
return 0;
}
- if (!TypeHandler ->WritePtr(TypeHandler, MemIO, Object, TagDescriptor ->ElemCount)) return 0;
+ if (!TypeHandler ->WritePtr(TypeHandler, MemIO, Object, TagDescriptor ->ElemCount)) {
+ cmsCloseIOhandler(MemIO);
+ return 0;
+ }
// Get Size and close
rc = MemIO ->Tell(MemIO);
@@ -1692,3 +1746,17 @@
return TRUE;
}
+
+
+// Returns the tag linked to sig, in the case two tags are sharing same resource
+cmsTagSignature CMSEXPORT cmsTagLinkedTo(cmsHPROFILE hProfile, cmsTagSignature sig)
+{
+ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
+ int i;
+
+ // Search for given tag in ICC profile directory
+ i = _cmsSearchTag(Icc, sig, FALSE);
+ if (i < 0) return (cmsTagSignature) 0; // Not found, return 0
+
+ return Icc -> TagLinked[i];
+}
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsio1.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -150,7 +150,7 @@
return TRUE;
}
- return _cmsAdaptationMatrix(Dest, NULL, cmsD50_XYZ(), White);
+ return _cmsAdaptationMatrix(Dest, NULL, White, cmsD50_XYZ());
}
}
@@ -261,11 +261,81 @@
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, Shapes));
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 3, (cmsFloat64Number*) &Mat, NULL));
+
+ // Note that it is certainly possible a single profile would have a LUT based
+ // tag for output working in lab and a matrix-shaper for the fallback cases.
+ // This is not allowed by the spec, but this code is tolerant to those cases
+ if (cmsGetPCS(hProfile) == cmsSigLabData) {
+
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocXYZ2Lab(ContextID));
+ }
+
}
return Lut;
}
+
+
+// Read the DToAX tag, adjusting the encoding of Lab or XYZ if neded
+/*static
+cmsPipeline* _cmsReadFloatInputTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat)
+{
+ cmsContext ContextID = cmsGetProfileContextID(hProfile);
+ cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
+ cmsColorSpaceSignature spc = cmsGetColorSpace(hProfile);
+
+ if (Lut == NULL) return NULL;
+
+ // If PCS is Lab or XYZ, the floating point tag is accepting data in the space encoding,
+ // and since the formatter has already accomodated to 0..1.0, we should undo this change
+ if ( spc == cmsSigLabData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID));
+ }
+ else
+ if (spc == cmsSigXYZData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID));
+ }
+
+ return Lut;
+}
+*/
+static
+cmsPipeline* _cmsReadFloatInputTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat)
+{
+ cmsContext ContextID = cmsGetProfileContextID(hProfile);
+ cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
+ cmsColorSpaceSignature spc = cmsGetColorSpace(hProfile);
+ cmsColorSpaceSignature PCS = cmsGetPCS(hProfile);
+
+ if (Lut == NULL) return NULL;
+
+ // input and output of transform are in lcms 0..1 encoding. If XYZ or Lab spaces are used,
+ // these need to be normalized into the appropriate ranges (Lab = 100,0,0, XYZ=1.0,1.0,1.0)
+ if ( spc == cmsSigLabData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID));
+ }
+ else if (spc == cmsSigXYZData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID));
+ }
+
+ if ( PCS == cmsSigLabData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID));
+ }
+ else if( PCS == cmsSigXYZData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID));
+ }
+
+ return Lut;
+}
+
+
// Read and create a BRAND NEW MPE LUT from a given profile. All stuff dependent of version, etc
// is adjusted here in order to create a LUT that takes care of all those details
cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent)
@@ -275,10 +345,30 @@
cmsTagSignature tagFloat = Device2PCSFloat[Intent];
cmsContext ContextID = cmsGetProfileContextID(hProfile);
+ // On named color, take the appropiate tag
+ if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
+
+ cmsPipeline* Lut;
+ cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) cmsReadTag(hProfile, cmsSigNamedColor2Tag);
+
+ if (nc == NULL) return NULL;
+
+ Lut = cmsPipelineAlloc(ContextID, 0, 0);
+ if (Lut == NULL) {
+ cmsFreeNamedColorList(nc);
+ return NULL;
+ }
+
+ cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, TRUE));
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID));
+ return Lut;
+ }
+
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
- // Floating point LUT are always V4, so no adjustment is required
- return cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
+ // Floating point LUT are always V4, but the encoding range is no
+ // longer 0..1.0, so we need to add an stage depending on the color space
+ return _cmsReadFloatInputTag(hProfile, tagFloat);
}
// Revert to perceptual if no tag is found
@@ -304,6 +394,10 @@
if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData)
return Lut;
+ // If the input is Lab, add also a conversion at the begin
+ if (cmsGetColorSpace(hProfile) == cmsSigLabData)
+ cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID));
+
// Add a matrix for conversion V2 to V4 Lab PCS
cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID));
return Lut;
@@ -407,6 +501,14 @@
Lut = cmsPipelineAlloc(ContextID, 3, 3);
if (Lut != NULL) {
+ // Note that it is certainly possible a single profile would have a LUT based
+ // tag for output working in lab and a matrix-shaper for the fallback cases.
+ // This is not allowed by the spec, but this code is tolerant to those cases
+ if (cmsGetPCS(hProfile) == cmsSigLabData) {
+
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLab2XYZ(ContextID));
+ }
+
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocMatrix(ContextID, 3, 3, (cmsFloat64Number*) &Inv, NULL));
cmsPipelineInsertStage(Lut, cmsAT_END, cmsStageAllocToneCurves(ContextID, 3, InvShapes));
}
@@ -415,6 +517,88 @@
return Lut;
}
+
+// Change CLUT interpolation to trilinear
+static
+void ChangeInterpolationToTrilinear(cmsPipeline* Lut)
+{
+ cmsStage* Stage;
+
+ for (Stage = cmsPipelineGetPtrToFirstStage(Lut);
+ Stage != NULL;
+ Stage = cmsStageNext(Stage)) {
+
+ if (cmsStageType(Stage) == cmsSigCLutElemType) {
+
+ _cmsStageCLutData* CLUT = (_cmsStageCLutData*) Stage ->Data;
+
+ CLUT ->Params->dwFlags |= CMS_LERP_FLAGS_TRILINEAR;
+ _cmsSetInterpolationRoutine(CLUT ->Params);
+ }
+ }
+}
+
+
+// Read the DToAX tag, adjusting the encoding of Lab or XYZ if neded
+/*static
+cmsPipeline* _cmsReadFloatOutputTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat)
+{
+ cmsContext ContextID = cmsGetProfileContextID(hProfile);
+ cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
+ cmsColorSpaceSignature PCS = cmsGetPCS(hProfile);
+
+ if (Lut == NULL) return NULL;
+
+ // If PCS is Lab or XYZ, the floating point tag is accepting data in the space encoding,
+ // and since the formatter has already accomodated to 0..1.0, we should undo this change
+ if ( PCS == cmsSigLabData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID));
+ }
+ else
+ if (PCS == cmsSigXYZData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID));
+ }
+
+ return Lut;
+}*/
+
+static
+cmsPipeline* _cmsReadFloatOutputTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat)
+{
+ cmsContext ContextID = cmsGetProfileContextID(hProfile);
+ cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
+ cmsColorSpaceSignature PCS = cmsGetPCS(hProfile);
+ cmsColorSpaceSignature dataSpace = cmsGetColorSpace(hProfile);
+
+ if (Lut == NULL) return NULL;
+
+ // If PCS is Lab or XYZ, the floating point tag is accepting data in the space encoding,
+ // and since the formatter has already accomodated to 0..1.0, we should undo this change
+ if ( PCS == cmsSigLabData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID));
+ }
+ else
+ if (PCS == cmsSigXYZData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID));
+ }
+
+ // the output can be Lab or XYZ, in which case normalisation is needed on the end of the pipeline
+ if ( dataSpace == cmsSigLabData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID));
+ }
+ else if ( dataSpace == cmsSigXYZData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID));
+ }
+
+ return Lut;
+}
+
// Create an output MPE LUT from agiven profile. Version mismatches are handled here
cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent)
{
@@ -425,8 +609,8 @@
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
- // Floating point LUT are always V4, so no adjustment is required
- return cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
+ // Floating point LUT are always V4
+ return _cmsReadFloatOutputTag(hProfile, tagFloat);
}
// Revert to perceptual if no tag is found
@@ -447,6 +631,12 @@
// The profile owns the Lut, so we need to copy it
Lut = cmsPipelineDup(Lut);
+ if (Lut == NULL) return NULL;
+
+ // Now it is time for a controversial stuff. I found that for 3D LUTS using
+ // Lab used as indexer space, trilinear interpolation should be used
+ if (cmsGetPCS(hProfile) == cmsSigLabData)
+ ChangeInterpolationToTrilinear(Lut);
// We need to adjust data only for Lab and Lut16 type
if (OriginalType != cmsSigLut16Type || cmsGetPCS(hProfile) != cmsSigLabData)
@@ -454,6 +644,11 @@
// Add a matrix for conversion V4 to V2 Lab PCS
cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocLabV4ToV2(ContextID));
+
+ // If the output is Lab, add also a conversion at the end
+ if (cmsGetColorSpace(hProfile) == cmsSigLabData)
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID));
+
return Lut;
}
@@ -467,12 +662,46 @@
return BuildGrayOutputPipeline(hProfile);
}
- // Not gray, create a normal matrix-shaper
+ // Not gray, create a normal matrix-shaper, which only operates in XYZ space
return BuildRGBOutputMatrixShaper(hProfile);
}
// ---------------------------------------------------------------------------------------------------------------
+// Read the AToD0 tag, adjusting the encoding of Lab or XYZ if neded
+static
+cmsPipeline* _cmsReadFloatDevicelinkTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat)
+{
+ cmsContext ContextID = cmsGetProfileContextID(hProfile);
+ cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
+ cmsColorSpaceSignature PCS = cmsGetPCS(hProfile);
+ cmsColorSpaceSignature spc = cmsGetColorSpace(hProfile);
+
+ if (Lut == NULL) return NULL;
+
+ if (spc == cmsSigLabData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToLabFloat(ContextID));
+ }
+ else
+ if (spc == cmsSigXYZData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageNormalizeToXyzFloat(ContextID));
+ }
+
+ if (PCS == cmsSigLabData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID));
+ }
+ else
+ if (PCS == cmsSigXYZData)
+ {
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID));
+ }
+
+ return Lut;
+}
+
// This one includes abstract profiles as well. Matrix-shaper cannot be obtained on that device class. The
// tag name here may default to AToB0
cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent)
@@ -483,10 +712,30 @@
cmsTagSignature tagFloat = Device2PCSFloat[Intent];
cmsContext ContextID = cmsGetProfileContextID(hProfile);
+
+ // On named color, take the appropiate tag
+ if (cmsGetDeviceClass(hProfile) == cmsSigNamedColorClass) {
+
+ cmsNAMEDCOLORLIST* nc = (cmsNAMEDCOLORLIST*) cmsReadTag(hProfile, cmsSigNamedColor2Tag);
+
+ if (nc == NULL) return NULL;
+
+ Lut = cmsPipelineAlloc(ContextID, 0, 0);
+ if (Lut == NULL) {
+ cmsFreeNamedColorList(nc);
+ return NULL;
+ }
+
+ cmsPipelineInsertStage(Lut, cmsAT_BEGIN, _cmsStageAllocNamedColor(nc, FALSE));
+ if (cmsGetColorSpace(hProfile) == cmsSigLabData)
+ cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageAllocLabV2ToV4(ContextID));
+ return Lut;
+ }
+
if (cmsIsTag(hProfile, tagFloat)) { // Float tag takes precedence
- // Floating point LUT are always V4, no adjustment is required
- return cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat));
+ // Floating point LUT are always V
+ return _cmsReadFloatDevicelinkTag(hProfile, tagFloat);
}
tagFloat = Device2PCSFloat[0];
@@ -509,6 +758,12 @@
// The profile owns the Lut, so we need to copy it
Lut = cmsPipelineDup(Lut);
+ if (Lut == NULL) return NULL;
+
+ // Now it is time for a controversial stuff. I found that for 3D LUTS using
+ // Lab used as indexer space, trilinear interpolation should be used
+ if (cmsGetColorSpace(hProfile) == cmsSigLabData)
+ ChangeInterpolationToTrilinear(Lut);
// After reading it, we have info about the original type
OriginalType = _cmsGetTagTrueType(hProfile, tag16);
@@ -558,7 +813,7 @@
}
// Returns TRUE if the intent is implemented as CLUT
-cmsBool CMSEXPORT cmsIsCLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent, int UsedDirection)
+cmsBool CMSEXPORT cmsIsCLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number UsedDirection)
{
const cmsTagSignature* TagTable;
@@ -589,7 +844,7 @@
// Return info about supported intents
cmsBool CMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile,
- cmsUInt32Number Intent, int UsedDirection)
+ cmsUInt32Number Intent, cmsUInt32Number UsedDirection)
{
if (cmsIsCLUT(hProfile, Intent, UsedDirection)) return TRUE;
@@ -607,7 +862,6 @@
// Read both, profile sequence description and profile sequence id if present. Then combine both to
// create qa unique structure holding both. Shame on ICC to store things in such complicated way.
-
cmsSEQ* _cmsReadProfileSequence(cmsHPROFILE hProfile)
{
cmsSEQ* ProfileSeq;
@@ -632,12 +886,13 @@
NewSeq = cmsDupProfileSequenceDescription(ProfileSeq);
// Ok, proceed to the mixing
- for (i=0; i < ProfileSeq ->n; i++) {
+ if (NewSeq != NULL) {
+ for (i=0; i < ProfileSeq ->n; i++) {
- memmove(&NewSeq ->seq[i].ProfileID, &ProfileId ->seq[i].ProfileID, sizeof(cmsProfileID));
- NewSeq ->seq[i].Description = cmsMLUdup(ProfileId ->seq[i].Description);
+ memmove(&NewSeq ->seq[i].ProfileID, &ProfileId ->seq[i].ProfileID, sizeof(cmsProfileID));
+ NewSeq ->seq[i].Description = cmsMLUdup(ProfileId ->seq[i].Description);
+ }
}
-
return NewSeq;
}
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmslut.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -154,7 +154,7 @@
for (i=0; i < n; i++) {
// Get asked type
- Type = va_arg(args, cmsStageSignature);
+ Type = (cmsStageSignature)va_arg(args, cmsStageSignature);
if (mpe ->Type != Type) {
va_end(args); // Mismatch. We are done.
@@ -197,9 +197,14 @@
cmsFloat32Number Out[],
const cmsStage *mpe)
{
- _cmsStageToneCurvesData* Data = (_cmsStageToneCurvesData*) mpe ->Data;
+ _cmsStageToneCurvesData* Data;
cmsUInt32Number i;
+ _cmsAssert(mpe != NULL);
+
+ Data = (_cmsStageToneCurvesData*) mpe ->Data;
+ if (Data == NULL) return;
+
if (Data ->TheCurves == NULL) return;
for (i=0; i < Data ->nCurves; i++) {
@@ -210,9 +215,14 @@
static
void CurveSetElemTypeFree(cmsStage* mpe)
{
- _cmsStageToneCurvesData* Data = (_cmsStageToneCurvesData*) mpe ->Data;
+ _cmsStageToneCurvesData* Data;
cmsUInt32Number i;
+ _cmsAssert(mpe != NULL);
+
+ Data = (_cmsStageToneCurvesData*) mpe ->Data;
+ if (Data == NULL) return;
+
if (Data ->TheCurves != NULL) {
for (i=0; i < Data ->nCurves; i++) {
if (Data ->TheCurves[i] != NULL)
@@ -275,12 +285,14 @@
EvaluateCurves, CurveSetDup, CurveSetElemTypeFree, NULL );
if (NewMPE == NULL) return NULL;
- NewElem = (_cmsStageToneCurvesData*) _cmsMalloc(ContextID, sizeof(_cmsStageToneCurvesData));
+ NewElem = (_cmsStageToneCurvesData*) _cmsMallocZero(ContextID, sizeof(_cmsStageToneCurvesData));
if (NewElem == NULL) {
cmsStageFree(NewMPE);
return NULL;
}
+ NewMPE ->Data = (void*) NewElem;
+
NewElem ->nCurves = nChannels;
NewElem ->TheCurves = (cmsToneCurve**) _cmsCalloc(ContextID, nChannels, sizeof(cmsToneCurve*));
if (NewElem ->TheCurves == NULL) {
@@ -301,11 +313,10 @@
cmsStageFree(NewMPE);
return NULL;
}
+
}
- NewMPE ->Data = (void*) NewElem;
-
- return NewMPE;
+ return NewMPE;
}
@@ -402,6 +413,9 @@
n = Rows * Cols;
// Check for overflow
+ if (n == 0) return NULL;
+ if (n >= UINT_MAX / Cols) return NULL;
+ if (n >= UINT_MAX / Rows) return NULL;
if (n < Rows || n < Cols) return NULL;
NewMPE = _cmsStageAllocPlaceholder(ContextID, cmsSigMatrixElemType, Cols, Rows,
@@ -479,10 +493,20 @@
static
cmsUInt32Number CubeSize(const cmsUInt32Number Dims[], cmsUInt32Number b)
{
- cmsUInt32Number rv;
+ cmsUInt32Number rv, dim;
+
+ _cmsAssert(Dims != NULL);
+
+ for (rv = 1; b > 0; b--) {
- for (rv = 1; b > 0; b--)
- rv *= Dims[b-1];
+ dim = Dims[b-1];
+ if (dim == 0) return 0; // Error
+
+ rv *= dim;
+
+ // Check for overflow
+ if (rv > UINT_MAX / dim) return 0;
+ }
return rv;
}
@@ -549,17 +573,35 @@
_cmsStageCLutData* NewElem;
cmsStage* NewMPE;
+ _cmsAssert(clutPoints != NULL);
+
+ if (inputChan > MAX_INPUT_DIMENSIONS) {
+ cmsSignalError(ContextID, cmsERROR_RANGE, "Too many input channels (%d channels, max=%d)", inputChan, MAX_INPUT_DIMENSIONS);
+ return NULL;
+ }
+
NewMPE = _cmsStageAllocPlaceholder(ContextID, cmsSigCLutElemType, inputChan, outputChan,
EvaluateCLUTfloatIn16, CLUTElemDup, CLutElemTypeFree, NULL );
if (NewMPE == NULL) return NULL;
- NewElem = (_cmsStageCLutData*) _cmsMalloc(ContextID, sizeof(_cmsStageCLutData));
- if (NewElem == NULL) return NULL;
+ NewElem = (_cmsStageCLutData*) _cmsMallocZero(ContextID, sizeof(_cmsStageCLutData));
+ if (NewElem == NULL) {
+ cmsStageFree(NewMPE);
+ return NULL;
+ }
+
+ NewMPE ->Data = (void*) NewElem;
NewElem -> nEntries = n = outputChan * CubeSize(clutPoints, inputChan);
NewElem -> HasFloatValues = FALSE;
+ if (n == 0) {
+ cmsStageFree(NewMPE);
+ return NULL;
+ }
+
+
NewElem ->Tab.T = (cmsUInt16Number*) _cmsCalloc(ContextID, n, sizeof(cmsUInt16Number));
if (NewElem ->Tab.T == NULL) {
cmsStageFree(NewMPE);
@@ -578,8 +620,6 @@
return NULL;
}
- NewMPE ->Data = (void*) NewElem;
-
return NewMPE;
}
@@ -623,18 +663,37 @@
{
cmsUInt32Number i, n;
_cmsStageCLutData* NewElem;
- cmsStage* NewMPE = _cmsStageAllocPlaceholder(ContextID, cmsSigCLutElemType, inputChan, outputChan,
+ cmsStage* NewMPE;
+
+ _cmsAssert(clutPoints != NULL);
+
+ if (inputChan > MAX_INPUT_DIMENSIONS) {
+ cmsSignalError(ContextID, cmsERROR_RANGE, "Too many input channels (%d channels, max=%d)", inputChan, MAX_INPUT_DIMENSIONS);
+ return NULL;
+ }
+
+ NewMPE = _cmsStageAllocPlaceholder(ContextID, cmsSigCLutElemType, inputChan, outputChan,
EvaluateCLUTfloat, CLUTElemDup, CLutElemTypeFree, NULL);
-
if (NewMPE == NULL) return NULL;
- NewElem = (_cmsStageCLutData*) _cmsMalloc(ContextID, sizeof(_cmsStageCLutData));
- if (NewElem == NULL) return NULL;
+ NewElem = (_cmsStageCLutData*) _cmsMallocZero(ContextID, sizeof(_cmsStageCLutData));
+ if (NewElem == NULL) {
+ cmsStageFree(NewMPE);
+ return NULL;
+ }
+
+ NewMPE ->Data = (void*) NewElem;
- NewElem -> nEntries = n = outputChan * CubeSize( clutPoints, inputChan);
+ // There is a potential integer overflow on conputing n and nEntries.
+ NewElem -> nEntries = n = outputChan * CubeSize(clutPoints, inputChan);
NewElem -> HasFloatValues = TRUE;
+ if (n == 0) {
+ cmsStageFree(NewMPE);
+ return NULL;
+ }
+
NewElem ->Tab.TFloat = (cmsFloat32Number*) _cmsCalloc(ContextID, n, sizeof(cmsFloat32Number));
if (NewElem ->Tab.TFloat == NULL) {
cmsStageFree(NewMPE);
@@ -647,7 +706,6 @@
}
}
- NewMPE ->Data = (void*) NewElem;
NewElem ->Params = _cmsComputeInterpParamsEx(ContextID, clutPoints, inputChan, outputChan, NewElem ->Tab.TFloat, CMS_LERP_FLAGS_FLOAT);
if (NewElem ->Params == NULL) {
@@ -715,8 +773,13 @@
int nInputs, nOutputs;
cmsUInt32Number* nSamples;
cmsUInt16Number In[cmsMAXCHANNELS], Out[MAX_STAGE_CHANNELS];
- _cmsStageCLutData* clut = (_cmsStageCLutData*) mpe->Data;
+ _cmsStageCLutData* clut;
+
+ if (mpe == NULL) return FALSE;
+ clut = (_cmsStageCLutData*) mpe->Data;
+
+ if (clut == NULL) return FALSE;
nSamples = clut->Params ->nSamples;
nInputs = clut->Params ->nInputs;
@@ -726,6 +789,7 @@
if (nOutputs >= MAX_STAGE_CHANNELS) return FALSE;
nTotalPoints = CubeSize(nSamples, nInputs);
+ if (nTotalPoints == 0) return FALSE;
index = 0;
for (i = 0; i < nTotalPoints; i++) {
@@ -779,6 +843,7 @@
if (nOutputs >= MAX_STAGE_CHANNELS) return FALSE;
nTotalPoints = CubeSize(nSamples, nInputs);
+ if (nTotalPoints == 0) return FALSE;
index = 0;
for (i = 0; i < nTotalPoints; i++) {
@@ -828,6 +893,7 @@
if (nInputs >= cmsMAXCHANNELS) return FALSE;
nTotalPoints = CubeSize(clutPoints, nInputs);
+ if (nTotalPoints == 0) return FALSE;
for (i = 0; i < nTotalPoints; i++) {
@@ -857,6 +923,7 @@
if (nInputs >= cmsMAXCHANNELS) return FALSE;
nTotalPoints = CubeSize(clutPoints, nInputs);
+ if (nTotalPoints == 0) return FALSE;
for (i = 0; i < nTotalPoints; i++) {
@@ -992,6 +1059,89 @@
}
+// To Lab to float. Note that the MPE gives numbers in normal Lab range
+// and we need 0..1.0 range for the formatters
+// L* : 0...100 => 0...1.0 (L* / 100)
+// ab* : -128..+127 to 0..1 ((ab* + 128) / 255)
+
+cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID)
+{
+ static const cmsFloat64Number a1[] = {
+ 1.0/100.0, 0, 0,
+ 0, 1.0/255.0, 0,
+ 0, 0, 1.0/255.0
+ };
+
+ static const cmsFloat64Number o1[] = {
+ 0,
+ 128.0/255.0,
+ 128.0/255.0
+ };
+
+ cmsStage *mpe = cmsStageAllocMatrix(ContextID, 3, 3, a1, o1);
+
+ if (mpe == NULL) return mpe;
+ mpe ->Implements = cmsSigLab2FloatPCS;
+ return mpe;
+}
+
+// Fom XYZ to floating point PCS
+cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID)
+{
+#define n (32768.0/65535.0)
+ static const cmsFloat64Number a1[] = {
+ n, 0, 0,
+ 0, n, 0,
+ 0, 0, n
+ };
+#undef n
+
+ cmsStage *mpe = cmsStageAllocMatrix(ContextID, 3, 3, a1, NULL);
+
+ if (mpe == NULL) return mpe;
+ mpe ->Implements = cmsSigXYZ2FloatPCS;
+ return mpe;
+}
+
+cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID)
+{
+ static const cmsFloat64Number a1[] = {
+ 100.0, 0, 0,
+ 0, 255.0, 0,
+ 0, 0, 255.0
+ };
+
+ static const cmsFloat64Number o1[] = {
+ 0,
+ -128.0,
+ -128.0
+ };
+
+ cmsStage *mpe = cmsStageAllocMatrix(ContextID, 3, 3, a1, o1);
+ if (mpe == NULL) return mpe;
+ mpe ->Implements = cmsSigFloatPCS2Lab;
+ return mpe;
+}
+
+cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID)
+{
+#define n (65535.0/32768.0)
+
+ static const cmsFloat64Number a1[] = {
+ n, 0, 0,
+ 0, n, 0,
+ 0, 0, n
+ };
+#undef n
+
+ cmsStage *mpe = cmsStageAllocMatrix(ContextID, 3, 3, a1, NULL);
+ if (mpe == NULL) return mpe;
+ mpe ->Implements = cmsSigFloatPCS2XYZ;
+ return mpe;
+}
+
+
+
// ********************************************************************************
// Type cmsSigXYZ2LabElemType
// ********************************************************************************
@@ -1201,22 +1351,28 @@
NewLUT ->DupDataFn = NULL;
NewLUT ->FreeDataFn = NULL;
NewLUT ->Data = NewLUT;
-
- NewLUT ->ContextID = ContextID;
+ NewLUT ->ContextID = ContextID;
BlessLUT(NewLUT);
return NewLUT;
}
+cmsContext CMSEXPORT cmsGetPipelineContextID(const cmsPipeline* lut)
+{
+ _cmsAssert(lut != NULL);
+ return lut ->ContextID;
+}
cmsUInt32Number CMSEXPORT cmsPipelineInputChannels(const cmsPipeline* lut)
{
+ _cmsAssert(lut != NULL);
return lut ->InputChannels;
}
cmsUInt32Number CMSEXPORT cmsPipelineOutputChannels(const cmsPipeline* lut)
{
+ _cmsAssert(lut != NULL);
return lut ->OutputChannels;
}
@@ -1244,6 +1400,7 @@
// Default to evaluate the LUT on 16 bit-basis.
void CMSEXPORT cmsPipelineEval16(const cmsUInt16Number In[], cmsUInt16Number Out[], const cmsPipeline* lut)
{
+ _cmsAssert(lut != NULL);
lut ->Eval16Fn(In, Out, lut->Data);
}
@@ -1251,6 +1408,7 @@
// Does evaluate the LUT on cmsFloat32Number-basis.
void CMSEXPORT cmsPipelineEvalFloat(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsPipeline* lut)
{
+ _cmsAssert(lut != NULL);
lut ->EvalFloatFn(In, Out, lut);
}
@@ -1288,8 +1446,10 @@
Anterior = NewMPE;
}
- NewLUT ->DupDataFn = lut ->DupDataFn;
- NewLUT ->FreeDataFn = lut ->FreeDataFn;
+ NewLUT ->Eval16Fn = lut ->Eval16Fn;
+ NewLUT ->EvalFloatFn = lut ->EvalFloatFn;
+ NewLUT ->DupDataFn = lut ->DupDataFn;
+ NewLUT ->FreeDataFn = lut ->FreeDataFn;
if (NewLUT ->DupDataFn != NULL)
NewLUT ->Data = NewLUT ->DupDataFn(lut ->ContextID, lut->Data);
@@ -1306,6 +1466,9 @@
{
cmsStage* Anterior = NULL, *pt;
+ _cmsAssert(lut != NULL);
+ _cmsAssert(mpe != NULL);
+
switch (loc) {
case cmsAT_BEGIN:
@@ -1456,13 +1619,13 @@
return n;
}
-// This function may be used to set the optional evalueator and a block of private data. If private data is being used, an optional
+// This function may be used to set the optional evaluator and a block of private data. If private data is being used, an optional
// duplicator and free functions should also be specified in order to duplicate the LUT construct. Use NULL to inhibit such functionality.
void CMSEXPORT _cmsPipelineSetOptimizationParameters(cmsPipeline* Lut,
_cmsOPTeval16Fn Eval16,
void* PrivateData,
- _cmsOPTfreeDataFn FreePrivateDataFn,
- _cmsOPTdupDataFn DupPrivateDataFn)
+ _cmsFreeUserDataFn FreePrivateDataFn,
+ _cmsDupUserDataFn DupPrivateDataFn)
{
Lut ->Eval16Fn = Eval16;
@@ -1640,3 +1803,4 @@
return TRUE;
}
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmd5.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmd5.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -202,3 +202,4 @@
r->n[VZ] = a->v[2].n[VX]*v->n[VX] + a->v[2].n[VY]*v->n[VY] + a->v[2].n[VZ]*v->n[VZ];
}
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2012 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -117,7 +117,7 @@
}
-// Grows a ntry table for a MLU. Each time this function is called, table size is multiplied times two.
+// Grows a entry table for a MLU. Each time this function is called, table size is multiplied times two.
static
cmsBool GrowMLUtable(cmsMLU* mlu)
{
@@ -130,7 +130,7 @@
AllocatedEntries = mlu ->AllocatedEntries * 2;
// Check for overflow
- if (AllocatedEntries < mlu ->AllocatedEntries) return FALSE;
+ if (AllocatedEntries / 2 != mlu ->AllocatedEntries) return FALSE;
// Reallocate the memory
NewPtr = (_cmsMLUentry*)_cmsRealloc(mlu ->ContextID, mlu ->Entries, AllocatedEntries*sizeof(_cmsMLUentry));
@@ -359,9 +359,9 @@
if (Best == -1)
Best = 0;
- v = mlu ->Entries + Best;
+ v = mlu ->Entries + Best;
- if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language;
+ if (UsedLanguageCode != NULL) *UsedLanguageCode = v ->Language;
if (UsedCountryCode != NULL) *UsedCountryCode = v ->Country;
if (len != NULL) *len = v ->Len;
@@ -372,8 +372,8 @@
// Obtain an ASCII representation of the wide string. Setting buffer to NULL returns the len
cmsUInt32Number CMSEXPORT cmsMLUgetASCII(const cmsMLU* mlu,
- const char LanguageCode[3], const char CountryCode[3],
- char* Buffer, cmsUInt32Number BufferSize)
+ const char LanguageCode[3], const char CountryCode[3],
+ char* Buffer, cmsUInt32Number BufferSize)
{
const wchar_t *Wide;
cmsUInt32Number StrLen = 0;
@@ -417,8 +417,8 @@
// Obtain a wide representation of the MLU, on depending on current locale settings
cmsUInt32Number CMSEXPORT cmsMLUgetWide(const cmsMLU* mlu,
- const char LanguageCode[3], const char CountryCode[3],
- wchar_t* Buffer, cmsUInt32Number BufferSize)
+ const char LanguageCode[3], const char CountryCode[3],
+ wchar_t* Buffer, cmsUInt32Number BufferSize)
{
const wchar_t *Wide;
cmsUInt32Number StrLen = 0;
@@ -491,6 +491,9 @@
else
size = v ->Allocated * 2;
+ // Keep a maximum color lists can grow, 100K entries seems reasonable
+ if (size > 1024*100) return FALSE;
+
NewPtr = (_cmsNAMEDCOLOR*) _cmsRealloc(v ->ContextID, v ->List, size * sizeof(_cmsNAMEDCOLOR));
if (NewPtr == NULL)
return FALSE;
@@ -516,6 +519,8 @@
strncpy(v ->Prefix, Prefix, sizeof(v ->Prefix));
strncpy(v ->Suffix, Suffix, sizeof(v ->Suffix));
+ v->Prefix[32] = v->Suffix[32] = 0;
+
v -> ColorantCount = ColorantCount;
return v;
@@ -569,9 +574,14 @@
for (i=0; i < 3; i++)
NamedColorList ->List[NamedColorList ->nColors].PCS[i] = PCS == NULL ? 0 : PCS[i];
- if (Name != NULL)
+ if (Name != NULL) {
+
strncpy(NamedColorList ->List[NamedColorList ->nColors].Name, Name,
sizeof(NamedColorList ->List[NamedColorList ->nColors].Name));
+
+ NamedColorList ->List[NamedColorList ->nColors].Name[cmsMAX_PATH-1] = 0;
+
+ }
else
NamedColorList ->List[NamedColorList ->nColors].Name[0] = 0;
@@ -645,6 +655,24 @@
}
static
+void EvalNamedColorPCS(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe)
+{
+ cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) mpe ->Data;
+ cmsUInt16Number index = (cmsUInt16Number) _cmsQuickSaturateWord(In[0] * 65535.0);
+
+ if (index >= NamedColorList-> nColors) {
+ cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range; ignored", index);
+ }
+ else {
+
+ // Named color always uses Lab
+ Out[0] = (cmsFloat32Number) (NamedColorList->List[index].PCS[0] / 65535.0);
+ Out[1] = (cmsFloat32Number) (NamedColorList->List[index].PCS[1] / 65535.0);
+ Out[2] = (cmsFloat32Number) (NamedColorList->List[index].PCS[2] / 65535.0);
+ }
+}
+
+static
void EvalNamedColor(const cmsFloat32Number In[], cmsFloat32Number Out[], const cmsStage *mpe)
{
cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) mpe ->Data;
@@ -662,15 +690,15 @@
// Named color lookup element
-cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList)
+cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS)
{
return _cmsStageAllocPlaceholder(NamedColorList ->ContextID,
- cmsSigNamedColorElemType,
- 1, 3,
- EvalNamedColor,
- DupNamedColorList,
- FreeNamedColorList,
- cmsDupNamedColorList(NamedColorList));
+ cmsSigNamedColorElemType,
+ 1, UsePCS ? 3 : NamedColorList ->ColorantCount,
+ UsePCS ? EvalNamedColorPCS : EvalNamedColor,
+ DupNamedColorList,
+ FreeNamedColorList,
+ cmsDupNamedColorList(NamedColorList));
}
@@ -771,3 +799,131 @@
return NULL;
}
+// Dictionaries --------------------------------------------------------------------------------------------------------
+
+// Dictionaries are just very simple linked lists
+
+
+typedef struct _cmsDICT_struct {
+ cmsDICTentry* head;
+ cmsContext ContextID;
+} _cmsDICT;
+
+
+// Allocate an empty dictionary
+cmsHANDLE CMSEXPORT cmsDictAlloc(cmsContext ContextID)
+{
+ _cmsDICT* dict = (_cmsDICT*) _cmsMallocZero(ContextID, sizeof(_cmsDICT));
+ if (dict == NULL) return NULL;
+
+ dict ->ContextID = ContextID;
+ return (cmsHANDLE) dict;
+
+}
+
+// Dispose resources
+void CMSEXPORT cmsDictFree(cmsHANDLE hDict)
+{
+ _cmsDICT* dict = (_cmsDICT*) hDict;
+ cmsDICTentry *entry, *next;
+
+ _cmsAssert(dict != NULL);
+
+ // Walk the list freeing all nodes
+ entry = dict ->head;
+ while (entry != NULL) {
+
+ if (entry ->DisplayName != NULL) cmsMLUfree(entry ->DisplayName);
+ if (entry ->DisplayValue != NULL) cmsMLUfree(entry ->DisplayValue);
+ if (entry ->Name != NULL) _cmsFree(dict ->ContextID, entry -> Name);
+ if (entry ->Value != NULL) _cmsFree(dict ->ContextID, entry -> Value);
+
+ // Don't fall in the habitual trap...
+ next = entry ->Next;
+ _cmsFree(dict ->ContextID, entry);
+
+ entry = next;
+ }
+
+ _cmsFree(dict ->ContextID, dict);
+}
+
+
+// Duplicate a wide char string
+static
+wchar_t* DupWcs(cmsContext ContextID, const wchar_t* ptr)
+{
+ if (ptr == NULL) return NULL;
+ return (wchar_t*) _cmsDupMem(ContextID, ptr, (mywcslen(ptr) + 1) * sizeof(wchar_t));
+}
+
+// Add a new entry to the linked list
+cmsBool CMSEXPORT cmsDictAddEntry(cmsHANDLE hDict, const wchar_t* Name, const wchar_t* Value, const cmsMLU *DisplayName, const cmsMLU *DisplayValue)
+{
+ _cmsDICT* dict = (_cmsDICT*) hDict;
+ cmsDICTentry *entry;
+
+ _cmsAssert(dict != NULL);
+ _cmsAssert(Name != NULL);
+
+ entry = (cmsDICTentry*) _cmsMallocZero(dict ->ContextID, sizeof(cmsDICTentry));
+ if (entry == NULL) return FALSE;
+
+ entry ->DisplayName = cmsMLUdup(DisplayName);
+ entry ->DisplayValue = cmsMLUdup(DisplayValue);
+ entry ->Name = DupWcs(dict ->ContextID, Name);
+ entry ->Value = DupWcs(dict ->ContextID, Value);
+
+ entry ->Next = dict ->head;
+ dict ->head = entry;
+
+ return TRUE;
+}
+
+
+// Duplicates an existing dictionary
+cmsHANDLE CMSEXPORT cmsDictDup(cmsHANDLE hDict)
+{
+ _cmsDICT* old_dict = (_cmsDICT*) hDict;
+ cmsHANDLE hNew;
+ _cmsDICT* new_dict;
+ cmsDICTentry *entry;
+
+ _cmsAssert(old_dict != NULL);
+
+ hNew = cmsDictAlloc(old_dict ->ContextID);
+ if (hNew == NULL) return NULL;
+
+ new_dict = (_cmsDICT*) hNew;
+
+ // Walk the list freeing all nodes
+ entry = old_dict ->head;
+ while (entry != NULL) {
+
+ if (!cmsDictAddEntry(hNew, entry ->Name, entry ->Value, entry ->DisplayName, entry ->DisplayValue)) {
+
+ cmsDictFree(hNew);
+ return NULL;
+ }
+
+ entry = entry -> Next;
+ }
+
+ return hNew;
+}
+
+// Get a pointer to the linked list
+const cmsDICTentry* CMSEXPORT cmsDictGetEntryList(cmsHANDLE hDict)
+{
+ _cmsDICT* dict = (_cmsDICT*) hDict;
+
+ if (dict == NULL) return NULL;
+ return dict ->head;
+}
+
+// Helper For external languages
+const cmsDICTentry* CMSEXPORT cmsDictNextEntry(const cmsDICTentry* e)
+{
+ if (e == NULL) return NULL;
+ return e ->Next;
+}
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsopt.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsopt.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2011 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -223,6 +223,12 @@
// Remove V2 to V4 followed by V4 to V2
Opt |= _Remove2Op(Lut, cmsSigLabV2toV4, cmsSigLabV4toV2);
+ // Remove float pcs Lab conversions
+ Opt |= _Remove2Op(Lut, cmsSigLab2FloatPCS, cmsSigFloatPCS2Lab);
+
+ // Remove float pcs Lab conversions
+ Opt |= _Remove2Op(Lut, cmsSigXYZ2FloatPCS, cmsSigFloatPCS2XYZ);
+
if (Opt) AnyOpt = TRUE;
} while (Opt);
@@ -298,7 +304,7 @@
int nOutputs, cmsToneCurve** Out )
{
int i;
- Prelin16Data* p16 = (Prelin16Data*) _cmsMallocZero(ContextID, sizeof(Prelin16Data));
+ Prelin16Data* p16 = _cmsMallocZero(ContextID, sizeof(Prelin16Data));
if (p16 == NULL) return NULL;
p16 ->nInputs = nInputs;
@@ -411,17 +417,17 @@
return FALSE;
}
- px = ((cmsFloat64Number) At[0] * (p16->Domain[0])) / 65535.0;
- py = ((cmsFloat64Number) At[1] * (p16->Domain[1])) / 65535.0;
- pz = ((cmsFloat64Number) At[2] * (p16->Domain[2])) / 65535.0;
- pw = ((cmsFloat64Number) At[3] * (p16->Domain[3])) / 65535.0;
+ if (nChannelsIn == 4) {
- x0 = (int) floor(px);
- y0 = (int) floor(py);
- z0 = (int) floor(pz);
- w0 = (int) floor(pw);
+ px = ((cmsFloat64Number) At[0] * (p16->Domain[0])) / 65535.0;
+ py = ((cmsFloat64Number) At[1] * (p16->Domain[1])) / 65535.0;
+ pz = ((cmsFloat64Number) At[2] * (p16->Domain[2])) / 65535.0;
+ pw = ((cmsFloat64Number) At[3] * (p16->Domain[3])) / 65535.0;
- if (nChannelsIn == 4) {
+ x0 = (int) floor(px);
+ y0 = (int) floor(py);
+ z0 = (int) floor(pz);
+ w0 = (int) floor(pw);
if (((px - x0) != 0) ||
((py - y0) != 0) ||
@@ -429,24 +435,36 @@
((pw - w0) != 0)) return FALSE; // Not on exact node
index = p16 -> opta[3] * x0 +
- p16 -> opta[2] * y0 +
- p16 -> opta[1] * z0 +
- p16 -> opta[0] * w0;
+ p16 -> opta[2] * y0 +
+ p16 -> opta[1] * z0 +
+ p16 -> opta[0] * w0;
}
else
if (nChannelsIn == 3) {
+ px = ((cmsFloat64Number) At[0] * (p16->Domain[0])) / 65535.0;
+ py = ((cmsFloat64Number) At[1] * (p16->Domain[1])) / 65535.0;
+ pz = ((cmsFloat64Number) At[2] * (p16->Domain[2])) / 65535.0;
+
+ x0 = (int) floor(px);
+ y0 = (int) floor(py);
+ z0 = (int) floor(pz);
+
if (((px - x0) != 0) ||
((py - y0) != 0) ||
((pz - z0) != 0)) return FALSE; // Not on exact node
index = p16 -> opta[2] * x0 +
- p16 -> opta[1] * y0 +
- p16 -> opta[0] * z0;
+ p16 -> opta[1] * y0 +
+ p16 -> opta[0] * z0;
}
else
if (nChannelsIn == 1) {
+ px = ((cmsFloat64Number) At[0] * (p16->Domain[0])) / 65535.0;
+
+ x0 = (int) floor(px);
+
if (((px - x0) != 0)) return FALSE; // Not on exact node
index = p16 -> opta[0] * x0;
@@ -462,13 +480,15 @@
return TRUE;
}
-// Auxiliar, to see if two values are equal.
+// Auxiliar, to see if two values are equal or very different
static
cmsBool WhitesAreEqual(int n, cmsUInt16Number White1[], cmsUInt16Number White2[] )
{
int i;
for (i=0; i < n; i++) {
+
+ if (abs(White1[i] - White2[i]) > 0xf000) return TRUE; // Values are so extremly different that the fixup should be avoided
if (White1[i] != White2[i]) return FALSE;
}
return TRUE;
@@ -491,6 +511,8 @@
&WhitePointOut, NULL, &nOuts)) return FALSE;
// It needs to be fixed?
+ if (Lut ->InputChannels != nIns) return FALSE;
+ if (Lut ->OutputChannels != nOuts) return FALSE;
cmsPipelineEval16(WhitePointIn, ObtainedOut, Lut);
@@ -555,6 +577,7 @@
{
cmsPipeline* Src;
cmsPipeline* Dest;
+ cmsStage* mpe;
cmsStage* CLUT;
cmsStage *KeepPreLin = NULL, *KeepPostLin = NULL;
int nGridPoints;
@@ -580,6 +603,13 @@
Src = *Lut;
+ // Named color pipelines cannot be optimized either
+ for (mpe = cmsPipelineGetPtrToFirstStage(Src);
+ mpe != NULL;
+ mpe = cmsStageNext(mpe)) {
+ if (cmsStageType(mpe) == cmsSigNamedColorElemType) return FALSE;
+ }
+
// Allocate an empty LUT
Dest = cmsPipelineAlloc(Src ->ContextID, Src ->InputChannels, Src ->OutputChannels);
if (!Dest) return FALSE;
@@ -817,8 +847,8 @@
cmsUInt8Number r, g, b;
cmsS15Fixed16Number rx, ry, rz;
cmsS15Fixed16Number c0, c1, c2, c3, Rest;
- int OutChan;
- register cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
+ int OutChan;
+ register cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
Prelin8Data* p8 = (Prelin8Data*) D;
register const cmsInterpParams* p = p8 ->p;
int TotalOut = p -> nOutputs;
@@ -892,15 +922,35 @@
}
- Rest = c1 * rx + c2 * ry + c3 * rz;
-
- Output[OutChan] = (cmsUInt16Number)c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest));
+ Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001;
+ Output[OutChan] = (cmsUInt16Number)c0 + ((Rest + (Rest>>16))>>16);
}
}
#undef DENS
+
+// Curves that contain wide empty areas are not optimizeable
+static
+cmsBool IsDegenerated(const cmsToneCurve* g)
+{
+ int i, Zeros = 0, Poles = 0;
+ int nEntries = g ->nEntries;
+
+ for (i=0; i < nEntries; i++) {
+
+ if (g ->Table16[i] == 0x0000) Zeros++;
+ if (g ->Table16[i] == 0xffff) Poles++;
+ }
+
+ if (Zeros == 1 && Poles == 1) return FALSE; // For linear tables
+ if (Zeros > (nEntries / 4)) return TRUE; // Degenerated, mostly zeros
+ if (Poles > (nEntries / 4)) return TRUE; // Degenerated, mostly poles
+
+ return FALSE;
+}
+
// --------------------------------------------------------------------------------------------------------------
// We need xput over here
@@ -917,6 +967,7 @@
cmsStage* OptimizedCLUTmpe;
cmsColorSpaceSignature ColorSpace, OutputColorSpace;
cmsStage* OptimizedPrelinMpe;
+ cmsStage* mpe;
cmsToneCurve** OptimizedPrelinCurves;
_cmsStageCLutData* OptimizedPrelinCLUT;
@@ -935,6 +986,14 @@
}
OriginalLut = *Lut;
+
+ // Named color pipelines cannot be optimized either
+ for (mpe = cmsPipelineGetPtrToFirstStage(OriginalLut);
+ mpe != NULL;
+ mpe = cmsStageNext(mpe)) {
+ if (cmsStageType(mpe) == cmsSigNamedColorElemType) return FALSE;
+ }
+
ColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*InputFormat));
OutputColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*OutputFormat));
nGridPoints = _cmsReasonableGridpointsByColorspace(ColorSpace, *dwFlags);
@@ -981,6 +1040,9 @@
// Exclude if non-monotonic
if (!cmsIsToneCurveMonotonic(Trans[t]))
lIsSuitable = FALSE;
+
+ if (IsDegenerated(Trans[t]))
+ lIsSuitable = FALSE;
}
// If it is not suitable, just quit
@@ -1413,12 +1475,12 @@
// first we compute the resulting byte and then we store the byte times
// 257. This quantization allows to round very quick by doing a >> 8, but
// since the low byte is always equal to msb, we can do a & 0xff and this works!
- cmsUInt16Number w = _cmsQuickSaturateWord(Val * 65535.0 + 0.5);
+ cmsUInt16Number w = _cmsQuickSaturateWord(Val * 65535.0);
cmsUInt8Number b = FROM_16_TO_8(w);
Table[i] = FROM_8_TO_16(b);
}
- else Table[i] = _cmsQuickSaturateWord(Val * 65535.0 + 0.5);
+ else Table[i] = _cmsQuickSaturateWord(Val * 65535.0);
}
}
@@ -1655,3 +1717,5 @@
return AnySuccess;
}
+
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmspack.c Fri Nov 02 17:32:30 2012 -0700
@@ -57,8 +57,8 @@
// This module handles all formats supported by lcms. There are two flavors, 16 bits and
// floating point. Floating point is supported only in a subset, those formats holding
-// cmsFloat32Number (4 bytes per component) and double (marked as 0 bytes per component as special
-// case)
+// cmsFloat32Number (4 bytes per component) and double (marked as 0 bytes per component
+// as special case)
// ---------------------------------------------------------------------------
@@ -73,9 +73,7 @@
// * 0xffff / 0xff00 = (255 * 257) / (255 * 256) = 257 / 256
cmsINLINE cmsUInt16Number FomLabV2ToLabV4(cmsUInt16Number x)
{
- int a;
-
- a = (x << 8 | x) >> 8; // * 257 / 256
+ int a = (x << 8 | x) >> 8; // * 257 / 256
if ( a > 0xffff) return 0xffff;
return (cmsUInt16Number) a;
}
@@ -90,17 +88,18 @@
typedef struct {
cmsUInt32Number Type;
cmsUInt32Number Mask;
- cmsFormatter16 Frm;
+ cmsFormatter16 Frm;
} cmsFormatters16;
typedef struct {
cmsUInt32Number Type;
cmsUInt32Number Mask;
- cmsFormatterFloat Frm;
+ cmsFormatterFloat Frm;
} cmsFormattersFloat;
+
#define ANYSPACE COLORSPACE_SH(31)
#define ANYCHANNELS CHANNELS_SH(15)
#define ANYEXTRA EXTRA_SH(7)
@@ -119,6 +118,7 @@
// Unpacking routines (16 bits) ----------------------------------------------------------------------------------------
+
// Does almost everything but is slow
static
cmsUInt8Number* UnrollChunkyBytes(register _cmsTRANSFORM* info,
@@ -131,7 +131,7 @@
int Reverse = T_FLAVOR(info ->InputFormat);
int SwapFirst = T_SWAPFIRST(info -> InputFormat);
int Extra = T_EXTRA(info -> InputFormat);
- int ExtraFirst = DoSwap && !SwapFirst;
+ int ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt16Number v;
int i;
@@ -160,6 +160,10 @@
}
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
+
}
// Extra channels are just ignored because come in the next planes
@@ -169,13 +173,14 @@
register cmsUInt8Number* accum,
register cmsUInt32Number Stride)
{
- int nChan = T_CHANNELS(info -> InputFormat);
- int DoSwap= T_DOSWAP(info ->InputFormat);
- int Reverse= T_FLAVOR(info ->InputFormat);
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int DoSwap = T_DOSWAP(info ->InputFormat);
+ int SwapFirst = T_SWAPFIRST(info ->InputFormat);
+ int Reverse = T_FLAVOR(info ->InputFormat);
int i;
cmsUInt8Number* Init = accum;
- if (DoSwap) {
+ if (DoSwap ^ SwapFirst) {
accum += T_EXTRA(info -> InputFormat) * Stride;
}
@@ -204,6 +209,9 @@
wIn[3] = FROM_8_TO_16(*accum); accum++; // K
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -218,6 +226,9 @@
wIn[3] = FROM_8_TO_16(REVERSE_FLAVOR_8(*accum)); accum++; // K
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -232,6 +243,9 @@
wIn[2] = FROM_8_TO_16(*accum); accum++; // Y
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
// KYMC
@@ -247,6 +261,9 @@
wIn[0] = FROM_8_TO_16(*accum); accum++; // C
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -261,6 +278,9 @@
wIn[3] = FROM_8_TO_16(*accum); accum++; // C
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -274,6 +294,9 @@
wIn[2] = FROM_8_TO_16(*accum); accum++; // B
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -288,6 +311,9 @@
wIn[0] = FROM_8_TO_16(*accum); accum++; // R
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -302,6 +328,9 @@
wIn[2] = FROM_8_TO_16(*accum); accum++; // B
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
@@ -317,6 +346,9 @@
wIn[0] = FROM_8_TO_16(*accum); accum++; // R
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -330,6 +362,9 @@
wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -344,6 +379,9 @@
wIn[2] = FomLabV2ToLabV4(FROM_8_TO_16(*accum)); accum++; // b
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -357,34 +395,30 @@
wIn[2] = FomLabV2ToLabV4(*(cmsUInt16Number*) accum); accum += 2; // b
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
-
-
-// Monochrome + alpha. Alpha is lost
+// for duplex
static
cmsUInt8Number* Unroll2Bytes(register _cmsTRANSFORM* info,
- register cmsUInt16Number wIn[],
- register cmsUInt8Number* accum,
- register cmsUInt32Number Stride)
-{
- wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
- wIn[3] = FROM_8_TO_16(*accum); accum++; // alpha
- return accum;
-}
-
-static
-cmsUInt8Number* Unroll2ByteSwapFirst(register _cmsTRANSFORM* info,
register cmsUInt16Number wIn[],
register cmsUInt8Number* accum,
register cmsUInt32Number Stride)
{
- wIn[3] = FROM_8_TO_16(*accum); accum++; // alpha
- wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
+ wIn[0] = FROM_8_TO_16(*accum); accum++; // ch1
+ wIn[1] = FROM_8_TO_16(*accum); accum++; // ch2
+
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
+
+
// Monochrome duplicates L into RGB for null-transforms
static
cmsUInt8Number* Unroll1Byte(register _cmsTRANSFORM* info,
@@ -393,7 +427,27 @@
register cmsUInt32Number Stride)
{
wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
+
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
+}
+
+
+static
+cmsUInt8Number* Unroll1ByteSkip1(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
+ accum += 1;
+
+ return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -404,7 +458,11 @@
{
wIn[0] = wIn[1] = wIn[2] = FROM_8_TO_16(*accum); accum++; // L
accum += 2;
+
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -414,7 +472,11 @@
register cmsUInt32Number Stride)
{
wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(FROM_8_TO_16(*accum)); accum++; // L
+
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
@@ -430,7 +492,7 @@
int Reverse = T_FLAVOR(info ->InputFormat);
int SwapFirst = T_SWAPFIRST(info -> InputFormat);
int Extra = T_EXTRA(info -> InputFormat);
- int ExtraFirst = DoSwap && !SwapFirst;
+ int ExtraFirst = DoSwap ^ SwapFirst;
int i;
if (ExtraFirst) {
@@ -463,6 +525,8 @@
}
return accum;
+
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -511,6 +575,9 @@
wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // K
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -525,6 +592,9 @@
wIn[3] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2; // K
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -539,6 +609,9 @@
wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
// KYMC
@@ -554,6 +627,9 @@
wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -568,6 +644,9 @@
wIn[3] = *(cmsUInt16Number*) accum; accum+= 2; // C
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -579,7 +658,11 @@
wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // C R
wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
+
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -591,7 +674,11 @@
wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // C R
wIn[1] = *(cmsUInt16Number*) accum; accum+= 2; // M G
wIn[0] = *(cmsUInt16Number*) accum; accum+= 2; // Y B
+
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -606,6 +693,9 @@
wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // B
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -620,6 +710,9 @@
wIn[2] = *(cmsUInt16Number*) accum; accum += 2; // B
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -629,7 +722,11 @@
register cmsUInt32Number Stride)
{
wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // L
+
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -639,7 +736,11 @@
register cmsUInt32Number Stride)
{
wIn[0] = wIn[1] = wIn[2] = REVERSE_FLAVOR_16(*(cmsUInt16Number*) accum); accum+= 2;
+
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -651,33 +752,29 @@
wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum;
accum += 8;
+
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
cmsUInt8Number* Unroll2Words(register _cmsTRANSFORM* info,
- register cmsUInt16Number wIn[],
- register cmsUInt8Number* accum,
- register cmsUInt32Number Stride)
-{
- wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // L
- wIn[3] = *(cmsUInt16Number*) accum; accum += 2; // alpha
-
- return accum;
-}
-
-static
-cmsUInt8Number* Unroll2WordSwapFirst(register _cmsTRANSFORM* info,
register cmsUInt16Number wIn[],
register cmsUInt8Number* accum,
register cmsUInt32Number Stride)
{
- wIn[3] = *(cmsUInt16Number*) accum; accum += 2; // alpha
- wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // L
+ wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // ch1
+ wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // ch2
return accum;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
+
// This is a conversion of Lab double to 16 bits
static
cmsUInt8Number* UnrollLabDoubleTo16(register _cmsTRANSFORM* info,
@@ -701,7 +798,41 @@
else {
cmsFloat2LabEncoded(wIn, (cmsCIELab*) accum);
- accum += sizeof(cmsCIELab);
+ accum += sizeof(cmsCIELab) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
+ return accum;
+ }
+}
+
+
+// This is a conversion of Lab float to 16 bits
+static
+cmsUInt8Number* UnrollLabFloatTo16(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+ cmsCIELab Lab;
+
+ if (T_PLANAR(info -> InputFormat)) {
+
+ cmsFloat32Number* Pt = (cmsFloat32Number*) accum;
+
+
+ Lab.L = Pt[0];
+ Lab.a = Pt[Stride];
+ Lab.b = Pt[Stride*2];
+
+ cmsFloat2LabEncoded(wIn, &Lab);
+ return accum + sizeof(cmsFloat32Number);
+ }
+ else {
+
+ Lab.L = ((cmsFloat32Number*) accum)[0];
+ Lab.a = ((cmsFloat32Number*) accum)[1];
+ Lab.b = ((cmsFloat32Number*) accum)[2];
+
+ cmsFloat2LabEncoded(wIn, &Lab);
+ accum += (3 + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
return accum;
}
}
@@ -729,7 +860,7 @@
else {
cmsFloat2XYZEncoded(wIn, (cmsCIEXYZ*) accum);
- accum += sizeof(cmsCIEXYZ);
+ accum += sizeof(cmsCIEXYZ) + T_EXTRA(info ->InputFormat) * sizeof(cmsFloat64Number);
return accum;
}
@@ -761,65 +892,117 @@
// Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits
static
cmsUInt8Number* UnrollDoubleTo16(register _cmsTRANSFORM* info,
- register cmsUInt16Number wIn[],
- register cmsUInt8Number* accum,
- register cmsUInt32Number Stride)
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
{
- cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
- int nChan = T_CHANNELS(info -> InputFormat);
- int Planar = T_PLANAR(info -> InputFormat);
- int i;
+
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int DoSwap = T_DOSWAP(info ->InputFormat);
+ int Reverse = T_FLAVOR(info ->InputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> InputFormat);
+ int Extra = T_EXTRA(info -> InputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ int Planar = T_PLANAR(info -> InputFormat);
cmsFloat64Number v;
- cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
+ cmsUInt16Number vi;
+ int i, start = 0;
+ cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
+
+
+ if (ExtraFirst)
+ start = Extra;
for (i=0; i < nChan; i++) {
+ int index = DoSwap ? (nChan - i - 1) : i;
+
if (Planar)
-
- v = Inks[i * Stride];
+ v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
else
- v = Inks[i];
-
- wIn[i] = _cmsQuickSaturateWord(v * maximum);
+ v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[i + start];
+
+ vi = _cmsQuickSaturateWord(v * maximum);
+
+ if (Reverse)
+ vi = REVERSE_FLAVOR_16(vi);
+
+ wIn[index] = vi;
+ }
+
+
+ if (Extra == 0 && SwapFirst) {
+ cmsUInt16Number tmp = wIn[0];
+
+ memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
+ wIn[nChan-1] = tmp;
}
if (T_PLANAR(info -> InputFormat))
return accum + sizeof(cmsFloat64Number);
else
- return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat64Number);
+ return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
}
+
+
static
cmsUInt8Number* UnrollFloatTo16(register _cmsTRANSFORM* info,
register cmsUInt16Number wIn[],
register cmsUInt8Number* accum,
register cmsUInt32Number Stride)
{
- cmsFloat32Number* Inks = (cmsFloat32Number*) accum;
- int nChan = T_CHANNELS(info -> InputFormat);
- int Planar = T_PLANAR(info -> InputFormat);
- int i;
+
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int DoSwap = T_DOSWAP(info ->InputFormat);
+ int Reverse = T_FLAVOR(info ->InputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> InputFormat);
+ int Extra = T_EXTRA(info -> InputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ int Planar = T_PLANAR(info -> InputFormat);
cmsFloat32Number v;
- cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
+ cmsUInt16Number vi;
+ int i, start = 0;
+ cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0;
+
+
+ if (ExtraFirst)
+ start = Extra;
for (i=0; i < nChan; i++) {
+ int index = DoSwap ? (nChan - i - 1) : i;
+
if (Planar)
-
- v = Inks[i * Stride];
+ v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
else
- v = Inks[i];
-
- wIn[i] = _cmsQuickSaturateWord(v * maximum);
+ v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
+
+ vi = _cmsQuickSaturateWord(v * maximum);
+
+ if (Reverse)
+ vi = REVERSE_FLAVOR_16(vi);
+
+ wIn[index] = vi;
+ }
+
+
+ if (Extra == 0 && SwapFirst) {
+ cmsUInt16Number tmp = wIn[0];
+
+ memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
+ wIn[nChan-1] = tmp;
}
if (T_PLANAR(info -> InputFormat))
return accum + sizeof(cmsFloat32Number);
else
- return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
+ return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
}
+
+
// For 1 channel, we need to duplicate data (it comes in 0..1.0 range)
static
cmsUInt8Number* UnrollDouble1Chan(register _cmsTRANSFORM* info,
@@ -832,12 +1015,13 @@
wIn[0] = wIn[1] = wIn[2] = _cmsQuickSaturateWord(Inks[0] * 65535.0);
return accum + sizeof(cmsFloat64Number);
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
//-------------------------------------------------------------------------------------------------------------------
-// True cmsFloat32Number transformation.
-
// For anything going from cmsFloat32Number
static
cmsUInt8Number* UnrollFloatsToFloat(_cmsTRANSFORM* info,
@@ -845,55 +1029,104 @@
cmsUInt8Number* accum,
cmsUInt32Number Stride)
{
- cmsFloat32Number* Inks = (cmsFloat32Number*) accum;
- int nChan = T_CHANNELS(info -> InputFormat);
- int Planar = T_PLANAR(info -> InputFormat);
- int i;
- cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
-
-
- for (i=0; i < nChan; i++) {
+
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int DoSwap = T_DOSWAP(info ->InputFormat);
+ int Reverse = T_FLAVOR(info ->InputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> InputFormat);
+ int Extra = T_EXTRA(info -> InputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ int Planar = T_PLANAR(info -> InputFormat);
+ cmsFloat32Number v;
+ int i, start = 0;
+ cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
+
+
+ if (ExtraFirst)
+ start = Extra;
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
if (Planar)
- wIn[i] = (cmsFloat32Number) (Inks[i * Stride] / maximum);
+ v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride];
else
- wIn[i] = (cmsFloat32Number) (Inks[i] / maximum);
+ v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[i + start];
+
+ v /= maximum;
+
+ wIn[index] = Reverse ? 1 - v : v;
+ }
+
+
+ if (Extra == 0 && SwapFirst) {
+ cmsFloat32Number tmp = wIn[0];
+
+ memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
+ wIn[nChan-1] = tmp;
}
if (T_PLANAR(info -> InputFormat))
return accum + sizeof(cmsFloat32Number);
else
- return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat32Number);
+ return accum + (nChan + Extra) * sizeof(cmsFloat32Number);
}
// For anything going from double
+
static
cmsUInt8Number* UnrollDoublesToFloat(_cmsTRANSFORM* info,
- cmsFloat32Number wIn[],
- cmsUInt8Number* accum,
- cmsUInt32Number Stride)
+ cmsFloat32Number wIn[],
+ cmsUInt8Number* accum,
+ cmsUInt32Number Stride)
{
- cmsFloat64Number* Inks = (cmsFloat64Number*) accum;
- int nChan = T_CHANNELS(info -> InputFormat);
- int Planar = T_PLANAR(info -> InputFormat);
- int i;
+
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int DoSwap = T_DOSWAP(info ->InputFormat);
+ int Reverse = T_FLAVOR(info ->InputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> InputFormat);
+ int Extra = T_EXTRA(info -> InputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ int Planar = T_PLANAR(info -> InputFormat);
+ cmsFloat64Number v;
+ int i, start = 0;
cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0;
- for (i=0; i < nChan; i++) {
+
+ if (ExtraFirst)
+ start = Extra;
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
if (Planar)
- wIn[i] = (cmsFloat32Number) (Inks[i * Stride] / maximum);
+ v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[(i + start) * Stride];
else
- wIn[i] = (cmsFloat32Number) (Inks[i] / maximum);
+ v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[i + start];
+
+ v /= maximum;
+
+ wIn[index] = (cmsFloat32Number) (Reverse ? 1.0 - v : v);
+ }
+
+
+ if (Extra == 0 && SwapFirst) {
+ cmsFloat32Number tmp = wIn[0];
+
+ memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
+ wIn[nChan-1] = tmp;
}
if (T_PLANAR(info -> InputFormat))
return accum + sizeof(cmsFloat64Number);
else
- return accum + (nChan + T_EXTRA(info ->InputFormat)) * sizeof(cmsFloat64Number);
+ return accum + (nChan + Extra) * sizeof(cmsFloat64Number);
}
+
// From Lab double to cmsFloat32Number
static
cmsUInt8Number* UnrollLabDoubleToFloat(_cmsTRANSFORM* info,
@@ -913,11 +1146,11 @@
}
else {
- wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
+ wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
- accum += sizeof(cmsFloat64Number)*3;
+ accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
return accum;
}
}
@@ -933,7 +1166,7 @@
if (T_PLANAR(info -> InputFormat)) {
- wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
+ wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1
wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0);
@@ -941,16 +1174,17 @@
}
else {
- wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
+ wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1
wIn[1] = (cmsFloat32Number) ((Pt[1] + 128) / 255.0); // form -128..+127 to 0..1
wIn[2] = (cmsFloat32Number) ((Pt[2] + 128) / 255.0);
- accum += sizeof(cmsFloat32Number)*3;
+ accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
return accum;
}
}
+
// 1.15 fixed point, that means maximum value is MAX_ENCODEABLE_XYZ (0xFFFF)
static
cmsUInt8Number* UnrollXYZDoubleToFloat(_cmsTRANSFORM* info,
@@ -974,7 +1208,7 @@
wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
- accum += sizeof(cmsFloat64Number)*3;
+ accum += sizeof(cmsFloat64Number)*(3 + T_EXTRA(info ->InputFormat));
return accum;
}
}
@@ -1001,11 +1235,13 @@
wIn[1] = (cmsFloat32Number) (Pt[1] / MAX_ENCODEABLE_XYZ);
wIn[2] = (cmsFloat32Number) (Pt[2] / MAX_ENCODEABLE_XYZ);
- accum += sizeof(cmsFloat32Number)*3;
+ accum += sizeof(cmsFloat32Number)*(3 + T_EXTRA(info ->InputFormat));
return accum;
}
}
+
+
// Packing routines -----------------------------------------------------------------------------------------------------------
@@ -1022,7 +1258,7 @@
int Reverse = T_FLAVOR(info ->OutputFormat);
int Extra = T_EXTRA(info -> OutputFormat);
int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int ExtraFirst = DoSwap && !SwapFirst;
+ int ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt8Number* swap1;
cmsUInt8Number v = 0;
int i;
@@ -1057,6 +1293,8 @@
return output;
+
+ cmsUNUSED_PARAMETER(Stride);
}
@@ -1073,7 +1311,7 @@
int Reverse = T_FLAVOR(info ->OutputFormat);
int Extra = T_EXTRA(info -> OutputFormat);
int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int ExtraFirst = DoSwap && !SwapFirst;
+ int ExtraFirst = DoSwap ^ SwapFirst;
cmsUInt16Number* swap1;
cmsUInt16Number v = 0;
int i;
@@ -1113,6 +1351,8 @@
return output;
+
+ cmsUNUSED_PARAMETER(Stride);
}
@@ -1122,12 +1362,19 @@
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse= T_FLAVOR(info ->OutputFormat);
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info ->OutputFormat);
+ int Reverse = T_FLAVOR(info ->OutputFormat);
int i;
cmsUInt8Number* Init = output;
+
+ if (DoSwap ^ SwapFirst) {
+ output += T_EXTRA(info -> OutputFormat) * Stride;
+ }
+
+
for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i;
@@ -1138,6 +1385,8 @@
}
return (Init + 1);
+
+ cmsUNUSED_PARAMETER(Stride);
}
@@ -1194,6 +1443,9 @@
*output++ = FROM_16_TO_8(wOut[5]);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
// KCMYcm
@@ -1212,6 +1464,9 @@
*output++ = FROM_16_TO_8(wOut[0]);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
// CMYKcm
@@ -1235,6 +1490,9 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
// KCMYcm
@@ -1258,6 +1516,9 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
@@ -1273,6 +1534,9 @@
*output++ = FROM_16_TO_8(wOut[3]);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -1287,6 +1551,9 @@
*output++ = REVERSE_FLAVOR_8(FROM_16_TO_8(wOut[3]));
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
@@ -1302,6 +1569,9 @@
*output++ = FROM_16_TO_8(wOut[2]);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
// ABGR
@@ -1317,6 +1587,9 @@
*output++ = FROM_16_TO_8(wOut[0]);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -1331,6 +1604,9 @@
*output++ = FROM_16_TO_8(wOut[3]);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -1349,6 +1625,9 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -1367,6 +1646,9 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
// ABGR
@@ -1386,6 +1668,9 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
// CMYK
@@ -1405,6 +1690,9 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
@@ -1419,6 +1707,9 @@
*output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -1433,6 +1724,9 @@
*output++ = FROM_16_TO_8(FomLabV4ToLabV2(wOut[2]));
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -1449,6 +1743,9 @@
output += 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -1462,6 +1759,9 @@
*output++ = FROM_16_TO_8(wOut[2]);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -1475,6 +1775,9 @@
*output++ = (wOut[2] & 0xFF);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -1488,6 +1791,9 @@
*output++ = FROM_16_TO_8(wOut[0]);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -1501,6 +1807,9 @@
*output++ = (wOut[0] & 0xFF);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
@@ -1518,6 +1827,9 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -1534,6 +1846,9 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
@@ -1550,10 +1865,13 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack3BytesAndSkip1(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack3BytesAndSkip1(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1564,10 +1882,13 @@
output++;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack3BytesAndSkip1Optimized(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1578,11 +1899,14 @@
output++;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack3BytesAndSkip1SwapFirst(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1593,10 +1917,13 @@
*output++ = FROM_16_TO_8(wOut[2]);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack3BytesAndSkip1SwapFirstOptimized(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1607,10 +1934,13 @@
*output++ = (wOut[2] & 0xFF);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack3BytesAndSkip1Swap(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack3BytesAndSkip1Swap(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1621,10 +1951,13 @@
*output++ = FROM_16_TO_8(wOut[0]);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack3BytesAndSkip1SwapOptimized(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1635,11 +1968,14 @@
*output++ = (wOut[0] & 0xFF);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1650,10 +1986,13 @@
output++;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack3BytesAndSkip1SwapSwapFirstOptimized(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1664,10 +2003,13 @@
output++;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack3WordsAndSkip1(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack3WordsAndSkip1(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1681,10 +2023,13 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack3WordsAndSkip1Swap(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack3WordsAndSkip1Swap(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1698,11 +2043,14 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack3WordsAndSkip1SwapFirst(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1716,11 +2064,14 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack3WordsAndSkip1SwapSwapFirst(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1734,46 +2085,61 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack1Byte(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack1Byte(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[0]);
+
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack1ByteReversed(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack1ByteReversed(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(REVERSE_FLAVOR_16(wOut[0]));
+
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack1ByteSkip1(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack1ByteSkip1(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
{
*output++ = FROM_16_TO_8(wOut[0]);
output++;
+
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack1ByteSkip1SwapFirst(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack1ByteSkip1SwapFirst(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1782,10 +2148,13 @@
*output++ = FROM_16_TO_8(wOut[0]);
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack1Word(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack1Word(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1794,11 +2163,14 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack1WordReversed(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack1WordReversed(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1807,10 +2179,13 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack1WordBigEndian(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack1WordBigEndian(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1819,11 +2194,14 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack1WordSkip1(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack1WordSkip1(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1832,10 +2210,13 @@
output+= 4;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
static
-cmsUInt8Number* Pack1WordSkip1SwapFirst(register _cmsTRANSFORM* Info,
+cmsUInt8Number* Pack1WordSkip1SwapFirst(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
@@ -1845,18 +2226,21 @@
output+= 2;
return output;
+
+ cmsUNUSED_PARAMETER(info);
+ cmsUNUSED_PARAMETER(Stride);
}
// Unencoded Float values -- don't try optimize speed
static
-cmsUInt8Number* PackLabDoubleFrom16(register _cmsTRANSFORM* Info,
+cmsUInt8Number* PackLabDoubleFrom16(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
{
- if (T_PLANAR(Info -> OutputFormat)) {
+ if (T_PLANAR(info -> OutputFormat)) {
cmsCIELab Lab;
cmsFloat64Number* Out = (cmsFloat64Number*) output;
@@ -1871,9 +2255,38 @@
else {
cmsLabEncoded2Float((cmsCIELab*) output, wOut);
- return output + (sizeof(cmsCIELab) + T_EXTRA(Info ->OutputFormat) * sizeof(cmsFloat64Number));
+ return output + (sizeof(cmsCIELab) + T_EXTRA(info ->OutputFormat) * sizeof(cmsFloat64Number));
}
-
+}
+
+
+static
+cmsUInt8Number* PackLabFloatFrom16(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ cmsCIELab Lab;
+ cmsLabEncoded2Float(&Lab, wOut);
+
+ if (T_PLANAR(info -> OutputFormat)) {
+
+ cmsFloat32Number* Out = (cmsFloat32Number*) output;
+
+ Out[0] = (cmsFloat32Number)Lab.L;
+ Out[Stride] = (cmsFloat32Number)Lab.a;
+ Out[Stride*2] = (cmsFloat32Number)Lab.b;
+
+ return output + sizeof(cmsFloat32Number);
+ }
+ else {
+
+ ((cmsFloat32Number*) output)[0] = (cmsFloat32Number) Lab.L;
+ ((cmsFloat32Number*) output)[1] = (cmsFloat32Number) Lab.a;
+ ((cmsFloat32Number*) output)[2] = (cmsFloat32Number) Lab.b;
+
+ return output + (3 + T_EXTRA(info ->OutputFormat)) * sizeof(cmsFloat32Number);
+ }
}
static
@@ -1888,7 +2301,7 @@
cmsFloat64Number* Out = (cmsFloat64Number*) output;
cmsXYZEncoded2Float(&XYZ, wOut);
- Out[0] = XYZ.X;
+ Out[0] = XYZ.X;
Out[Stride] = XYZ.Y;
Out[Stride*2] = XYZ.Z;
@@ -1904,97 +2317,136 @@
}
static
-cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* Info,
- register cmsUInt16Number wOut[],
- register cmsUInt8Number* output,
- register cmsUInt32Number Stride)
-{
- cmsFloat64Number* Inks = (cmsFloat64Number*) output;
- int nChan = T_CHANNELS(Info -> OutputFormat);
- int i;
- cmsFloat64Number maximum = IsInkSpace(Info ->InputFormat) ? 655.35 : 65535.0;
-
- if (T_PLANAR(Info -> OutputFormat)) {
-
- for (i=0; i < nChan; i++) {
-
- Inks[i*Stride] = wOut[i] / maximum;
- }
-
- return output + sizeof(cmsFloat64Number);
- }
- else {
-
- for (i=0; i < nChan; i++) {
-
- Inks[i] = wOut[i] / maximum;
- }
-
-
- return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(cmsFloat64Number);
- }
-
-}
-
-static
-cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* Info,
+cmsUInt8Number* PackDoubleFrom16(register _cmsTRANSFORM* info,
register cmsUInt16Number wOut[],
register cmsUInt8Number* output,
register cmsUInt32Number Stride)
{
- cmsFloat32Number* Inks = (cmsFloat32Number*) output;
- int nChan = T_CHANNELS(Info -> OutputFormat);
- int i;
- cmsFloat64Number maximum = IsInkSpace(Info ->OutputFormat) ? 655.35 : 65535.0;
-
- if (T_PLANAR(Info -> OutputFormat)) {
-
- for (i=0; i < nChan; i++) {
-
- Inks[i*Stride] = (cmsFloat32Number) (wOut[i] / maximum);
- }
-
- return output + sizeof(cmsFloat32Number);
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int Reverse = T_FLAVOR(info ->OutputFormat);
+ int Extra = T_EXTRA(info -> OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
+ int Planar = T_PLANAR(info -> OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
+ cmsFloat64Number v = 0;
+ cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
+ int i, start = 0;
+
+ if (ExtraFirst)
+ start = Extra;
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ v = (cmsFloat64Number) wOut[index] / maximum;
+
+ if (Reverse)
+ v = maximum - v;
+
+ if (Planar)
+ ((cmsFloat64Number*) output)[(i + start) * Stride]= v;
+ else
+ ((cmsFloat64Number*) output)[i + start] = v;
}
- else {
-
- for (i=0; i < nChan; i++) {
-
- Inks[i] = (cmsFloat32Number) (wOut[i] / maximum);
- }
-
-
- return output + (nChan + T_EXTRA(Info ->OutputFormat)) * sizeof(cmsFloat32Number);
+
+ if (!ExtraFirst) {
+ output += Extra * sizeof(cmsFloat64Number);
}
+ if (Extra == 0 && SwapFirst) {
+
+ memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
+ *swap1 = v;
+ }
+
+ if (T_PLANAR(info -> OutputFormat))
+ return output + sizeof(cmsFloat64Number);
+ else
+ return output + nChan * sizeof(cmsFloat64Number);
+
}
-// --------------------------------------------------------------------------------------------------------
-
static
-cmsUInt8Number* PackChunkyFloatsFromFloat(_cmsTRANSFORM* info,
- cmsFloat32Number wOut[],
- cmsUInt8Number* output,
- cmsUInt32Number Stride)
+cmsUInt8Number* PackFloatFrom16(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
{
int nChan = T_CHANNELS(info -> OutputFormat);
int DoSwap = T_DOSWAP(info ->OutputFormat);
int Reverse = T_FLAVOR(info ->OutputFormat);
int Extra = T_EXTRA(info -> OutputFormat);
int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int ExtraFirst = DoSwap && !SwapFirst;
- cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
- cmsFloat32Number* swap1;
+ int Planar = T_PLANAR(info -> OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0;
cmsFloat64Number v = 0;
- int i;
-
- swap1 = (cmsFloat32Number*) output;
-
- if (ExtraFirst) {
+ cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
+ int i, start = 0;
+
+ if (ExtraFirst)
+ start = Extra;
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ v = (cmsFloat64Number) wOut[index] / maximum;
+
+ if (Reverse)
+ v = maximum - v;
+
+ if (Planar)
+ ((cmsFloat32Number*) output)[(i + start ) * Stride]= (cmsFloat32Number) v;
+ else
+ ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
+ }
+
+ if (!ExtraFirst) {
output += Extra * sizeof(cmsFloat32Number);
}
+ if (Extra == 0 && SwapFirst) {
+
+ memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
+ *swap1 = (cmsFloat32Number) v;
+ }
+
+ if (T_PLANAR(info -> OutputFormat))
+ return output + sizeof(cmsFloat32Number);
+ else
+ return output + nChan * sizeof(cmsFloat32Number);
+}
+
+
+
+// --------------------------------------------------------------------------------------------------------
+
+static
+cmsUInt8Number* PackFloatsFromFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wOut[],
+ cmsUInt8Number* output,
+ cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int Reverse = T_FLAVOR(info ->OutputFormat);
+ int Extra = T_EXTRA(info -> OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
+ int Planar = T_PLANAR(info -> OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
+ cmsFloat32Number* swap1 = (cmsFloat32Number*) output;
+ cmsFloat64Number v = 0;
+ int i, start = 0;
+
+ if (ExtraFirst)
+ start = Extra;
+
for (i=0; i < nChan; i++) {
int index = DoSwap ? (nChan - i - 1) : i;
@@ -2004,42 +2456,48 @@
if (Reverse)
v = maximum - v;
- *(cmsFloat32Number*) output = (cmsFloat32Number) v;
-
- output += sizeof(cmsFloat32Number);
+ if (Planar)
+ ((cmsFloat32Number*) output)[(i + start)* Stride]= (cmsFloat32Number) v;
+ else
+ ((cmsFloat32Number*) output)[i + start] = (cmsFloat32Number) v;
}
if (!ExtraFirst) {
output += Extra * sizeof(cmsFloat32Number);
}
- if (Extra == 0 && SwapFirst) {
-
- memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
+ if (Extra == 0 && SwapFirst) {
+
+ memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat32Number));
*swap1 = (cmsFloat32Number) v;
}
-
- return output;
+ if (T_PLANAR(info -> OutputFormat))
+ return output + sizeof(cmsFloat32Number);
+ else
+ return output + nChan * sizeof(cmsFloat32Number);
}
static
-cmsUInt8Number* PackPlanarFloatsFromFloat(_cmsTRANSFORM* info,
- cmsFloat32Number wOut[],
- cmsUInt8Number* output,
- cmsUInt32Number Stride)
+cmsUInt8Number* PackDoublesFromFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wOut[],
+ cmsUInt8Number* output,
+ cmsUInt32Number Stride)
{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse= T_FLAVOR(info ->OutputFormat);
- int i;
- cmsUInt8Number* Init = output;
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int Reverse = T_FLAVOR(info ->OutputFormat);
+ int Extra = T_EXTRA(info -> OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
+ int Planar = T_PLANAR(info -> OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
- cmsFloat64Number v;
-
- if (DoSwap) {
- output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsFloat32Number);
- }
+ cmsFloat64Number v = 0;
+ cmsFloat64Number* swap1 = (cmsFloat64Number*) output;
+ int i, start = 0;
+
+ if (ExtraFirst)
+ start = Extra;
for (i=0; i < nChan; i++) {
@@ -2048,100 +2506,32 @@
v = wOut[index] * maximum;
if (Reverse)
- v = maximum - v;
-
- *(cmsFloat32Number*) output = (cmsFloat32Number) v;
- output += (Stride * sizeof(cmsFloat32Number));
- }
-
- return (Init + sizeof(cmsFloat32Number));
-}
-
-
-static
-cmsUInt8Number* PackChunkyDoublesFromFloat(_cmsTRANSFORM* info,
- cmsFloat32Number wOut[],
- cmsUInt8Number* output,
- cmsUInt32Number Stride)
-{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse = T_FLAVOR(info ->OutputFormat);
- int Extra = T_EXTRA(info -> OutputFormat);
- int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
- int ExtraFirst = DoSwap && !SwapFirst;
- cmsFloat64Number* swap1;
- cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
- cmsFloat64Number v = 0;
- int i;
-
- swap1 = (cmsFloat64Number*) output;
-
- if (ExtraFirst) {
- output += Extra * sizeof(cmsFloat64Number);
- }
-
- for (i=0; i < nChan; i++) {
-
- int index = DoSwap ? (nChan - i - 1) : i;
-
- v = (cmsFloat64Number) wOut[index] * maximum;
-
- if (Reverse)
v = maximum - v;
- *(cmsFloat64Number*) output = v;
-
- output += sizeof(cmsFloat64Number);
+ if (Planar)
+ ((cmsFloat64Number*) output)[(i + start) * Stride] = v;
+ else
+ ((cmsFloat64Number*) output)[i + start] = v;
}
if (!ExtraFirst) {
output += Extra * sizeof(cmsFloat64Number);
}
- if (Extra == 0 && SwapFirst) {
-
- memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
+ if (Extra == 0 && SwapFirst) {
+
+ memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsFloat64Number));
*swap1 = v;
}
- return output;
+ if (T_PLANAR(info -> OutputFormat))
+ return output + sizeof(cmsFloat64Number);
+ else
+ return output + nChan * sizeof(cmsFloat64Number);
+
}
-static
-cmsUInt8Number* PackPlanarDoublesFromFloat(_cmsTRANSFORM* info,
- cmsFloat32Number wOut[],
- cmsUInt8Number* output,
- cmsUInt32Number Stride)
-{
- int nChan = T_CHANNELS(info -> OutputFormat);
- int DoSwap = T_DOSWAP(info ->OutputFormat);
- int Reverse= T_FLAVOR(info ->OutputFormat);
- int i;
- cmsUInt8Number* Init = output;
- cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0 : 1.0;
- cmsFloat64Number v;
-
- if (DoSwap) {
- output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsFloat64Number);
- }
-
- for (i=0; i < nChan; i++) {
-
- int index = DoSwap ? (nChan - i - 1) : i;
-
- v = (cmsFloat64Number) wOut[index] * maximum;
-
- if (Reverse)
- v = maximum - v;
-
- *(cmsFloat64Number*) output = v;
- output += (Stride * sizeof(cmsFloat64Number));
- }
-
- return (Init + sizeof(cmsFloat64Number));
-}
@@ -2156,7 +2546,7 @@
if (T_PLANAR(Info -> OutputFormat)) {
- Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
+ Out[0] = (cmsFloat32Number) (wOut[0] * 100.0);
Out[Stride] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0);
Out[Stride*2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0);
@@ -2173,6 +2563,7 @@
}
+
static
cmsUInt8Number* PackLabDoubleFromFloat(_cmsTRANSFORM* Info,
cmsFloat32Number wOut[],
@@ -2183,7 +2574,7 @@
if (T_PLANAR(Info -> OutputFormat)) {
- Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
+ Out[0] = (cmsFloat64Number) (wOut[0] * 100.0);
Out[Stride] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0);
Out[Stride*2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0);
@@ -2212,7 +2603,7 @@
if (T_PLANAR(Info -> OutputFormat)) {
- Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
+ Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
Out[Stride] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
Out[Stride*2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
@@ -2229,7 +2620,6 @@
}
-
// Same, but convert to double
static
cmsUInt8Number* PackXYZDoubleFromFloat(_cmsTRANSFORM* Info,
@@ -2241,7 +2631,7 @@
if (T_PLANAR(Info -> OutputFormat)) {
- Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
+ Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ);
Out[Stride] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ);
Out[Stride*2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ);
@@ -2261,24 +2651,246 @@
// ----------------------------------------------------------------------------------------------------------------
+#ifndef CMS_NO_HALF_SUPPORT
+
+// Decodes an stream of half floats to wIn[] described by input format
+
+static
+cmsUInt8Number* UnrollHalfTo16(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wIn[],
+ register cmsUInt8Number* accum,
+ register cmsUInt32Number Stride)
+{
+
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int DoSwap = T_DOSWAP(info ->InputFormat);
+ int Reverse = T_FLAVOR(info ->InputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> InputFormat);
+ int Extra = T_EXTRA(info -> InputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ int Planar = T_PLANAR(info -> InputFormat);
+ cmsFloat32Number v;
+ int i, start = 0;
+ cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F;
+
+
+ if (ExtraFirst)
+ start = Extra;
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ if (Planar)
+ v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
+ else
+ v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
+
+ if (Reverse) v = maximum - v;
+
+ wIn[index] = _cmsQuickSaturateWord(v * maximum);
+ }
+
+
+ if (Extra == 0 && SwapFirst) {
+ cmsUInt16Number tmp = wIn[0];
+
+ memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsUInt16Number));
+ wIn[nChan-1] = tmp;
+ }
+
+ if (T_PLANAR(info -> InputFormat))
+ return accum + sizeof(cmsUInt16Number);
+ else
+ return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
+}
+
+// Decodes an stream of half floats to wIn[] described by input format
+
+static
+cmsUInt8Number* UnrollHalfToFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wIn[],
+ cmsUInt8Number* accum,
+ cmsUInt32Number Stride)
+{
+
+ int nChan = T_CHANNELS(info -> InputFormat);
+ int DoSwap = T_DOSWAP(info ->InputFormat);
+ int Reverse = T_FLAVOR(info ->InputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> InputFormat);
+ int Extra = T_EXTRA(info -> InputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ int Planar = T_PLANAR(info -> InputFormat);
+ cmsFloat32Number v;
+ int i, start = 0;
+ cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F;
+
+
+ if (ExtraFirst)
+ start = Extra;
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ if (Planar)
+ v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] );
+ else
+ v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[i + start] ) ;
+
+ v /= maximum;
+
+ wIn[index] = Reverse ? 1 - v : v;
+ }
+
+
+ if (Extra == 0 && SwapFirst) {
+ cmsFloat32Number tmp = wIn[0];
+
+ memmove(&wIn[0], &wIn[1], (nChan-1) * sizeof(cmsFloat32Number));
+ wIn[nChan-1] = tmp;
+ }
+
+ if (T_PLANAR(info -> InputFormat))
+ return accum + sizeof(cmsUInt16Number);
+ else
+ return accum + (nChan + Extra) * sizeof(cmsUInt16Number);
+}
+
+
+static
+cmsUInt8Number* PackHalfFrom16(register _cmsTRANSFORM* info,
+ register cmsUInt16Number wOut[],
+ register cmsUInt8Number* output,
+ register cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int Reverse = T_FLAVOR(info ->OutputFormat);
+ int Extra = T_EXTRA(info -> OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
+ int Planar = T_PLANAR(info -> OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35F : 65535.0F;
+ cmsFloat32Number v = 0;
+ cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
+ int i, start = 0;
+
+ if (ExtraFirst)
+ start = Extra;
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ v = (cmsFloat32Number) wOut[index] / maximum;
+
+ if (Reverse)
+ v = maximum - v;
+
+ if (Planar)
+ ((cmsUInt16Number*) output)[(i + start ) * Stride]= _cmsFloat2Half(v);
+ else
+ ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half(v);
+ }
+
+ if (!ExtraFirst) {
+ output += Extra * sizeof(cmsUInt16Number);
+ }
+
+ if (Extra == 0 && SwapFirst) {
+
+ memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
+ *swap1 = _cmsFloat2Half(v);
+ }
+
+ if (T_PLANAR(info -> OutputFormat))
+ return output + sizeof(cmsUInt16Number);
+ else
+ return output + nChan * sizeof(cmsUInt16Number);
+}
+
+
+
+static
+cmsUInt8Number* PackHalfFromFloat(_cmsTRANSFORM* info,
+ cmsFloat32Number wOut[],
+ cmsUInt8Number* output,
+ cmsUInt32Number Stride)
+{
+ int nChan = T_CHANNELS(info -> OutputFormat);
+ int DoSwap = T_DOSWAP(info ->OutputFormat);
+ int Reverse = T_FLAVOR(info ->OutputFormat);
+ int Extra = T_EXTRA(info -> OutputFormat);
+ int SwapFirst = T_SWAPFIRST(info -> OutputFormat);
+ int Planar = T_PLANAR(info -> OutputFormat);
+ int ExtraFirst = DoSwap ^ SwapFirst;
+ cmsFloat32Number maximum = IsInkSpace(info ->OutputFormat) ? 100.0F : 1.0F;
+ cmsUInt16Number* swap1 = (cmsUInt16Number*) output;
+ cmsFloat32Number v = 0;
+ int i, start = 0;
+
+ if (ExtraFirst)
+ start = Extra;
+
+ for (i=0; i < nChan; i++) {
+
+ int index = DoSwap ? (nChan - i - 1) : i;
+
+ v = wOut[index] * maximum;
+
+ if (Reverse)
+ v = maximum - v;
+
+ if (Planar)
+ ((cmsUInt16Number*) output)[(i + start)* Stride]= _cmsFloat2Half( v );
+ else
+ ((cmsUInt16Number*) output)[i + start] = _cmsFloat2Half( v );
+ }
+
+ if (!ExtraFirst) {
+ output += Extra * sizeof(cmsUInt16Number);
+ }
+
+ if (Extra == 0 && SwapFirst) {
+
+ memmove(swap1 + 1, swap1, (nChan-1)* sizeof(cmsUInt16Number));
+ *swap1 = (cmsUInt16Number) _cmsFloat2Half( v );
+ }
+
+ if (T_PLANAR(info -> OutputFormat))
+ return output + sizeof(cmsUInt16Number);
+ else
+ return output + nChan * sizeof(cmsUInt16Number);
+}
+
+#endif
+
+// ----------------------------------------------------------------------------------------------------------------
+
static cmsFormatters16 InputFormatters16[] = {
// Type Mask Function
// ---------------------------- ------------------------------------ ----------------------------
- { TYPE_Lab_DBL, ANYPLANAR, UnrollLabDoubleTo16},
- { TYPE_XYZ_DBL, ANYPLANAR, UnrollXYZDoubleTo16},
+ { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleTo16},
+ { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleTo16},
+ { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatTo16},
{ TYPE_GRAY_DBL, 0, UnrollDouble1Chan},
- { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, UnrollDoubleTo16},
- { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, UnrollFloatTo16},
-
+ { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
+ ANYSWAP|ANYEXTRA|ANYSPACE, UnrollDoubleTo16},
+ { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
+ ANYSWAP|ANYEXTRA|ANYSPACE, UnrollFloatTo16},
+#ifndef CMS_NO_HALF_SUPPORT
+ { FLOAT_SH(1)|BYTES_SH(2), ANYCHANNELS|ANYPLANAR|ANYSWAPFIRST|ANYFLAVOR|
+ ANYEXTRA|ANYSWAP|ANYSPACE, UnrollHalfTo16},
+#endif
{ CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Unroll1Byte},
+ { CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Unroll1ByteSkip1},
{ CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(2), ANYSPACE, Unroll1ByteSkip2},
{ CHANNELS_SH(1)|BYTES_SH(1)|FLAVOR_SH(1), ANYSPACE, Unroll1ByteReversed},
-
- { CHANNELS_SH(2)|BYTES_SH(1), ANYSPACE, Unroll2Bytes},
- { CHANNELS_SH(2)|BYTES_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll2ByteSwapFirst},
+ { COLORSPACE_SH(PT_MCH2)|CHANNELS_SH(2)|BYTES_SH(1), 0, Unroll2Bytes},
{ TYPE_LabV2_8, 0, UnrollLabV2_8 },
{ TYPE_ALabV2_8, 0, UnrollALabV2_8 },
@@ -2295,17 +2907,17 @@
{ CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1), ANYSPACE, Unroll4BytesSwap},
{ CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4BytesSwapSwapFirst},
- { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarBytes},
- { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollChunkyBytes},
-
+ { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|
+ ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarBytes},
+
+ { BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
+ ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollChunkyBytes},
{ CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Unroll1Word},
{ CHANNELS_SH(1)|BYTES_SH(2)|FLAVOR_SH(1), ANYSPACE, Unroll1WordReversed},
{ CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(3), ANYSPACE, Unroll1WordSkip3},
{ CHANNELS_SH(2)|BYTES_SH(2), ANYSPACE, Unroll2Words},
- { CHANNELS_SH(2)|BYTES_SH(2)|SWAPFIRST_SH(1), ANYSPACE, Unroll2WordSwapFirst},
-
{ CHANNELS_SH(3)|BYTES_SH(2), ANYSPACE, Unroll3Words},
{ CHANNELS_SH(4)|BYTES_SH(2), ANYSPACE, Unroll4Words},
@@ -2318,7 +2930,7 @@
{ CHANNELS_SH(4)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Unroll4WordsSwapSwapFirst},
- { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarWords },
+ { BYTES_SH(2)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollPlanarWords},
{ BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYENDIAN|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollAnyWords},
};
@@ -2328,13 +2940,21 @@
// Type Mask Function
// ---------------------------- ------------------------------------ ----------------------------
- { TYPE_Lab_DBL, ANYPLANAR, UnrollLabDoubleToFloat},
- { TYPE_Lab_FLT, ANYPLANAR, UnrollLabFloatToFloat},
- { TYPE_XYZ_DBL, ANYPLANAR, UnrollXYZDoubleToFloat},
- { TYPE_XYZ_FLT, ANYPLANAR, UnrollXYZFloatToFloat},
-
- { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollFloatsToFloat},
- { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|ANYEXTRA|ANYCHANNELS|ANYSPACE, UnrollDoublesToFloat},
+ { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, UnrollLabDoubleToFloat},
+ { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, UnrollLabFloatToFloat},
+
+ { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, UnrollXYZDoubleToFloat},
+ { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, UnrollXYZFloatToFloat},
+
+ { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
+ ANYCHANNELS|ANYSPACE, UnrollFloatsToFloat},
+
+ { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
+ ANYCHANNELS|ANYSPACE, UnrollDoublesToFloat},
+#ifndef CMS_NO_HALF_SUPPORT
+ { FLOAT_SH(1)|BYTES_SH(2), ANYPLANAR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|
+ ANYCHANNELS|ANYSPACE, UnrollHalfToFloat},
+#endif
};
@@ -2345,9 +2965,9 @@
cmsUInt32Number i;
cmsFormatter fr;
-
- if (!(dwFlags & CMS_PACK_FLAGS_FLOAT)) {
-
+ switch (dwFlags) {
+
+ case CMS_PACK_FLAGS_16BITS: {
for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) {
cmsFormatters16* f = InputFormatters16 + i;
@@ -2357,7 +2977,9 @@
}
}
}
- else {
+ break;
+
+ case CMS_PACK_FLAGS_FLOAT: {
for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
cmsFormattersFloat* f = InputFormattersFloat + i;
@@ -2367,6 +2989,11 @@
}
}
}
+ break;
+
+ default:;
+
+ }
fr.Fmt16 = NULL;
return fr;
@@ -2376,10 +3003,19 @@
// Type Mask Function
// ---------------------------- ------------------------------------ ----------------------------
- { TYPE_Lab_DBL, ANYPLANAR, PackLabDoubleFrom16},
- { TYPE_XYZ_DBL, ANYPLANAR, PackXYZDoubleFrom16},
- { FLOAT_SH(1)|BYTES_SH(0), ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackDoubleFrom16},
- { FLOAT_SH(1)|BYTES_SH(4), ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackFloatFrom16},
+ { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFrom16},
+ { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFrom16},
+
+ { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFrom16},
+
+ { FLOAT_SH(1)|BYTES_SH(0), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
+ ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackDoubleFrom16},
+ { FLOAT_SH(1)|BYTES_SH(4), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
+ ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackFloatFrom16},
+#ifndef CMS_NO_HALF_SUPPORT
+ { FLOAT_SH(1)|BYTES_SH(2), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|
+ ANYCHANNELS|ANYPLANAR|ANYEXTRA|ANYSPACE, PackHalfFrom16},
+#endif
{ CHANNELS_SH(1)|BYTES_SH(1), ANYSPACE, Pack1Byte},
{ CHANNELS_SH(1)|BYTES_SH(1)|EXTRA_SH(1), ANYSPACE, Pack1ByteSkip1},
@@ -2419,7 +3055,7 @@
{ CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1), ANYSPACE, Pack4BytesSwapSwapFirst},
{ BYTES_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackAnyBytes},
- { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarBytes},
+ { BYTES_SH(1)|PLANAR_SH(1), ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarBytes},
{ CHANNELS_SH(1)|BYTES_SH(2), ANYSPACE, Pack1Word},
{ CHANNELS_SH(1)|BYTES_SH(2)|EXTRA_SH(1), ANYSPACE, Pack1WordSkip1},
@@ -2453,29 +3089,51 @@
static cmsFormattersFloat OutputFormattersFloat[] = {
// Type Mask Function
// ---------------------------- --------------------------------------------------- ----------------------------
- { TYPE_Lab_FLT, ANYPLANAR, PackLabFloatFromFloat},
- { TYPE_XYZ_FLT, ANYPLANAR, PackXYZFloatFromFloat},
- { TYPE_Lab_DBL, ANYPLANAR, PackLabDoubleFromFloat},
- { TYPE_XYZ_DBL, ANYPLANAR, PackXYZDoubleFromFloat},
- { FLOAT_SH(1)|BYTES_SH(4),
- ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackChunkyFloatsFromFloat },
- { FLOAT_SH(1)|BYTES_SH(4)|PLANAR_SH(1), ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarFloatsFromFloat},
- { FLOAT_SH(1)|BYTES_SH(0),
- ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackChunkyDoublesFromFloat },
- { FLOAT_SH(1)|BYTES_SH(0)|PLANAR_SH(1), ANYEXTRA|ANYCHANNELS|ANYSPACE, PackPlanarDoublesFromFloat},
+ { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFromFloat},
+ { TYPE_XYZ_FLT, ANYPLANAR|ANYEXTRA, PackXYZFloatFromFloat},
+
+ { TYPE_Lab_DBL, ANYPLANAR|ANYEXTRA, PackLabDoubleFromFloat},
+ { TYPE_XYZ_DBL, ANYPLANAR|ANYEXTRA, PackXYZDoubleFromFloat},
+
+ { FLOAT_SH(1)|BYTES_SH(4), ANYPLANAR|
+ ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackFloatsFromFloat },
+ { FLOAT_SH(1)|BYTES_SH(0), ANYPLANAR|
+ ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackDoublesFromFloat },
+#ifndef CMS_NO_HALF_SUPPORT
+ { FLOAT_SH(1)|BYTES_SH(2),
+ ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackHalfFromFloat },
+#endif
+
};
// Bit fields set to one in the mask are not compared
+static
cmsFormatter _cmsGetStockOutputFormatter(cmsUInt32Number dwInput, cmsUInt32Number dwFlags)
{
cmsUInt32Number i;
cmsFormatter fr;
- if (dwFlags & CMS_PACK_FLAGS_FLOAT) {
+ switch (dwFlags)
+ {
+
+ case CMS_PACK_FLAGS_16BITS: {
+
+ for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) {
+ cmsFormatters16* f = OutputFormatters16 + i;
+
+ if ((dwInput & ~f ->Mask) == f ->Type) {
+ fr.Fmt16 = f ->Frm;
+ return fr;
+ }
+ }
+ }
+ break;
+
+ case CMS_PACK_FLAGS_FLOAT: {
for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) {
cmsFormattersFloat* f = OutputFormattersFloat + i;
@@ -2485,18 +3143,11 @@
return fr;
}
}
-
- }
- else {
-
- for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) {
- cmsFormatters16* f = OutputFormatters16 + i;
-
- if ((dwInput & ~f ->Mask) == f ->Type) {
- fr.Fmt16 = f ->Frm;
- return fr;
- }
}
+ break;
+
+ default:;
+
}
fr.Fmt16 = NULL;
@@ -2523,8 +3174,8 @@
// Reset
if (Data == NULL) {
- FactoryList = NULL;
- return TRUE;
+ FactoryList = NULL;
+ return TRUE;
}
fl = (cmsFormattersFactoryList*) _cmsPluginMalloc(sizeof(cmsFormattersFactoryList));
@@ -2540,7 +3191,7 @@
cmsFormatter _cmsGetFormatter(cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8
cmsFormatterDirection Dir,
- cmsUInt32Number dwFlags) // Float or 16 bits
+ cmsUInt32Number dwFlags)
{
cmsFormattersFactoryList* f;
@@ -2597,3 +3248,4 @@
// Create a fake formatter for result
return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
}
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmspcs.c Fri Nov 02 17:32:30 2012 -0700
@@ -898,6 +898,7 @@
{
switch (ColorSpace) {
+ case cmsSig1colorData:
case cmsSigGrayData: return 1;
case cmsSig2colorData: return 2;
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsplugin.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsplugin.c Fri Nov 02 17:32:30 2012 -0700
@@ -105,12 +105,12 @@
// 1 2 3 4 5 6 7 8
// 8 7 6 5 4 3 2 1
-void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number QWord)
+void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord)
{
#ifndef CMS_USE_BIG_ENDIAN
- cmsUInt8Number* pIn = (cmsUInt8Number*) &QWord;
+ cmsUInt8Number* pIn = (cmsUInt8Number*) QWord;
cmsUInt8Number* pOut = (cmsUInt8Number*) Result;
_cmsAssert(Result != NULL);
@@ -128,7 +128,7 @@
_cmsAssert(Result != NULL);
- *Result = QWord;
+ *Result = *QWord;
#endif
}
@@ -218,7 +218,7 @@
if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1)
return FALSE;
- if (n != NULL) _cmsAdjustEndianess64(n, tmp);
+ if (n != NULL) _cmsAdjustEndianess64(n, &tmp);
return TRUE;
}
@@ -340,7 +340,7 @@
return TRUE;
}
-cmsBool CMSEXPORT _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number n)
+cmsBool CMSEXPORT _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n)
{
cmsUInt64Number tmp;
@@ -568,7 +568,7 @@
if (Plugin ->ExpectedVersion > LCMS_VERSION) {
cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "plugin needs Little CMS %d, current version is %d",
- Plugin ->ExpectedVersion, LCMS_VERSION);
+ Plugin ->ExpectedVersion, LCMS_VERSION);
return FALSE;
}
@@ -610,6 +610,10 @@
if (!_cmsRegisterOptimizationPlugin(Plugin)) return FALSE;
break;
+ case cmsPluginTransformSig:
+ if (!_cmsRegisterTransformPlugin(Plugin)) return FALSE;
+ break;
+
default:
cmsSignalError(0, cmsERROR_UNKNOWN_EXTENSION, "Unrecognized plugin type '%X'", Plugin -> Type);
return FALSE;
@@ -633,6 +637,7 @@
_cmsRegisterParametricCurvesPlugin(NULL);
_cmsRegisterMultiProcessElementPlugin(NULL);
_cmsRegisterOptimizationPlugin(NULL);
+ _cmsRegisterTransformPlugin(NULL);
if (PluginPool != NULL)
_cmsSubAllocDestroy(PluginPool);
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2008 Marti Maria Saguer
+// Copyright (c) 1998-2011 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -329,9 +329,9 @@
static
cmsUInt8Number L2Byte(cmsUInt16Number w)
{
- int ww = w + 0x0080;
+ int ww = w + 0x0080;
- if (ww > 0xFFFF) return 0xFF;
+ if (ww > 0xFFFF) return 0xFF;
return (cmsUInt8Number) ((cmsUInt16Number) (ww >> 8) & 0xFF);
}
@@ -498,6 +498,7 @@
cmsUInt32Number i;
cmsFloat64Number gamma;
+ if (Table == NULL) return; // Error
if (Table ->nEntries <= 0) return; // Empty table
@@ -577,6 +578,8 @@
for( i=0; i < n; i++ )
{
+ if (g[i] == NULL) return; // Error
+
if (i > 0 && GammaTableEquals(g[i-1]->Table16, g[i]->Table16, g[i]->nEntries)) {
_cmsIOPrintf(m, "dup ");
@@ -674,6 +677,7 @@
cmsUInt16Number wWordOut = Out[i];
cmsUInt8Number wByteOut; // Value as byte
+
// We always deal with Lab4
wByteOut = Word2Byte(wWordOut);
@@ -771,9 +775,9 @@
for( i=0; i < 3; i++ ) {
- _cmsIOPrintf(m, "%.6f %.6f %.6f ", Matrix[0 + 3*i],
- Matrix[1 + 3*i],
- Matrix[2 + 3*i]);
+ _cmsIOPrintf(m, "%.6f %.6f %.6f ", Matrix[i + 3*0],
+ Matrix[i + 3*1],
+ Matrix[i + 3*2]);
}
@@ -857,21 +861,23 @@
// Generates a curve from a gray profile
static
-cmsToneCurve* ExtractGray2Y(cmsContext ContextID, cmsHPROFILE hProfile, int Intent)
+ cmsToneCurve* ExtractGray2Y(cmsContext ContextID, cmsHPROFILE hProfile, int Intent)
{
cmsToneCurve* Out = cmsBuildTabulatedToneCurve16(ContextID, 256, NULL);
cmsHPROFILE hXYZ = cmsCreateXYZProfile();
cmsHTRANSFORM xform = cmsCreateTransformTHR(ContextID, hProfile, TYPE_GRAY_8, hXYZ, TYPE_XYZ_DBL, Intent, cmsFLAGS_NOOPTIMIZE);
int i;
- for (i=0; i < 256; i++) {
+ if (Out != NULL) {
+ for (i=0; i < 256; i++) {
- cmsUInt8Number Gray = (cmsUInt8Number) i;
- cmsCIEXYZ XYZ;
+ cmsUInt8Number Gray = (cmsUInt8Number) i;
+ cmsCIEXYZ XYZ;
- cmsDoTransform(xform, &Gray, &XYZ, 1);
+ cmsDoTransform(xform, &Gray, &XYZ, 1);
- Out ->Table16[i] =_cmsQuickSaturateWord(XYZ.Y * 65535.0);
+ Out ->Table16[i] =_cmsQuickSaturateWord(XYZ.Y * 65535.0);
+ }
}
cmsDeleteTransform(xform);
@@ -924,7 +930,7 @@
switch (nChannels) {
case 1: {
- cmsToneCurve* Gray2Y = ExtractGray2Y(m ->ContextID, hProfile, Intent);
+ cmsToneCurve* Gray2Y = ExtractGray2Y(m ->ContextID, hProfile, Intent);
EmitCIEBasedA(m, Gray2Y, &BlackPointAdaptedToD50);
cmsFreeToneCurve(Gray2Y);
}
@@ -932,7 +938,7 @@
case 3:
case 4: {
- cmsUInt32Number OutFrm = TYPE_Lab_16;
+ cmsUInt32Number OutFrm = TYPE_Lab_16;
cmsPipeline* DeviceLink;
_cmsTRANSFORM* v = (_cmsTRANSFORM*) xform;
@@ -984,14 +990,23 @@
if (ColorSpace == cmsSigGrayData) {
cmsToneCurve** ShaperCurve = _cmsStageGetPtrToCurveSet(Shaper);
- rc = EmitCIEBasedA(m, ShaperCurve[0], &BlackPointAdaptedToD50);
+ rc = EmitCIEBasedA(m, ShaperCurve[0], &BlackPointAdaptedToD50);
}
else
if (ColorSpace == cmsSigRgbData) {
- rc = EmitCIEBasedABC(m, GetPtrToMatrix(Matrix),
- _cmsStageGetPtrToCurveSet(Shaper),
+ cmsMAT3 Mat;
+ int i, j;
+
+ memmove(&Mat, GetPtrToMatrix(Matrix), sizeof(Mat));
+
+ for (i=0; i < 3; i++)
+ for (j=0; j < 3; j++)
+ Mat.v[i].n[j] *= MAX_ENCODEABLE_XYZ;
+
+ rc = EmitCIEBasedABC(m, (cmsFloat64Number *) &Mat,
+ _cmsStageGetPtrToCurveSet(Shaper),
&BlackPointAdaptedToD50);
}
else {
@@ -1000,7 +1015,7 @@
return 0;
}
- return rc;
+ return rc;
}
@@ -1084,8 +1099,8 @@
if (ColorSpace != cmsSigXYZData &&
ColorSpace != cmsSigLabData) {
- cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "Invalid output color space");
- goto Error;
+ cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "Invalid output color space");
+ goto Error;
}
@@ -1101,8 +1116,8 @@
}
else {
- // We need a LUT for the rest
- if (!WriteInputLUT(mem, hProfile, Intent, dwFlags)) goto Error;
+ // We need a LUT for the rest
+ if (!WriteInputLUT(mem, hProfile, Intent, dwFlags)) goto Error;
}
}
@@ -1211,7 +1226,7 @@
"{0.9642 mul %g div exch pop exch pop exch pop exch pop} bind\n"
"{1.0000 mul %g div exch pop exch pop exch pop exch pop} bind\n"
"{0.8249 mul %g div exch pop exch pop exch pop exch pop} bind\n]\n",
- White.X, White.Y, White.Z);
+ White.X, White.Y, White.Z);
return;
}
@@ -1534,24 +1549,25 @@
cmsUInt32Number CMSEXPORT cmsGetPostScriptColorResource(cmsContext ContextID,
- cmsPSResourceType Type,
- cmsHPROFILE hProfile,
- cmsUInt32Number Intent,
- cmsUInt32Number dwFlags,
- cmsIOHANDLER* io)
+ cmsPSResourceType Type,
+ cmsHPROFILE hProfile,
+ cmsUInt32Number Intent,
+ cmsUInt32Number dwFlags,
+ cmsIOHANDLER* io)
{
cmsUInt32Number rc;
switch (Type) {
- case cmsPS_RESOURCE_CSA:
- rc = GenerateCSA(ContextID, hProfile, Intent, dwFlags, io);
- break;
- default:
- case cmsPS_RESOURCE_CRD:
- rc = GenerateCRD(ContextID, hProfile, Intent, dwFlags, io);
- break;
+ case cmsPS_RESOURCE_CSA:
+ rc = GenerateCSA(ContextID, hProfile, Intent, dwFlags, io);
+ break;
+
+ default:
+ case cmsPS_RESOURCE_CRD:
+ rc = GenerateCRD(ContextID, hProfile, Intent, dwFlags, io);
+ break;
}
return rc;
@@ -1560,7 +1576,7 @@
cmsUInt32Number CMSEXPORT cmsGetPostScriptCRD(cmsContext ContextID,
- cmsHPROFILE hProfile,
+ cmsHPROFILE hProfile,
cmsUInt32Number Intent, cmsUInt32Number dwFlags,
void* Buffer, cmsUInt32Number dwBufferLen)
{
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmssamp.c Fri Nov 02 17:32:30 2012 -0700
@@ -216,7 +216,6 @@
// just that. There is a special flag for using black point tag, but turned
// off by default because it is bogus on most profiles. The detection algorithm
// involves to turn BP to neutral and to use only L component.
-
cmsBool CMSEXPORT cmsDetectBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
{
@@ -292,3 +291,307 @@
return BlackPointAsDarkerColorant(hProfile, Intent, BlackPoint, dwFlags);
}
+
+
+// ---------------------------------------------------------------------------------------------------------
+
+// Least Squares Fit of a Quadratic Curve to Data
+// http://www.personal.psu.edu/jhm/f90/lectures/lsq2.html
+
+static
+cmsFloat64Number RootOfLeastSquaresFitQuadraticCurve(int n, cmsFloat64Number x[], cmsFloat64Number y[])
+{
+ double sum_x = 0, sum_x2 = 0, sum_x3 = 0, sum_x4 = 0;
+ double sum_y = 0, sum_yx = 0, sum_yx2 = 0;
+ double disc;
+ int i;
+ cmsMAT3 m;
+ cmsVEC3 v, res;
+
+ if (n < 4) return 0;
+
+ for (i=0; i < n; i++) {
+
+ double xn = x[i];
+ double yn = y[i];
+
+ sum_x += xn;
+ sum_x2 += xn*xn;
+ sum_x3 += xn*xn*xn;
+ sum_x4 += xn*xn*xn*xn;
+
+ sum_y += yn;
+ sum_yx += yn*xn;
+ sum_yx2 += yn*xn*xn;
+ }
+
+ _cmsVEC3init(&m.v[0], n, sum_x, sum_x2);
+ _cmsVEC3init(&m.v[1], sum_x, sum_x2, sum_x3);
+ _cmsVEC3init(&m.v[2], sum_x2, sum_x3, sum_x4);
+
+ _cmsVEC3init(&v, sum_y, sum_yx, sum_yx2);
+
+ if (!_cmsMAT3solve(&res, &m, &v)) return 0;
+
+ // y = t x2 + u x + c
+ // x = ( - u + Sqrt( u^2 - 4 t c ) ) / ( 2 t )
+ disc = res.n[1]*res.n[1] - 4.0 * res.n[0] * res.n[2];
+ if (disc < 0) return -1;
+
+ return ( -1.0 * res.n[1] + sqrt( disc )) / (2.0 * res.n[0]);
+}
+
+static
+cmsBool IsMonotonic(int n, const cmsFloat64Number Table[])
+{
+ int i;
+ cmsFloat64Number last;
+
+ last = Table[n-1];
+
+ for (i = n-2; i >= 0; --i) {
+
+ if (Table[i] > last)
+
+ return FALSE;
+ else
+ last = Table[i];
+
+ }
+
+ return TRUE;
+}
+
+// Calculates the black point of a destination profile.
+// This algorithm comes from the Adobe paper disclosing its black point compensation method.
+cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags)
+{
+ cmsColorSpaceSignature ColorSpace;
+ cmsHTRANSFORM hRoundTrip = NULL;
+ cmsCIELab InitialLab, destLab, Lab;
+
+ cmsFloat64Number MinL, MaxL;
+ cmsBool NearlyStraightMidRange = FALSE;
+ cmsFloat64Number L;
+ cmsFloat64Number x[101], y[101];
+ cmsFloat64Number lo, hi, NonMonoMin;
+ int n, l, i, NonMonoIndx;
+
+
+ // Make sure intent is adequate
+ if (Intent != INTENT_PERCEPTUAL &&
+ Intent != INTENT_RELATIVE_COLORIMETRIC &&
+ Intent != INTENT_SATURATION) {
+ BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
+ return FALSE;
+ }
+
+
+ // v4 + perceptual & saturation intents does have its own black point, and it is
+ // well specified enough to use it. Black point tag is deprecated in V4.
+ if ((cmsGetEncodedICCversion(hProfile) >= 0x4000000) &&
+ (Intent == INTENT_PERCEPTUAL || Intent == INTENT_SATURATION)) {
+
+ // Matrix shaper share MRC & perceptual intents
+ if (cmsIsMatrixShaper(hProfile))
+ return BlackPointAsDarkerColorant(hProfile, INTENT_RELATIVE_COLORIMETRIC, BlackPoint, 0);
+
+ // Get Perceptual black out of v4 profiles. That is fixed for perceptual & saturation intents
+ BlackPoint -> X = cmsPERCEPTUAL_BLACK_X;
+ BlackPoint -> Y = cmsPERCEPTUAL_BLACK_Y;
+ BlackPoint -> Z = cmsPERCEPTUAL_BLACK_Z;
+ return TRUE;
+ }
+
+
+ // Check if the profile is lut based and gray, rgb or cmyk (7.2 in Adobe's document)
+ ColorSpace = cmsGetColorSpace(hProfile);
+ if (!cmsIsCLUT(hProfile, Intent, LCMS_USED_AS_OUTPUT ) ||
+ (ColorSpace != cmsSigGrayData &&
+ ColorSpace != cmsSigRgbData &&
+ ColorSpace != cmsSigCmykData)) {
+
+ // In this case, handle as input case
+ return cmsDetectBlackPoint(BlackPoint, hProfile, Intent, dwFlags);
+ }
+
+ // It is one of the valid cases!, presto chargo hocus pocus, go for the Adobe magic
+
+ // Step 1
+ // ======
+
+ // Set a first guess, that should work on good profiles.
+ if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
+
+ cmsCIEXYZ IniXYZ;
+
+ // calculate initial Lab as source black point
+ if (!cmsDetectBlackPoint(&IniXYZ, hProfile, Intent, dwFlags)) {
+ return FALSE;
+ }
+
+ // convert the XYZ to lab
+ cmsXYZ2Lab(NULL, &InitialLab, &IniXYZ);
+
+ } else {
+
+ // set the initial Lab to zero, that should be the black point for perceptual and saturation
+ InitialLab.L = 0;
+ InitialLab.a = 0;
+ InitialLab.b = 0;
+ }
+
+
+ // Step 2
+ // ======
+
+ // Create a roundtrip. Define a Transform BT for all x in L*a*b*
+ hRoundTrip = CreateRoundtripXForm(hProfile, Intent);
+ if (hRoundTrip == NULL) return FALSE;
+
+ // Calculate Min L*
+ Lab = InitialLab;
+ Lab.L = 0;
+ cmsDoTransform(hRoundTrip, &Lab, &destLab, 1);
+ MinL = destLab.L;
+
+ // Calculate Max L*
+ Lab = InitialLab;
+ Lab.L = 100;
+ cmsDoTransform(hRoundTrip, &Lab, &destLab, 1);
+ MaxL = destLab.L;
+
+ // Step 3
+ // ======
+
+ // check if quadratic estimation needs to be done.
+ if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
+
+ // Conceptually, this code tests how close the source l and converted L are to one another in the mid-range
+ // of the values. If the converted ramp of L values is close enough to a straight line y=x, then InitialLab
+ // is good enough to be the DestinationBlackPoint,
+ NearlyStraightMidRange = TRUE;
+
+ for (l=0; l <= 100; l++) {
+
+ Lab.L = l;
+ Lab.a = InitialLab.a;
+ Lab.b = InitialLab.b;
+
+ cmsDoTransform(hRoundTrip, &Lab, &destLab, 1);
+
+ L = destLab.L;
+
+ // Check the mid range in 20% after MinL
+ if (L > (MinL + 0.2 * (MaxL - MinL))) {
+
+ // Is close enough?
+ if (fabs(L - l) > 4.0) {
+
+ // Too far away, profile is buggy!
+ NearlyStraightMidRange = FALSE;
+ break;
+ }
+ }
+ }
+ }
+ else {
+ // Check is always performed for perceptual and saturation intents
+ NearlyStraightMidRange = FALSE;
+ }
+
+
+ // If no furter checking is needed, we are done
+ if (NearlyStraightMidRange) {
+
+ cmsLab2XYZ(NULL, BlackPoint, &InitialLab);
+ cmsDeleteTransform(hRoundTrip);
+ return TRUE;
+ }
+
+ // The round-trip curve normally looks like a nearly constant section at the black point,
+ // with a corner and a nearly straight line to the white point.
+
+ // STEP 4
+ // =======
+
+ // find the black point using the least squares error quadratic curve fitting
+
+ if (Intent == INTENT_RELATIVE_COLORIMETRIC) {
+ lo = 0.1;
+ hi = 0.5;
+ }
+ else {
+
+ // Perceptual and saturation
+ lo = 0.03;
+ hi = 0.25;
+ }
+
+ // Capture points for the fitting.
+ n = 0;
+ for (l=0; l <= 100; l++) {
+
+ cmsFloat64Number ff;
+
+ Lab.L = (cmsFloat64Number) l;
+ Lab.a = InitialLab.a;
+ Lab.b = InitialLab.b;
+
+ cmsDoTransform(hRoundTrip, &Lab, &destLab, 1);
+
+ ff = (destLab.L - MinL)/(MaxL - MinL);
+
+ if (ff >= lo && ff < hi) {
+
+ x[n] = Lab.L;
+ y[n] = ff;
+ n++;
+ }
+
+ }
+
+ // This part is not on the Adobe paper, but I found is necessary for getting any result.
+
+ if (IsMonotonic(n, y)) {
+
+ // Monotonic means lower point is stil valid
+ cmsLab2XYZ(NULL, BlackPoint, &InitialLab);
+ cmsDeleteTransform(hRoundTrip);
+ return TRUE;
+ }
+
+ // No suitable points, regret and use safer algorithm
+ if (n == 0) {
+ cmsDeleteTransform(hRoundTrip);
+ return cmsDetectBlackPoint(BlackPoint, hProfile, Intent, dwFlags);
+ }
+
+
+ NonMonoMin = 100;
+ NonMonoIndx = 0;
+ for (i=0; i < n; i++) {
+
+ if (y[i] < NonMonoMin) {
+ NonMonoIndx = i;
+ NonMonoMin = y[i];
+ }
+ }
+
+ Lab.L = x[NonMonoIndx];
+
+ // fit and get the vertex of quadratic curve
+ Lab.L = RootOfLeastSquaresFitQuadraticCurve(n, x, y);
+
+ if (Lab.L < 0.0 || Lab.L > 50.0) { // clip to zero L* if the vertex is negative
+ Lab.L = 0;
+ }
+
+ Lab.a = InitialLab.a;
+ Lab.b = InitialLab.b;
+
+ cmsLab2XYZ(NULL, BlackPoint, &Lab);
+
+ cmsDeleteTransform(hRoundTrip);
+ return TRUE;
+}
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmssm.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmssm.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2011 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -468,7 +468,8 @@
int FindNearSectors(cmsGDB* gbd, int alpha, int theta, cmsGDBPoint* Close[])
{
int nSectors = 0;
- int i, a, t;
+ int a, t;
+ cmsUInt32Number i;
cmsGDBPoint* pt;
for (i=0; i < NSTEPS; i++) {
@@ -505,7 +506,7 @@
cmsVEC3 Centre;
cmsLine ray;
int nCloseSectors;
- cmsGDBPoint* Close[NSTEPS];
+ cmsGDBPoint* Close[NSTEPS + 1];
cmsSpherical closel, templ;
cmsLine edge;
int k, m;
@@ -582,13 +583,13 @@
_cmsAssert(hGBD != NULL);
// Interpolate black
- for (alpha = 0; alpha <= SECTORS; alpha++) {
+ for (alpha = 0; alpha < SECTORS; alpha++) {
if (!InterpolateMissingSector(gbd, alpha, 0)) return FALSE;
}
// Interpolate white
- for (alpha = 0; alpha <= SECTORS; alpha++) {
+ for (alpha = 0; alpha < SECTORS; alpha++) {
if (!InterpolateMissingSector(gbd, alpha, SECTORS-1)) return FALSE;
}
@@ -596,7 +597,7 @@
// Interpolate Mid
for (theta = 1; theta < SECTORS; theta++) {
- for (alpha = 0; alpha <= SECTORS; alpha++) {
+ for (alpha = 0; alpha < SECTORS; alpha++) {
if (!InterpolateMissingSector(gbd, alpha, theta)) return FALSE;
}
@@ -760,3 +761,4 @@
return TRUE;
}
#endif
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmstypes.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmstypes.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2011 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -84,10 +84,10 @@
#define DUP_FN(x) Type_##x##_Dup
// Helper macro to define a handler. Callbacks do have a fixed naming convention.
-#define TYPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), DUP_FN(x), FREE_FN(x) }
+#define TYPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), DUP_FN(x), FREE_FN(x), NULL, 0 }
// Helper macro to define a MPE handler. Callbacks do have a fixed naming convention
-#define TYPE_MPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), GenericMPEdup, GenericMPEfree }
+#define TYPE_MPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), GenericMPEdup, GenericMPEfree, NULL, 0 }
// Register a new type handler. This routine is shared between normal types and MPE
static
@@ -154,7 +154,7 @@
cmsUInt32Number i;
_cmsAssert(io != NULL);
- _cmsAssert(Array != NULL);
+ _cmsAssert(!(Array == NULL && n > 0));
for (i=0; i < n; i++) {
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) Array[i])) return FALSE;
@@ -163,6 +163,28 @@
return TRUE;
}
+static
+cmsBool _cmsReadWCharArray(cmsIOHANDLER* io, cmsUInt32Number n, wchar_t* Array)
+{
+ cmsUInt32Number i;
+ cmsUInt16Number tmp;
+
+ _cmsAssert(io != NULL);
+
+ for (i=0; i < n; i++) {
+
+ if (Array != NULL) {
+
+ if (!_cmsReadUInt16Number(io, &tmp)) return FALSE;
+ Array[i] = (wchar_t) tmp;
+ }
+ else {
+ if (!_cmsReadUInt16Number(io, NULL)) return FALSE;
+ }
+
+ }
+ return TRUE;
+}
// To deal with position tables
typedef cmsBool (* PositionTableEntryFn)(struct _cms_typehandler_struct* self,
@@ -171,8 +193,8 @@
cmsUInt32Number n,
cmsUInt32Number SizeOfTag);
-// Helper function to deal with position tables as decribed in several addendums to ICC spec 4.2
-// A table of n elements is written, where first comes n records containing offsets and sizes and
+// Helper function to deal with position tables as decribed in ICC spec 4.3
+// A table of n elements is readed, where first comes n records containing offsets and sizes and
// then a block containing the data itself. This allows to reuse same data in more than one entry
static
cmsBool ReadPositionTable(struct _cms_typehandler_struct* self,
@@ -224,7 +246,7 @@
static
cmsBool WritePositionTable(struct _cms_typehandler_struct* self,
cmsIOHANDLER* io,
- cmsUInt32Number SizeOfTag,
+ cmsUInt32Number SizeOfTag,
cmsUInt32Number Count,
cmsUInt32Number BaseOffset,
void *Cargo,
@@ -713,6 +735,8 @@
*nItems = 0;
// We need to store the "\0" at the end, so +1
+ if (SizeOfTag == UINT_MAX) goto Error;
+
Text = (char*) _cmsMalloc(self ->ContextID, SizeOfTag + 1);
if (Text == NULL) goto Error;
@@ -807,13 +831,20 @@
cmsUInt32Number LenOfData;
*nItems = 0;
+
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
+
LenOfData = SizeOfTag - sizeof(cmsUInt32Number);
+ if (LenOfData > INT_MAX) return NULL;
BinData = (cmsICCData*) _cmsMalloc(self ->ContextID, sizeof(cmsICCData) + LenOfData - 1);
if (BinData == NULL) return NULL;
BinData ->len = LenOfData;
- if (!_cmsReadUInt32Number(io, &BinData->flag)) return NULL;
+ if (!_cmsReadUInt32Number(io, &BinData->flag)) {
+ _cmsFree(self ->ContextID, BinData);
+ return NULL;
+ }
if (io -> Read(io, BinData ->data, sizeof(cmsUInt8Number), LenOfData) != LenOfData) {
@@ -1104,6 +1135,9 @@
default: // Curve
+ if (Count > 0x7FFF)
+ return NULL; // This is to prevent bad guys for doing bad things
+
NewGamma = cmsBuildTabulatedToneCurve16(self ->ContextID, Count, NULL);
if (!NewGamma) return NULL;
@@ -1219,17 +1253,23 @@
cmsBool Type_ParametricCurve_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsToneCurve* Curve = (cmsToneCurve*) Ptr;
- int i, nParams;
+ int i, nParams, typen;
static const int ParamsByType[] = { 0, 1, 3, 4, 5, 7 };
-
- if (Curve ->nSegments > 1 || Curve -> Segments[0].Type < 1) {
-
- cmsSignalError(self->ContextID, 0, "Multisegment or Inverted parametric curves cannot be written");
+ typen = Curve -> Segments[0].Type;
+
+ if (Curve ->nSegments > 1 || typen < 1) {
+
+ cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Multisegment or Inverted parametric curves cannot be written");
return FALSE;
}
- nParams = ParamsByType[Curve ->Segments[0].Type];
+ if (typen > 5) {
+ cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported parametric curve");
+ return FALSE;
+ }
+
+ nParams = ParamsByType[typen];
if (!_cmsWriteUInt16Number(io, (cmsUInt16Number) (Curve ->Segments[0].Type - 1))) return FALSE;
if (!_cmsWriteUInt16Number(io, 0)) return FALSE; // Reserved
@@ -1394,13 +1434,11 @@
// ********************************************************************************
// Type cmsSigMultiLocalizedUnicodeType
// ********************************************************************************
-
//
// Do NOT trust SizeOfTag as there is an issue on the definition of profileSequenceDescTag. See the TechNote from
// Max Derhak and Rohit Patil about this: basically the size of the string table should be guessed and cannot be
// taken from the size of tag if this tag is embedded as part of bigger structures (profileSequenceDescTag, for instance)
//
-// FIXME: this doesn't work if sizeof(wchat_t) != 2 !!!
static
void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
@@ -1410,7 +1448,7 @@
cmsUInt32Number SizeOfHeader;
cmsUInt32Number Len, Offset;
cmsUInt32Number i;
- cmsUInt16Number* Block;
+ wchar_t* Block;
cmsUInt32Number BeginOfThisString, EndOfThisString, LargestPosition;
*nItems = 0;
@@ -1438,12 +1476,17 @@
// Now deal with Len and offset.
if (!_cmsReadUInt32Number(io, &Len)) goto Error;
- mlu ->Entries[i].Len = Len;
-
if (!_cmsReadUInt32Number(io, &Offset)) goto Error;
+ // Check for overflow
+ if (Offset < (SizeOfHeader + 8)) goto Error;
+
+ // True begin of the string
BeginOfThisString = Offset - SizeOfHeader - 8;
- mlu ->Entries[i].StrW = BeginOfThisString;
+
+ // Ajust to wchar_t elements
+ mlu ->Entries[i].Len = (Len * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
+ mlu ->Entries[i].StrW = (BeginOfThisString * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
// To guess maximum size, add offset + len
EndOfThisString = BeginOfThisString + Len;
@@ -1452,15 +1495,22 @@
}
// Now read the remaining of tag and fill all strings. Substract the directory
- SizeOfTag = LargestPosition;
-
- Block = (cmsUInt16Number*) _cmsMalloc(self ->ContextID, SizeOfTag);
- if (Block == NULL) goto Error;
-
- NumOfWchar = SizeOfTag / sizeof(cmsUInt16Number);
-
- if (!_cmsReadUInt16Array(io, NumOfWchar, Block)) goto Error;
- mlu ->MemPool = Block;
+ SizeOfTag = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
+ if (SizeOfTag == 0)
+ {
+ Block = NULL;
+ NumOfWchar = 0;
+
+ }
+ else
+ {
+ Block = (wchar_t*) _cmsMalloc(self ->ContextID, SizeOfTag);
+ if (Block == NULL) goto Error;
+ NumOfWchar = SizeOfTag / sizeof(wchar_t);
+ if (!_cmsReadWCharArray(io, NumOfWchar, Block)) goto Error;
+ }
+
+ mlu ->MemPool = Block;
mlu ->PoolSize = SizeOfTag;
mlu ->PoolUsed = SizeOfTag;
@@ -1476,9 +1526,18 @@
cmsBool Type_MLU_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
{
cmsMLU* mlu =(cmsMLU*) Ptr;
- cmsUInt32Number HeaderSize, Offset;
+ cmsUInt32Number HeaderSize;
+ cmsUInt32Number Len, Offset;
int i;
+ if (Ptr == NULL) {
+
+ // Empty placeholder
+ if (!_cmsWriteUInt32Number(io, 0)) return FALSE;
+ if (!_cmsWriteUInt32Number(io, 12)) return FALSE;
+ return TRUE;
+ }
+
if (!_cmsWriteUInt32Number(io, mlu ->UsedEntries)) return FALSE;
if (!_cmsWriteUInt32Number(io, 12)) return FALSE;
@@ -1486,16 +1545,19 @@
for (i=0; i < mlu ->UsedEntries; i++) {
+ Len = mlu ->Entries[i].Len;
+ Offset = mlu ->Entries[i].StrW;
+
+ Len = (Len * sizeof(cmsUInt16Number)) / sizeof(wchar_t);
+ Offset = (Offset * sizeof(cmsUInt16Number)) / sizeof(wchar_t) + HeaderSize + 8;
+
if (!_cmsWriteUInt16Number(io, mlu ->Entries[i].Language)) return FALSE;
if (!_cmsWriteUInt16Number(io, mlu ->Entries[i].Country)) return FALSE;
- if (!_cmsWriteUInt32Number(io, mlu ->Entries[i].Len)) return FALSE;
-
- Offset = mlu ->Entries[i].StrW + HeaderSize + 8;
-
+ if (!_cmsWriteUInt32Number(io, Len)) return FALSE;
if (!_cmsWriteUInt32Number(io, Offset)) return FALSE;
}
- if (!_cmsWriteUInt16Array(io, mlu ->PoolUsed / sizeof(cmsUInt16Number), (cmsUInt16Number*) mlu ->MemPool)) return FALSE;
+ if (!_cmsWriteWCharArray(io, mlu ->PoolUsed / sizeof(wchar_t), (wchar_t*) mlu ->MemPool)) return FALSE;
return TRUE;
@@ -1584,6 +1646,7 @@
cmsToneCurve* Tables[cmsMAXCHANNELS];
if (nChannels > cmsMAXCHANNELS) return FALSE;
+ if (nChannels <= 0) return FALSE;
memset(Tables, 0, sizeof(Tables));
@@ -1604,6 +1667,7 @@
}
_cmsFree(ContextID, Temp);
+ Temp = NULL;
mpe = cmsStageAllocToneCurves(ContextID, nChannels, Tables);
@@ -1658,12 +1722,28 @@
}
+// Check overflow
static
-unsigned int uipow(cmsUInt32Number a, cmsUInt32Number b) {
- cmsUInt32Number rv = 1;
- for (; b > 0; b--)
+size_t uipow(cmsUInt32Number n, cmsUInt32Number a, cmsUInt32Number b)
+{
+ cmsUInt32Number rv = 1, rc;
+
+ if (a == 0) return 0;
+ if (n == 0) return 0;
+
+ for (; b > 0; b--) {
+
rv *= a;
- return rv;
+
+ // Check for overflow
+ if (rv > UINT_MAX / a) return (size_t) -1;
+
+ }
+
+ rc = rv * n;
+
+ if (rv != rc / n) return (size_t) -1;
+ return rc;
}
@@ -1687,6 +1767,8 @@
if (!_cmsReadUInt8Number(io, &OutputChannels)) goto Error;
if (!_cmsReadUInt8Number(io, &CLUTpoints)) goto Error;
+ if (CLUTpoints == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least
+
// Padding
if (!_cmsReadUInt8Number(io, NULL)) goto Error;
@@ -1722,8 +1804,9 @@
// Get input tables
if (!Read8bitTables(self ->ContextID, io, NewLUT, InputChannels)) goto Error;
- // Get 3D CLUT
- nTabSize = (OutputChannels * uipow(CLUTpoints, InputChannels));
+ // Get 3D CLUT. Check the overflow....
+ nTabSize = uipow(OutputChannels, CLUTpoints, InputChannels);
+ if (nTabSize == (size_t) -1) goto Error;
if (nTabSize > 0) {
cmsUInt16Number *PtrW, *T;
@@ -1850,15 +1933,18 @@
// The prelinearization table
if (!Write8bitTables(self ->ContextID, io, NewLUT ->InputChannels, PreMPE)) return FALSE;
- nTabSize = (NewLUT->OutputChannels * uipow(clutPoints, NewLUT ->InputChannels));
-
- // The 3D CLUT.
- if (clut != NULL) {
-
- for (j=0; j < nTabSize; j++) {
-
- val = (cmsUInt8Number) FROM_16_TO_8(clut ->Tab.T[j]);
- if (!_cmsWriteUInt8Number(io, val)) return FALSE;
+ nTabSize = uipow(NewLUT->OutputChannels, clutPoints, NewLUT ->InputChannels);
+ if (nTabSize == (size_t) -1) return FALSE;
+ if (nTabSize > 0) {
+
+ // The 3D CLUT.
+ if (clut != NULL) {
+
+ for (j=0; j < nTabSize; j++) {
+
+ val = (cmsUInt8Number) FROM_16_TO_8(clut ->Tab.T[j]);
+ if (!_cmsWriteUInt8Number(io, val)) return FALSE;
+ }
}
}
@@ -1905,6 +1991,7 @@
if (nEntries <= 0) return TRUE;
// Check for malicious profiles
+ if (nEntries < 2) return FALSE;
if (nChannels > cmsMAXCHANNELS) return FALSE;
// Init table to zero
@@ -1979,13 +2066,12 @@
if (!_cmsReadUInt8Number(io, &InputChannels)) return NULL;
if (!_cmsReadUInt8Number(io, &OutputChannels)) return NULL;
- if (!_cmsReadUInt8Number(io, &CLUTpoints)) return NULL;
+ if (!_cmsReadUInt8Number(io, &CLUTpoints)) return NULL; // 255 maximum
// Padding
if (!_cmsReadUInt8Number(io, NULL)) return NULL;
// Do some checking
- if (CLUTpoints > 100) goto Error;
if (InputChannels > cmsMAXCHANNELS) goto Error;
if (OutputChannels > cmsMAXCHANNELS) goto Error;
@@ -2006,7 +2092,6 @@
// Only operates on 3 channels
-
if ((InputChannels == 3) && !_cmsMAT3isIdentity((cmsMAT3*) Matrix)) {
mpemat = cmsStageAllocMatrix(self ->ContextID, 3, 3, Matrix, NULL);
@@ -2014,15 +2099,18 @@
cmsPipelineInsertStage(NewLUT, cmsAT_END, mpemat);
}
- if (!_cmsReadUInt16Number(io, &InputEntries)) return NULL;
- if (!_cmsReadUInt16Number(io, &OutputEntries)) return NULL;
-
+ if (!_cmsReadUInt16Number(io, &InputEntries)) goto Error;
+ if (!_cmsReadUInt16Number(io, &OutputEntries)) goto Error;
+
+ if (InputEntries > 0x7FFF || OutputEntries > 0x7FFF) goto Error;
+ if (CLUTpoints == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least
// Get input tables
if (!Read16bitTables(self ->ContextID, io, NewLUT, InputChannels, InputEntries)) goto Error;
// Get 3D CLUT
- nTabSize = (OutputChannels * uipow(CLUTpoints, InputChannels));
+ nTabSize = uipow(OutputChannels, CLUTpoints, InputChannels);
+ if (nTabSize == (size_t) -1) goto Error;
if (nTabSize > 0) {
cmsUInt16Number *T;
@@ -2030,10 +2118,17 @@
T = (cmsUInt16Number*) _cmsCalloc(self ->ContextID, nTabSize, sizeof(cmsUInt16Number));
if (T == NULL) goto Error;
- if (!_cmsReadUInt16Array(io, nTabSize, T)) goto Error;
+ if (!_cmsReadUInt16Array(io, nTabSize, T)) {
+ _cmsFree(self ->ContextID, T);
+ goto Error;
+ }
mpeclut = cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T);
- if (mpeclut == NULL) goto Error;
+ if (mpeclut == NULL) {
+ _cmsFree(self ->ContextID, T);
+ goto Error;
+ }
+
cmsPipelineInsertStage(NewLUT, cmsAT_END, mpeclut);
_cmsFree(self ->ContextID, T);
}
@@ -2155,11 +2250,13 @@
if (!Write16bitTables(self ->ContextID, io, PreMPE)) return FALSE;
}
- nTabSize = (OutputChannels * uipow(clutPoints, InputChannels));
-
- // The 3D CLUT.
- if (clut != NULL) {
- if (!_cmsWriteUInt16Array(io, nTabSize, clut->Tab.T)) return FALSE;
+ nTabSize = uipow(OutputChannels, clutPoints, InputChannels);
+ if (nTabSize == (size_t) -1) return FALSE;
+ if (nTabSize > 0) {
+ // The 3D CLUT.
+ if (clut != NULL) {
+ if (!_cmsWriteUInt16Array(io, nTabSize, clut->Tab.T)) return FALSE;
+ }
}
// The postlinearization table
@@ -2246,8 +2343,12 @@
if (!io -> Seek(io, Offset)) return NULL;
if (io -> Read(io, gridPoints8, cmsMAXCHANNELS, 1) != 1) return NULL;
- for (i=0; i < cmsMAXCHANNELS; i++)
+
+ for (i=0; i < cmsMAXCHANNELS; i++) {
+
+ if (gridPoints8[i] == 1) return NULL; // Impossible value, 0 for no CLUT and then 2 at least
GridPoints[i] = gridPoints8[i];
+ }
if (!_cmsReadUInt8Number(io, &Precision)) return NULL;
@@ -2256,6 +2357,8 @@
if (!_cmsReadUInt8Number(io, NULL)) return NULL;
CLUT = cmsStageAllocCLut16bitGranular(self ->ContextID, GridPoints, InputChannels, OutputChannels, NULL);
+ if (CLUT == NULL) return NULL;
+
Data = (_cmsStageCLutData*) CLUT ->Data;
// Precision can be 1 or 2 bytes
@@ -2276,7 +2379,7 @@
if (!_cmsReadUInt16Array(io, Data->nEntries, Data ->Tab.T)) return NULL;
}
else {
- cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknow precision of '%d'", Precision);
+ cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision);
return NULL;
}
@@ -2304,7 +2407,7 @@
char String[5];
_cmsTagSignature2String(String, (cmsTagSignature) BaseType);
- cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknow curve type '%s'", String);
+ cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve type '%s'", String);
}
return NULL;
}
@@ -2313,26 +2416,30 @@
// Read a set of curves from specific offset
static
-cmsStage* ReadSetOfCurves(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset, int nCurves)
+cmsStage* ReadSetOfCurves(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset, cmsUInt32Number nCurves)
{
cmsToneCurve* Curves[cmsMAXCHANNELS];
- int i;
- cmsStage* Lin;
-
+ cmsUInt32Number i;
+ cmsStage* Lin = NULL;
if (nCurves > cmsMAXCHANNELS) return FALSE;
if (!io -> Seek(io, Offset)) return FALSE;
+ for (i=0; i < nCurves; i++)
+ Curves[i] = NULL;
+
for (i=0; i < nCurves; i++) {
Curves[i] = ReadEmbeddedCurve(self, io);
- if (Curves[i] == NULL) return FALSE;
- if (!_cmsReadAlignment(io)) return FALSE;
+ if (Curves[i] == NULL) goto Error;
+ if (!_cmsReadAlignment(io)) goto Error;
+
}
Lin = cmsStageAllocToneCurves(self ->ContextID, nCurves, Curves);
+Error:
for (i=0; i < nCurves; i++)
cmsFreeToneCurve(Curves[i]);
@@ -2395,26 +2502,31 @@
if (offsetA!= 0) {
mpe = ReadSetOfCurves(self, io, BaseOffset + offsetA, inputChan);
+ if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; }
cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetC != 0) {
mpe = ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan);
+ if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; }
cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetM != 0) {
mpe = ReadSetOfCurves(self, io, BaseOffset + offsetM, outputChan);
+ if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; }
cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetMat != 0) {
mpe = ReadMatrix(self, io, BaseOffset + offsetMat);
+ if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; }
cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetB != 0) {
mpe = ReadSetOfCurves(self, io, BaseOffset + offsetB, outputChan);
+ if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; }
cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
@@ -2441,9 +2553,19 @@
if (!_cmsWrite15Fixed16Number(io, m -> Double[7])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, m -> Double[8])) return FALSE;
+ if (m ->Offset != NULL) {
+
if (!_cmsWrite15Fixed16Number(io, m -> Offset[0])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, m -> Offset[1])) return FALSE;
if (!_cmsWrite15Fixed16Number(io, m -> Offset[2])) return FALSE;
+ }
+ else {
+ if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
+ if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
+ if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
+
+ }
+
return TRUE;
@@ -2468,7 +2590,8 @@
// If this is a table-based curve, use curve type even on V4
CurrentType = Type;
- if (Curves[i] ->nSegments == 0)
+ if ((Curves[i] ->nSegments == 0)||
+ ((Curves[i]->nSegments == 2) && (Curves[i] ->Segments[1].Type == 0)) )
CurrentType = cmsSigCurveType;
else
if (Curves[i] ->Segments[0].Type < 0)
@@ -2491,7 +2614,7 @@
char String[5];
_cmsTagSignature2String(String, (cmsTagSignature) Type);
- cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknow curve type '%s'", String);
+ cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve type '%s'", String);
}
return FALSE;
}
@@ -2511,6 +2634,11 @@
cmsUInt32Number i;
_cmsStageCLutData* CLUT = ( _cmsStageCLutData*) mpe -> Data;
+ if (CLUT ->HasFloatValues) {
+ cmsSignalError(self ->ContextID, cmsERROR_NOT_SUITABLE, "Cannot save floating point data, CLUT are 8 or 16 bit only");
+ return FALSE;
+ }
+
memset(gridPoints, 0, sizeof(gridPoints));
for (i=0; i < (cmsUInt32Number) CLUT ->Params ->nInputs; i++)
gridPoints[i] = (cmsUInt8Number) CLUT ->Params ->nSamples[i];
@@ -2536,7 +2664,7 @@
if (!_cmsWriteUInt16Array(io, CLUT->nEntries, CLUT ->Tab.T)) return FALSE;
}
else {
- cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknow precision of '%d'", Precision);
+ cmsSignalError(self ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown precision of '%d'", Precision);
return FALSE;
}
@@ -2694,26 +2822,31 @@
if (offsetB != 0) {
mpe = ReadSetOfCurves(self, io, BaseOffset + offsetB, inputChan);
+ if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; }
cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetMat != 0) {
mpe = ReadMatrix(self, io, BaseOffset + offsetMat);
+ if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; }
cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetM != 0) {
mpe = ReadSetOfCurves(self, io, BaseOffset + offsetM, inputChan);
+ if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; }
cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetC != 0) {
mpe = ReadCLUT(self, io, BaseOffset + offsetC, inputChan, outputChan);
+ if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; }
cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
if (offsetA!= 0) {
mpe = ReadSetOfCurves(self, io, BaseOffset + offsetA, outputChan);
+ if (mpe == NULL) { cmsPipelineFree(NewLUT); return NULL; }
cmsPipelineInsertStage(NewLUT, cmsAT_END, mpe);
}
@@ -2978,7 +3111,10 @@
prefix[31] = suffix[31] = 0;
v = cmsAllocNamedColorList(self ->ContextID, count, nDeviceCoords, prefix, suffix);
- if (v == NULL) return NULL;
+ if (v == NULL) {
+ cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many named colors '%d'", count);
+ return NULL;
+ }
if (nDeviceCoords > cmsMAXCHANNELS) {
cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many device coordinates '%d'", nDeviceCoords);
@@ -3076,6 +3212,13 @@
// Type cmsSigProfileSequenceDescType
// ********************************************************************************
+// This type is an array of structures, each of which contains information from the
+// header fields and tags from the original profiles which were combined to create
+// the final profile. The order of the structures is the order in which the profiles
+// were combined and includes a structure for the final profile. This provides a
+// description of the profile sequence from source to destination,
+// typically used with the DeviceLink profile.
+
static
cmsBool ReadEmbeddedText(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU** mlu, cmsUInt32Number SizeOfTag)
{
@@ -3119,6 +3262,8 @@
*nItems = 0;
if (!_cmsReadUInt32Number(io, &Count)) return NULL;
+
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
@@ -3133,40 +3278,42 @@
cmsPSEQDESC* sec = &OutSeq -> seq[i];
- if (!_cmsReadUInt32Number(io, &sec ->deviceMfg)) return NULL;
+ if (!_cmsReadUInt32Number(io, &sec ->deviceMfg)) goto Error;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error;
SizeOfTag -= sizeof(cmsUInt32Number);
- if (!_cmsReadUInt32Number(io, &sec ->deviceModel)) return NULL;
+ if (!_cmsReadUInt32Number(io, &sec ->deviceModel)) goto Error;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error;
SizeOfTag -= sizeof(cmsUInt32Number);
- if (!_cmsReadUInt64Number(io, &sec ->attributes)) return NULL;
+ if (!_cmsReadUInt64Number(io, &sec ->attributes)) goto Error;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error;
SizeOfTag -= sizeof(cmsUInt64Number);
- if (!_cmsReadUInt32Number(io, (cmsUInt32Number *)&sec ->technology)) return NULL;
+ if (!_cmsReadUInt32Number(io, (cmsUInt32Number *)&sec ->technology)) goto Error;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) goto Error;
SizeOfTag -= sizeof(cmsUInt32Number);
- if (!ReadEmbeddedText(self, io, &sec ->Manufacturer, SizeOfTag)) return NULL;
- if (!ReadEmbeddedText(self, io, &sec ->Model, SizeOfTag)) return NULL;
+ if (!ReadEmbeddedText(self, io, &sec ->Manufacturer, SizeOfTag)) goto Error;
+ if (!ReadEmbeddedText(self, io, &sec ->Model, SizeOfTag)) goto Error;
}
*nItems = 1;
return OutSeq;
+
+Error:
+ cmsFreeProfileSequenceDescription(OutSeq);
+ return NULL;
}
// Aux--Embed a text description type. It can be of type text description or multilocalized unicode
+// and it depends of the version number passed on cmsTagDescriptor structure instead of stack
static
cmsBool SaveDescription(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsMLU* Text)
{
- if (Text == NULL) {
-
- // Placeholder for a null entry
- if (!_cmsWriteTypeBase(io, cmsSigTextDescriptionType)) return FALSE;
- return Type_Text_Description_Write(self, io, NULL, 1);
-
- }
-
- if (Text->UsedEntries <= 1) {
+ if (self ->ICCVersion < 0x4000000) {
+
if (!_cmsWriteTypeBase(io, cmsSigTextDescriptionType)) return FALSE;
return Type_Text_Description_Write(self, io, Text, 1);
}
@@ -3191,7 +3338,7 @@
if (!_cmsWriteUInt32Number(io, sec ->deviceMfg)) return FALSE;
if (!_cmsWriteUInt32Number(io, sec ->deviceModel)) return FALSE;
- if (!_cmsWriteUInt64Number(io, sec ->attributes)) return FALSE;
+ if (!_cmsWriteUInt64Number(io, &sec ->attributes)) return FALSE;
if (!_cmsWriteUInt32Number(io, sec ->technology)) return FALSE;
if (!SaveDescription(self, io, sec ->Manufacturer)) return FALSE;
@@ -3366,26 +3513,33 @@
// First curve is Under color removal
if (!_cmsReadUInt32Number(io, &CountUcr)) return NULL;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
n ->Ucr = cmsBuildTabulatedToneCurve16(self ->ContextID, CountUcr, NULL);
if (n ->Ucr == NULL) return NULL;
if (!_cmsReadUInt16Array(io, CountUcr, n ->Ucr->Table16)) return NULL;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= CountUcr * sizeof(cmsUInt16Number);
// Second curve is Black generation
if (!_cmsReadUInt32Number(io, &CountBg)) return NULL;
+ if (SizeOfTag < sizeof(cmsUInt32Number)) return NULL;
SizeOfTag -= sizeof(cmsUInt32Number);
n ->Bg = cmsBuildTabulatedToneCurve16(self ->ContextID, CountBg, NULL);
if (n ->Bg == NULL) return NULL;
if (!_cmsReadUInt16Array(io, CountBg, n ->Bg->Table16)) return NULL;
+ if (SizeOfTag < CountBg * sizeof(cmsUInt16Number)) return NULL;
SizeOfTag -= CountBg * sizeof(cmsUInt16Number);
+ if (SizeOfTag == UINT_MAX) return NULL;
// Now comes the text. The length is specified by the tag size
n ->Desc = cmsMLUalloc(self ->ContextID, 1);
- ASCIIString = (char*) _cmsMalloc(self ->ContextID, sizeof(cmsUInt8Number)*(SizeOfTag + 1));
+ if (n ->Desc == NULL) return NULL;
+
+ ASCIIString = (char*) _cmsMalloc(self ->ContextID, SizeOfTag + 1);
if (io ->Read(io, ASCIIString, sizeof(char), SizeOfTag) != SizeOfTag) return NULL;
ASCIIString[SizeOfTag] = 0;
cmsMLUsetASCII(n ->Desc, cmsNoLanguage, cmsNoCountry, ASCIIString);
@@ -3482,7 +3636,9 @@
if (!_cmsReadUInt32Number(io, &Count)) return FALSE;
+ if (Count > UINT_MAX - sizeof(cmsUInt32Number)) return FALSE;
if (*SizeOfTag < Count + sizeof(cmsUInt32Number)) return FALSE;
+
Text = (char*) _cmsMalloc(self ->ContextID, Count+1);
if (Text == NULL) return FALSE;
@@ -3600,6 +3756,9 @@
if (!_cmsReadUInt32Number(io, &sc ->Flag)) goto Error;
if (!_cmsReadUInt32Number(io, &sc ->nChannels)) goto Error;
+ if (sc ->nChannels > cmsMAXCHANNELS - 1)
+ sc ->nChannels = cmsMAXCHANNELS - 1;
+
for (i=0; i < sc ->nChannels; i++) {
if (!_cmsRead15Fixed16Number(io, &sc ->Channels[i].Frequency)) goto Error;
@@ -3778,6 +3937,7 @@
if (!_cmsReadUInt16Number(io, &nSegments)) return NULL;
if (!_cmsReadUInt16Number(io, NULL)) return NULL;
+ if (nSegments < 1) return NULL;
Segments = (cmsCurveSegment*) _cmsCalloc(self ->ContextID, nSegments, sizeof(cmsCurveSegment));
if (Segments == NULL) return NULL;
@@ -4137,7 +4297,7 @@
// Copy MAX_INPUT_DIMENSIONS at most. Expand to cmsUInt32Number
nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? MAX_INPUT_DIMENSIONS : InputChans;
- for (i=0; i < nMaxGrids; i++) GridPoints[i] = Dimensions8[i];
+ for (i=0; i < nMaxGrids; i++) GridPoints[i] = (cmsUInt32Number) Dimensions8[i];
// Allocate the true CLUT
mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL);
@@ -4202,8 +4362,8 @@
// This is the list of built-in MPE types
static _cmsTagTypeLinkedList SupportedMPEtypes[] = {
-{{ (cmsTagTypeSignature) cmsSigBAcsElemType, NULL, NULL, NULL, NULL }, &SupportedMPEtypes[1] }, // Ignore those elements for now
-{{ (cmsTagTypeSignature) cmsSigEAcsElemType, NULL, NULL, NULL, NULL }, &SupportedMPEtypes[2] }, // (That's what the spec says)
+{{ (cmsTagTypeSignature) cmsSigBAcsElemType, NULL, NULL, NULL, NULL, NULL, 0 }, &SupportedMPEtypes[1] }, // Ignore those elements for now
+{{ (cmsTagTypeSignature) cmsSigEAcsElemType, NULL, NULL, NULL, NULL, NULL, 0 }, &SupportedMPEtypes[2] }, // (That's what the spec says)
{TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigCurveSetElemType, MPEcurve), &SupportedMPEtypes[3] },
{TYPE_MPE_HANDLER((cmsTagTypeSignature) cmsSigMatrixElemType, MPEmatrix), &SupportedMPEtypes[4] },
@@ -4466,6 +4626,11 @@
if (!_cmsReadUInt16Number(io, &nElems)) goto Error;
if (!_cmsReadUInt16Number(io, &nBytes)) goto Error;
+ // Adobe's quirk fixup. Fixing broken profiles...
+ if (nElems == 256 && nBytes == 1 && SizeOfTag == 1576)
+ nBytes = 2;
+
+
// Populate tone curves
for (n=0; n < 3; n++) {
@@ -4571,21 +4736,21 @@
cmsGetToneCurveParametricType(Curves[1]) == 5 &&
cmsGetToneCurveParametricType(Curves[2]) == 5) {
- if (!_cmsWriteUInt32Number(io, cmsVideoCardGammaFormulaType)) return FALSE;
-
- // Save parameters
- for (i=0; i < 3; i++) {
-
- _cmsVCGTGAMMA v;
-
- v.Gamma = Curves[i] ->Segments[0].Params[0];
- v.Min = Curves[i] ->Segments[0].Params[5];
- v.Max = pow(Curves[i] ->Segments[0].Params[1], v.Gamma) + v.Min;
-
- if (!_cmsWrite15Fixed16Number(io, v.Gamma)) return FALSE;
- if (!_cmsWrite15Fixed16Number(io, v.Min)) return FALSE;
- if (!_cmsWrite15Fixed16Number(io, v.Max)) return FALSE;
- }
+ if (!_cmsWriteUInt32Number(io, cmsVideoCardGammaFormulaType)) return FALSE;
+
+ // Save parameters
+ for (i=0; i < 3; i++) {
+
+ _cmsVCGTGAMMA v;
+
+ v.Gamma = Curves[i] ->Segments[0].Params[0];
+ v.Min = Curves[i] ->Segments[0].Params[5];
+ v.Max = pow(Curves[i] ->Segments[0].Params[1], v.Gamma) + v.Min;
+
+ if (!_cmsWrite15Fixed16Number(io, v.Gamma)) return FALSE;
+ if (!_cmsWrite15Fixed16Number(io, v.Min)) return FALSE;
+ if (!_cmsWrite15Fixed16Number(io, v.Max)) return FALSE;
+ }
}
else {
@@ -4639,6 +4804,435 @@
_cmsFree(self ->ContextID, Ptr);
}
+
+// ********************************************************************************
+// Type cmsSigDictType
+// ********************************************************************************
+
+// Single column of the table can point to wchar or MLUC elements. Holds arrays of data
+typedef struct {
+ cmsContext ContextID;
+ cmsUInt32Number *Offsets;
+ cmsUInt32Number *Sizes;
+} _cmsDICelem;
+
+typedef struct {
+ _cmsDICelem Name, Value, DisplayName, DisplayValue;
+
+} _cmsDICarray;
+
+// Allocate an empty array element
+static
+cmsBool AllocElem(cmsContext ContextID, _cmsDICelem* e, cmsUInt32Number Count)
+{
+ e->Offsets = (cmsUInt32Number *) _cmsCalloc(ContextID, Count, sizeof(cmsUInt32Number *));
+ if (e->Offsets == NULL) return FALSE;
+
+ e->Sizes = (cmsUInt32Number *) _cmsCalloc(ContextID, Count, sizeof(cmsUInt32Number *));
+ if (e->Sizes == NULL) {
+
+ _cmsFree(ContextID, e -> Offsets);
+ return FALSE;
+ }
+
+ e ->ContextID = ContextID;
+ return TRUE;
+}
+
+// Free an array element
+static
+void FreeElem(_cmsDICelem* e)
+{
+ if (e ->Offsets != NULL) _cmsFree(e -> ContextID, e -> Offsets);
+ if (e ->Sizes != NULL) _cmsFree(e -> ContextID, e ->Sizes);
+ e->Offsets = e ->Sizes = NULL;
+}
+
+// Get rid of whole array
+static
+void FreeArray( _cmsDICarray* a)
+{
+ if (a ->Name.Offsets != NULL) FreeElem(&a->Name);
+ if (a ->Value.Offsets != NULL) FreeElem(&a ->Value);
+ if (a ->DisplayName.Offsets != NULL) FreeElem(&a->DisplayName);
+ if (a ->DisplayValue.Offsets != NULL) FreeElem(&a ->DisplayValue);
+}
+
+
+// Allocate whole array
+static
+cmsBool AllocArray(cmsContext ContextID, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length)
+{
+ // Empty values
+ memset(a, 0, sizeof(_cmsDICarray));
+
+ // On depending on record size, create column arrays
+ if (!AllocElem(ContextID, &a ->Name, Count)) goto Error;
+ if (!AllocElem(ContextID, &a ->Value, Count)) goto Error;
+
+ if (Length > 16) {
+ if (!AllocElem(ContextID, &a -> DisplayName, Count)) goto Error;
+
+ }
+ if (Length > 24) {
+ if (!AllocElem(ContextID, &a ->DisplayValue, Count)) goto Error;
+ }
+ return TRUE;
+
+Error:
+ FreeArray(a);
+ return FALSE;
+}
+
+// Read one element
+static
+cmsBool ReadOneElem(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, cmsUInt32Number BaseOffset)
+{
+ if (!_cmsReadUInt32Number(io, &e->Offsets[i])) return FALSE;
+ if (!_cmsReadUInt32Number(io, &e ->Sizes[i])) return FALSE;
+
+ // An offset of zero has special meaning and shal be preserved
+ if (e ->Offsets[i] > 0)
+ e ->Offsets[i] += BaseOffset;
+ return TRUE;
+}
+
+
+static
+cmsBool ReadOffsetArray(cmsIOHANDLER* io, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length, cmsUInt32Number BaseOffset)
+{
+ cmsUInt32Number i;
+
+ // Read column arrays
+ for (i=0; i < Count; i++) {
+
+ if (!ReadOneElem(io, &a -> Name, i, BaseOffset)) return FALSE;
+ if (!ReadOneElem(io, &a -> Value, i, BaseOffset)) return FALSE;
+
+ if (Length > 16) {
+
+ if (!ReadOneElem(io, &a ->DisplayName, i, BaseOffset)) return FALSE;
+
+ }
+
+ if (Length > 24) {
+
+ if (!ReadOneElem(io, & a -> DisplayValue, i, BaseOffset)) return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
+// Write one element
+static
+cmsBool WriteOneElem(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i)
+{
+ if (!_cmsWriteUInt32Number(io, e->Offsets[i])) return FALSE;
+ if (!_cmsWriteUInt32Number(io, e ->Sizes[i])) return FALSE;
+
+ return TRUE;
+}
+
+static
+cmsBool WriteOffsetArray(cmsIOHANDLER* io, _cmsDICarray* a, cmsUInt32Number Count, cmsUInt32Number Length)
+{
+ cmsUInt32Number i;
+
+ for (i=0; i < Count; i++) {
+
+ if (!WriteOneElem(io, &a -> Name, i)) return FALSE;
+ if (!WriteOneElem(io, &a -> Value, i)) return FALSE;
+
+ if (Length > 16) {
+
+ if (!WriteOneElem(io, &a -> DisplayName, i)) return FALSE;
+ }
+
+ if (Length > 24) {
+
+ if (!WriteOneElem(io, &a -> DisplayValue, i)) return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static
+cmsBool ReadOneWChar(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, wchar_t ** wcstr)
+{
+
+ cmsUInt32Number nChars;
+
+ // Special case for undefined strings (see ICC Votable
+ // Proposal Submission, Dictionary Type and Metadata TAG Definition)
+ if (e -> Offsets[i] == 0) {
+
+ *wcstr = NULL;
+ return TRUE;
+ }
+
+ if (!io -> Seek(io, e -> Offsets[i])) return FALSE;
+
+ nChars = e ->Sizes[i] / sizeof(cmsUInt16Number);
+
+
+ *wcstr = (wchar_t*) _cmsMallocZero(e ->ContextID, (nChars + 1) * sizeof(wchar_t));
+ if (*wcstr == NULL) return FALSE;
+
+ if (!_cmsReadWCharArray(io, nChars, *wcstr)) {
+ _cmsFree(e ->ContextID, *wcstr);
+ return FALSE;
+ }
+
+ // End of string marker
+ (*wcstr)[nChars] = 0;
+ return TRUE;
+}
+
+static
+cmsUInt32Number mywcslen(const wchar_t *s)
+{
+ const wchar_t *p;
+
+ p = s;
+ while (*p)
+ p++;
+
+ return (cmsUInt32Number)(p - s);
+}
+
+static
+cmsBool WriteOneWChar(cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, const wchar_t * wcstr, cmsUInt32Number BaseOffset)
+{
+ cmsUInt32Number Before = io ->Tell(io);
+ cmsUInt32Number n;
+
+ e ->Offsets[i] = Before - BaseOffset;
+
+ if (wcstr == NULL) {
+ e ->Sizes[i] = 0;
+ e ->Offsets[i] = 0;
+ return TRUE;
+ }
+
+ n = mywcslen(wcstr);
+ if (!_cmsWriteWCharArray(io, n, wcstr)) return FALSE;
+
+ e ->Sizes[i] = io ->Tell(io) - Before;
+ return TRUE;
+}
+
+static
+cmsBool ReadOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, cmsMLU** mlu)
+{
+ cmsUInt32Number nItems = 0;
+
+ // A way to get null MLUCs
+ if (e -> Offsets[i] == 0 || e ->Sizes[i] == 0) {
+
+ *mlu = NULL;
+ return TRUE;
+ }
+
+ if (!io -> Seek(io, e -> Offsets[i])) return FALSE;
+
+ *mlu = (cmsMLU*) Type_MLU_Read(self, io, &nItems, e ->Sizes[i]);
+ return *mlu != NULL;
+}
+
+static
+cmsBool WriteOneMLUC(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, _cmsDICelem* e, cmsUInt32Number i, const cmsMLU* mlu, cmsUInt32Number BaseOffset)
+{
+ cmsUInt32Number Before;
+
+ // Special case for undefined strings (see ICC Votable
+ // Proposal Submission, Dictionary Type and Metadata TAG Definition)
+ if (mlu == NULL) {
+ e ->Sizes[i] = 0;
+ e ->Offsets[i] = 0;
+ return TRUE;
+ }
+
+ Before = io ->Tell(io);
+ e ->Offsets[i] = Before - BaseOffset;
+
+ if (!Type_MLU_Write(self, io, (void*) mlu, 1)) return FALSE;
+
+ e ->Sizes[i] = io ->Tell(io) - Before;
+ return TRUE;
+}
+
+
+static
+void *Type_Dictionary_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
+{
+ cmsHANDLE hDict;
+ cmsUInt32Number i, Count, Length;
+ cmsUInt32Number BaseOffset;
+ _cmsDICarray a;
+ wchar_t *NameWCS = NULL, *ValueWCS = NULL;
+ cmsMLU *DisplayNameMLU = NULL, *DisplayValueMLU=NULL;
+ cmsBool rc;
+
+ *nItems = 0;
+
+ // Get actual position as a basis for element offsets
+ BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
+
+ // Get name-value record count
+ if (!_cmsReadUInt32Number(io, &Count)) return NULL;
+ SizeOfTag -= sizeof(cmsUInt32Number);
+
+ // Get rec lenghth
+ if (!_cmsReadUInt32Number(io, &Length)) return NULL;
+ SizeOfTag -= sizeof(cmsUInt32Number);
+
+ // Check for valid lengths
+ if (Length != 16 && Length != 24 && Length != 32) {
+ cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown record length in dictionary '%d'", Length);
+ return NULL;
+ }
+
+ // Creates an empty dictionary
+ hDict = cmsDictAlloc(self -> ContextID);
+ if (hDict == NULL) return NULL;
+
+ // On depending on record size, create column arrays
+ if (!AllocArray(self -> ContextID, &a, Count, Length)) goto Error;
+
+ // Read column arrays
+ if (!ReadOffsetArray(io, &a, Count, Length, BaseOffset)) goto Error;
+
+ // Seek to each element and read it
+ for (i=0; i < Count; i++) {
+
+ if (!ReadOneWChar(io, &a.Name, i, &NameWCS)) goto Error;
+ if (!ReadOneWChar(io, &a.Value, i, &ValueWCS)) goto Error;
+
+ if (Length > 16) {
+ if (!ReadOneMLUC(self, io, &a.DisplayName, i, &DisplayNameMLU)) goto Error;
+ }
+
+ if (Length > 24) {
+ if (!ReadOneMLUC(self, io, &a.DisplayValue, i, &DisplayValueMLU)) goto Error;
+ }
+
+ rc = cmsDictAddEntry(hDict, NameWCS, ValueWCS, DisplayNameMLU, DisplayValueMLU);
+
+ if (NameWCS != NULL) _cmsFree(self ->ContextID, NameWCS);
+ if (ValueWCS != NULL) _cmsFree(self ->ContextID, ValueWCS);
+ if (DisplayNameMLU != NULL) cmsMLUfree(DisplayNameMLU);
+ if (DisplayValueMLU != NULL) cmsMLUfree(DisplayValueMLU);
+
+ if (!rc) return FALSE;
+ }
+
+ FreeArray(&a);
+ *nItems = 1;
+ return (void*) hDict;
+
+Error:
+ FreeArray(&a);
+ cmsDictFree(hDict);
+ return NULL;
+}
+
+
+static
+cmsBool Type_Dictionary_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems)
+{
+ cmsHANDLE hDict = (cmsHANDLE) Ptr;
+ const cmsDICTentry* p;
+ cmsBool AnyName, AnyValue;
+ cmsUInt32Number i, Count, Length;
+ cmsUInt32Number DirectoryPos, CurrentPos, BaseOffset;
+ _cmsDICarray a;
+
+ if (hDict == NULL) return FALSE;
+
+ BaseOffset = io ->Tell(io) - sizeof(_cmsTagBase);
+
+ // Let's inspect the dictionary
+ Count = 0; AnyName = FALSE; AnyValue = FALSE;
+ for (p = cmsDictGetEntryList(hDict); p != NULL; p = cmsDictNextEntry(p)) {
+
+ if (p ->DisplayName != NULL) AnyName = TRUE;
+ if (p ->DisplayValue != NULL) AnyValue = TRUE;
+ Count++;
+ }
+
+ Length = 16;
+ if (AnyName) Length += 8;
+ if (AnyValue) Length += 8;
+
+ if (!_cmsWriteUInt32Number(io, Count)) return FALSE;
+ if (!_cmsWriteUInt32Number(io, Length)) return FALSE;
+
+ // Keep starting position of offsets table
+ DirectoryPos = io ->Tell(io);
+
+ // Allocate offsets array
+ if (!AllocArray(self ->ContextID, &a, Count, Length)) goto Error;
+
+ // Write a fake directory to be filled latter on
+ if (!WriteOffsetArray(io, &a, Count, Length)) goto Error;
+
+ // Write each element. Keep track of the size as well.
+ p = cmsDictGetEntryList(hDict);
+ for (i=0; i < Count; i++) {
+
+ if (!WriteOneWChar(io, &a.Name, i, p ->Name, BaseOffset)) goto Error;
+ if (!WriteOneWChar(io, &a.Value, i, p ->Value, BaseOffset)) goto Error;
+
+ if (p ->DisplayName != NULL) {
+ if (!WriteOneMLUC(self, io, &a.DisplayName, i, p ->DisplayName, BaseOffset)) goto Error;
+ }
+
+ if (p ->DisplayValue != NULL) {
+ if (!WriteOneMLUC(self, io, &a.DisplayValue, i, p ->DisplayValue, BaseOffset)) goto Error;
+ }
+
+ p = cmsDictNextEntry(p);
+ }
+
+ // Write the directory
+ CurrentPos = io ->Tell(io);
+ if (!io ->Seek(io, DirectoryPos)) goto Error;
+
+ if (!WriteOffsetArray(io, &a, Count, Length)) goto Error;
+
+ if (!io ->Seek(io, CurrentPos)) goto Error;
+
+ FreeArray(&a);
+ return TRUE;
+
+Error:
+ FreeArray(&a);
+ return FALSE;
+
+ cmsUNUSED_PARAMETER(nItems);
+}
+
+
+static
+void* Type_Dictionary_Dup(struct _cms_typehandler_struct* self, const void *Ptr, cmsUInt32Number n)
+{
+ return (void*) cmsDictDup((cmsHANDLE) Ptr);
+
+ cmsUNUSED_PARAMETER(n);
+ cmsUNUSED_PARAMETER(self);
+}
+
+
+static
+void Type_Dictionary_Free(struct _cms_typehandler_struct* self, void* Ptr)
+{
+ cmsDictFree((cmsHANDLE) Ptr);
+ cmsUNUSED_PARAMETER(self);
+}
+
+
// ********************************************************************************
// Type support main routines
// ********************************************************************************
@@ -4676,6 +5270,7 @@
{TYPE_HANDLER(cmsCorbisBrokenXYZtype, XYZ), &SupportedTagTypes[27] },
{TYPE_HANDLER(cmsMonacoBrokenCurveType, Curve), &SupportedTagTypes[28] },
{TYPE_HANDLER(cmsSigProfileSequenceIdType, ProfileSequenceId), &SupportedTagTypes[29] },
+{TYPE_HANDLER(cmsSigDictType, Dictionary), &SupportedTagTypes[30] },
{TYPE_HANDLER(cmsSigVcgtType, vcgt), NULL }
};
@@ -4795,6 +5390,7 @@
{ cmsSigScreeningTag, { 1, 1, { cmsSigScreeningType}, NULL }, &SupportedTags[59]},
{ cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]},
+ { cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]},
{ cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL}, NULL}
};
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2011 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -143,7 +143,7 @@
if (!hICC) // can't allocate
return NULL;
- cmsSetProfileVersion(hICC, 4.2);
+ cmsSetProfileVersion(hICC, 4.3);
cmsSetDeviceClass(hICC, cmsSigDisplayClass);
cmsSetColorSpace(hICC, cmsSigRgbData);
@@ -247,7 +247,7 @@
if (!hICC) // can't allocate
return NULL;
- cmsSetProfileVersion(hICC, 4.2);
+ cmsSetProfileVersion(hICC, 4.3);
cmsSetDeviceClass(hICC, cmsSigDisplayClass);
cmsSetColorSpace(hICC, cmsSigGrayData);
@@ -310,7 +310,7 @@
if (!hICC)
return NULL;
- cmsSetProfileVersion(hICC, 4.2);
+ cmsSetProfileVersion(hICC, 4.3);
cmsSetDeviceClass(hICC, cmsSigLinkClass);
cmsSetColorSpace(hICC, ColorSpace);
@@ -430,7 +430,7 @@
if (!hICC) // can't allocate
return NULL;
- cmsSetProfileVersion(hICC, 4.2);
+ cmsSetProfileVersion(hICC, 4.3);
cmsSetDeviceClass(hICC, cmsSigLinkClass);
cmsSetColorSpace(hICC, ColorSpace);
@@ -538,7 +538,7 @@
hProfile = cmsCreateRGBProfileTHR(ContextID, WhitePoint == NULL ? cmsD50_xyY() : WhitePoint, NULL, NULL);
if (hProfile == NULL) return NULL;
- cmsSetProfileVersion(hProfile, 4.2);
+ cmsSetProfileVersion(hProfile, 4.3);
cmsSetDeviceClass(hProfile, cmsSigAbstractClass);
cmsSetColorSpace(hProfile, cmsSigLabData);
@@ -583,7 +583,7 @@
hProfile = cmsCreateRGBProfileTHR(ContextID, cmsD50_xyY(), NULL, NULL);
if (hProfile == NULL) return NULL;
- cmsSetProfileVersion(hProfile, 4.2);
+ cmsSetProfileVersion(hProfile, 4.3);
cmsSetDeviceClass(hProfile, cmsSigAbstractClass);
cmsSetColorSpace(hProfile, cmsSigXYZData);
@@ -838,7 +838,7 @@
if (!hProfile) // can't allocate
return NULL;
- cmsSetProfileVersion(hProfile, 4.2);
+ cmsSetProfileVersion(hProfile, 4.3);
if (!SetTextTags(hProfile, L"NULL profile built-in")) goto Error;
@@ -963,6 +963,11 @@
// Colorant count now depends on the output space
nc2 ->ColorantCount = cmsPipelineOutputChannels(v ->Lut);
+ // Make sure we have proper formatters
+ cmsChangeBuffersFormat(xform, TYPE_NAMED_COLOR_INDEX,
+ FLOAT_SH(0) | COLORSPACE_SH(_cmsLCMScolorSpace(v ->ExitColorSpace))
+ | BYTES_SH(2) | CHANNELS_SH(cmsChannelsOf(v ->ExitColorSpace)));
+
// Apply the transfor to colorants.
for (i=0; i < nColors; i++) {
cmsDoTransform(xform, &i, nc2 ->List[i].DeviceColorant, 1);
@@ -983,6 +988,7 @@
typedef struct {
cmsBool IsV4; // Is a V4 tag?
+ cmsTagSignature RequiredTag; // Set to 0 for both types
cmsTagTypeSignature LutType; // The LUT type
int nTypes; // Number of types (up to 5)
cmsStageSignature MpeTypes[5]; // 5 is the maximum number
@@ -991,16 +997,16 @@
static const cmsAllowedLUT AllowedLUTTypes[] = {
- { FALSE, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
- { FALSE, cmsSigLut16Type, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
- { TRUE , cmsSigLutAtoBType, 1, { cmsSigCurveSetElemType } },
- { TRUE , cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType } },
- { TRUE , cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType } },
- { TRUE , cmsSigLutAtoBType, 5, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType }},
- { TRUE , cmsSigLutBtoAType, 1, { cmsSigCurveSetElemType }},
- { TRUE , cmsSigLutBtoAType, 3, { cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType }},
- { TRUE , cmsSigLutBtoAType, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType }},
- { TRUE , cmsSigLutBtoAType, 5, { cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType }}
+ { FALSE, 0, cmsSigLut16Type, 4, { cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
+ { FALSE, 0, cmsSigLut16Type, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType}},
+ { TRUE , 0, cmsSigLutAtoBType, 1, { cmsSigCurveSetElemType }},
+ { TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType } },
+ { TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType } },
+ { TRUE , cmsSigAToB0Tag, cmsSigLutAtoBType, 5, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType }},
+ { TRUE , cmsSigBToA0Tag, cmsSigLutBtoAType, 1, { cmsSigCurveSetElemType }},
+ { TRUE , cmsSigBToA0Tag, cmsSigLutBtoAType, 3, { cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType }},
+ { TRUE , cmsSigBToA0Tag, cmsSigLutBtoAType, 3, { cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType }},
+ { TRUE , cmsSigBToA0Tag, cmsSigLutBtoAType, 5, { cmsSigCurveSetElemType, cmsSigMatrixElemType, cmsSigCurveSetElemType, cmsSigCLutElemType, cmsSigCurveSetElemType }}
};
#define SIZE_OF_ALLOWED_LUT (sizeof(AllowedLUTTypes)/sizeof(cmsAllowedLUT))
@@ -1023,15 +1029,17 @@
static
-const cmsAllowedLUT* FindCombination(const cmsPipeline* Lut, cmsBool IsV4)
+const cmsAllowedLUT* FindCombination(const cmsPipeline* Lut, cmsBool IsV4, cmsTagSignature DestinationTag)
{
- int n;
+ cmsUInt32Number n;
for (n=0; n < SIZE_OF_ALLOWED_LUT; n++) {
const cmsAllowedLUT* Tab = AllowedLUTTypes + n;
if (IsV4 ^ Tab -> IsV4) continue;
+ if ((Tab ->RequiredTag != 0) && (Tab ->RequiredTag != DestinationTag)) continue;
+
if (CheckOne(Tab, Lut)) return Tab;
}
@@ -1050,6 +1058,7 @@
cmsStage* mpe;
cmsContext ContextID = cmsGetTransformContextID(hTransform);
const cmsAllowedLUT* AllowedLUT;
+ cmsTagSignature DestinationTag;
_cmsAssert(hTransform != NULL);
@@ -1080,6 +1089,14 @@
cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocLabV4ToV2(ContextID));
}
+
+ hProfile = cmsCreateProfilePlaceholder(ContextID);
+ if (!hProfile) goto Error; // can't allocate
+
+ cmsSetProfileVersion(hProfile, Version);
+
+ FixColorSpaces(hProfile, xform -> EntryColorSpace, xform -> ExitColorSpace, dwFlags);
+
// Optimize the LUT and precalculate a devicelink
ChansIn = cmsChannelsOf(xform -> EntryColorSpace);
@@ -1092,17 +1109,22 @@
FrmOut = COLORSPACE_SH(ColorSpaceBitsOut) | CHANNELS_SH(ChansOut)|BYTES_SH(2);
+ if (cmsGetDeviceClass(hProfile) == cmsSigOutputClass)
+ DestinationTag = cmsSigBToA0Tag;
+ else
+ DestinationTag = cmsSigAToB0Tag;
+
// Check if the profile/version can store the result
if (dwFlags & cmsFLAGS_FORCE_CLUT)
AllowedLUT = NULL;
else
- AllowedLUT = FindCombination(LUT, Version >= 4.0);
+ AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag);
if (AllowedLUT == NULL) {
// Try to optimize
_cmsOptimizePipeline(&LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
- AllowedLUT = FindCombination(LUT, Version >= 4.0);
+ AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag);
}
@@ -1113,13 +1135,13 @@
_cmsOptimizePipeline(&LUT, xform ->RenderingIntent, &FrmIn, &FrmOut, &dwFlags);
// Put identity curves if needed
- if (cmsPipelineStageCount(LUT) == 1) {
+ if (cmsPipelineGetPtrToFirstStage(LUT) ->Type != cmsSigCurveSetElemType)
+ cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, ChansIn));
- cmsPipelineInsertStage(LUT, cmsAT_BEGIN, _cmsStageAllocIdentityCurves(ContextID, ChansIn));
- cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, ChansOut));
- }
+ if (cmsPipelineGetPtrToLastStage(LUT) ->Type != cmsSigCurveSetElemType)
+ cmsPipelineInsertStage(LUT, cmsAT_END, _cmsStageAllocIdentityCurves(ContextID, ChansOut));
- AllowedLUT = FindCombination(LUT, Version >= 4.0);
+ AllowedLUT = FindCombination(LUT, Version >= 4.0, DestinationTag);
}
// Somethings is wrong...
@@ -1127,25 +1149,15 @@
goto Error;
}
- hProfile = cmsCreateProfilePlaceholder(ContextID);
- if (!hProfile) goto Error; // can't allocate
-
- cmsSetProfileVersion(hProfile, Version);
-
- FixColorSpaces(hProfile, xform -> EntryColorSpace, xform -> ExitColorSpace, dwFlags);
if (dwFlags & cmsFLAGS_8BITS_DEVICELINK)
cmsPipelineSetSaveAs8bitsFlag(LUT, TRUE);
// Tag profile with information
- if (!SetTextTags(hProfile, L"devicelink")) return NULL;
-
- if (cmsGetDeviceClass(hProfile) == cmsSigOutputClass) {
+ if (!SetTextTags(hProfile, L"devicelink")) goto Error;
- if (!cmsWriteTag(hProfile, cmsSigBToA0Tag, LUT)) goto Error;
- }
- else
- if (!cmsWriteTag(hProfile, cmsSigAToB0Tag, LUT)) goto Error;
+ // Store result
+ if (!cmsWriteTag(hProfile, DestinationTag, LUT)) goto Error;
if (xform -> InputColorant != NULL) {
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c Fri Nov 02 17:32:30 2012 -0700
@@ -172,7 +172,7 @@
// Robertson's method
cmsBool CMSEXPORT cmsTempFromWhitePoint(cmsFloat64Number* TempK, const cmsCIExyY* WhitePoint)
{
- int j;
+ cmsUInt32Number j;
cmsFloat64Number us,vs;
cmsFloat64Number uj,vj,tj,di,dj,mi,mj;
cmsFloat64Number xs, ys;
@@ -263,10 +263,10 @@
cmsBool _cmsAdaptationMatrix(cmsMAT3* r, const cmsMAT3* ConeMatrix, const cmsCIEXYZ* FromIll, const cmsCIEXYZ* ToIll)
{
cmsMAT3 LamRigg = {{ // Bradford matrix
- {{ 0.8951, 0.2664, -0.1614 }},
- {{ -0.7502, 1.7135, 0.0367 }},
- {{ 0.0389, -0.0685, 1.0296 }}
- }};
+ {{ 0.8951, 0.2664, -0.1614 }},
+ {{ -0.7502, 1.7135, 0.0367 }},
+ {{ 0.0389, -0.0685, 1.0296 }}
+ }};
if (ConeMatrix == NULL)
ConeMatrix = &LamRigg;
@@ -376,3 +376,5 @@
return TRUE;
}
+
+
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsxform.c Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2011 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -60,8 +60,8 @@
// Alarm codes for 16-bit transformations, because the fixed range of containers there are
// no values left to mark out of gamut. volatile is C99 per 6.2.5
-static volatile cmsUInt16Number Alarm[cmsMAXCHANNELS];
-static volatile cmsFloat64Number GlobalAdaptationState = 0;
+static volatile cmsUInt16Number Alarm[cmsMAXCHANNELS] = { 0x7F00, 0x7F00, 0x7F00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static volatile cmsFloat64Number GlobalAdaptationState = 1;
// The adaptation state may be defaulted by this function. If you don't like it, use the extended transform routine
cmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d)
@@ -118,11 +118,13 @@
if (p ->Sequence)
cmsFreeProfileSequenceDescription(p ->Sequence);
- LCMS_FREE_LOCK(&p->rwlock);
+ if (p ->UserData)
+ p ->FreeUserData(p ->ContextID, p ->UserData);
+
_cmsFree(p ->ContextID, (void *) p);
}
-// Apply transform
+// Apply transform.
void CMSEXPORT cmsDoTransform(cmsHTRANSFORM Transform,
const void* InputBuffer,
void* OutputBuffer,
@@ -131,7 +133,20 @@
{
_cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
- p -> xform(p, InputBuffer, OutputBuffer, Size);
+ p -> xform(p, InputBuffer, OutputBuffer, Size, Size);
+}
+
+
+// Apply transform.
+void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
+ const void* InputBuffer,
+ void* OutputBuffer,
+ cmsUInt32Number Size, cmsUInt32Number Stride)
+
+{
+ _cmsTRANSFORM* p = (_cmsTRANSFORM*) Transform;
+
+ p -> xform(p, InputBuffer, OutputBuffer, Size, Stride);
}
@@ -142,7 +157,7 @@
static
void FloatXFORM(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size)
+ void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
@@ -155,7 +170,7 @@
for (i=0; i < Size; i++) {
- accum = p -> FromInputFloat(p, fIn, accum, Size);
+ accum = p -> FromInputFloat(p, fIn, accum, Stride);
// Any gamut chack to do?
if (p ->GamutCheck != NULL) {
@@ -183,7 +198,7 @@
}
// Back to asked representation
- output = p -> ToOutputFloat(p, fOut, output, Size);
+ output = p -> ToOutputFloat(p, fOut, output, Stride);
}
}
@@ -193,7 +208,8 @@
static
void NullXFORM(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size)
+ void* out, cmsUInt32Number Size,
+ cmsUInt32Number Stride)
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
@@ -206,8 +222,8 @@
for (i=0; i < n; i++) {
- accum = p -> FromInput(p, wIn, accum, Size);
- output = p -> ToOutput(p, wIn, output, Size);
+ accum = p -> FromInput(p, wIn, accum, Stride);
+ output = p -> ToOutput(p, wIn, output, Stride);
}
}
@@ -216,7 +232,7 @@
static
void PrecalculatedXFORM(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size)
+ void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
{
register cmsUInt8Number* accum;
register cmsUInt8Number* output;
@@ -229,9 +245,9 @@
for (i=0; i < n; i++) {
- accum = p -> FromInput(p, wIn, accum, Size);
+ accum = p -> FromInput(p, wIn, accum, Stride);
p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
- output = p -> ToOutput(p, wOut, output, Size);
+ output = p -> ToOutput(p, wOut, output, Stride);
}
}
@@ -260,7 +276,7 @@
static
void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size)
+ void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
@@ -273,9 +289,9 @@
for (i=0; i < n; i++) {
- accum = p -> FromInput(p, wIn, accum, Size);
+ accum = p -> FromInput(p, wIn, accum, Stride);
TransformOnePixelWithGamutCheck(p, wIn, wOut);
- output = p -> ToOutput(p, wOut, output, Size);
+ output = p -> ToOutput(p, wOut, output, Stride);
}
}
@@ -284,13 +300,13 @@
static
void CachedXFORM(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size)
+ void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
cmsUInt32Number i, n;
- cmsUInt16Number CacheIn[cmsMAXCHANNELS], CacheOut[cmsMAXCHANNELS];
+ _cmsCACHE Cache;
accum = (cmsUInt8Number*) in;
output = (cmsUInt8Number*) out;
@@ -300,36 +316,28 @@
memset(wIn, 0, sizeof(wIn));
memset(wOut, 0, sizeof(wOut));
-
- LCMS_READ_LOCK(&p ->rwlock);
- memmove(CacheIn, p ->CacheIn, sizeof(CacheIn));
- memmove(CacheOut, p ->CacheOut, sizeof(CacheOut));
- LCMS_UNLOCK(&p ->rwlock);
+ // Get copy of zero cache
+ memcpy(&Cache, &p ->Cache, sizeof(Cache));
for (i=0; i < n; i++) {
- accum = p -> FromInput(p, wIn, accum, Size);
+ accum = p -> FromInput(p, wIn, accum, Stride);
- if (memcmp(wIn, CacheIn, sizeof(CacheIn)) == 0) {
+ if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
- memmove(wOut, CacheOut, sizeof(CacheOut));
+ memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
}
else {
p ->Lut ->Eval16Fn(wIn, wOut, p -> Lut->Data);
- memmove(CacheIn, wIn, sizeof(CacheIn));
- memmove(CacheOut, wOut, sizeof(CacheOut));
+ memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
+ memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
}
- output = p -> ToOutput(p, wOut, output, Size);
+ output = p -> ToOutput(p, wOut, output, Stride);
}
-
- LCMS_WRITE_LOCK(&p ->rwlock);
- memmove(p->CacheIn, CacheIn, sizeof(CacheIn));
- memmove(p->CacheOut, CacheOut, sizeof(CacheOut));
- LCMS_UNLOCK(&p ->rwlock);
}
@@ -337,13 +345,13 @@
static
void CachedXFORMGamutCheck(_cmsTRANSFORM* p,
const void* in,
- void* out, cmsUInt32Number Size)
+ void* out, cmsUInt32Number Size, cmsUInt32Number Stride)
{
cmsUInt8Number* accum;
cmsUInt8Number* output;
cmsUInt16Number wIn[cmsMAXCHANNELS], wOut[cmsMAXCHANNELS];
cmsUInt32Number i, n;
- cmsUInt16Number CacheIn[cmsMAXCHANNELS], CacheOut[cmsMAXCHANNELS];
+ _cmsCACHE Cache;
accum = (cmsUInt8Number*) in;
output = (cmsUInt8Number*) out;
@@ -353,51 +361,158 @@
memset(wIn, 0, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
memset(wOut, 0, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
- LCMS_READ_LOCK(&p ->rwlock);
- memmove(CacheIn, p ->CacheIn, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
- memmove(CacheOut, p ->CacheOut, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
- LCMS_UNLOCK(&p ->rwlock);
-
+ // Get copy of zero cache
+ memcpy(&Cache, &p ->Cache, sizeof(Cache));
for (i=0; i < n; i++) {
- accum = p -> FromInput(p, wIn, accum, Size);
+ accum = p -> FromInput(p, wIn, accum, Stride);
- if (memcmp(wIn, CacheIn, sizeof(cmsUInt16Number) * cmsMAXCHANNELS) == 0) {
- memmove(wOut, CacheOut, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
+ if (memcmp(wIn, Cache.CacheIn, sizeof(Cache.CacheIn)) == 0) {
+ memcpy(wOut, Cache.CacheOut, sizeof(Cache.CacheOut));
}
else {
TransformOnePixelWithGamutCheck(p, wIn, wOut);
- memmove(CacheIn, wIn, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
- memmove(CacheOut, wOut, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
+ memcpy(Cache.CacheIn, wIn, sizeof(Cache.CacheIn));
+ memcpy(Cache.CacheOut, wOut, sizeof(Cache.CacheOut));
}
- output = p -> ToOutput(p, wOut, output, Size);
+ output = p -> ToOutput(p, wOut, output, Stride);
}
- LCMS_WRITE_LOCK(&p ->rwlock);
- memmove(p->CacheIn, CacheIn, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
- memmove(p->CacheOut, CacheOut, sizeof(cmsUInt16Number) * cmsMAXCHANNELS);
- LCMS_UNLOCK(&p ->rwlock);
+}
+
+// -------------------------------------------------------------------------------------------------------------
+
+// List of used-defined transform factories
+typedef struct _cmsTransformCollection_st {
+
+ _cmsTransformFactory Factory;
+ struct _cmsTransformCollection_st *Next;
+
+} _cmsTransformCollection;
+
+// The linked list head
+static _cmsTransformCollection* TransformCollection = NULL;
+
+// Register new ways to transform
+cmsBool _cmsRegisterTransformPlugin(cmsPluginBase* Data)
+{
+ cmsPluginTransform* Plugin = (cmsPluginTransform*) Data;
+ _cmsTransformCollection* fl;
+
+ if (Data == NULL) {
+
+ // Free the chain. Memory is safely freed at exit
+ TransformCollection = NULL;
+ return TRUE;
+ }
+
+ // Factory callback is required
+ if (Plugin ->Factory == NULL) return FALSE;
+
+
+ fl = (_cmsTransformCollection*) _cmsPluginMalloc(sizeof(_cmsTransformCollection));
+ if (fl == NULL) return FALSE;
+
+ // Copy the parameters
+ fl ->Factory = Plugin ->Factory;
+
+ // Keep linked list
+ fl ->Next = TransformCollection;
+ TransformCollection = fl;
+
+ // All is ok
+ return TRUE;
}
+void CMSEXPORT _cmsSetTransformUserData(struct _cmstransform_struct *CMMcargo, void* ptr, _cmsFreeUserDataFn FreePrivateDataFn)
+{
+ _cmsAssert(CMMcargo != NULL);
+ CMMcargo ->UserData = ptr;
+ CMMcargo ->FreeUserData = FreePrivateDataFn;
+}
+
+// returns the pointer defined by the plug-in to store private data
+void * CMSEXPORT _cmsGetTransformUserData(struct _cmstransform_struct *CMMcargo)
+{
+ _cmsAssert(CMMcargo != NULL);
+ return CMMcargo ->UserData;
+}
+
+// returns the current formatters
+void CMSEXPORT _cmsGetTransformFormatters16(struct _cmstransform_struct *CMMcargo, cmsFormatter16* FromInput, cmsFormatter16* ToOutput)
+{
+ _cmsAssert(CMMcargo != NULL);
+ if (FromInput) *FromInput = CMMcargo ->FromInput;
+ if (ToOutput) *ToOutput = CMMcargo ->ToOutput;
+}
+
+void CMSEXPORT _cmsGetTransformFormattersFloat(struct _cmstransform_struct *CMMcargo, cmsFormatterFloat* FromInput, cmsFormatterFloat* ToOutput)
+{
+ _cmsAssert(CMMcargo != NULL);
+ if (FromInput) *FromInput = CMMcargo ->FromInputFloat;
+ if (ToOutput) *ToOutput = CMMcargo ->ToOutputFloat;
+}
-// Allocate transform struct and set it to defaults
+// Allocate transform struct and set it to defaults. Ask the optimization plug-in about if those formats are proper
+// for separated transforms. If this is the case,
static
-_cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsUInt32Number InputFormat, cmsUInt32Number OutputFormat, cmsUInt32Number dwFlags)
+_cmsTRANSFORM* AllocEmptyTransform(cmsContext ContextID, cmsPipeline* lut,
+ cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags)
{
+ _cmsTransformCollection* Plugin;
+
// Allocate needed memory
_cmsTRANSFORM* p = (_cmsTRANSFORM*) _cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM));
if (!p) return NULL;
+ // Store the proposed pipeline
+ p ->Lut = lut;
+
+ // Let's see if any plug-in want to do the transform by itself
+ for (Plugin = TransformCollection;
+ Plugin != NULL;
+ Plugin = Plugin ->Next) {
+
+ if (Plugin ->Factory(&p->xform, &p->UserData, &p ->FreeUserData, &p ->Lut, InputFormat, OutputFormat, dwFlags)) {
+
+ // Last plugin in the declaration order takes control. We just keep
+ // the original parameters as a logging.
+ // Note that cmsFLAGS_CAN_CHANGE_FORMATTER is not set, so by default
+ // an optimized transform is not reusable. The plug-in can, however, change
+ // the flags and make it suitable.
+
+ p ->ContextID = ContextID;
+ p ->InputFormat = *InputFormat;
+ p ->OutputFormat = *OutputFormat;
+ p ->dwOriginalFlags = *dwFlags;
+
+ // Fill the formatters just in case the optimized routine is interested.
+ // No error is thrown if the formatter doesn't exist. It is up to the optimization
+ // factory to decide what to do in those cases.
+ p ->FromInput = _cmsGetFormatter(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
+ p ->ToOutput = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
+ p ->FromInputFloat = _cmsGetFormatter(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+ p ->ToOutputFloat = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+
+ return p;
+ }
+ }
+
+ // Not suitable for the transform plug-in, let's check the pipeline plug-in
+ if (p ->Lut != NULL)
+ _cmsOptimizePipeline(&p->Lut, Intent, InputFormat, OutputFormat, dwFlags);
+
// Check whatever this is a true floating point transform
- if (_cmsFormatterIsFloat(InputFormat) && _cmsFormatterIsFloat(OutputFormat)) {
+ if (_cmsFormatterIsFloat(*InputFormat) && _cmsFormatterIsFloat(*OutputFormat)) {
// Get formatter function always return a valid union, but the contents of this union may be NULL.
- p ->FromInputFloat = _cmsGetFormatter(InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
- p ->ToOutputFloat = _cmsGetFormatter(OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+ p ->FromInputFloat = _cmsGetFormatter(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+ p ->ToOutputFloat = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat;
+ *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER;
if (p ->FromInputFloat == NULL || p ->ToOutputFloat == NULL) {
@@ -411,31 +526,45 @@
}
else {
- p ->FromInput = _cmsGetFormatter(InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
- p ->ToOutput = _cmsGetFormatter(OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
+ if (*InputFormat == 0 && *OutputFormat == 0) {
+ p ->FromInput = p ->ToOutput = NULL;
+ *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER;
+ }
+ else {
+
+ int BytesPerPixelInput;
+
+ p ->FromInput = _cmsGetFormatter(*InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
+ p ->ToOutput = _cmsGetFormatter(*OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
- if (p ->FromInput == NULL || p ->ToOutput == NULL) {
+ if (p ->FromInput == NULL || p ->ToOutput == NULL) {
- cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format");
- _cmsFree(ContextID, p);
- return NULL;
+ cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format");
+ _cmsFree(ContextID, p);
+ return NULL;
+ }
+
+ BytesPerPixelInput = T_BYTES(p ->InputFormat);
+ if (BytesPerPixelInput == 0 || BytesPerPixelInput >= 2)
+ *dwFlags |= cmsFLAGS_CAN_CHANGE_FORMATTER;
+
}
- if (dwFlags & cmsFLAGS_NULLTRANSFORM) {
+ if (*dwFlags & cmsFLAGS_NULLTRANSFORM) {
p ->xform = NullXFORM;
}
else {
- if (dwFlags & cmsFLAGS_NOCACHE) {
+ if (*dwFlags & cmsFLAGS_NOCACHE) {
- if (dwFlags & cmsFLAGS_GAMUTCHECK)
+ if (*dwFlags & cmsFLAGS_GAMUTCHECK)
p ->xform = PrecalculatedXFORMGamutCheck; // Gamut check, no caché
else
p ->xform = PrecalculatedXFORM; // No caché, no gamut check
}
else {
- if (dwFlags & cmsFLAGS_GAMUTCHECK)
+ if (*dwFlags & cmsFLAGS_GAMUTCHECK)
p ->xform = CachedXFORMGamutCheck; // Gamut check, caché
else
p ->xform = CachedXFORM; // No gamut check, caché
@@ -444,14 +573,11 @@
}
}
-
- // Create a mutex for shared memory
- LCMS_CREATE_LOCK(&p->rwlock);
-
- p ->InputFormat = InputFormat;
- p ->OutputFormat = OutputFormat;
- p ->dwOriginalFlags = dwFlags;
+ p ->InputFormat = *InputFormat;
+ p ->OutputFormat = *OutputFormat;
+ p ->dwOriginalFlags = *dwFlags;
p ->ContextID = ContextID;
+ p ->UserData = NULL;
return p;
}
@@ -462,12 +588,14 @@
cmsColorSpaceSignature PostColorSpace;
int i;
+ if (nProfiles <= 0) return FALSE;
if (hProfiles[0] == NULL) return FALSE;
*Input = PostColorSpace = cmsGetColorSpace(hProfiles[0]);
for (i=0; i < nProfiles; i++) {
+ cmsProfileClassSignature cls;
cmsHPROFILE hProfile = hProfiles[i];
int lIsInput = (PostColorSpace != cmsSigXYZData) &&
@@ -475,17 +603,28 @@
if (hProfile == NULL) return FALSE;
- if (lIsInput) {
+ cls = cmsGetDeviceClass(hProfile);
+
+ if (cls == cmsSigNamedColorClass) {
+
+ ColorSpaceIn = cmsSig1colorData;
+ ColorSpaceOut = (nProfiles > 1) ? cmsGetPCS(hProfile) : cmsGetColorSpace(hProfile);
+ }
+ else
+ if (lIsInput || (cls == cmsSigLinkClass)) {
ColorSpaceIn = cmsGetColorSpace(hProfile);
ColorSpaceOut = cmsGetPCS(hProfile);
}
- else {
-
+ else
+ {
ColorSpaceIn = cmsGetPCS(hProfile);
ColorSpaceOut = cmsGetColorSpace(hProfile);
}
+ if (i==0)
+ *Input = ColorSpaceIn;
+
PostColorSpace = ColorSpaceOut;
}
@@ -531,6 +670,12 @@
cmsPipeline* Lut;
cmsUInt32Number LastIntent = Intents[nProfiles-1];
+ // If it is a fake transform
+ if (dwFlags & cmsFLAGS_NULLTRANSFORM)
+ {
+ return AllocEmptyTransform(ContextID, NULL, INTENT_PERCEPTUAL, &InputFormat, &OutputFormat, &dwFlags);
+ }
+
// If gamut check is requested, make sure we have a gamut profile
if (dwFlags & cmsFLAGS_GAMUTCHECK) {
if (hGamutProfile == NULL) dwFlags &= ~cmsFLAGS_GAMUTCHECK;
@@ -566,21 +711,24 @@
return NULL;
}
- // Optimize the LUT if possible
- _cmsOptimizePipeline(&Lut, LastIntent, &InputFormat, &OutputFormat, &dwFlags);
+ // Check channel count
+ if ((cmsChannelsOf(EntryColorSpace) != cmsPipelineInputChannels(Lut)) ||
+ (cmsChannelsOf(ExitColorSpace) != cmsPipelineOutputChannels(Lut))) {
+ cmsSignalError(ContextID, cmsERROR_NOT_SUITABLE, "Channel count doesn't match. Profile is corrupted");
+ return NULL;
+ }
// All seems ok
- xform = AllocEmptyTransform(ContextID, InputFormat, OutputFormat, dwFlags);
+ xform = AllocEmptyTransform(ContextID, Lut, LastIntent, &InputFormat, &OutputFormat, &dwFlags);
if (xform == NULL) {
- cmsPipelineFree(Lut);
return NULL;
}
// Keep values
xform ->EntryColorSpace = EntryColorSpace;
xform ->ExitColorSpace = ExitColorSpace;
- xform ->Lut = Lut;
+ xform ->RenderingIntent = Intents[nProfiles-1];
// Create a gamut check LUT if requested
@@ -627,14 +775,14 @@
// If this is a cached transform, init first value, which is zero (16 bits only)
if (!(dwFlags & cmsFLAGS_NOCACHE)) {
- memset(&xform ->CacheIn, 0, sizeof(xform ->CacheIn));
+ memset(&xform ->Cache.CacheIn, 0, sizeof(xform ->Cache.CacheIn));
if (xform ->GamutCheck != NULL) {
- TransformOnePixelWithGamutCheck(xform, xform ->CacheIn, xform->CacheOut);
+ TransformOnePixelWithGamutCheck(xform, xform ->Cache.CacheIn, xform->Cache.CacheOut);
}
else {
- xform ->Lut ->Eval16Fn(xform ->CacheIn, xform->CacheOut, xform -> Lut->Data);
+ xform ->Lut ->Eval16Fn(xform ->Cache.CacheIn, xform->Cache.CacheOut, xform -> Lut->Data);
}
}
@@ -643,7 +791,6 @@
}
// Multiprofile transforms: Gamut check is not available here, as it is unclear from which profile the gamut comes.
-
cmsHTRANSFORM CMSEXPORT cmsCreateMultiprofileTransformTHR(cmsContext ContextID,
cmsHPROFILE hProfiles[],
cmsUInt32Number nProfiles,
@@ -785,3 +932,53 @@
if (xform == NULL) return NULL;
return xform -> ContextID;
}
+
+// Grab the input/output formats
+cmsUInt32Number CMSEXPORT cmsGetTransformInputFormat(cmsHTRANSFORM hTransform)
+{
+ _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
+
+ if (xform == NULL) return 0;
+ return xform->InputFormat;
+}
+
+cmsUInt32Number CMSEXPORT cmsGetTransformOutputFormat(cmsHTRANSFORM hTransform)
+{
+ _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
+
+ if (xform == NULL) return 0;
+ return xform->OutputFormat;
+}
+
+// For backwards compatibility
+cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
+ cmsUInt32Number InputFormat,
+ cmsUInt32Number OutputFormat)
+{
+
+ _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
+ cmsFormatter16 FromInput, ToOutput;
+
+
+ // We only can afford to change formatters if previous transform is at least 16 bits
+ if (!(xform ->dwOriginalFlags & cmsFLAGS_CAN_CHANGE_FORMATTER)) {
+
+ cmsSignalError(xform ->ContextID, cmsERROR_NOT_SUITABLE, "cmsChangeBuffersFormat works only on transforms created originally with at least 16 bits of precision");
+ return FALSE;
+ }
+
+ FromInput = _cmsGetFormatter(InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16;
+ ToOutput = _cmsGetFormatter(OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16;
+
+ if (FromInput == NULL || ToOutput == NULL) {
+
+ cmsSignalError(xform -> ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format");
+ return FALSE;
+ }
+
+ xform ->InputFormat = InputFormat;
+ xform ->OutputFormat = OutputFormat;
+ xform ->FromInput = FromInput;
+ xform ->ToOutput = ToOutput;
+ return TRUE;
+}
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/lcms2.h Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/lcms2.h Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2011 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -52,7 +52,7 @@
//
//---------------------------------------------------------------------------------
//
-// Version 2.0
+// Version 2.4
//
#ifndef _lcms2_H
@@ -69,9 +69,6 @@
// Uncomment this if your compiler doesn't work with fast floor function
// #define CMS_DONT_USE_FAST_FLOOR 1
-// Uncomment this line if your system does not support multithreading
-#define CMS_DONT_USE_PTHREADS 1
-
// Uncomment this line if you want lcms to use the black point tag in profile,
// if commented, lcms will compute the black point by its own.
// It is safer to leave it commented out
@@ -84,6 +81,9 @@
// require "KEYWORD" on undefined identifiers, keep it comented out unless needed
// #define CMS_STRICT_CGATS 1
+// Uncomment to get rid of the tables for "half" float support
+// #define CMS_NO_HALF_SUPPORT 1
+
// ********** End of configuration toggles ******************************
// Needed for streams
@@ -101,7 +101,7 @@
#endif
// Version/release
-#define LCMS_VERSION 2000
+#define LCMS_VERSION 2040
// I will give the chance of redefining basic types for compilers that are not fully C99 compliant
#ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
@@ -110,6 +110,10 @@
typedef unsigned char cmsUInt8Number; // That is guaranteed by the C99 spec
typedef signed char cmsInt8Number; // That is guaranteed by the C99 spec
+#if CHAR_BIT != 8
+# error "Unable to find 8 bit type, unsupported compiler"
+#endif
+
// IEEE float storage numbers
typedef float cmsFloat32Number;
typedef double cmsFloat64Number;
@@ -211,11 +215,13 @@
#endif
#ifdef TARGET_CPU_PPC
+# if TARGET_CPU_PPC
# define CMS_USE_BIG_ENDIAN 1
+# endif
#endif
#ifdef macintosh
-# ifndef __LITTLE_ENDIAN__
+# ifdef __BIG_ENDIAN__
# define CMS_USE_BIG_ENDIAN 1
# endif
#endif
@@ -276,6 +282,7 @@
cmsSigCrdInfoType = 0x63726469, // 'crdi'
cmsSigCurveType = 0x63757276, // 'curv'
cmsSigDataType = 0x64617461, // 'data'
+ cmsSigDictType = 0x64696374, // 'dict'
cmsSigDateTimeType = 0x6474696D, // 'dtim'
cmsSigDeviceSettingsType = 0x64657673, // 'devs'
cmsSigLut16Type = 0x6d667432, // 'mft2'
@@ -302,9 +309,10 @@
cmsSigUInt32ArrayType = 0x75693332, // 'ui32'
cmsSigUInt64ArrayType = 0x75693634, // 'ui64'
cmsSigUInt8ArrayType = 0x75693038, // 'ui08'
+ cmsSigVcgtType = 0x76636774, // 'vcgt'
cmsSigViewingConditionsType = 0x76696577, // 'view'
- cmsSigXYZType = 0x58595A20, // 'XYZ '
- cmsSigVcgtType = 0x76636774 // 'vcgt'
+ cmsSigXYZType = 0x58595A20 // 'XYZ '
+
} cmsTagTypeSignature;
@@ -377,7 +385,8 @@
cmsSigUcrBgTag = 0x62666420, // 'bfd '
cmsSigViewingCondDescTag = 0x76756564, // 'vued'
cmsSigViewingConditionsTag = 0x76696577, // 'view'
- cmsSigVcgtTag = 0x76636774 // 'vcgt'
+ cmsSigVcgtTag = 0x76636774, // 'vcgt'
+ cmsSigMetaTag = 0x6D657461 // 'meta'
} cmsTagSignature;
@@ -409,7 +418,7 @@
cmsSigMotionPictureFilmScanner = 0x6D706673, // 'mpfs'
cmsSigMotionPictureFilmRecorder = 0x6D706672, // 'mpfr'
cmsSigDigitalMotionPictureCamera = 0x646D7063, // 'dmpc'
- cmsSigDigitalCinemaProjector = 0x64636A70, // 'dcpj'
+ cmsSigDigitalCinemaProjector = 0x64636A70 // 'dcpj'
} cmsTechnologySignature;
@@ -436,12 +445,12 @@
cmsSigMCH7Data = 0x4D434837, // 'MCH7'
cmsSigMCH8Data = 0x4D434838, // 'MCH8'
cmsSigMCH9Data = 0x4D434839, // 'MCH9'
- cmsSigMCHAData = 0x4D43483A, // 'MCHA'
- cmsSigMCHBData = 0x4D43483B, // 'MCHB'
- cmsSigMCHCData = 0x4D43483C, // 'MCHC'
- cmsSigMCHDData = 0x4D43483D, // 'MCHD'
- cmsSigMCHEData = 0x4D43483E, // 'MCHE'
- cmsSigMCHFData = 0x4D43483F, // 'MCHF'
+ cmsSigMCHAData = 0x4D434841, // 'MCHA'
+ cmsSigMCHBData = 0x4D434842, // 'MCHB'
+ cmsSigMCHCData = 0x4D434843, // 'MCHC'
+ cmsSigMCHDData = 0x4D434844, // 'MCHD'
+ cmsSigMCHEData = 0x4D434845, // 'MCHE'
+ cmsSigMCHFData = 0x4D434846, // 'MCHF'
cmsSigNamedData = 0x6e6d636c, // 'nmcl'
cmsSig1colorData = 0x31434C52, // '1CLR'
cmsSig2colorData = 0x32434C52, // '2CLR'
@@ -470,7 +479,7 @@
cmsSigLinkClass = 0x6C696E6B, // 'link'
cmsSigAbstractClass = 0x61627374, // 'abst'
cmsSigColorSpaceClass = 0x73706163, // 'spac'
- cmsSigNamedColorClass = 0x6e6d636c, // 'nmcl'
+ cmsSigNamedColorClass = 0x6e6d636c // 'nmcl'
} cmsProfileClassSignature;
@@ -512,7 +521,13 @@
cmsSigLabV4toV2 = 0x34203220, // '4 2 '
// Identities
- cmsSigIdentityElemType = 0x69646E20 // 'idn '
+ cmsSigIdentityElemType = 0x69646E20, // 'idn '
+
+ // Float to floatPCS
+ cmsSigLab2FloatPCS = 0x64326C20, // 'd2l '
+ cmsSigFloatPCS2Lab = 0x6C326420, // 'l2d '
+ cmsSigXYZ2FloatPCS = 0x64327820, // 'd2x '
+ cmsSigFloatPCS2XYZ = 0x78326420 // 'x2d '
} cmsStageSignature;
@@ -635,7 +650,9 @@
// Format of pixel is defined by one cmsUInt32Number, using bit fields as follows
//
-// A O TTTTT U Y F P X S EEE CCCC BBB
+// 2 1 0
+// 3 2 10987 6 5 4 3 2 1 098 7654 321
+// A O TTTTT U Y F P X S EEE CCCC BBB
//
// A: Floating point -- With this flag we can differentiate 16 bits as float and as int
// O: Optimized -- previous optimization already returns the final 8-bit value
@@ -743,16 +760,19 @@
#define TYPE_RGBA_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1))
#define TYPE_ARGB_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|SWAPFIRST_SH(1))
+#define TYPE_ARGB_8_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|SWAPFIRST_SH(1)|PLANAR_SH(1))
#define TYPE_ARGB_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|SWAPFIRST_SH(1))
#define TYPE_ABGR_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1))
+#define TYPE_ABGR_8_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|PLANAR_SH(1))
#define TYPE_ABGR_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1))
#define TYPE_ABGR_16_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|PLANAR_SH(1))
#define TYPE_ABGR_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|ENDIAN16_SH(1))
#define TYPE_BGRA_8 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1))
+#define TYPE_BGRA_8_PLANAR (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1)|PLANAR_SH(1))
#define TYPE_BGRA_16 (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1))
-#define TYPE_BGRA_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)|SWAPFIRST_SH(1))
+#define TYPE_BGRA_16_SE (COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|ENDIAN16_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1))
#define TYPE_CMY_8 (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(1))
#define TYPE_CMY_8_PLANAR (COLORSPACE_SH(PT_CMY)|CHANNELS_SH(3)|BYTES_SH(1)|PLANAR_SH(1))
@@ -834,8 +854,8 @@
#define TYPE_Lab_8 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(1))
#define TYPE_LabV2_8 (COLORSPACE_SH(PT_LabV2)|CHANNELS_SH(3)|BYTES_SH(1))
-#define TYPE_ALab_8 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1))
-#define TYPE_ALabV2_8 (COLORSPACE_SH(PT_LabV2)|CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|DOSWAP_SH(1))
+#define TYPE_ALab_8 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1))
+#define TYPE_ALabV2_8 (COLORSPACE_SH(PT_LabV2)|CHANNELS_SH(3)|BYTES_SH(1)|EXTRA_SH(1)|SWAPFIRST_SH(1))
#define TYPE_Lab_16 (COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(2))
#define TYPE_LabV2_16 (COLORSPACE_SH(PT_LabV2)|CHANNELS_SH(3)|BYTES_SH(2))
#define TYPE_Yxy_16 (COLORSPACE_SH(PT_Yxy)|CHANNELS_SH(3)|BYTES_SH(2))
@@ -874,8 +894,16 @@
// Float formatters.
#define TYPE_XYZ_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_XYZ)|CHANNELS_SH(3)|BYTES_SH(4))
#define TYPE_Lab_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(4))
+#define TYPE_LabA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_Lab)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4))
#define TYPE_GRAY_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(4))
#define TYPE_RGB_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4))
+
+#define TYPE_RGBA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4))
+#define TYPE_ARGB_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|SWAPFIRST_SH(1))
+#define TYPE_BGR_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1))
+#define TYPE_BGRA_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1)|SWAPFIRST_SH(1))
+#define TYPE_ABGR_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(4)|DOSWAP_SH(1))
+
#define TYPE_CMYK_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(4))
// Floating point formatters.
@@ -884,8 +912,21 @@
#define TYPE_Lab_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_Lab)|CHANNELS_SH(3)|BYTES_SH(0))
#define TYPE_GRAY_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(0))
#define TYPE_RGB_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(0))
+#define TYPE_BGR_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(0)|DOSWAP_SH(1))
#define TYPE_CMYK_DBL (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(0))
+// IEEE 754-2008 "half"
+#define TYPE_GRAY_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_GRAY)|CHANNELS_SH(1)|BYTES_SH(2))
+#define TYPE_RGB_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2))
+#define TYPE_RGBA_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2))
+#define TYPE_CMYK_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(2))
+
+#define TYPE_RGBA_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2))
+#define TYPE_ARGB_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|SWAPFIRST_SH(1))
+#define TYPE_BGR_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1))
+#define TYPE_BGRA_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|EXTRA_SH(1)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1)|SWAPFIRST_SH(1))
+#define TYPE_ABGR_HALF_FLT (FLOAT_SH(1)|COLORSPACE_SH(PT_RGB)|CHANNELS_SH(3)|BYTES_SH(2)|DOSWAP_SH(1))
+
#endif
// Colorspaces
@@ -1116,6 +1157,10 @@
CMSAPI cmsInt32Number CMSEXPORT cmsGetToneCurveParametricType(const cmsToneCurve* t);
CMSAPI cmsFloat64Number CMSEXPORT cmsEstimateGamma(const cmsToneCurve* t, cmsFloat64Number Precision);
+// Tone curve tabular estimation
+CMSAPI cmsUInt32Number CMSEXPORT cmsGetToneCurveEstimatedTableEntries(const cmsToneCurve* t);
+CMSAPI const cmsUInt16Number* CMSEXPORT cmsGetToneCurveEstimatedTable(const cmsToneCurve* t);
+
// Implements pipelines of multi-processing elements -------------------------------------------------------------
@@ -1128,6 +1173,7 @@
CMSAPI void CMSEXPORT cmsPipelineFree(cmsPipeline* lut);
CMSAPI cmsPipeline* CMSEXPORT cmsPipelineDup(const cmsPipeline* Orig);
+CMSAPI cmsContext CMSEXPORT cmsGetPipelineContextID(const cmsPipeline* lut);
CMSAPI cmsUInt32Number CMSEXPORT cmsPipelineInputChannels(const cmsPipeline* lut);
CMSAPI cmsUInt32Number CMSEXPORT cmsPipelineOutputChannels(const cmsPipeline* lut);
@@ -1188,10 +1234,9 @@
#define SAMPLER_INSPECT 0x01000000
// For CLUT only
-CMSAPI cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, void* Cargo, cmsUInt32Number dwFlags);
+CMSAPI cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, void* Cargo, cmsUInt32Number dwFlags);
CMSAPI cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler, void* Cargo, cmsUInt32Number dwFlags);
-
// Slicers
CMSAPI cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[],
cmsSAMPLER16 Sampler, void * Cargo);
@@ -1301,6 +1346,7 @@
// Profile sequence descriptor. Some fields come from profile sequence descriptor tag, others
// come from Profile Sequence Identifier Tag
typedef struct {
+
cmsSignature deviceMfg;
cmsSignature deviceModel;
cmsUInt64Number attributes;
@@ -1324,6 +1370,27 @@
CMSAPI cmsSEQ* CMSEXPORT cmsDupProfileSequenceDescription(const cmsSEQ* pseq);
CMSAPI void CMSEXPORT cmsFreeProfileSequenceDescription(cmsSEQ* pseq);
+// Dictionaries --------------------------------------------------------------------------------------------------------
+
+typedef struct _cmsDICTentry_struct {
+
+ struct _cmsDICTentry_struct* Next;
+
+ cmsMLU *DisplayName;
+ cmsMLU *DisplayValue;
+ wchar_t* Name;
+ wchar_t* Value;
+
+} cmsDICTentry;
+
+CMSAPI cmsHANDLE CMSEXPORT cmsDictAlloc(cmsContext ContextID);
+CMSAPI void CMSEXPORT cmsDictFree(cmsHANDLE hDict);
+CMSAPI cmsHANDLE CMSEXPORT cmsDictDup(cmsHANDLE hDict);
+
+CMSAPI cmsBool CMSEXPORT cmsDictAddEntry(cmsHANDLE hDict, const wchar_t* Name, const wchar_t* Value, const cmsMLU *DisplayName, const cmsMLU *DisplayValue);
+CMSAPI const cmsDICTentry* CMSEXPORT cmsDictGetEntryList(cmsHANDLE hDict);
+CMSAPI const cmsDICTentry* CMSEXPORT cmsDictNextEntry(const cmsDICTentry* e);
+
// Access to Profile data ----------------------------------------------------------------------------------------------
CMSAPI cmsHPROFILE CMSEXPORT cmsCreateProfilePlaceholder(cmsContext ContextID);
@@ -1336,12 +1403,18 @@
CMSAPI void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig);
CMSAPI cmsBool CMSEXPORT cmsWriteTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data);
CMSAPI cmsBool CMSEXPORT cmsLinkTag(cmsHPROFILE hProfile, cmsTagSignature sig, cmsTagSignature dest);
+CMSAPI cmsTagSignature CMSEXPORT cmsTagLinkedTo(cmsHPROFILE hProfile, cmsTagSignature sig);
// Read and write raw data
CMSAPI cmsInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* Buffer, cmsUInt32Number BufferSize);
CMSAPI cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size);
// Access header data
+#define cmsEmbeddedProfileFalse 0x00000000
+#define cmsEmbeddedProfileTrue 0x00000001
+#define cmsUseAnywhere 0x00000000
+#define cmsUseWithEmbeddedDataOnly 0x00000002
+
CMSAPI cmsUInt32Number CMSEXPORT cmsGetHeaderFlags(cmsHPROFILE hProfile);
CMSAPI void CMSEXPORT cmsGetHeaderAttributes(cmsHPROFILE hProfile, cmsUInt64Number* Flags);
CMSAPI void CMSEXPORT cmsGetHeaderProfileID(cmsHPROFILE hProfile, cmsUInt8Number* ProfileID);
@@ -1377,9 +1450,9 @@
#define LCMS_USED_AS_OUTPUT 1
#define LCMS_USED_AS_PROOF 2
-CMSAPI cmsBool CMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, cmsUInt32Number Intent, int UsedDirection);
+CMSAPI cmsBool CMSEXPORT cmsIsIntentSupported(cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number UsedDirection);
CMSAPI cmsBool CMSEXPORT cmsIsMatrixShaper(cmsHPROFILE hProfile);
-CMSAPI cmsBool CMSEXPORT cmsIsCLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent, int UsedDirection);
+CMSAPI cmsBool CMSEXPORT cmsIsCLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number UsedDirection);
// Translate form/to our notation to ICC
CMSAPI cmsColorSpaceSignature CMSEXPORT _cmsICCcolorSpace(int OurNotation);
@@ -1528,7 +1601,6 @@
#define cmsFLAGS_NOOPTIMIZE 0x0100 // Inhibit optimizations
#define cmsFLAGS_NULLTRANSFORM 0x0200 // Don't transform anyway
-
// Proofing flags
#define cmsFLAGS_GAMUTCHECK 0x1000 // Out of Gamut alarm
#define cmsFLAGS_SOFTPROOFING 0x4000 // Do softproofing
@@ -1626,14 +1698,32 @@
void * OutputBuffer,
cmsUInt32Number Size);
+CMSAPI void CMSEXPORT cmsDoTransformStride(cmsHTRANSFORM Transform,
+ const void * InputBuffer,
+ void * OutputBuffer,
+ cmsUInt32Number Size,
+ cmsUInt32Number Stride);
+
+
CMSAPI void CMSEXPORT cmsSetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
CMSAPI void CMSEXPORT cmsGetAlarmCodes(cmsUInt16Number NewAlarm[cmsMAXCHANNELS]);
// Adaptation state for absolute colorimetric intent
CMSAPI cmsFloat64Number CMSEXPORT cmsSetAdaptationState(cmsFloat64Number d);
+// Grab the ContextID from an open transform. Returns NULL if a NULL transform is passed
CMSAPI cmsContext CMSEXPORT cmsGetTransformContextID(cmsHTRANSFORM hTransform);
+// Grab the input/output formats
+CMSAPI cmsUInt32Number CMSEXPORT cmsGetTransformInputFormat(cmsHTRANSFORM hTransform);
+CMSAPI cmsUInt32Number CMSEXPORT cmsGetTransformOutputFormat(cmsHTRANSFORM hTransform);
+
+// For backwards compatibility
+CMSAPI cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
+ cmsUInt32Number InputFormat,
+ cmsUInt32Number OutputFormat);
+
+
// PostScript ColorRenderingDictionary and ColorSpaceArray ----------------------------------------------------
@@ -1677,12 +1767,15 @@
CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyStr(cmsHANDLE hIT8, const char* cProp, const char *Str);
CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyDbl(cmsHANDLE hIT8, const char* cProp, cmsFloat64Number Val);
CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyHex(cmsHANDLE hIT8, const char* cProp, cmsUInt32Number Val);
+CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char* SubKey, const char *Buffer);
CMSAPI cmsBool CMSEXPORT cmsIT8SetPropertyUncooked(cmsHANDLE hIT8, const char* Key, const char* Buffer);
CMSAPI const char* CMSEXPORT cmsIT8GetProperty(cmsHANDLE hIT8, const char* cProp);
CMSAPI cmsFloat64Number CMSEXPORT cmsIT8GetPropertyDbl(cmsHANDLE hIT8, const char* cProp);
+CMSAPI const char* CMSEXPORT cmsIT8GetPropertyMulti(cmsHANDLE hIT8, const char* Key, const char *SubKey);
CMSAPI cmsUInt32Number CMSEXPORT cmsIT8EnumProperties(cmsHANDLE hIT8, char ***PropertyNames);
+CMSAPI cmsUInt32Number CMSEXPORT cmsIT8EnumPropertyMulti(cmsHANDLE hIT8, const char* cProp, const char ***SubpropertyNames);
// Datasets
CMSAPI const char* CMSEXPORT cmsIT8GetDataRowCol(cmsHANDLE hIT8, int row, int col);
@@ -1712,10 +1805,13 @@
CMSAPI int CMSEXPORT cmsIT8EnumDataFormat(cmsHANDLE hIT8, char ***SampleNames);
CMSAPI const char* CMSEXPORT cmsIT8GetPatchName(cmsHANDLE hIT8, int nPatch, char* buffer);
+CMSAPI int CMSEXPORT cmsIT8GetPatchByName(cmsHANDLE hIT8, const char *cPatch);
// The LABEL extension
CMSAPI int CMSEXPORT cmsIT8SetTableByLabel(cmsHANDLE hIT8, const char* cSet, const char* cField, const char* ExpectedType);
+CMSAPI cmsBool CMSEXPORT cmsIT8SetIndexColumn(cmsHANDLE hIT8, const char* cSample);
+
// Formatter for double
CMSAPI void CMSEXPORT cmsIT8DefineDblFormat(cmsHANDLE hIT8, const char* Formatter);
@@ -1731,6 +1827,7 @@
// Estimate the black point
CMSAPI cmsBool CMSEXPORT cmsDetectBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags);
+CMSAPI cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags);
// Estimate total area coverage
CMSAPI cmsFloat64Number CMSEXPORT cmsDetectTAC(cmsHPROFILE hProfile);
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/lcms2_internal.h Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/lcms2_internal.h Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2011 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -75,16 +75,18 @@
# define M_LOG10E 0.434294481903251827651
#endif
-// BorlandC 5.5 is broken on that
-#ifdef __BORLANDC__
+// BorlandC 5.5, VC2003 are broken on that
+#if defined(__BORLANDC__) || (_MSC_VER < 1400) // 1400 == VC++ 8.0
#define sinf(x) (float)sin((float)x)
#define sqrtf(x) (float)sqrt((float)x)
#endif
// Alignment of ICC file format uses 4 bytes (cmsUInt32Number)
-#define _cmsSIZEOFLONGMINUS1 (sizeof(cmsUInt32Number)-1)
-#define _cmsALIGNLONG(x) (((x)+_cmsSIZEOFLONGMINUS1) & ~(_cmsSIZEOFLONGMINUS1))
+#define _cmsALIGNLONG(x) (((x)+(sizeof(cmsUInt32Number)-1)) & ~(sizeof(cmsUInt32Number)-1))
+
+// Alignment to memory pointer
+#define _cmsALIGNMEM(x) (((x)+(sizeof(void *) - 1)) & ~(sizeof(void *) - 1))
// Maximum encodeable values in floating point
#define MAX_ENCODEABLE_XYZ (1.0 + 32767.0/32768.0)
@@ -94,7 +96,7 @@
#define MAX_ENCODEABLE_ab4 (127.0)
// Maximum of channels for internal pipeline evaluation
-#define MAX_STAGE_CHANNELS 128
+#define MAX_STAGE_CHANNELS 128
// Unused parameter warning supression
#define cmsUNUSED_PARAMETER(x) ((void)x)
@@ -117,36 +119,6 @@
# endif
#endif
-// Pthreads. In windows we use the native WIN32 API instead
-#ifdef CMS_DONT_USE_PTHREADS
-typedef int LCMS_RWLOCK_T;
-# define LCMS_CREATE_LOCK(x)
-# define LCMS_FREE_LOCK(x)
-# define LCMS_READ_LOCK(x)
-# define LCMS_WRITE_LOCK(x)
-# define LCMS_UNLOCK(x)
-#else
-#ifdef CMS_IS_WINDOWS_
-# ifndef WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-# endif
-# include <windows.h>
- typedef CRITICAL_SECTION LCMS_RWLOCK_T;
-# define LCMS_CREATE_LOCK(x) InitializeCriticalSection((x))
-# define LCMS_FREE_LOCK(x) DeleteCriticalSection((x))
-# define LCMS_READ_LOCK(x) EnterCriticalSection((x))
-# define LCMS_WRITE_LOCK(x) EnterCriticalSection((x))
-# define LCMS_UNLOCK(x) LeaveCriticalSection((x))
-#else
-# include <pthread.h>
- typedef pthread_rwlock_t LCMS_RWLOCK_T;
-# define LCMS_CREATE_LOCK(x) pthread_rwlock_init((x), NULL)
-# define LCMS_FREE_LOCK(x) pthread_rwlock_destroy((x))
-# define LCMS_READ_LOCK(x) pthread_rwlock_rdlock((x))
-# define LCMS_WRITE_LOCK(x) pthread_rwlock_wrlock((x))
-# define LCMS_UNLOCK(x) pthread_rwlock_unlock((x))
-#endif
-#endif
// A fast way to convert from/to 16 <-> 8 bits
#define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb))
@@ -253,6 +225,8 @@
// Optimization
cmsBool _cmsRegisterOptimizationPlugin(cmsPluginBase* Plugin);
+// Transform
+cmsBool _cmsRegisterTransformPlugin(cmsPluginBase* Plugin);
// ---------------------------------------------------------------------------------------------------------
@@ -396,6 +370,7 @@
cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags);
void _cmsFreeInterpParams(cmsInterpParams* p);
+cmsBool _cmsSetInterpolationRoutine(cmsInterpParams* p);
// Curves ----------------------------------------------------------------------------------------------------------------
@@ -443,37 +418,6 @@
struct _cmsStage_struct* Next;
};
-// Data kept in "Element" member of cmsStage
-
-// Curves
-typedef struct {
- cmsUInt32Number nCurves;
- cmsToneCurve** TheCurves;
-
-} _cmsStageToneCurvesData;
-
-// Matrix
-typedef struct {
- cmsFloat64Number* Double; // floating point for the matrix
- cmsFloat64Number* Offset; // The offset
-
-} _cmsStageMatrixData;
-
-// CLUT
-typedef struct {
-
- union { // Can have only one of both representations at same time
- cmsUInt16Number* T; // Points to the table 16 bits table
- cmsFloat32Number* TFloat; // Points to the cmsFloat32Number table
-
- } Tab;
-
- cmsInterpParams* Params;
- cmsUInt32Number nEntries;
- cmsBool HasFloatValues;
-
-} _cmsStageCLutData;
-
// Special Stages (cannot be saved)
cmsStage* _cmsStageAllocLab2XYZ(cmsContext ContextID);
@@ -482,9 +426,13 @@
cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID);
cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID);
cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID);
-cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList);
+cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS);
cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels);
cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan);
+cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID);
+cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID);
+cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID);
+cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID);
// For curve set only
cmsToneCurve** _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
@@ -505,12 +453,12 @@
_cmsOPTeval16Fn Eval16Fn;
_cmsPipelineEvalFloatFn EvalFloatFn;
- _cmsOPTfreeDataFn FreeDataFn;
- _cmsOPTdupDataFn DupDataFn;
+ _cmsFreeUserDataFn FreeDataFn;
+ _cmsDupUserDataFn DupDataFn;
cmsContext ContextID; // Environment
- cmsBool SaveAs8Bits; // Implemntation-specific: save as 8 bits if possible
+ cmsBool SaveAs8Bits; // Implementation-specific: save as 8 bits if possible
};
// LUT reading & creation -------------------------------------------------------------------------------------------
@@ -573,6 +521,8 @@
// Formatters ------------------------------------------------------------------------------------------------------------
+#define cmsFLAGS_CAN_CHANGE_FORMATTER 0x02000000 // Allow change buffer format
+
cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type);
cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type);
@@ -581,21 +531,27 @@
cmsUInt32Number dwFlags);
+#ifndef CMS_NO_HALF_SUPPORT
+
+// Half float
+cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h);
+cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt);
+
+#endif
+
// Transform logic ------------------------------------------------------------------------------------------------------
struct _cmstransform_struct;
-// Full xform
-typedef void (* _cmsTransformFn)(struct _cmstransform_struct *Transform,
- const void* InputBuffer,
- void* OutputBuffer, cmsUInt32Number Size);
-
typedef struct {
- cmsUInt32Number InputFormat, OutputFormat; // Keep formats for further reference
- cmsUInt32Number StrideIn, StrideOut; // Planar support
+ // 1-pixel cache (16 bits only)
+ cmsUInt16Number CacheIn[cmsMAXCHANNELS];
+ cmsUInt16Number CacheOut[cmsMAXCHANNELS];
-} cmsFormatterInfo;
+} _cmsCACHE;
+
+
// Transformation
typedef struct _cmstransform_struct {
@@ -612,17 +568,13 @@
cmsFormatterFloat FromInputFloat;
cmsFormatterFloat ToOutputFloat;
- // 1-pixel cache (16 bits only)
- cmsUInt16Number CacheIn[cmsMAXCHANNELS];
- cmsUInt16Number CacheOut[cmsMAXCHANNELS];
+ // 1-pixel cache seed for zero as input (16 bits, read only)
+ _cmsCACHE Cache;
- // Semaphor for cache
- LCMS_RWLOCK_T rwlock;
-
- // A MPE LUT holding the full (optimized) transform
+ // A Pipeline holding the full (optimized) transform
cmsPipeline* Lut;
- // A MPE LUT holding the gamut check. It goes from the input space to bilevel
+ // A Pipeline holding the gamut check. It goes from the input space to bilevel
cmsPipeline* GamutCheck;
// Colorant tables
@@ -645,6 +597,10 @@
// An id that uniquely identifies the running context. May be null.
cmsContext ContextID;
+ // A user-defined pointer that can be used to store data for transform plug-ins
+ void* UserData;
+ _cmsFreeUserDataFn FreeUserData;
+
} _cmsTRANSFORM;
// --------------------------------------------------------------------------------------------------
--- a/jdk/src/share/native/sun/java2d/cmm/lcms/lcms2_plugin.h Thu Nov 01 14:12:21 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/cmm/lcms/lcms2_plugin.h Fri Nov 02 17:32:30 2012 -0700
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------------
//
// Little Color Management System
-// Copyright (c) 1998-2010 Marti Maria Saguer
+// Copyright (c) 1998-2011 Marti Maria Saguer
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the "Software"),
@@ -144,6 +144,7 @@
cmsContext ContextID;
cmsUInt32Number UsedSpace;
+ cmsUInt32Number ReportedSize;
char PhysicalFile[cmsMAX_PATH];
cmsUInt32Number (* Read)(struct _cms_io_handler* iohandler, void *Buffer,
@@ -159,7 +160,7 @@
// Endianess adjust functions
CMSAPI cmsUInt16Number CMSEXPORT _cmsAdjustEndianess16(cmsUInt16Number Word);
CMSAPI cmsUInt32Number CMSEXPORT _cmsAdjustEndianess32(cmsUInt32Number Value);
-CMSAPI void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number QWord);
+CMSAPI void CMSEXPORT _cmsAdjustEndianess64(cmsUInt64Number* Result, cmsUInt64Number* QWord);
// Helper IO functions
CMSAPI cmsBool CMSEXPORT _cmsReadUInt8Number(cmsIOHANDLER* io, cmsUInt8Number* n);
@@ -175,7 +176,7 @@
CMSAPI cmsBool CMSEXPORT _cmsWriteUInt16Number(cmsIOHANDLER* io, cmsUInt16Number n);
CMSAPI cmsBool CMSEXPORT _cmsWriteUInt32Number(cmsIOHANDLER* io, cmsUInt32Number n);
CMSAPI cmsBool CMSEXPORT _cmsWriteFloat32Number(cmsIOHANDLER* io, cmsFloat32Number n);
-CMSAPI cmsBool CMSEXPORT _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number n);
+CMSAPI cmsBool CMSEXPORT _cmsWriteUInt64Number(cmsIOHANDLER* io, cmsUInt64Number* n);
CMSAPI cmsBool CMSEXPORT _cmsWrite15Fixed16Number(cmsIOHANDLER* io, cmsFloat64Number n);
CMSAPI cmsBool CMSEXPORT _cmsWriteXYZNumber(cmsIOHANDLER* io, const cmsCIEXYZ* XYZ);
CMSAPI cmsBool CMSEXPORT _cmsWriteUInt16Array(cmsIOHANDLER* io, cmsUInt32Number n, const cmsUInt16Number* Array);
@@ -209,6 +210,11 @@
CMSAPI void CMSEXPORT _cmsEncodeDateTimeNumber(cmsDateTimeNumber *Dest, const struct tm *Source);
CMSAPI void CMSEXPORT _cmsDecodeDateTimeNumber(const cmsDateTimeNumber *Source, struct tm *Dest);
+//----------------------------------------------------------------------------------------------------------
+
+// Shared callbacks for user data
+typedef void (* _cmsFreeUserDataFn)(cmsContext ContextID, void* Data);
+typedef void* (* _cmsDupUserDataFn)(cmsContext ContextID, const void* Data);
//----------------------------------------------------------------------------------------------------------
@@ -224,6 +230,7 @@
#define cmsPluginRenderingIntentSig 0x696E7448 // 'intH'
#define cmsPluginMultiProcessElementSig 0x6D706548 // 'mpeH'
#define cmsPluginOptimizationSig 0x6F707448 // 'optH'
+#define cmsPluginTransformSig 0x7A666D48 // 'xfmH'
typedef struct _cmsPluginBaseStruct {
@@ -414,8 +421,9 @@
void (* FreePtr)(struct _cms_typehandler_struct* self,
void *Ptr);
- // The calling thread
- cmsContext ContextID;
+ // Additional parameters used by the calling thread
+ cmsContext ContextID;
+ cmsUInt32Number ICCVersion;
} cmsTagTypeHandler;
@@ -513,6 +521,39 @@
} cmsPluginMultiProcessElement;
+
+// Data kept in "Element" member of cmsStage
+
+// Curves
+typedef struct {
+ cmsUInt32Number nCurves;
+ cmsToneCurve** TheCurves;
+
+} _cmsStageToneCurvesData;
+
+// Matrix
+typedef struct {
+ cmsFloat64Number* Double; // floating point for the matrix
+ cmsFloat64Number* Offset; // The offset
+
+} _cmsStageMatrixData;
+
+// CLUT
+typedef struct {
+
+ union { // Can have only one of both representations at same time
+ cmsUInt16Number* T; // Points to the table 16 bits table
+ cmsFloat32Number* TFloat; // Points to the cmsFloat32Number table
+
+ } Tab;
+
+ cmsInterpParams* Params;
+ cmsUInt32Number nEntries;
+ cmsBool HasFloatValues;
+
+} _cmsStageCLutData;
+
+
//----------------------------------------------------------------------------------------------------------
// Optimization. Using this plug-in, additional optimization strategies may be implemented.
// The function should return TRUE if any optimization is done on the LUT, this terminates
@@ -523,9 +564,6 @@
register cmsUInt16Number Out[],
register const void* Data);
-typedef void (* _cmsOPTfreeDataFn)(cmsContext ContextID, void* Data);
-typedef void* (* _cmsOPTdupDataFn)(cmsContext ContextID, const void* Data);
-
typedef cmsBool (* _cmsOPToptimizeFn)(cmsPipeline** Lut,
cmsUInt32Number Intent,
@@ -539,8 +577,8 @@
CMSAPI void CMSEXPORT _cmsPipelineSetOptimizationParameters(cmsPipeline* Lut,
_cmsOPTeval16Fn Eval16,
void* PrivateData,
- _cmsOPTfreeDataFn FreePrivateDataFn,
- _cmsOPTdupDataFn DupPrivateDataFn);
+ _cmsFreeUserDataFn FreePrivateDataFn,
+ _cmsDupUserDataFn DupPrivateDataFn);
typedef struct {
cmsPluginBase base;
@@ -551,6 +589,39 @@
} cmsPluginOptimization;
//----------------------------------------------------------------------------------------------------------
+// Full xform
+typedef void (* _cmsTransformFn)(struct _cmstransform_struct *CMMcargo,
+ const void* InputBuffer,
+ void* OutputBuffer,
+ cmsUInt32Number Size,
+ cmsUInt32Number Stride);
+
+typedef cmsBool (* _cmsTransformFactory)(_cmsTransformFn* xform,
+ void** UserData,
+ _cmsFreeUserDataFn* FreePrivateDataFn,
+ cmsPipeline** Lut,
+ cmsUInt32Number* InputFormat,
+ cmsUInt32Number* OutputFormat,
+ cmsUInt32Number* dwFlags);
+
+
+// Retrieve user data as specified by the factory
+CMSAPI void CMSEXPORT _cmsSetTransformUserData(struct _cmstransform_struct *CMMcargo, void* ptr, _cmsFreeUserDataFn FreePrivateDataFn);
+CMSAPI void * CMSEXPORT _cmsGetTransformUserData(struct _cmstransform_struct *CMMcargo);
+
+
+// Retrieve formatters
+CMSAPI void CMSEXPORT _cmsGetTransformFormatters16 (struct _cmstransform_struct *CMMcargo, cmsFormatter16* FromInput, cmsFormatter16* ToOutput);
+CMSAPI void CMSEXPORT _cmsGetTransformFormattersFloat(struct _cmstransform_struct *CMMcargo, cmsFormatterFloat* FromInput, cmsFormatterFloat* ToOutput);
+
+typedef struct {
+ cmsPluginBase base;
+
+ // Transform entry point
+ _cmsTransformFactory Factory;
+
+} cmsPluginTransform;
+
#ifndef CMS_USE_CPP_API
# ifdef __cplusplus