From c0b89ac5bfb90835ef01573267020e42d4fe070c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 23 Aug 2015 12:17:05 +0200 Subject: Imported Upstream version 1.8.0 --- icc/icc.c | 217 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 135 insertions(+), 82 deletions(-) mode change 100644 => 100755 icc/icc.c (limited to 'icc/icc.c') diff --git a/icc/icc.c b/icc/icc.c old mode 100644 new mode 100755 index 87ce500..92611c3 --- a/icc/icc.c +++ b/icc/icc.c @@ -74,7 +74,7 @@ #endif #include "icc.h" -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(vsnprintf) #define vsnprintf _vsnprintf #define snprintf _snprintf #endif @@ -11801,7 +11801,7 @@ static int icc_check_id( return 1; } - if ((md5 = new_icmMD5(p->al)) == NULL) { + if ((md5 = new_icmMD5_a(p->al)) == NULL) { sprintf(p->err,"icc_check_id: new_icmMD5 failed"); return p->errc = 3; } @@ -11855,84 +11855,11 @@ static int icc_check_id( return 2; /* Didn't match */ } -/* Return the total size needed for the profile */ -/* Return 0 on error. */ -static unsigned int icc_get_size( - icc *p -) { - unsigned int i, size = 0; - -#ifdef ICM_STRICT - /* Check that the right tags etc. are present for a legal ICC profile */ - if (check_icc_legal(p) != 0) { - return 0; - } -#endif /* ICM_STRICT */ - - /* Compute the total size and tag element data offsets */ - if (p->header == NULL) { - sprintf(p->err,"icc_get_size: No header defined"); - p->errc = 1; - return 0; - } - - size = sat_add(size, p->header->get_size(p->header)); - /* Assume header is aligned */ - size = sat_addaddmul(size, 4, p->count, 12); /* Tag table length */ - size = sat_align(ALIGN_SIZE, size); - - if (size == UINT_MAX) { - sprintf(p->err,"icc_get_size: size overflow"); - return p->errc = 1; - } - - /* Reset touched flag for each tag type */ - for (i = 0; i < p->count; i++) { - if (p->data[i].objp == NULL) { - sprintf(p->err,"icc_get_size: Internal error - NULL tag element"); - p->errc = 1; - return 0; - } - p->data[i].objp->touched = 0; - } - /* Get size for each tag type, skipping links */ - for (i = 0; i < p->count; i++) { - if (p->data[i].objp->touched == 0) { /* Not alllowed for previously */ - size = sat_add(size, p->data[i].objp->get_size(p->data[i].objp)); - size = sat_align(ALIGN_SIZE, size); - p->data[i].objp->touched = 1; /* Don't account for this again */ - } - } - - return size; /* Total size needed, or UINT_MAX if overflow */ -} - void quantize3x3S15Fixed16(double targ[3], double mat[3][3], double in[3]); -/* Write the contents of the object. Return 0 on sucess, error code on failure */ -/* NOTE: fp ownership is taken even if the function fails. */ -static int icc_write_x( - icc *p, - icmFile *fp, /* File to write to */ - unsigned int of, /* File offset to write to */ - int take_fp /* NZ if icc is to take ownership of fp */ -) { - char *bp, *buf; /* tag table buffer */ - unsigned int len; - int rv = 0; - unsigned int i, size = 0; - unsigned char pbuf[ALIGN_SIZE]; - - p->fp = fp; /* Open file pointer */ - if (take_fp) - p->del_fp = 1; - p->of = of; /* Offset of ICC profile */ - - /* Compute the total size and tag element data offsets */ - if (p->header == NULL) { - sprintf(p->err,"icc_write: No header defined"); - return p->errc = 1; - } +/* Add any automatically created tags. */ +/* (Hmm. Should we remove them if they shouldn't be there ?) */ +static int icc_add_auto_tags(icc *p) { /* If we're using the ArgyllCMS 'arts' tag to record the chromatic */ /* adapation cone matrix used for the Media Relative WP Transformation, */ @@ -11940,6 +11867,7 @@ static int icc_write_x( /* Don't write it if there is to 'wtpt' tag (i.e. it's a device link) */ if (p->useArts && p->find_tag(p, icSigMediaWhitePointTag) == 0) { + int rv; icmS15Fixed16Array *artsTag; /* Make sure no 'arts' tag currently exists */ @@ -11981,6 +11909,7 @@ static int icc_write_x( /* ICCV4 style, then set the media white point tag to D50 and save */ /* the chromatic adapation matrix to the 'chad' tag. */ { + int rv; icmXYZArray *whitePointTag; icmS15Fixed16Array *chadTag; @@ -12035,6 +11964,94 @@ static int icc_write_x( whitePointTag->data[0] = icmD50; } } + return 0; +} + +/* Return the total size needed for the profile. */ +/* This will add any automatic tags such as 'arts' tag, */ +/* so the current information needs to be final enough */ +/* for the automatic tag creation to be correct. */ +/* Return 0 on error. */ +static unsigned int icc_get_size( + icc *p +) { + unsigned int i, size = 0; + + /* Ignore any errors this time */ + icc_add_auto_tags(p); + +#ifdef ICM_STRICT + /* Check that the right tags etc. are present for a legal ICC profile */ + if (check_icc_legal(p) != 0) { + return 0; + } +#endif /* ICM_STRICT */ + + /* Compute the total size and tag element data offsets */ + if (p->header == NULL) { + sprintf(p->err,"icc_get_size: No header defined"); + p->errc = 1; + return 0; + } + + size = sat_add(size, p->header->get_size(p->header)); + /* Assume header is aligned */ + size = sat_addaddmul(size, 4, p->count, 12); /* Tag table length */ + size = sat_align(ALIGN_SIZE, size); + + if (size == UINT_MAX) { + sprintf(p->err,"icc_get_size: size overflow"); + return p->errc = 1; + } + + /* Reset touched flag for each tag type */ + for (i = 0; i < p->count; i++) { + if (p->data[i].objp == NULL) { + sprintf(p->err,"icc_get_size: Internal error - NULL tag element"); + p->errc = 1; + return 0; + } + p->data[i].objp->touched = 0; + } + /* Get size for each tag type, skipping links */ + for (i = 0; i < p->count; i++) { + if (p->data[i].objp->touched == 0) { /* Not alllowed for previously */ + size = sat_add(size, p->data[i].objp->get_size(p->data[i].objp)); + size = sat_align(ALIGN_SIZE, size); + p->data[i].objp->touched = 1; /* Don't account for this again */ + } + } + + return size; /* Total size needed, or UINT_MAX if overflow */ +} + +/* Write the contents of the object. Return 0 on sucess, error code on failure */ +/* NOTE: fp ownership is taken even if the function fails. */ +static int icc_write_x( + icc *p, + icmFile *fp, /* File to write to */ + unsigned int of, /* File offset to write to */ + int take_fp /* NZ if icc is to take ownership of fp */ +) { + char *bp, *buf; /* tag table buffer */ + unsigned int len; + int rv = 0; + unsigned int i, size = 0; + unsigned char pbuf[ALIGN_SIZE]; + + if ((rv = icc_add_auto_tags(p)) != 0) + return rv; + + p->fp = fp; /* Open file pointer */ + if (take_fp) + p->del_fp = 1; + p->of = of; /* Offset of ICC profile */ + + /* Compute the total size and tag element data offsets */ + if (p->header == NULL) { + sprintf(p->err,"icc_write: No header defined"); + return p->errc = 1; + } /* Check that the right tags etc. are present for a legal ICC profile */ if ((rv = check_icc_legal(p)) != 0) { @@ -12132,7 +12149,7 @@ static int icc_write_x( icmMD5 *md5 = NULL; icmFile *ofp, *dfp = NULL; - if ((md5 = new_icmMD5(p->al)) == NULL) { + if ((md5 = new_icmMD5_a(p->al)) == NULL) { sprintf(p->err,"icc_write: new_icmMD5 failed"); p->al->free(p->al, buf); return p->errc = 2; @@ -13747,7 +13764,7 @@ void icmScale33(double out[3], double in1[3], double in0[3], double rat) { out[2] = in0[2] + (in1[2] - in0[2]) * rat; } -/* Normalise a two point vector to the given length. */ +/* Normalise a vector from 0->1 to the given length. */ /* The new location of in1[] is returned in out[]. */ /* Return nz if not normalisable */ int icmNormalize33(double out[3], double in1[3], double in0[3], double len) { @@ -13963,6 +13980,35 @@ double ve_0[3] /* Second point on line */ return 0; } +/* - - - - - - - - - - - - - - - - - - - - - - - - */ +/* Compute the closest point on a line to a point. */ +/* Return closest point and parameter value if not NULL. */ +/* Return nz if the line length is zero */ +int icmLinePointClosest(double cp[3], double *pa, + double la0[3], double la1[3], double pp[3]) { + double va[3], vp[3]; + double val; /* Vector length */ + double a; /* Parameter value */ + + icmSub3(va, la1, la0); /* Line vector */ + val = icmNorm3(va); /* Vector length */ + + if (val < 1e-12) + return 1; + + icmSub3(vp, pp, la0); /* Point vector to line base */ + + a = icmDot3(vp, va) / val; /* Normalised dist of point projected onto line */ + + if (cp != NULL) + icmBlend3(cp, la0, la1, a); + + if (pa != NULL) + *pa = a; + + return 0; +} + /* - - - - - - - - - - - - - - - - - - - - - - - - */ /* Compute the closest points between two lines a and b. */ /* Return closest points and parameter values if not NULL. */ @@ -15909,12 +15955,19 @@ static void icmMD5_get(icmMD5 *p, ORD8 chsum[16]) { /* Delete the instance */ static void icmMD5_del(icmMD5 *p) { - p->al->free(p->al, p); + icmAlloc *al = p->al; + int del_al = p->del_al; + + /* This object */ + al->free(al, p); + + if (del_al) /* We are responsible for deleting allocator */ + al->del(al); } /* Create a new MD5 checksumming object, with a reset checksum value */ /* Return it or NULL if there is an error */ -icmMD5 *new_icmMD5(icmAlloc *al) { +icmMD5 *new_icmMD5_a(icmAlloc *al) { icmMD5 *p; if ((p = (icmMD5 *)al->calloc(al,1,sizeof(icmMD5))) == NULL) -- cgit v1.2.3