summaryrefslogtreecommitdiff
path: root/icc
diff options
context:
space:
mode:
Diffstat (limited to 'icc')
-rw-r--r--icc/License4.txt (renamed from icc/License.txt)2
-rw-r--r--icc/Readme.txt2
-rw-r--r--icc/afiles2
-rw-r--r--icc/icc.c448
-rw-r--r--icc/icc.h132
-rw-r--r--icc/iccV42.h2
-rw-r--r--icc/iccdump.c2
-rw-r--r--icc/icclu.c2
-rw-r--r--icc/iccrw.c2
-rw-r--r--icc/iccstd.c2
-rw-r--r--icc/icctest.c2
-rw-r--r--icc/log.txt4
-rw-r--r--icc/lutest.c2
-rw-r--r--icc/mcheck.c2
-rw-r--r--icc/mkDispProf.c4
-rw-r--r--icc/sRGB.icmbin3268 -> 3268 bytes
16 files changed, 462 insertions, 148 deletions
diff --git a/icc/License.txt b/icc/License4.txt
index bd0c4f2..61be41a 100644
--- a/icc/License.txt
+++ b/icc/License4.txt
@@ -1,5 +1,5 @@
*************************************************************************
-Copyright (c) 1997-2013 Graeme W. Gill
+Copyright (c) 1997-2015 Graeme W. Gill
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/icc/Readme.txt b/icc/Readme.txt
index d39e9da..2b5fd53 100644
--- a/icc/Readme.txt
+++ b/icc/Readme.txt
@@ -74,7 +74,7 @@ Package contents:
icclib.zip ZIP archive of the following files
README.txt This file.
- License.txt Important! - Permissions for use of this package.
+ License4.txt Important! - Permissions for use of this package.
icc.c Library source file.
iccstd.c Library source that uses stdio and malloc system calls.
diff --git a/icc/afiles b/icc/afiles
index acb730e..3ee789a 100644
--- a/icc/afiles
+++ b/icc/afiles
@@ -1,5 +1,5 @@
Readme.txt
-License.txt
+License4.txt
todo.txt
log.txt
Jamfile
diff --git a/icc/icc.c b/icc/icc.c
index d5b72ce..b239060 100644
--- a/icc/icc.c
+++ b/icc/icc.c
@@ -10,7 +10,7 @@
* Copyright 1997 - 2013 Graeme W. Gill
*
* This material is licensed with an "MIT" free use license:-
- * see the License.txt file in this directory for licensing details.
+ * see the License4.txt file in this directory for licensing details.
*/
/*
@@ -1034,7 +1034,7 @@ unsigned int str2tag(
}
/* helper - return 1 if the string doesn't have a */
-/* null terminator within len, return 0 has null at exactly len, */
+/* null terminator within len, return 0 if it has null at exactly len, */
/* and 2 if it has null before len. */
/* Note: will return 1 if len == 0 */
static int check_null_string(char *cp, int len) {
@@ -8241,18 +8241,19 @@ static int icmTextDescription_core_read(
p->size = read_UInt32Number(bp);
bp += 4;
if (p->size > 0) {
+ int chrv;
if (bp > end || p->size > (end - bp)) {
*bpp = bp;
sprintf(icp->err,"icmTextDescription_read: Data too short to read Ascii string");
return icp->errc = 1;
}
- if ((rv = check_null_string(bp,p->size)) == 1) {
+ if ((chrv = check_null_string(bp,p->size)) == 1) {
*bpp = bp;
sprintf(icp->err,"icmTextDescription_read: ascii string is not terminated");
return icp->errc = 1;
}
#ifdef ICM_STRICT
- if (rv == 2) {
+ if (chrv == 2) {
*bpp = bp;
sprintf(icp->err,"icmTextDescription_read: ascii string is shorter than count");
return icp->errc = 1;
@@ -8263,6 +8264,9 @@ static int icmTextDescription_core_read(
}
strcpy(p->desc, bp);
bp += p->size;
+
+ if (chrv == 2)
+ p->size = strlen(bp); /* Repair string */
}
/* Read the Unicode string */
@@ -8276,20 +8280,21 @@ static int icmTextDescription_core_read(
p->ucSize = read_UInt32Number(bp);
bp += 4;
if (p->ucSize > 0) {
- ORD16 *up;
+ int chrv;
+ ORD16 *up, len;
char *tbp;
if (bp > end || p->ucSize > (end - bp)/2) {
*bpp = bp;
sprintf(icp->err,"icmTextDescription_read: Data too short to read Unicode string");
return icp->errc = 1;
}
- if ((rv = check_null_string16(bp,p->ucSize)) == 1) {
+ if ((chrv = check_null_string16(bp,p->ucSize)) == 1) {
*bpp = bp;
sprintf(icp->err,"icmTextDescription_read: Unicode string is not terminated");
return icp->errc = 1;
}
#ifdef ICM_STRICT
- if (rv == 2) {
+ if (chrv == 2) {
*bpp = bp;
sprintf(icp->err,"icmTextDescription_read: Unicode string is shorter than count");
return icp->errc = 1;
@@ -8298,10 +8303,12 @@ static int icmTextDescription_core_read(
if ((rv = p->allocate((icmBase *)p)) != 0) {
return rv;
}
- for (up = p->ucDesc, tbp = bp; tbp[0] != 0 || tbp[1] != 0; up++, tbp += 2)
+ for (len = 0, up = p->ucDesc, tbp = bp; tbp[0] != 0 || tbp[1] != 0; up++, tbp += 2, len++)
*up = read_UInt16Number(tbp);
*up = 0; /* Unicode null */
bp += p->ucSize * 2;
+ if (chrv == 2)
+ p->ucSize = len+1; /* Repair string */
}
/* Read the ScriptCode string */
@@ -8387,7 +8394,7 @@ static int icmTextDescription_write(
/* Core write the contents of the object. Return 0 on sucess, error code on failure */
static int icmTextDescription_core_write(
icmTextDescription *p,
- char **bpp /* Pointer to buffer pointer, returns next after read */
+ char **bpp /* Pointer to buffer pointer, returns next after write */
) {
icc *icp = p->icp;
char *bp = *bpp;
@@ -11728,18 +11735,20 @@ static int icc_read_x(
icmCpy3x3(p->iwpchtmx, icmWrongVonKries);
}
- p->useArts = 0; /* Don't save it if it wasn't in profile */
+ p->useArts = 0; /* Don't save it, as it wasn't in profile */
}
- p->autoWpchtmx = 0; /* It's been set on reading - don't set automatically */
+ p->wpchtmx_class = p->header->deviceClass; /* It's set for this class now */
}
- /* If this is a Display profile, check if there is a 'chad' tag, and read it */
- /* in if it exists. We will use this latter. */
+ /* If this is a Display or Output profile, check if there is a 'chad' tag, and read it */
+ /* in if it exists. We will use this latter when we interpret absolute colorimetric, */
+ /* and this also prevents auto creation of a chad tag on write if wrD/OChad is set. */
{
icmS15Fixed16Array *chadTag;
- if (p->header->deviceClass == icSigDisplayClass
+ if ((p->header->deviceClass == icSigDisplayClass
+ || p->header->deviceClass == icSigOutputClass)
&& (chadTag = (icmS15Fixed16Array *)p->read_tag(p, icSigChromaticAdaptationTag)) != NULL
&& chadTag->ttype == icSigS15Fixed16ArrayType
&& chadTag->size == 9) {
@@ -11754,12 +11763,18 @@ static int icc_read_x(
p->chadmx[2][1] = chadTag->data[7];
p->chadmx[2][2] = chadTag->data[8];
- p->chadValid = 1;
-
- p->useChad = 1; /* Use it when writing */
+ p->naturalChad = 1;
+ p->chadmxValid = 1;
}
}
+ /* It would be nice to have an option to convert 'chad' based profile */
+ /* into non-chad profiles, but this is non trivial, since the wpchtmx would */
+ /* need to be determined from the chad matrix. While this is technically */
+ /* possible (see chex.c for an attempt at this), it is not easy, and */
+ /* it's possible for the chad matrix to be a non Von Kries type transformation, */
+ /* which cannot be exactly decomposed into a cone space matrix + Von Kries scaling. */
+
return er;
}
@@ -11855,21 +11870,29 @@ static int icc_check_id(
return 2; /* Didn't match */
}
-void quantize3x3S15Fixed16(double targ[3], double mat[3][3], double in[3]);
+static void icc_setup_wpchtmx(icc *p);
+void icmQuantize3x3S15Fixed16(double targ[3], double mat[3][3], double in[3]);
/* Add any automatically created tags. */
-/* (Hmm. Should we remove them if they shouldn't be there ?) */
-static int icc_add_auto_tags(icc *p) {
+/* Modify white point value if wr is nz. (i.e. in middle of ->write()) */
+/* The 'chad' tag is only added if there is no natural 'chad' tag, */
+/* and will be remove once the write is complete. */
+static int icc_add_auto_tags(icc *p, int wr) {
/* If we're using the ArgyllCMS 'arts' tag to record the chromatic */
/* adapation cone matrix used for the Media Relative WP Transformation, */
/* create it and set it from the wpchtmx[][] matrix. */
- /* Don't write it if there is to 'wtpt' tag (i.e. it's a device link) */
+ /* Don't write it if there is no 'wtpt' tag (i.e. it's a device link) */
if (p->useArts
&& p->find_tag(p, icSigMediaWhitePointTag) == 0) {
int rv;
icmS15Fixed16Array *artsTag;
+ /* Make sure wpchtmx[][] has been set correctly for device class */
+ if (p->wpchtmx_class != p->header->deviceClass) {
+ icc_setup_wpchtmx(p);
+ }
+
/* Make sure no 'arts' tag currently exists */
if (p->delete_tag(p, icmSigAbsToRelTransSpace) != 0
&& p->errc != 2) {
@@ -11889,20 +11912,22 @@ static int icc_add_auto_tags(icc *p) {
return p->errc = 1;
}
- /* The cone matrix is assumed to be arranged conventionaly for matrix */
- /* times vector multiplication. */
- /* Consistent with ICC usage, the dimension corresponding to the matrix */
- /* rows varies least rapidly while the one corresponding to the matrix */
- /* columns varies most rapidly. */
- artsTag->data[0] = p->wpchtmx[0][0];
- artsTag->data[1] = p->wpchtmx[0][1];
- artsTag->data[2] = p->wpchtmx[0][2];
- artsTag->data[3] = p->wpchtmx[1][0];
- artsTag->data[4] = p->wpchtmx[1][1];
- artsTag->data[5] = p->wpchtmx[1][2];
- artsTag->data[6] = p->wpchtmx[2][0];
- artsTag->data[7] = p->wpchtmx[2][1];
- artsTag->data[8] = p->wpchtmx[2][2];
+ if (wr) {
+ /* The cone matrix is assumed to be arranged conventionaly for matrix */
+ /* times vector multiplication. */
+ /* Consistent with ICC usage, the dimension corresponding to the matrix */
+ /* rows varies least rapidly while the one corresponding to the matrix */
+ /* columns varies most rapidly. */
+ artsTag->data[0] = p->wpchtmx[0][0];
+ artsTag->data[1] = p->wpchtmx[0][1];
+ artsTag->data[2] = p->wpchtmx[0][2];
+ artsTag->data[3] = p->wpchtmx[1][0];
+ artsTag->data[4] = p->wpchtmx[1][1];
+ artsTag->data[5] = p->wpchtmx[1][2];
+ artsTag->data[6] = p->wpchtmx[2][0];
+ artsTag->data[7] = p->wpchtmx[2][1];
+ artsTag->data[8] = p->wpchtmx[2][2];
+ }
}
/* If this is a Display profile, and we have been told to save it in */
@@ -11914,20 +11939,22 @@ static int icc_add_auto_tags(icc *p) {
icmS15Fixed16Array *chadTag;
if (p->header->deviceClass == icSigDisplayClass
- && p->useChad
+ && p->wrDChad && !p->naturalChad
&& (whitePointTag = (icmXYZArray *)p->read_tag(p, icSigMediaWhitePointTag)) != NULL
&& whitePointTag->ttype == icSigXYZType
&& whitePointTag->size >= 1) {
/* If we've set this profile, not just read it, */
/* compute the fromAbs/chad matrix from media white point and cone matrix */
- if (!p->chadValid) {
+ if (!p->chadmxValid) {
double wp[3];
- p->chromAdaptMatrix(p, ICM_CAM_NONE, icmD50, whitePointTag->data[0], p->chadmx);
+ p->chromAdaptMatrix(p, ICM_CAM_NONE, NULL, p->chadmx,
+ icmD50, whitePointTag->data[0]);
/* Optimally quantize chad matrix to preserver white point */
icmXYZ2Ary(wp, whitePointTag->data[0]);
- quantize3x3S15Fixed16(icmD50_ary3, p->chadmx, wp);
+ icmQuantize3x3S15Fixed16(icmD50_ary3, p->chadmx, wp);
+ p->chadmxValid = 1;
}
/* Make sure no 'chad' tag currently exists */
@@ -11948,22 +11975,143 @@ static int icc_add_auto_tags(icc *p) {
sprintf(p->err,"icc_write: Allocating 'chad' tag failed");
return p->errc = 1;
}
+
+ p->tempChad = 1;
- /* Save in ICC matrix order */
- chadTag->data[0] = p->chadmx[0][0];
- chadTag->data[1] = p->chadmx[0][1];
- chadTag->data[2] = p->chadmx[0][2];
- chadTag->data[3] = p->chadmx[1][0];
- chadTag->data[4] = p->chadmx[1][1];
- chadTag->data[5] = p->chadmx[1][2];
- chadTag->data[6] = p->chadmx[2][0];
- chadTag->data[7] = p->chadmx[2][1];
- chadTag->data[8] = p->chadmx[2][2];
+ if (wr) {
+ /* Save in ICC matrix order */
+ chadTag->data[0] = p->chadmx[0][0];
+ chadTag->data[1] = p->chadmx[0][1];
+ chadTag->data[2] = p->chadmx[0][2];
+ chadTag->data[3] = p->chadmx[1][0];
+ chadTag->data[4] = p->chadmx[1][1];
+ chadTag->data[5] = p->chadmx[1][2];
+ chadTag->data[6] = p->chadmx[2][0];
+ chadTag->data[7] = p->chadmx[2][1];
+ chadTag->data[8] = p->chadmx[2][2];
+
+ /* Set 'chad' adhusted white point */
+ p->tempWP = whitePointTag->data[0];
+ whitePointTag->data[0] = icmD50;
+ }
+ }
+ }
- /* Set the media white point to D50 */
- whitePointTag->data[0] = icmD50;
+ /* If this is an Output profile with a non-standard illuminant set, */
+ /* and we have been told to save it using a 'chad' tag to represent */
+ /* the illuminant difference, then adjust the media white point tag */
+ /* for the illuminant, and change the 'chad' tag. */
+ {
+ int rv;
+ icmXYZArray *whitePointTag;
+ icmS15Fixed16Array *chadTag;
+
+ if (p->header->deviceClass == icSigOutputClass
+ && p->chadmxValid
+ && p->wrOChad && !p->naturalChad
+ && (whitePointTag = (icmXYZArray *)p->read_tag(p, icSigMediaWhitePointTag)) != NULL
+ && whitePointTag->ttype == icSigXYZType
+ && whitePointTag->size >= 1) {
+ double wp[3];
+
+ /* Make sure no 'chad' tag currently exists */
+ if (p->delete_tag(p, icSigChromaticAdaptationTag) != 0
+ && p->errc != 2) {
+ sprintf(p->err,"icc_write: Deleting existing 'chad' tag failed");
+ return p->errc = 1;
+ }
+
+ /* Add one */
+ if ((chadTag = (icmS15Fixed16Array *)p->add_tag(p, icSigChromaticAdaptationTag,
+ icSigS15Fixed16ArrayType)) == NULL) {
+ sprintf(p->err,"icc_write: Adding 'chad' tag failed");
+ return p->errc = 1;
+ }
+ chadTag->size = 9;
+ if ((rv = chadTag->allocate((icmBase *)chadTag) ) != 0) {
+ sprintf(p->err,"icc_write: Allocating 'chad' tag failed");
+ return p->errc = 1;
+ }
+
+ p->tempChad = 1;
+
+ if (wr) {
+ /* Save in ICC matrix order */
+ chadTag->data[0] = p->chadmx[0][0];
+ chadTag->data[1] = p->chadmx[0][1];
+ chadTag->data[2] = p->chadmx[0][2];
+ chadTag->data[3] = p->chadmx[1][0];
+ chadTag->data[4] = p->chadmx[1][1];
+ chadTag->data[5] = p->chadmx[1][2];
+ chadTag->data[6] = p->chadmx[2][0];
+ chadTag->data[7] = p->chadmx[2][1];
+ chadTag->data[8] = p->chadmx[2][2];
+
+ /* Transform white point to take 'chad' into account */
+ p->tempWP = whitePointTag->data[0];
+ icmXYZ2Ary(wp, whitePointTag->data[0]);
+ icmMulBy3x3(wp, p->chadmx, wp);
+ icmAry2XYZ(whitePointTag->data[0], wp);
+ }
}
}
+
+ return 0;
+}
+
+/* Restore profile after creating temporary 'chad' tag, and */
+/* modifying the white point. */
+static int icc_rem_temp_tags(icc *p) {
+
+ /* Restore profile if Display 'chad' has been temporarily added. */
+ {
+ int rv;
+ icmXYZArray *whitePointTag;
+ icmS15Fixed16Array *chadTag;
+
+ if (p->header->deviceClass == icSigDisplayClass
+ && p->tempChad && p->wrDChad && !p->naturalChad
+ && (whitePointTag = (icmXYZArray *)p->read_tag(p, icSigMediaWhitePointTag)) != NULL
+ && whitePointTag->ttype == icSigXYZType
+ && whitePointTag->size >= 1) {
+
+ /* Remove temporary 'chad' tag */
+ if (p->delete_tag(p, icSigChromaticAdaptationTag) != 0
+ && p->errc != 2) {
+ sprintf(p->err,"icc_write: Deleting temporary 'chad' tag failed");
+ return p->errc = 1;
+ }
+
+ /* Restore original white point */
+ whitePointTag->data[0] = p->tempWP;
+ }
+ }
+
+ /* Restore profile if Output 'chad' has been temporarily added. */
+ {
+ int rv;
+ icmXYZArray *whitePointTag;
+ icmS15Fixed16Array *chadTag;
+
+ if (p->header->deviceClass == icSigOutputClass
+ && p->tempChad && p->wrOChad && !p->naturalChad
+ && (whitePointTag = (icmXYZArray *)p->read_tag(p, icSigMediaWhitePointTag)) != NULL
+ && whitePointTag->ttype == icSigXYZType
+ && whitePointTag->size >= 1) {
+ double wp[3];
+
+ /* Remove temporary 'chad' tag */
+ if (p->delete_tag(p, icSigChromaticAdaptationTag) != 0
+ && p->errc != 2) {
+ sprintf(p->err,"icc_write: Deleting temporary 'chad' tag failed");
+ return p->errc = 1;
+ }
+
+ /* Restore original white point */
+ whitePointTag->data[0] = p->tempWP;
+ }
+ }
+
return 0;
}
@@ -11977,8 +12125,8 @@ static unsigned int icc_get_size(
) {
unsigned int i, size = 0;
- /* Ignore any errors this time */
- icc_add_auto_tags(p);
+ /* Add 'arts' tag and temporary 'chad' tag if so configured */
+ icc_add_auto_tags(p, 0);
#ifdef ICM_STRICT
/* Check that the right tags etc. are present for a legal ICC profile */
@@ -12039,7 +12187,8 @@ static int icc_write_x(
unsigned int i, size = 0;
unsigned char pbuf[ALIGN_SIZE];
- if ((rv = icc_add_auto_tags(p)) != 0)
+ /* Add 'arts' tag and temporary 'chad' tag and modify white point, if so configured */
+ if ((rv = icc_add_auto_tags(p, 1)) != 0)
return rv;
p->fp = fp; /* Open file pointer */
@@ -12260,6 +12409,10 @@ static int icc_write_x(
p->data[i].objp->touched = 0; /* Written it, so don't write it again. */
}
+ /* Remove any temporary 'chad' tag and restore white point */
+ if ((rv = icc_rem_temp_tags(p)) != 0)
+ return rv;
+
if (p->fp->flush(p->fp) != 0) {
sprintf(p->err,"icc_write flush() failed");
return p->errc = 1;
@@ -12372,6 +12525,10 @@ static icmBase *icc_add_tag(
p->data[p->count].objp = nob; /* Empty object */
p->count++;
+ /* Track whether we have a natural 'chad' tag */
+ if (sig == icSigChromaticAdaptationTag)
+ p->naturalChad = 1;
+
return nob;
}
@@ -12453,6 +12610,10 @@ static icmBase *icc_link_tag(
p->data[exi].objp->refcount++; /* Bump reference count on tag type */
p->count++;
+ /* Track whether we have a natural 'chad' tag */
+ if (sig == icSigChromaticAdaptationTag)
+ p->naturalChad = 1;
+
return p->data[exi].objp;
}
@@ -12657,6 +12818,12 @@ static int icc_rename_tag(
/* change its signature */
p->data[k].sig = sigNew;
+ /* Track whether we have a natural 'chad' tag */
+ if (sig == icSigChromaticAdaptationTag)
+ p->naturalChad = 0;
+ if (sigNew == icSigChromaticAdaptationTag)
+ p->naturalChad = 1;
+
return 0;
}
@@ -12715,7 +12882,6 @@ static int icc_unread_tag(
/* Delete the tag, and free the underlying tag type, */
/* if this was the last reference to it. */
-/* Note this finds the first tag with a matching signature. */
/* Returns non-zero on error: */
/* tag not found - icc->errc will contain 2 */
static int icc_delete_tag_ix(
@@ -12753,6 +12919,7 @@ static int icc_delete_tag(
icTagSignature sig /* Tag signature - may be unknown */
) {
unsigned int i;
+ int rv;
/* Search for signature */
for (i = 0; i < p->count; i++) {
@@ -12764,7 +12931,15 @@ static int icc_delete_tag(
return p->errc = 2;
}
- return icc_delete_tag_ix(p, i);
+ rv = icc_delete_tag_ix(p, i);
+
+ /* Track whether we still have a natural 'chad' tag */
+ if (rv == 0) {
+ if (sig == icSigChromaticAdaptationTag)
+ p->naturalChad = 0;
+ }
+
+ return rv;
}
/* Read all the tags into memory, including unknown types. */
@@ -14971,12 +15146,15 @@ void icmChromAdaptMatrix(
/* We're done */
}
-/* Setup the wpchtmx appropriately for creating profile */
+/* Setup the wpchtmx appropriately for creating profile. */
+/* This is called if the deviceClass has changed on a call */
+/* to ->chromAdaptMatrix(), ->get_size() or ->write(). */
static void icc_setup_wpchtmx(icc *p) {
int useBradford = 1; /* Default use Bradford */
- if (!p->autoWpchtmx)
- return; /* Reading profile has set wpchtmx[][] */
+ /* If set by reading profile or already set appropriately */
+ if (p->wpchtmx_class == p->header->deviceClass)
+ return;
/* If we should use ICC standard Wrong Von Kries for white point chromatic adapation */
if (p->header->deviceClass == icSigOutputClass
@@ -14996,49 +15174,88 @@ static void icc_setup_wpchtmx(icc *p) {
p->wpchtmx_class = p->header->deviceClass;
}
-/* icc Chromatic adaptation transform utility using */
-/* the current Absolute to Media Relative Transformation Space wpchtmx. */
-/* Return a 3x3 chromatic adaptation matrix */
+/* Clear any existing 'chad' matrix, and if Output type profile */
+/* and ARGYLL_CREATE_OUTPUT_PROFILE_WITH_CHAD set and */
+/* ill_wp != NULL, create a 'chad' matrix. */
+static void icc_set_illum(struct _icc *p, double ill_wp[3]) {
+
+ p->chadmxValid = 0; /* Calling set_illum signals profile creation, */
+ /* so discard any previous (i.e. read) chad matrix */
+
+ if (ill_wp != NULL) {
+ icmCpy3(p->illwp, ill_wp);
+ p->illwpValid = 1;
+ }
+
+ /* Is illuminant chromatic adapation chad matrix needed ? */
+ if (p->header->deviceClass == icSigOutputClass
+ && p->illwpValid
+ && p->wrOChad) {
+ double wp[3];
+ icmXYZNumber iwp;
+
+ /* Create Output illuminant 'chad' matrix */
+ icmAry2XYZ(iwp, p->illwp);
+ icmChromAdaptMatrix(ICM_CAM_BRADFORD, icmD50, iwp, p->chadmx);
+
+ /* Optimally quantize chad matrix to preserver white point */
+ icmQuantize3x3S15Fixed16(icmD50_ary3, p->chadmx, p->illwp);
+
+ p->chadmxValid = 1;
+ }
+}
+
+/* Return an overall Chromatic Adaptation Matrix for the given source and */
+/* destination white points. This will depend on the icc profiles current setup */
+/* for Abs->Rel conversion (wpchtmx[][] set to wrong Von Kries or not, whether */
+/* 'arts' tag has been read), and whether an Output profile 'chad' tag has bean read */
+/* or will be created. (i.e. on creation, assumes icc->set_illum() called). */
/* Use icmMulBy3x3(dst, mat, src) */
-/* NOTE that to transform primaries they */
-/* must be mat[XYZ][RGB] format! */
-/* NOTE that this resets the chadValid flag (i.e. we assume that if */
-/* this method gets called, that we are discarding any 'chad' tag */
-/* and creating our own chromatic adapation) */
+/* NOTE that to transform primaries they must be mat[XYZ][RGB] format! */
static void icc_chromAdaptMatrix(
icc *p,
- int flags, /* Transform given matrix flag */
- icmXYZNumber d_wp, /* Destination white point */
- icmXYZNumber s_wp, /* Source white point */
- double mat[3][3] /* Destination matrix */
+ int flags, /* ICM_CAM_NONE or ICM_CAM_MULMATRIX to mult by mat */
+ double imat[3][3], /* Optional inverse CAT matrix result */
+ double mat[3][3], /* CAT optional input if ICM_CAM_MULMATRIX & result matrix */
+ icmXYZNumber d_wp, /* Destination white point (Usually PCS D50) */
+ icmXYZNumber s_wp /* Source media absolute white point */
) {
double dst[3], src[3]; /* Source & destination white points */
double vkmat[3][3]; /* Von Kries matrix */
+ double omat[3][3]; /* Output matrix */
if (p->header->deviceClass == icMaxEnumClass) {
fprintf(stderr,"icc_chromAdaptMatrix called with no deviceClass!\n");
}
+ /* Take a copy of src/dst */
+ icmXYZ2Ary(src, s_wp);
+ icmXYZ2Ary(dst, d_wp);
+
/* See if the profile type has changed, re-evaluate wpchtmx */
if (p->wpchtmx_class != p->header->deviceClass) {
icc_setup_wpchtmx(p);
}
/* Set initial matrix to unity if creating from scratch */
- if (!(flags & ICM_CAM_MULMATRIX)) {
- icmSetUnity3x3(mat);
- }
+ if (flags & ICM_CAM_MULMATRIX)
+ icmCpy3x3(omat, mat);
+ else
+ icmSetUnity3x3(omat);
- /* Take a copy of src/dst */
- icmXYZ2Ary(src, s_wp);
- icmXYZ2Ary(dst, d_wp);
+ /* Incorporate Output chad matrix if we will be creating one */
+ if (p->header->deviceClass == icSigOutputClass
+ && p->chadmxValid) {
+ icmMulBy3x3(src, p->chadmx, src);
+ icmMul3x3(omat, p->chadmx);
+ }
/* Transform src/dst to cone space */
icmMulBy3x3(src, p->wpchtmx, src);
icmMulBy3x3(dst, p->wpchtmx, dst);
- /* Transform incoming matrix cone space */
- icmMul3x3(mat, p->wpchtmx);
+ /* Transform incoming matrix to cone space */
+ icmMul3x3(omat, p->wpchtmx);
/* Setup the Von Kries white point adaptation matrix */
vkmat[0][0] = dst[0]/src[0];
@@ -15049,14 +15266,16 @@ static void icc_chromAdaptMatrix(
vkmat[2][0] = vkmat[2][1] = 0.0;
/* Apply chromatic adaptation */
- icmMul3x3(mat, vkmat);
+ icmMul3x3(omat, vkmat);
/* Transform from con space */
- icmMul3x3(mat, p->iwpchtmx);
+ icmMul3x3(omat, p->iwpchtmx);
- p->chadValid = 0; /* Don't use this now */
+ if (mat != NULL)
+ icmCpy3x3(mat, omat);
- /* We're done */
+ if (imat != NULL)
+ icmInverse3x3(imat, omat);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - */
@@ -15143,7 +15362,7 @@ int icmRGBYxyprim2matrix(
/* the matrix and the input value is the same as */
/* the quantized matrix product. This is used to improve accuracy */
/* of 'chad' tag in computing absolute white point. */
-void quantize3x3S15Fixed16(
+void icmQuantize3x3S15Fixed16(
double targ[3], /* Target of product */
double mat[3][3], /* matrix[][] to be quantized */
double in[3] /* Input of product - must not be 0.0! */
@@ -15491,7 +15710,7 @@ void icmRec709_50_YPbPr_2_RGBd(double out[3], double in[3]) {
}
-/* Convert Rec2020 RGB' into Non-constant liminance YPbPr, or "full range YCbCr" */
+/* Convert Rec2020 RGB' into Non-constant luminance YPbPr, or "full range YCbCr" */
/* where input 0..1, output 0..1, -0.5 .. 0.5, -0.5 .. 0.5 */
/* [From the Rec2020 specification] */
void icmRec2020_NCL_RGBd_2_YPbPr(double out[3], double in[3]) {
@@ -15512,7 +15731,7 @@ void icmRec2020_NCL_RGBd_2_YPbPr(double out[3], double in[3]) {
out[2] = tt[2];
}
-/* Convert Rec2020 Non-constant liminance YPbPr into RGB' (== "full range YCbCr") */
+/* Convert Rec2020 Non-constant luminance YPbPr into RGB' (== "full range YCbCr") */
/* where input 0..1, -0.5 .. 0.5, -0.5 .. 0.5, output 0.0 .. 1 */
/* [Inverse of above] */
void icmRec2020_NCL_YPbPr_2_RGBd(double out[3], double in[3]) {
@@ -15527,7 +15746,7 @@ void icmRec2020_NCL_YPbPr_2_RGBd(double out[3], double in[3]) {
out[2] = tt[2];
}
-/* Convert Rec2020 RGB' into Constant liminance YPbPr, or "full range YCbCr" */
+/* Convert Rec2020 RGB' into Constant luminance YPbPr, or "full range YCbCr" */
/* where input 0..1, output 0..1, -0.5 .. 0.5, -0.5 .. 0.5 */
/* [From the Rec2020 specification] */
void icmRec2020_CL_RGBd_2_YPbPr(double out[3], double in[3]) {
@@ -15568,7 +15787,7 @@ void icmRec2020_CL_RGBd_2_YPbPr(double out[3], double in[3]) {
out[2] = tt[2];
}
-/* Convert Rec2020 Constant liminance YPbPr into RGB' (== "full range YCbCr") */
+/* Convert Rec2020 Constant luminance YPbPr into RGB' (== "full range YCbCr") */
/* where input 0..1, -0.5 .. 0.5, -0.5 .. 0.5, output 0.0 .. 1 */
/* [Inverse of above] */
void icmRec2020_CL_YPbPr_2_RGBd(double out[3], double in[3]) {
@@ -16278,13 +16497,14 @@ struct _icmLuBase *lup
lup->blackisassumed = 0; /* The black is from the tag */
}
- /* If this is a Display profile, check if there is a 'chad' tag, and setup the */
- /* white point and toAbs/fromAbs matricies from that, so as to implement an */
+ /* If this is a Display profile, check if there is a 'chad' tag, then */
+ /* setup the white point and toAbs/fromAbs matricies from that, so as to implement an */
/* effective Absolute Colorimetric intent for such profiles. */
if (p->header->deviceClass == icSigDisplayClass
- && p->chadValid) {
+ && p->naturalChad && p->chadmxValid) {
double wp[3];
+ /* Conversion matrix is chad matrix. */
icmCpy3x3(lup->fromAbs, p->chadmx);
icmInverse3x3(lup->toAbs, lup->fromAbs);
@@ -16300,10 +16520,28 @@ struct _icmLuBase *lup
DBLLL(("computed wp %.8f %.8f %.8f\n", lup->whitePoint.X,
lup->whitePoint.Y, lup->whitePoint.Z));
+ /* If this is an Output profile, check if there is a 'chad' tag, and */
+ /* setup the toAbs/fromAbs matricies so that they include it, so as to implement an */
+ /* effective Absolute Colorimetric intent for such profiles. */
+ } else if (p->header->deviceClass == icSigOutputClass
+ && p->naturalChad && p->chadmxValid) {
+ double wp[3];
+ double ichad[3][3];
+
+ /* Convert the white point tag value backwards through the 'chad' */
+ icmXYZ2Ary(wp, lup->whitePoint);
+ icmInverse3x3(ichad, p->chadmx);
+ icmMulBy3x3(wp, ichad, wp);
+ icmAry2XYZ(lup->whitePoint, wp);
+
+ /* Create absolute <-> relative conversion matricies */
+ p->chromAdaptMatrix(p, ICM_CAM_NONE, lup->toAbs, lup->fromAbs, icmD50, lup->whitePoint);
+ DBLLL(("toAbs and fromAbs created from 'chad' tag & WP tag\n"));
+ DBLLL(("toAbs and fromAbs created from wp %f %f %f and D50 %f %f %f\n", lup->whitePoint.X,
+ lup->whitePoint.Y, lup->whitePoint.Z, icmD50.X, icmD50.Y, icmD50.Z));
} else {
/* Create absolute <-> relative conversion matricies */
- p->chromAdaptMatrix(p, ICM_CAM_NONE, lup->whitePoint, icmD50, lup->toAbs);
- p->chromAdaptMatrix(p, ICM_CAM_NONE, icmD50, lup->whitePoint, lup->fromAbs);
+ p->chromAdaptMatrix(p, ICM_CAM_NONE, lup->toAbs, lup->fromAbs, icmD50, lup->whitePoint);
DBLLL(("toAbs and fromAbs created from wp %f %f %f and D50 %f %f %f\n", lup->whitePoint.X,
lup->whitePoint.Y, lup->whitePoint.Z, icmD50.X, icmD50.Y, icmD50.Z));
}
@@ -18935,6 +19173,7 @@ icmAlloc *al /* Memory allocator */
p->get_tac = icm_get_tac;
p->get_luobj = icc_get_luobj;
p->new_clutluobj = icc_new_icmLuLut;
+ p->set_illum = icc_set_illum;
p->chromAdaptMatrix = icc_chromAdaptMatrix;
#if defined(__IBMC__) && defined(_M_IX86)
@@ -18984,30 +19223,39 @@ icmAlloc *al /* Memory allocator */
for (i = 0; i < 16; i++)
p->header->id[i] = 0;
- p->autoWpchtmx = 1; /* Auto on create */
-
/* Should we use ICC standard Wrong Von Kries for */
/* white point chromatic adapation for output class ? */
if (getenv("ARGYLL_CREATE_WRONG_VON_KRIES_OUTPUT_CLASS_REL_WP") != NULL)
p->useLinWpchtmx = 1; /* Use Wrong Von Kries */
else
p->useLinWpchtmx = 0; /* Use Bradford by default */
- p->wpchtmx_class = icMaxEnumClass; /* Not set yet */
+ p->wpchtmx_class = icMaxEnumClass; /* Not set yet - auto set on create. */
/* Default to saving ArgyllCMS private 'arts' tag (if appropriate type of */
/* profile) to make white point chromatic adapation explicit. */
p->useArts = 1;
/* Should we create a V4 style Display profile with D50 media white point */
- /* tag and 'chad' tag ? */
+ /* tag and 'chad' tag ? - or - */
+ /* Should we create an Output profile using a 'chad' tag if it uses */
+ /* a non-standard illuminant ? */
if (getenv("ARGYLL_CREATE_DISPLAY_PROFILE_WITH_CHAD") != NULL)
- p->useChad = 1; /* Mark Media WP as D50 and put absolute to relative */
- /* transform matrix in 'chad' tag. */
+ p->wrDChad = 1; /* For Display profile mark media WP as D50 and put */
+ /* absolute to relative transform matrix in 'chad' tag. */
+ else
+ p->wrDChad = 0; /* No by default - use Bradford and store real Media WP */
+
+ /* Should we create an Output profile using a 'chad' tag if it uses */
+ /* a non-standard illuminant ? */
+ if (getenv("ARGYLL_CREATE_OUTPUT_PROFILE_WITH_CHAD") != NULL)
+ p->wrOChad = 1; /* For Output profile, put illuminant to D50 Bradford */
+ /* matrix in 'chad' tag, and transform real WP by it. */
else
- p->useChad = 0; /* No by default - use Bradford and store real Media WP */
+ p->wrOChad = 0; /* No by default - Media WP inclues effect of illuminant. */
/* Set a default wpchtmx in case the profile being read or written */
/* doesn't use a white point (i.e., it's a device link) */
+ /* This will be reset if the wpchtmx_class gets changed. */
if (!p->useLinWpchtmx) {
icmCpy3x3(p->wpchtmx, icmBradford);
icmInverse3x3(p->iwpchtmx, p->wpchtmx);
diff --git a/icc/icc.h b/icc/icc.h
index 36ec73a..e0bf88e 100644
--- a/icc/icc.h
+++ b/icc/icc.h
@@ -11,7 +11,7 @@
* Copyright 1997 - 2013 Graeme W. Gill
*
* This material is licensed with an "MIT" free use license:-
- * see the License.txt file in this directory for licensing details.
+ * see the License4.txt file in this directory for licensing details.
*/
/* We can get some subtle errors if certain headers aren't included */
@@ -30,8 +30,8 @@
/* Version of icclib release */
-#define ICCLIB_VERSION 0x020020
-#define ICCLIB_VERSION_STR "2.20"
+#define ICCLIB_VERSION 0x020021
+#define ICCLIB_VERSION_STR "2.21"
#undef ENABLE_V4 /* V4 is not fully implemented */
@@ -74,14 +74,16 @@
/* so long shouldn't really be used in any code.... */
/* (duplicated in icc.h) */
-/* Use __LP64__ as cross platform 64 bit pointer #define */
-#if !defined(__LP64__) && defined(_WIN64)
-# define __LP64__ 1
+/* Use __P64__ as cross platform 64 bit pointer #define */
+#if defined(__LP64__) || defined(__ILP64__) || defined(__LLP64__) || defined(_WIN64)
+# define __P64__ 1
#endif
#ifndef ORD32 /* If not defined elsewhere */
-#if (__STDC_VERSION__ >= 199901L) /* C99 */
+#if (__STDC_VERSION__ >= 199901L) /* C99 */ \
+ || defined(_STDINT_H_) || defined(_STDINT_H) \
+ || defined(_SYS_TYPES_H)
#include <stdint.h>
@@ -100,7 +102,11 @@
#define CF64PREC "LL" /* Constant precision specifier */
#ifndef ATTRIBUTE_NORETURN
-# define ATTRIBUTE_NORETURN __declspec(noreturn)
+# ifdef _MSC_VER
+# define ATTRIBUTE_NORETURN __declspec(noreturn)
+# else
+# define ATTRIBUTE_NORETURN __attribute__((noreturn))
+# endif
#endif
#else /* !__STDC_VERSION__ */
@@ -141,7 +147,7 @@
#define ORD32 unsigned int /* 32 bit unsigned */
#ifdef __GNUC__
-# ifdef __LP64__ /* long long could be 128 bit */
+# ifdef __LP64__ /* long long could be 128 bit ? */
# define INR64 long /* 64 bit signed - not used in icclib */
# define ORD64 unsigned long /* 64 bit unsigned - not used in icclib */
# define PF64PREC "l" /* printf format precision specifier */
@@ -1493,15 +1499,30 @@ struct _icc {
int (*delete_tag)(struct _icc *p, icTagSignature sig);
/* Returns 0 if deleted OK */
int (*check_id)(struct _icc *p, ORD8 *id); /* Returns 0 if ID is OK, 1 if not present etc. */
- double (*get_tac)(struct _icc *p, double *chmax, /* Returns total ink limit and channel maximums */
- void (*calfunc)(void *cntx, double *out, double *in), void *cntx);
- /* optional cal. lookup */
- void (*chromAdaptMatrix)(struct _icc *p, int flags, icmXYZNumber d_wp,
- icmXYZNumber s_wp, double mat[3][3]);
- /* Chromatic transform function that uses icc */
- /* Absolute to Media Relative Transformation Space matrix */
- /* Set header->deviceClass before calling this! */
-
+ double (*get_tac)(struct _icc *p, double *chmax,
+ void (*calfunc)(void *cntx, double *out, double *in), void *cntx);
+ /* Returns total ink limit and channel maximums */
+ /* calfunc is optional. */
+ void (*set_illum)(struct _icc *p, double ill_wp[3]);
+ /* Clear any existing 'chad' matrix, and if Output type profile */
+ /* and ARGYLL_CREATE_OUTPUT_PROFILE_WITH_CHAD set and */
+ /* ill_wp != NULL, create a 'chad' matrix. */
+ void (*chromAdaptMatrix)(struct _icc *p, int flags, double imat[3][3],
+ double mat[3][3], icmXYZNumber d_wp, icmXYZNumber s_wp);
+ /* Return an overall Chromatic Adaptation Matrix */
+ /* for the given source and destination white points. */
+ /* This will depened on the icc profiles current setup */
+ /* for Abs->Rel conversion (wpchtmx[][] set to wrong Von */
+ /* Kries or not, whether 'arts' tag has been read), and */
+ /* whether an Output profile 'chad' tag has bean read */
+ /* or will be created. (i.e. on writing assumes */
+ /* icc->set_illum() called or not). */
+ /* Set header->deviceClass before calling this! */
+ /* ICM_CAM_NONE or ICM_CAM_MULMATRIX to mult by mat. */
+ /* Return invers of matrix if imat != NULL. */
+ /* Use icmMulBy3x3(dst, mat, src). */
+ /* NOTE that to transform primaries they */
+ /* must be mat[XYZ][RGB] format! */
/* Get a particular color conversion function */
icmLuBase * (*get_luobj) (struct _icc *p,
@@ -1531,27 +1552,57 @@ struct _icc {
int errc; /* Error code */
int warnc; /* Warning code */
+ /* - - - - - - - - tweaks - - - - - - - */
int allowclutPoints256; /* Non standard - allow 256 res cLUT */
- int autoWpchtmx; /* Whether to automatically set wpchtmx[][] based on */
- /* the header and the state of the env override */
- /* ARGYLL_CREATE_WRONG_VON_KRIES_OUTPUT_CLASS_REL_WP. */
- /* Default true, set false on reading a profile. */
int useLinWpchtmx; /* Force Wrong Von Kries for output class (default false) */
- icProfileClassSignature wpchtmx_class; /* Class of profile wpchtmx was set for */
- double wpchtmx[3][3]; /* Absolute to Media Relative Transformation Space matrix */
+ /* Could be set by code, and is set set by */
+ /* ARGYLL_CREATE_WRONG_VON_KRIES_OUTPUT_CLASS_REL_WP env. */
+ icProfileClassSignature wpchtmx_class; /* Class of profile wpchtmx was set for. */
+ /* Set wpchtmx automatically on ->chromAdaptMatrix() */
+ /* or ->get_size() or ->write() if the profile class */
+ /* doesn't match wpchtmx_class. */
+ double wpchtmx[3][3]; /* Absolute to Media Relative Transformation Space (i.e. */
+ /* Cone Space transformation) matrix. */
double iwpchtmx[3][3]; /* Inverse of wpchtmx[][] */
/* (Default is Bradford matrix) */
- int useArts; /* Save ArgyllCMS private 'arts' tag (default yes) */
- /* (This creates 'arts' tag on writing) */
-
- int chadValid; /* nz if 'chad' tag has been read and chadmx is valid */
- double chadmx[3][3]; /* 'chad' tag matrix if read */
- int useChad; /* Create 'chad' tag for Display profile (default no) */
- /* Override with ARGYLL_CREATE_DISPLAY_PROFILE_WITH_CHAD */
- /* (This set media white point tag to D50 and */
- /* creates 'chad' tag on writing) */
-
+ int useArts; /* Save ArgyllCMS private 'arts' tag (default yes). */
+ /* This creates 'arts' tag on writing. */
+ /* This is cleared if 'arts' tag is not found on reading. */
+
+ double illwp[3]; /* Output type profile illuminant white point, */
+ /* used to create 'chad' tag if */
+ /* ARGYLL_CREATE_OUTPUT_PROFILE_WITH_CHAD is set. */
+ int illwpValid; /* illwp[] has been set. */
+
+ int naturalChad; /* nz if 'chad' tag is naturally present in the profile, */
+ /* because it was read or added. wrD/OChad will be */
+ /* ignored if this is the case. */
+
+ int chadmxValid; /* nz if 'chad' tag has been read, or created */
+ /* using ->set_illum() and chadmx is valid. */
+ double chadmx[3][3]; /* 'chad' tag matrix if read or created. */
+ /* (This is used to restore full absolute intent for */
+ /* Display and Output type profiles.) */
+
+ int wrDChad; /* Create 'chad' tag for Display profiles (default no). */
+ /* Override with ARGYLL_CREATE_DISPLAY_PROFILE_WITH_CHAD. */
+ /* On writing Display profiles this sets the media white */
+ /* point tag to D50 and creates 'chad' tag from the white */
+ /* point to D50. Ignored if naturalChad. */
+
+ int wrOChad; /* Create 'chad' tag for Output profiles (default no). */
+ /* Override with ARGYLL_CREATE_DISPLAY_PROFILE_WITH_CHAD. */
+ /* On writing an Output profile, this Creates a 'chad' */
+ /* tag frp, illwp[] to D50, and sets the white point */
+ /* tag to be the real value transformed by the */
+ /* 'chad' matrix. Ignored if naturalChad. */
+
+ int tempChad; /* nz while temporary chad tag is in place and */
+ /* white point has been modified, between */
+ /* ->get_size() to ->write() calls when wrD/OChad active. */
+ icmXYZNumber tempWP; /* Save real wp tag value here between ->get_size() */
+ /* to ->write() calls when wrD/OChad active. */
/* Private: ? */
icmAlloc *al; /* Heap allocator */
@@ -2082,7 +2133,8 @@ int icmRGBYxyprim2matrix(
/* Chromatic Adaption transform utility */
/* Return a 3x3 chromatic adaption matrix */
/* Use icmMulBy3x3(dst, mat, src) */
-/* [ use icc->chromAdaptMatrix() to use the profiles cone space matrix] */
+/* [ use icc->chromAdaptMatrix() to use the profiles cone space matrix rather */
+/* than specify a CAM ] */
#define ICM_CAM_NONE 0x0000 /* No flags */
#define ICM_CAM_BRADFORD 0x0001 /* Use Bradford sharpened response space */
@@ -2105,6 +2157,16 @@ void quantizeRGBprimsS15Fixed16(
double mat[3][3] /* matrix[RGB][XYZ] */
);
+/* Pre-round a 3x3 matrix to ensure that the product of */
+/* the matrix and the input value is the same as */
+/* the quantized matrix product. This is used to improve accuracy */
+/* of 'chad' tag in computing absolute white point. */
+void icmQuantize3x3S15Fixed16(
+ double targ[3], /* Target of product */
+ double mat[3][3], /* matrix[][] to be quantized */
+ double in[3] /* Input of product - must not be 0.0! */
+);
+
/* - - - - - - - - - - - - - - */
/* Video functions */
diff --git a/icc/iccV42.h b/icc/iccV42.h
index 2f3ec27..a84f79d 100644
--- a/icc/iccV42.h
+++ b/icc/iccV42.h
@@ -17,7 +17,7 @@
*
* Portions of this file are Copyright 2004 - 2005 Graeme W. Gill,
* This material is licensed with an "MIT" free use license:-
- * see the License.txt file in this directory for licensing details.
+ * see the License4.txt file in this directory for licensing details.
*
* Graeme Gill.
*/
diff --git a/icc/iccdump.c b/icc/iccdump.c
index 76959e7..8574258 100644
--- a/icc/iccdump.c
+++ b/icc/iccdump.c
@@ -10,7 +10,7 @@
* Copyright 1997 - 2012 Graeme W. Gill
*
* This material is licensed with an "MIT" free use license:-
- * see the License.txt file in this directory for licensing details.
+ * see the License4.txt file in this directory for licensing details.
*/
/*
diff --git a/icc/icclu.c b/icc/icclu.c
index 80126da..5c732d0 100644
--- a/icc/icclu.c
+++ b/icc/icclu.c
@@ -10,7 +10,7 @@
* Copyright 1998 - 2012 Graeme W. Gill
*
* This material is licensed with an "MIT" free use license:-
- * see the License.txt file in this directory for licensing details.
+ * see the License4.txt file in this directory for licensing details.
*/
/* TTBD:
diff --git a/icc/iccrw.c b/icc/iccrw.c
index 807c5f4..f33c164 100644
--- a/icc/iccrw.c
+++ b/icc/iccrw.c
@@ -10,7 +10,7 @@
* Copyright 1997 - 2012 Graeme W. Gill
*
* This material is licensed with an "MIT" free use license:-
- * see the License.txt file in this directory for licensing details.
+ * see the License4.txt file in this directory for licensing details.
*/
/* TTBD:
diff --git a/icc/iccstd.c b/icc/iccstd.c
index 1cb63eb..6629250 100644
--- a/icc/iccstd.c
+++ b/icc/iccstd.c
@@ -9,7 +9,7 @@
* Copyright 1997 - 2012 Graeme W. Gill
*
* This material is licensed with an "MIT" free use license:-
- * see the License.txt file in this directory for licensing details.
+ * see the License4.txt file in this directory for licensing details.
*
* These are kept in a separate file to allow them to be
* selectively ommitted from the icc library.
diff --git a/icc/icctest.c b/icc/icctest.c
index d04cc1e..647ba07 100644
--- a/icc/icctest.c
+++ b/icc/icctest.c
@@ -10,7 +10,7 @@
* Copyright 1997 - 2012 Graeme W. Gill
*
* This material is licensed with an "MIT" free use license:-
- * see the License.txt file in this directory for licensing details.
+ * see the License4.txt file in this directory for licensing details.
*/
/* TTBD:
diff --git a/icc/log.txt b/icc/log.txt
index 2e185dc..b531f5c 100644
--- a/icc/log.txt
+++ b/icc/log.txt
@@ -1,6 +1,10 @@
Change History: (See ArgyllCMS log.txt too)
+ 2.21
+ Automatically repair icmTextDescription strings have an allocation that is longer
+ than their size.
+
2.20
Add better cross compatibility with non-Argyll ICC profiles:
+ Use "wrong Von Kries" media white point adapation for non-Argyll non-display profile
diff --git a/icc/lutest.c b/icc/lutest.c
index 9bf127f..fb05ea9 100644
--- a/icc/lutest.c
+++ b/icc/lutest.c
@@ -10,7 +10,7 @@
* Copyright 1998 - 2012 Graeme W. Gill
*
* This material is licensed with an "MIT" free use license:-
- * see the License.txt file in this directory for licensing details.
+ * see the License4.txt file in this directory for licensing details.
*/
/* TTBD:
diff --git a/icc/mcheck.c b/icc/mcheck.c
index a392f31..51368ca 100644
--- a/icc/mcheck.c
+++ b/icc/mcheck.c
@@ -10,7 +10,7 @@
* Copyright 2000 - 2012 Graeme W. Gill
*
* This material is licensed with an "MIT" free use license:-
- * see the License.txt file in this directory for licensing details.
+ * see the License4.txt file in this directory for licensing details.
*/
/* TTBD:
diff --git a/icc/mkDispProf.c b/icc/mkDispProf.c
index 6878aad..b7c32c6 100644
--- a/icc/mkDispProf.c
+++ b/icc/mkDispProf.c
@@ -10,7 +10,7 @@
* Copyright 2006 - 2014 Graeme W. Gill
*
* This material is licensed with an "MIT" free use license:-
- * see the License.txt file in this directory for licensing details.
+ * see the License4.txt file in this directory for licensing details.
*
* Based on icc/lutest.c
*/
@@ -267,7 +267,7 @@ char *argv[]
/* Convert to D50 adapated */
icmAry2XYZ(white, wrgb[0]);
- wr_icco->chromAdaptMatrix(wr_icco, ICM_CAM_NONE, icmD50, white, fromAbs);
+ wr_icco->chromAdaptMatrix(wr_icco, ICM_CAM_NONE, NULL, fromAbs, icmD50, white);
icmMulBy3x3(d50m[0], fromAbs, mat[0]);
icmMulBy3x3(d50m[1], fromAbs, mat[1]);
icmMulBy3x3(d50m[2], fromAbs, mat[2]);
diff --git a/icc/sRGB.icm b/icc/sRGB.icm
index 9d33a4b..59b4507 100644
--- a/icc/sRGB.icm
+++ b/icc/sRGB.icm
Binary files differ