summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarti Maria <info@littlecms.com>2010-11-23 16:20:09 +0100
committerMarti Maria <info@littlecms.com>2010-11-23 16:20:09 +0100
commit3cb4dac6c35c30d05c35466cfdb31ffbee5a3e80 (patch)
treeb2df388d561e70511be7822aee8cfa034fb8dda2
parentd7a604e3e5e5ea358b72c1914428c9f4b9af2c79 (diff)
downloadlcms2-3cb4dac6c35c30d05c35466cfdb31ffbee5a3e80.tar.gz
Final changes to 2.1
-rw-r--r--ChangeLog1
-rw-r--r--Projects/BorlandC_5.5/lcms2.rc6
-rw-r--r--Projects/VC2008/lcms2.rc4
-rw-r--r--Projects/VC2010/lcms2.rc4
-rw-r--r--Projects/VC2010/resource.h2
-rw-r--r--src/cmsintrp.c118
-rw-r--r--src/cmspack.c41
-rw-r--r--src/cmsxform.c2
-rw-r--r--src/lcms2.def1
-rw-r--r--utils/common/vprf.c6
-rw-r--r--utils/jpgicc/jpgicc.c211
-rw-r--r--utils/tificc/tificc.c10
12 files changed, 363 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog
index e8b9d09..d3da4ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -20,6 +20,7 @@ Fixed an issue on curve inversion
Fixed several integer overflow and other integrity checks, thanks to Chris Evans
linkicc now stores the rendering intent in the profile header
Fixed delphi interface
+Added Duotone support (Bilinear interpolation)
2.1 Maintenance release
----------------------- \ No newline at end of file
diff --git a/Projects/BorlandC_5.5/lcms2.rc b/Projects/BorlandC_5.5/lcms2.rc
index 23b0d15..960d4ee 100644
--- a/Projects/BorlandC_5.5/lcms2.rc
+++ b/Projects/BorlandC_5.5/lcms2.rc
@@ -1,8 +1,8 @@
1 VERSIONINFO
-FILEVERSION 2, 0, 0, 0
-PRODUCTVERSION 2, 0, 0, 0
+FILEVERSION 2, 1, 0, 0
+PRODUCTVERSION 2, 1, 0, 0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
{
@@ -12,7 +12,7 @@ FILETYPE VFT_DLL
{
VALUE "CompanyName", "Marti Maria\000\000"
VALUE "FileDescription", "lcms color engine\000"
- VALUE "FileVersion", "2.00\000\000"
+ VALUE "FileVersion", "2.01\000\000"
VALUE "InternalName", "lcms\000"
VALUE "LegalCopyright", "Copyright © Marti Maria 2010\000\000"
VALUE "OriginalFilename", "lcms.dll\000"
diff --git a/Projects/VC2008/lcms2.rc b/Projects/VC2008/lcms2.rc
index 8fc7aa0..fa98520 100644
--- a/Projects/VC2008/lcms2.rc
+++ b/Projects/VC2008/lcms2.rc
@@ -30,8 +30,8 @@ LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_MODERN
//
1 VERSIONINFO
- FILEVERSION 2,0,0,0
- PRODUCTVERSION 2,0,0,0
+ FILEVERSION 2,1,0,0
+ PRODUCTVERSION 2,1,0,0
FILEFLAGSMASK 0x0L
#ifdef _DEBUG
FILEFLAGS 0x1L
diff --git a/Projects/VC2010/lcms2.rc b/Projects/VC2010/lcms2.rc
index 8fc7aa0..fa98520 100644
--- a/Projects/VC2010/lcms2.rc
+++ b/Projects/VC2010/lcms2.rc
@@ -30,8 +30,8 @@ LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_MODERN
//
1 VERSIONINFO
- FILEVERSION 2,0,0,0
- PRODUCTVERSION 2,0,0,0
+ FILEVERSION 2,1,0,0
+ PRODUCTVERSION 2,1,0,0
FILEFLAGSMASK 0x0L
#ifdef _DEBUG
FILEFLAGS 0x1L
diff --git a/Projects/VC2010/resource.h b/Projects/VC2010/resource.h
index 344dcda..a989cba 100644
--- a/Projects/VC2010/resource.h
+++ b/Projects/VC2010/resource.h
@@ -1,6 +1,6 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
-// Used by lcms.rc
+// Used by lcms2.rc
//
// Next default values for new objects
diff --git a/src/cmsintrp.c b/src/cmsintrp.c
index 5b35e87..a6e9994 100644
--- a/src/cmsintrp.c
+++ b/src/cmsintrp.c
@@ -26,7 +26,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
@@ -289,6 +289,116 @@ void Eval1InputFloat(const cmsFloat32Number Value[],
}
}
+// 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
@@ -1256,6 +1366,12 @@ cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cm
}
break;
+ case 2: // Duotone
+ if (IsFloat)
+ Interpolation.LerpFloat = BilinearInterpFloat;
+ else
+ Interpolation.Lerp16 = BilinearInterp16;
+ break;
case 3: // RGB et al
diff --git a/src/cmspack.c b/src/cmspack.c
index aa6e21f..196afa9 100644
--- a/src/cmspack.c
+++ b/src/cmspack.c
@@ -330,40 +330,41 @@ cmsUInt8Number* UnrollLabV2_16(register _cmsTRANSFORM* info,
return accum;
}
-
-
-// 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
+ wIn[0] = FROM_8_TO_16(*accum); accum++; // ch1
+ wIn[1] = FROM_8_TO_16(*accum); accum++; // ch2
return accum;
}
+
+
+
+// Monochrome duplicates L into RGB for null-transforms
static
-cmsUInt8Number* Unroll2ByteSwapFirst(register _cmsTRANSFORM* info,
+cmsUInt8Number* Unroll1Byte(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
return accum;
}
-// Monochrome duplicates L into RGB for null-transforms
static
-cmsUInt8Number* Unroll1Byte(register _cmsTRANSFORM* info,
+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;
}
@@ -631,23 +632,12 @@ cmsUInt8Number* Unroll2Words(register _cmsTRANSFORM* info,
register cmsUInt8Number* accum,
register cmsUInt32Number Stride)
{
- wIn[0] = wIn[1] = wIn[2] = *(cmsUInt16Number*) accum; accum+= 2; // L
- wIn[3] = *(cmsUInt16Number*) accum; accum += 2; // alpha
+ wIn[0] = *(cmsUInt16Number*) accum; accum += 2; // ch1
+ wIn[1] = *(cmsUInt16Number*) accum; accum += 2; // ch2
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
-
- return accum;
-}
// This is a conversion of Lab double to 16 bits
static
@@ -2245,11 +2235,10 @@ static cmsFormatters16 InputFormatters16[] = {
{ 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 },
@@ -2275,8 +2264,6 @@ static cmsFormatters16 InputFormatters16[] = {
{ 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},
diff --git a/src/cmsxform.c b/src/cmsxform.c
index a7742e6..7f5cc94 100644
--- a/src/cmsxform.c
+++ b/src/cmsxform.c
@@ -788,7 +788,7 @@ cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
BytesPerPixelInput = T_BYTES(xform ->InputFormat);
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");
+ cmsSignalError(xform ->ContextID, cmsERROR_NOT_SUITABLE, "cmsChangeBuffersFormat works only on transforms created originally with at least 16 bits of precision");
return FALSE;
}
diff --git a/src/lcms2.def b/src/lcms2.def
index e5ed7f4..d407502 100644
--- a/src/lcms2.def
+++ b/src/lcms2.def
@@ -297,3 +297,4 @@ cmsXYZ2xyY = cmsXYZ2xyY
cmsXYZEncoded2Float = cmsXYZEncoded2Float
cmsSliceSpace16 = cmsSliceSpace16
cmsSliceSpaceFloat = cmsSliceSpaceFloat
+cmsChangeBuffersFormat = cmsChangeBuffersFormat
diff --git a/utils/common/vprf.c b/utils/common/vprf.c
index 7c0ed35..b16048c 100644
--- a/utils/common/vprf.c
+++ b/utils/common/vprf.c
@@ -266,6 +266,9 @@ int PixelTypeFromChanCount(int ColorChannels)
{
switch (ColorChannels) {
+ case 1: return PT_GRAY;
+ case 2: return PT_MCH2;
+ case 3: return PT_MCH3;
case 4: return PT_CMYK;
case 5: return PT_MCH5;
case 6: return PT_MCH6;
@@ -303,6 +306,9 @@ int ChanCountFromPixelType(int ColorChannels)
case PT_YCbCr: return 3;
case PT_CMYK: return 4 ;
+ case PT_MCH2: return 2 ;
+ case PT_MCH3: return 3 ;
+ case PT_MCH4: return 4 ;
case PT_MCH5: return 5 ;
case PT_MCH6: return 6 ;
case PT_MCH7: return 7 ;
diff --git a/utils/jpgicc/jpgicc.c b/utils/jpgicc/jpgicc.c
index fc683de..18b23a1 100644
--- a/utils/jpgicc/jpgicc.c
+++ b/utils/jpgicc/jpgicc.c
@@ -36,6 +36,7 @@ static cmsBool IgnoreEmbedded = FALSE;
static cmsBool GamutCheck = FALSE;
static cmsBool lIsITUFax = FALSE;
static cmsBool lIsPhotoshopApp13 = FALSE;
+static cmsBool lIsEXIF;
static cmsBool lIsDeviceLink = FALSE;
static cmsBool EmbedProfile = FALSE;
@@ -66,6 +67,7 @@ static struct my_error_mgr {
} ErrorHandler;
+cmsUInt16Number Alarm[4] = {128,128,128,0};
// Out of mem
static
@@ -354,6 +356,187 @@ cmsBool HandlePhotoshopAPP13(jpeg_saved_marker_ptr ptr)
}
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+typedef unsigned int uint32_t;
+
+#define INTEL_BYTE_ORDER 0x4949
+#define XRESOLUTION 0x011a
+#define YRESOLUTION 0x011b
+#define RESOLUTION_UNIT 0x128
+
+// Read a 16-bit word
+static
+uint16_t read16(uint8_t* arr, int pos, int swapBytes)
+{
+ uint8_t b1 = arr[pos];
+ uint8_t b2 = arr[pos+1];
+
+ return (swapBytes) ? ((b2 << 8) | b1) : ((b1 << 8) | b2);
+}
+
+
+// Read a 32-bit word
+static
+uint32_t read32(uint8_t* arr, int pos, int swapBytes)
+{
+
+ if(!swapBytes) {
+
+ return (arr[pos] << 24) |
+ (arr[pos+1] << 16) |
+ (arr[pos+2] << 8) |
+ arr[pos+3];
+ }
+
+ return arr[pos] |
+ (arr[pos+1] << 8) |
+ (arr[pos+2] << 16) |
+ (arr[pos+3] << 24);
+}
+
+
+
+static
+int read_tag(uint8_t* arr, int pos, int swapBytes, void* dest)
+{
+ // Format should be 5 over here (rational)
+ uint32_t format = read16(arr, pos + 2, swapBytes);
+ // Components should be 1
+ uint32_t components = read32(arr, pos + 4, swapBytes);
+ // Points to the value
+ uint32_t offset;
+
+ // sanity
+ if (components != 1) return 0;
+
+ if (format == 3)
+ offset = pos + 8;
+ else
+ offset = read32(arr, pos + 8, swapBytes);
+
+ switch (format) {
+
+ case 5: // Rational
+ {
+ double num = read32(arr, offset, swapBytes);
+ double den = read32(arr, offset + 4, swapBytes);
+ *(double *) dest = num / den;
+ }
+ break;
+
+ case 3: // uint 16
+ *(int*) dest = read16(arr, offset, swapBytes);
+ break;
+
+ default: return 0;
+ }
+
+ return 1;
+}
+
+
+
+// Handler for EXIF data
+static
+ cmsBool HandleEXIF(struct jpeg_decompress_struct* cinfo)
+{
+ jpeg_saved_marker_ptr ptr;
+ uint32_t ifd_ofs;
+ int pos = 0, swapBytes = 0;
+ uint32_t i, numEntries;
+ double XRes = -1, YRes = -1;
+ int Unit = 2; // Inches
+
+
+ for (ptr = cinfo ->marker_list; ptr; ptr = ptr ->next) {
+
+ if ((ptr ->marker == JPEG_APP0+1) && ptr ->data_length > 6) {
+ JOCTET FAR* data = ptr -> data;
+
+ if (memcmp(data, "Exif\0\0", 6) == 0) {
+
+ data += 6; // Skip EXIF marker
+
+ // 8 byte TIFF header
+ // first two determine byte order
+ pos = 0;
+ if (read16(data, pos, 0) == INTEL_BYTE_ORDER) {
+ swapBytes = 1;
+ }
+
+ pos += 2;
+
+ // next two bytes are always 0x002A (TIFF version)
+ pos += 2;
+
+ // offset to Image File Directory (includes the previous 8 bytes)
+ ifd_ofs = read32(data, pos, swapBytes);
+
+ // Search the directory for resolution tags
+ numEntries = read16(data, ifd_ofs, swapBytes);
+
+ for (i=0; i < numEntries; i++) {
+
+ uint32_t entryOffset = ifd_ofs + 2 + (12 * i);
+ uint32_t tag = read16(data, entryOffset, swapBytes);
+
+ switch (tag) {
+
+ case RESOLUTION_UNIT:
+ if (!read_tag(data, entryOffset, swapBytes, &Unit)) return FALSE;
+ break;
+
+ case XRESOLUTION:
+ if (!read_tag(data, entryOffset, swapBytes, &XRes)) return FALSE;
+ break;
+
+ case YRESOLUTION:
+ if (!read_tag(data, entryOffset, swapBytes, &YRes)) return FALSE;
+ break;
+
+ default:;
+ }
+
+ }
+
+ // Proceed if all found
+
+ if (XRes != -1 && YRes != -1)
+ {
+
+ // 1 = None
+ // 2 = inches
+ // 3 = cm
+
+ switch (Unit) {
+
+ case 2:
+
+ cinfo ->X_density = (UINT16) floor(XRes + 0.5);
+ cinfo ->Y_density = (UINT16) floor(YRes + 0.5);
+ break;
+
+ case 1:
+
+ cinfo ->X_density = (UINT16) floor(XRes * 2.54 + 0.5);
+ cinfo ->Y_density = (UINT16) floor(YRes * 2.54 + 0.5);
+ break;
+
+ default: return FALSE;
+ }
+
+ cinfo ->density_unit = 1; /* 1 for dots/inch, or 2 for dots/cm.*/
+
+ }
+
+
+ }
+ }
+ }
+ return FALSE;
+}
+
static
cmsBool OpenInput(const char* FileName)
@@ -426,6 +609,7 @@ cmsUInt32Number GetInputPixelType(void)
lIsITUFax = IsITUFax(Decompressor.marker_list);
lIsPhotoshopApp13 = HandlePhotoshopAPP13(Decompressor.marker_list);
+ lIsEXIF = HandleEXIF(&Decompressor);
ColorChannels = Decompressor.num_components;
extra = 0; // Alpha = None
@@ -737,8 +921,10 @@ int TransformImage(char *cDefInpProf, char *cOutProf)
}
- if (GamutCheck)
+ if (GamutCheck) {
dwFlags |= cmsFLAGS_GAMUTCHECK;
+ cmsSetAlarmCodes(Alarm);
+ }
// Take input color space
wInput = GetInputPixelType();
@@ -788,10 +974,17 @@ int TransformImage(char *cDefInpProf, char *cOutProf)
if (cProofing != NULL) {
hProof = OpenStockProfile(0, cProofing);
+ if (hProof == NULL) {
+ FatalError("Proofing profile couldn't be read.");
+ }
dwFlags |= cmsFLAGS_SOFTPROOFING;
}
}
+ if (!hIn)
+ FatalError("Input profile couldn't be read.");
+ if (!hOut)
+ FatalError("Output profile couldn't be read.");
// Assure both, input profile and input JPEG are on same colorspace
if (cmsGetColorSpace(hIn) != _cmsICCcolorSpace(T_COLORSPACE(wInput)))
@@ -813,6 +1006,7 @@ int TransformImage(char *cDefInpProf, char *cOutProf)
wOutput = ComputeOutputFormatDescriptor(wInput, OutputColorSpace);
+
xform = cmsCreateProofingTransform(hIn, wInput,
hOut, wOutput,
hProof, Intent,
@@ -839,7 +1033,7 @@ int TransformImage(char *cDefInpProf, char *cOutProf)
static
void Help(int level)
{
- fprintf(stderr, "little cms ICC profile applier for JPEG - v3.0 [LittleCMS %2.2f]\n\n", LCMS_VERSION / 1000.0);
+ fprintf(stderr, "little cms ICC profile applier for JPEG - v3.1 [LittleCMS %2.2f]\n\n", LCMS_VERSION / 1000.0);
switch(level) {
@@ -869,6 +1063,7 @@ void Help(int level)
fprintf(stderr, "%cp<profile> - Soft proof profile\n", SW);
fprintf(stderr, "%cm<0,1,2,3> - SoftProof intent\n", SW);
fprintf(stderr, "%cg - Marks out-of-gamut colors on softproof\n", SW);
+ fprintf(stderr, "%c!<r>,<g>,<b> - Out-of-gamut marker channel values\n", SW);
fprintf(stderr, "\n");
fprintf(stderr, "%cq<0..100> - Output JPEG quality\n", SW);
@@ -918,7 +1113,7 @@ void HandleSwitches(int argc, char *argv[])
{
int s;
- while ((s=xgetopt(argc,argv,"bBnNvVGgh:H:i:I:o:O:P:p:t:T:c:C:Q:q:M:m:L:l:eEs:S:")) != EOF) {
+ while ((s=xgetopt(argc,argv,"bBnNvVGgh:H:i:I:o:O:P:p:t:T:c:C:Q:q:M:m:L:l:eEs:S:!:")) != EOF) {
switch (s)
{
@@ -1015,6 +1210,14 @@ void HandleSwitches(int argc, char *argv[])
case 'S': SaveEmbedded = xoptarg;
break;
+ case '!':
+ if (sscanf(xoptarg, "%hu,%hu,%hu", &Alarm[0], &Alarm[1], &Alarm[2]) == 3) {
+ int i;
+ for (i=0; i < 3; i++) {
+ Alarm[i] = (Alarm[i] << 8) | Alarm[i];
+ }
+ }
+ break;
default:
@@ -1032,12 +1235,12 @@ int main(int argc, char* argv[])
HandleSwitches(argc, argv);
if ((argc - xoptind) != 2) {
-
Help(0);
}
OpenInput(argv[xoptind]);
OpenOutput(argv[xoptind+1]);
+
TransformImage(cInpProf, cOutProf);
diff --git a/utils/tificc/tificc.c b/utils/tificc/tificc.c
index 5615415..8a0a9a1 100644
--- a/utils/tificc/tificc.c
+++ b/utils/tificc/tificc.c
@@ -501,6 +501,9 @@ void WriteOutputTags(TIFF *out, int Colorspace, int BytesPerSample)
// Multi-ink separations
+ case PT_MCH2:
+ case PT_MCH3:
+ case PT_MCH4:
case PT_MCH5:
case PT_MCH6:
case PT_MCH7:
@@ -516,12 +519,15 @@ void WriteOutputTags(TIFF *out, int Colorspace, int BytesPerSample)
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_SEPARATED);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, nChannels);
- if (StoreAsAlpha) {
+ if (StoreAsAlpha && nChannels >= 4) {
// CMYK plus extra alpha
TIFFSetField(out, TIFFTAG_EXTRASAMPLES, nChannels - 4, Extra);
+ TIFFSetField(out, TIFFTAG_INKSET, 1);
+ TIFFSetField(out, TIFFTAG_NUMBEROFINKS, 4);
}
else {
TIFFSetField(out, TIFFTAG_INKSET, 2);
+ TIFFSetField(out, TIFFTAG_NUMBEROFINKS, nChannels);
}
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, BitsPerSample);
@@ -862,7 +868,7 @@ int TransformImage(TIFF* in, TIFF* out, const char *cDefInpProf)
static
void Help(int level)
{
- fprintf(stderr, "little cms ICC profile applier for TIFF - v6.0 [LittleCMS %2.2f]\n\n", LCMS_VERSION / 1000.0);
+ fprintf(stderr, "little cms ICC profile applier for TIFF - v6.1 [LittleCMS %2.2f]\n\n", LCMS_VERSION / 1000.0);
fflush(stderr);
switch(level) {