From 3db384424bd7398ffbb7a355cab8f15f3add009f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 2 Oct 2016 19:24:58 +0200 Subject: New upstream version 1.9.1+repack --- icc/License.txt | 22 --- icc/License4.txt | 22 +++ icc/Readme.txt | 2 +- icc/afiles | 2 +- icc/icc.c | 448 ++++++++++++++++++++++++++++++++++++++++++------------- icc/icc.h | 132 +++++++++++----- icc/iccV42.h | 2 +- icc/iccdump.c | 2 +- icc/icclu.c | 2 +- icc/iccrw.c | 2 +- icc/iccstd.c | 2 +- icc/icctest.c | 2 +- icc/log.txt | 4 + icc/lutest.c | 2 +- icc/mcheck.c | 2 +- icc/mkDispProf.c | 4 +- icc/sRGB.icm | Bin 3268 -> 3268 bytes 17 files changed, 483 insertions(+), 169 deletions(-) delete mode 100644 icc/License.txt create mode 100644 icc/License4.txt (limited to 'icc') diff --git a/icc/License.txt b/icc/License.txt deleted file mode 100644 index bd0c4f2..0000000 --- a/icc/License.txt +++ /dev/null @@ -1,22 +0,0 @@ -************************************************************************* -Copyright (c) 1997-2013 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 -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. - -************************************************************************* diff --git a/icc/License4.txt b/icc/License4.txt new file mode 100644 index 0000000..61be41a --- /dev/null +++ b/icc/License4.txt @@ -0,0 +1,22 @@ +************************************************************************* +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 +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. + +************************************************************************* 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 @@ -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 Binary files a/icc/sRGB.icm and b/icc/sRGB.icm differ -- cgit v1.2.3