summaryrefslogtreecommitdiff
path: root/icc/icctest.c
diff options
context:
space:
mode:
Diffstat (limited to 'icc/icctest.c')
-rw-r--r--icc/icctest.c2393
1 files changed, 2393 insertions, 0 deletions
diff --git a/icc/icctest.c b/icc/icctest.c
new file mode 100644
index 0000000..97a3f62
--- /dev/null
+++ b/icc/icctest.c
@@ -0,0 +1,2393 @@
+
+/*
+ * International Color Consortium Format Library (icclib)
+ * Library Read/Write test and example code.
+ *
+ * Author: Graeme W. Gill
+ * Date: 1999/11/29
+ * Version: 2.15
+ *
+ * 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.
+ */
+
+/* TTBD:
+ *
+ * Fix enums to be selected randomly (ie. header)
+ *
+ * Should add test of ->delete_tag()
+ * Should add test of ->rename_tag()
+ *
+ * Add many extra comments and explanations.
+ *
+ */
+
+/*
+
+ This file is intended to serve two purposes. One
+ is to minimally test the ability of the icc library
+ to read and write all tag types. The other is as
+ a source code example of how to read and write
+ each tag type, since icc.h might otherwise take
+ some effort to understand.
+
+ Note XYZ scaling to 1.0, not 100.0
+
+ */
+
+#define NTRIALS 100
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <string.h>
+#ifdef __sun
+#include <unistd.h>
+#endif
+#include "icc.h"
+
+void error(char *fmt, ...), warning(char *fmt, ...);
+
+/* Rounded floating test numbers */
+int rand_int(int low, int high);
+unsigned int rand_o8(void), rand_o16(void), rand_o32(void);
+double rand_8f(void), rand_L8(void), rand_ab8(void);
+double rand_16f(void), rand_XYZ16(void), rand_u8f8(void), rand_L16(void), rand_ab16(void);
+double rand_u16f16(void), rand_s15f16(void);
+int dcomp(double a, double b);
+
+/* random ICC specific values */
+unsigned int rand_ScreenEncodings(void);
+unsigned int rand_DeviceAttributes(void);
+unsigned int rand_ProfileHeaderFlags(void);
+unsigned int rand_AsciiOrBinaryData(void);
+icColorSpaceSignature rand_ColorSpaceSignature(void);
+icColorSpaceSignature rand_PCS(void);
+icTechnologySignature rand_TechnologySignature(void);
+icProfileClassSignature rand_ProfileClassSignature(void);
+icPlatformSignature rand_PlatformSignature(void);
+icMeasurementFlare rand_MeasurementFlare(void);
+icMeasurementGeometry rand_MeasurementGeometry(void);
+icRenderingIntent rand_RenderingIntent(void);
+icSpotShape rand_SpotShape(void);
+icStandardObserver rand_StandardObserver(void);
+icIlluminant rand_Illuminant(void);
+
+/* declare some test functions */
+int md5_test(void);
+
+/*
+ I've split the functionality up into two pieces.
+ The main() code does the overall file write/read,
+ while the tag type code is all in the doit() function.
+ The write/read logic is all sandwiched together (distinguished
+ by the state of the mode flag), so that the code for each
+ tag type is kept adjacent.
+
+ In a real application, one wouldn't do it this way.
+*/
+
+int doit(int mode, icc *wr_icco, icc *rd_icco);
+
+int
+main(
+ int argc,
+ char *argv[]
+) {
+ char *file_name = "xxxx.icm";
+ icmFile *wr_fp, *rd_fp;
+ icc *wr_icco, *rd_icco; /* Keep object separate */
+ int rv = 0;
+ int i;
+ unsigned int offset = 0; /* File write/read offset, 0 for standard icc */
+
+ printf("ICC library regression test, V%s\n",ICCLIB_VERSION_STR);
+
+ /* Do any internal code tests. */
+
+ if (md5_test() != 0)
+ error ("MD5 checksum routine is faulty");
+
+ /* Outer loop does a number of file write/reads, */
+ /* in order to exercise random tests, and to test file offsets. */
+
+ for (i = 0; i < NTRIALS; i++) {
+ unsigned int size; /* Expected write size */
+
+ printf(".");
+ fflush(stdout);
+
+ /* -------------------------- */
+ /* Deal with writing the file */
+
+ /* Open up the file for writing */
+ if ((wr_fp = new_icmFileStd_name(file_name,"w")) == NULL)
+ error ("Write: Can't open file '%s'",file_name);
+
+ if ((wr_icco = new_icc()) == NULL)
+ error ("Write: Creation of ICC object failed");
+
+ /* Add all the tags with their tag types */
+ if ((rv = doit(0, wr_icco, NULL)) != 0)
+ error ("Write tags: %d, %s",rv,wr_icco->err);
+
+ /* Write the file (including all tags) out */
+ /* The last parameter is the offset to write the */
+ /* ICC profile into the file. For a standard ICC profile, */
+ /* this needs to be 0, but it might be non-zero if you are writing */
+ /* an embedded profile. */
+
+ /* Check that get_size() is working too. */
+ if ((size = wr_icco->get_size(wr_icco)) == 0)
+ error ("Write size: %d, %s",wr_icco->errc,wr_icco->err);
+
+ if ((rv = wr_icco->write(wr_icco,wr_fp,offset)) != 0)
+ error ("Write file: %d, %s",rv,wr_icco->err);
+
+ /* To check that get_size() is correct: */
+ {
+ icmFileStd *pp = (icmFileStd *)wr_fp; /* Cheat - Look inside icmFile */
+
+ if (fseek(pp->fp, 0, SEEK_END))
+ error ("Write: seek to EOF failed");
+ if ((unsigned int)ftell(pp->fp) != offset + size)
+ error ("Write: get_size function didn't return correct value - got %d, expected %d",
+ ftell(pp->fp),offset+size);
+ }
+
+ /*
+ Would normally call icco->free(wr_icco);
+ but leave it, so that we can verify the read.
+ */
+
+ wr_fp->del(wr_fp);
+
+ /* -------------------------- */
+ /* Deal with reading and verifying the file */
+
+ /* Open up the file for reading */
+ if ((rd_fp = new_icmFileStd_name(file_name,"r")) == NULL)
+ error ("Read: Can't open file '%s'",file_name);
+
+ if ((rd_icco = new_icc()) == NULL)
+ error ("Read: Creation of ICC object failed");
+
+ /* Read the header and tag list */
+ /* The last parameter is the offset to read the */
+ /* ICC profile from the file. For a standard ICC proifile, */
+ /* this needs to be 0, but it might be non-zero if you are writing */
+ /* an embedded profile this needs to be 0, but it might be non-zero */
+ /* if you are writing an embedded profile. */
+ if ((rv = rd_icco->read(rd_icco,rd_fp,offset)) != 0)
+ error ("Read: %d, %s",rv,rd_icco->err);
+
+ /* Read and verify all the tags and their tag types */
+ if ((rv = doit(1, wr_icco, rd_icco)) != 0)
+ error ("Read: %d, %s",rv,rd_icco->err);
+
+ /* -------- */
+ /* Clean up */
+ wr_icco->del(wr_icco);
+
+ rd_icco->del(rd_icco);
+ rd_fp->del(rd_fp);
+
+ /* choose another file offset to test */
+ offset = rand_int(0,72789);
+ }
+
+ printf("\nTest completed OK\n");
+
+ return 0;
+}
+
+/* -------------------------------------------------------------- */
+/* Internal routine checks. */
+
+/* Test the MD5 function. Return nz if fail. */
+int md5_test() {
+ int rv = 0;
+ int i, j;
+ icc *icco;
+ icmMD5 *m;
+
+ unsigned char chs1[16];
+ unsigned char chs2[16];
+
+ /* Standard RFC 1321 test cases */
+ struct {
+ char *s;
+ ORD32 sum[4];
+ } tc[] = {
+ { "", { 0xd41d8cd9, 0x8f00b204, 0xe9800998, 0xecf8427e } },
+ { "a", { 0x0cc175b9, 0xc0f1b6a8, 0x31c399e2, 0x69772661 } },
+ { "abc", { 0x90015098, 0x3cd24fb0, 0xd6963f7d, 0x28e17f72 } },
+ { "message digest", { 0xf96b697d, 0x7cb7938d, 0x525a2f31, 0xaaf161d0 } },
+ { "abcdefghijklmnopqrstuvwxyz", { 0xc3fcd3d7, 0x6192e400, 0x7dfb496c, 0xca67e13b } },
+ { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ { 0xd174ab98, 0xd277d9f5, 0xa5611c2c, 0x9f419d9f } },
+ { "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+ { 0x57edf4a2, 0x2be3c955, 0xac49da2e, 0x2107b67a } },
+ { NULL, { 0,0,0,0 } }
+ };
+
+ if ((icco = new_icc()) == NULL)
+ error ("Creation of ICC object failed");
+
+ m = new_icmMD5(icco->al);
+
+ for (i = 0; ; i++) {
+ if (tc[i].s == NULL)
+ break;
+
+ m->reset(m);
+
+ m->add(m, (unsigned char *)tc[i].s, strlen(tc[i].s));
+ m->get(m, chs2);
+
+ /* Convert reference to a byte stream */
+ chs1[0] = (tc[i].sum[0] >> 24) & 0xff,
+ chs1[1] = (tc[i].sum[0] >> 16) & 0xff,
+ chs1[2] = (tc[i].sum[0] >> 8) & 0xff,
+ chs1[3] = tc[i].sum[0] & 0xff,
+ chs1[4] = (tc[i].sum[1] >> 24) & 0xff,
+ chs1[5] = (tc[i].sum[1] >> 16) & 0xff,
+ chs1[6] = (tc[i].sum[1] >> 8) & 0xff,
+ chs1[7] = tc[i].sum[1] & 0xff,
+ chs1[8] = (tc[i].sum[2] >> 24) & 0xff,
+ chs1[9] = (tc[i].sum[2] >> 16) & 0xff,
+ chs1[10] = (tc[i].sum[2] >> 8) & 0xff,
+ chs1[11] = tc[i].sum[2] & 0xff,
+ chs1[12] = (tc[i].sum[3] >> 24) & 0xff,
+ chs1[13] = (tc[i].sum[3] >> 16) & 0xff,
+ chs1[14] = (tc[i].sum[3] >> 8) & 0xff,
+ chs1[15] = tc[i].sum[3] & 0xff;
+
+ for (j = 0; j < 16; j++) {
+ if (chs1[j] != chs2[j]) {
+ printf("MD5 check on '%s' fails at %d with:\n",tc[i].s,j);
+ printf("Sum is %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+ chs2[0], chs2[1], chs2[2], chs2[3], chs2[4], chs2[5], chs2[6], chs2[7],
+ chs2[8], chs2[9], chs2[10], chs2[11], chs2[12], chs2[13], chs2[14], chs2[15]);
+ printf("Should be %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+ chs1[0], chs1[1], chs1[2], chs1[3], chs1[4], chs1[5], chs1[6], chs1[7],
+ chs1[8], chs1[9], chs1[10], chs1[11], chs1[12], chs1[13], chs1[14], chs1[15]);
+ rv = 1;
+ break;
+ }
+ }
+
+ }
+ m->del(m);
+ icco->del(icco);
+
+ return rv;
+}
+
+/* -------------------------------------------------------------- */
+/* This is the code that inits and checks the header and tag data. */
+/* Note that to undestand this, you need a copy of the ICC profile */
+/* spec., and a copy of the icc header file (icc34.h in this code) */
+/* All items that begin "icXXX" are from the ICC generic icc34.h file, */
+/* while the items that begin "icmXXX" are machine versions of structures */
+/* that are specific to this library. */
+
+int doit(
+ int mode, /* 0 - write, 1 = read/verify */
+ icc *wr_icco, /* The write icc object */
+ icc *rd_icco /* The read icc object */
+) {
+ int rv = 0;
+
+ /* ----------- */
+ /* The header: */
+ if (mode == 0) {
+ icmHeader *wh = wr_icco->header;
+
+ /* Values that must be set before writing */
+ wh->deviceClass = icSigAbstractClass;
+ wh->colorSpace = rand_ColorSpaceSignature();
+ wh->pcs = rand_PCS();
+ wh->renderingIntent = rand_RenderingIntent();
+
+ /* Values that should be set before writing */
+ wh->manufacturer = str2tag("tst1");
+ wh->model = str2tag("1234");
+ wh->attributes.l = rand_DeviceAttributes();
+ wh->flags = rand_ProfileHeaderFlags();
+
+ /* Values that may optionally be set before writing */
+ wh->attributes.h = 0x12345678;
+ wh->creator = str2tag("tst2");
+
+ /* Values that are not normally set. Set them to non-defaults for testing */
+ wh->cmmId = str2tag("tst3");
+ wh->majv = 3; /* Default version 2.1.0 */
+ wh->minv = 2;
+ wh->bfv = 1;
+ wh->date.year = rand_int(1900,3000); /* Defaults to current date */
+ wh->date.month = rand_int(1,12);
+ wh->date.day = rand_int(1,31);
+ wh->date.hours = rand_int(0,23);
+ wh->date.minutes = rand_int(0,59);
+ wh->date.seconds = rand_int(0,59);
+ wh->platform = rand_PlatformSignature();
+ wh->illuminant.X = rand_XYZ16(); /* Defaults to D50 */
+ wh->illuminant.Y = rand_XYZ16();
+ wh->illuminant.Z = rand_XYZ16();
+ } else {
+ icmHeader *rh = rd_icco->header;
+ icmHeader *wh = wr_icco->header;
+
+ /* Check all the values */
+ rv |= (rh->deviceClass != wh->deviceClass);
+ rv |= (rh->colorSpace != wh->colorSpace);
+ rv |= (rh->pcs != wh->pcs);
+ rv |= (rh->renderingIntent != wh->renderingIntent);
+ rv |= (rh->manufacturer != wh->manufacturer);
+ rv |= (rh->model != wh->model);
+ rv |= (rh->attributes.l != wh->attributes.l);
+ rv |= (rh->attributes.h != wh->attributes.h);
+ rv |= (rh->flags != wh->flags);
+ rv |= (rh->creator != wh->creator);
+ rv |= (rh->cmmId != wh->cmmId);
+ rv |= (rh->majv != wh->majv);
+ rv |= (rh->minv != wh->minv);
+ rv |= (rh->bfv != wh->bfv);
+ rv |= (rh->date.year != wh->date.year);
+ rv |= (rh->date.month != wh->date.month);
+ rv |= (rh->date.day != wh->date.day);
+ rv |= (rh->date.hours != wh->date.hours);
+ rv |= (rh->date.minutes != wh->date.minutes);
+ rv |= (rh->date.seconds != wh->date.seconds);
+ rv |= (rh->platform != wh->platform);
+ rv |= dcomp(rh->illuminant.X, wh->illuminant.X);
+ rv |= dcomp(rh->illuminant.Y, wh->illuminant.Y);
+ rv |= dcomp(rh->illuminant.Z, wh->illuminant.Z);
+ if (rv)
+ error ("Header verify failed");
+ }
+ /* ------------- */
+ /* CrdInfo info: */
+ {
+ char *str1 = "Product Name";
+ char *str2[4] = { "Intent zero CRD Name",
+ "Intent one CRD Name",
+ "Intent two CRD Name",
+ "Intent three CRD Name" };
+ static icmCrdInfo *wo;
+ if (mode == 0) {
+ unsigned int i;
+ if ((wo = (icmCrdInfo *)wr_icco->add_tag(
+ wr_icco, icSigCrdInfoTag, icSigCrdInfoType)) == NULL)
+ return 1;
+
+ wo->ppsize = strlen(str1)+1; /* Allocated and used size of text, inc null */
+ for (i = 0; i < 4; i++)
+ wo->crdsize[i] = strlen(str2[i])+1; /* Allocated and used size of text, inc null */
+
+ wo->allocate((icmBase *)wo); /* Allocate space */
+ /* Note we could allocate and copy as we go, rather than doing them all at once. */
+
+ strcpy(wo->ppname, str1); /* Copy the text in */
+ for (i = 0; i < 4; i++)
+ strcpy(wo->crdname[i], str2[i]); /* Copy the text in */
+ } else {
+ icmCrdInfo *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmCrdInfo *)rd_icco->read_tag(rd_icco, icSigCrdInfoTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigCrdInfoType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->ppsize != wo->ppsize)
+ for (i = 0; i < 4; i++) {
+ if (ro->crdsize[i] != wo->crdsize[i])
+ error ("CrdInfo crdsize[%d] doesn't match",i);
+ }
+
+ rv |= strcmp(ro->ppname, wo->ppname);
+ for (i = 0; i < 4; i++) {
+ rv |= strcmp(ro->crdname[i], wo->crdname[i]);
+ }
+
+ if (rv)
+ error ("CrdInfo verify failed");
+ }
+ }
+ /* ---------------------- */
+ /* Curve - Linear version */
+ {
+ static icmCurve *wo;
+ if (mode == 0) {
+ if ((wo = (icmCurve *)wr_icco->add_tag(
+ wr_icco, icSigRedTRCTag, icSigCurveType)) == NULL)
+ return 1;
+
+ wo->flag = icmCurveLin; /* Linear version */
+ wo->allocate((icmBase *)wo);/* Allocate space */
+ } else {
+ icmCurve *ro;
+
+ /* Try and read the tag from the file */
+ ro = (icmCurve *)rd_icco->read_tag(rd_icco, icSigRedTRCTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigCurveType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->flag != wo->flag)
+ error ("Curve flag doesn't match for Linear");
+
+ if (ro->size != wo->size)
+ error ("Curve size doesn't match");
+
+ if (rv)
+ error ("Curve verify failed");
+ }
+ }
+ /* --------------------- */
+ /* Curve - Gamma version */
+ {
+ static icmCurve *wo;
+ if (mode == 0) {
+ if ((wo = (icmCurve *)wr_icco->add_tag(
+ wr_icco, icSigGreenTRCTag, icSigCurveType)) == NULL)
+ return 1;
+
+ wo->flag = icmCurveGamma; /* Gamma version */
+ wo->allocate((icmBase *)wo); /* Allocate space */
+ wo->data[0] = rand_u8f8(); /* Gamma value */
+ } else {
+ icmCurve *ro;
+
+ /* Try and read the tag from the file */
+ ro = (icmCurve *)rd_icco->read_tag(rd_icco, icSigGreenTRCTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigCurveType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->flag != wo->flag)
+ error ("Curve flag doesn't match for Gamma");
+
+ if (ro->size != wo->size)
+ error ("Curve size doesn't match");
+
+ rv |= dcomp(ro->data[0], wo->data[0]);
+
+ if (rv)
+ error ("Curve verify failed");
+ }
+ }
+ /* ------------------------- */
+ /* Curve - Specified version */
+ {
+ static icmCurve *wo;
+ if (mode == 0) {
+ unsigned int i;
+ if ((wo = (icmCurve *)wr_icco->add_tag(
+ wr_icco, icSigBlueTRCTag, icSigCurveType)) == NULL)
+ return 1;
+
+ wo->flag = icmCurveSpec; /* Specified version */
+ wo->size = rand_int(2,23); /* Number of entries (min must be 2!) */
+ wo->allocate((icmBase *)wo);/* Allocate space */
+ for (i = 0; i < wo->size; i++)
+ wo->data[i] = rand_16f(); /* Curve values 0.0 - 1.0 */
+ } else {
+ icmCurve *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmCurve *)rd_icco->read_tag(rd_icco, icSigBlueTRCTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigCurveType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->flag != wo->flag)
+ error ("Curve flag doesn't match for specified");
+
+ if (ro->size != wo->size)
+ error ("Curve size doesn't match");
+
+ for (i = 0; i < wo->size; i++)
+ rv |= dcomp(ro->data[i], wo->data[i]);
+
+ if (rv)
+ error ("Curve verify failed");
+ }
+ }
+ /* ------------------- */
+ /* Data - text version */
+ {
+ static icmData *wo;
+ char *ts1 = "This is a data string";
+ if (mode == 0) {
+ if ((wo = (icmData *)wr_icco->add_tag(
+ wr_icco, icSigPs2CRD0Tag, icSigDataType)) == NULL)
+ return 1;
+
+ wo->flag = icmDataASCII; /* Holding ASCII data */
+ wo->size = strlen(ts1)+1; /* Allocated and used size of text, inc null */
+ wo->allocate((icmBase *)wo);/* Allocate space */
+ strcpy((char *)wo->data, ts1); /* Copy the text in */
+ } else {
+ icmData *ro;
+
+ /* Try and read the tag from the file */
+ ro = (icmData *)rd_icco->read_tag(rd_icco, icSigPs2CRD0Tag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigDataType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->flag != wo->flag)
+ error ("Data size doesn't match");
+
+ if (ro->size != wo->size)
+ error ("Data size doesn't match");
+
+ rv |= strcmp((char *)ro->data, (char *)wo->data);
+
+ if (rv)
+ error ("Data verify failed");
+ }
+ }
+ /* --------------------- */
+ /* Data - Binary version */
+ {
+ static icmData *wo;
+ if (mode == 0) {
+ unsigned int i;
+ if ((wo = (icmData *)wr_icco->add_tag(
+ wr_icco, icSigPs2CRD1Tag, icSigDataType)) == NULL)
+ return 1;
+
+ wo->flag = icmDataBin; /* Holding binary data */
+ wo->size = rand_int(0,43); /* Space we need for data */
+ wo->allocate((icmBase *)wo);/* Allocate space */
+ for (i = 0; i < wo->size; i ++)
+ wo->data[i] = rand_o8();
+ } else {
+ icmData *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmData *)rd_icco->read_tag(rd_icco, icSigPs2CRD1Tag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigDataType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->flag != wo->flag)
+ error ("Data size doesn't match");
+
+ if (ro->size != wo->size)
+ error ("Data size doesn't match");
+
+ for (i = 0; i < wo->size; i++)
+ rv |= (ro->data[i] != wo->data[i]);
+
+ if (rv)
+ error ("Data verify failed");
+ }
+ }
+ /* --------- */
+ /* DateTime: */
+ {
+ static icmDateTimeNumber *wo;
+ if (mode == 0) {
+ if ((wo = (icmDateTimeNumber *)wr_icco->add_tag(
+ wr_icco, icSigCalibrationDateTimeTag, icSigDateTimeType)) == NULL)
+ return 1;
+
+ wo->year = rand_int(1900, 3000);
+ wo->month = rand_int(1, 12);
+ wo->day = rand_int(1, 31);
+ wo->hours = rand_int(0, 23);
+ wo->minutes = rand_int(0, 59);
+ wo->seconds = rand_int(0, 59);
+ } else {
+ icmDateTimeNumber *ro;
+
+ /* Try and read the tag from the file */
+ ro = (icmDateTimeNumber *)rd_icco->read_tag(rd_icco, icSigCalibrationDateTimeTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigDateTimeType)
+ return 1;
+
+ /* Now check it out */
+ rv |= (ro->year != wo->year);
+ rv |= (ro->month != wo->month);
+ rv |= (ro->day != wo->day);
+ rv |= (ro->hours != wo->hours);
+ rv |= (ro->minutes != wo->minutes);
+ rv |= (ro->seconds != wo->seconds);
+
+ if (rv)
+ error ("DateTime verify failed");
+ }
+ }
+ /* ----------- */
+ /* 16 bit lut: */
+ {
+ static icmLut *wo;
+ if (mode == 0) {
+ unsigned int i, j, k;
+ if ((wo = (icmLut *)wr_icco->add_tag(
+ wr_icco, icSigAToB0Tag, icSigLut16Type)) == NULL)
+ return 1;
+
+ wo->inputChan = 2;
+ wo->outputChan = 3;
+ wo->clutPoints = 5;
+ wo->inputEnt = 56;
+ wo->outputEnt = 73;
+ wo->allocate((icmBase *)wo);/* Allocate space */
+
+ /* The matrix is only applicable to XYZ input space */
+ for (i = 0; i < 3; i++) /* Matrix */
+ for (j = 0; j < 3; j++)
+ wo->e[i][j] = rand_s15f16();
+
+ /* See icc.getNormFuncs() for normalizing functions */
+ /* The input table index range is over the normalized range 0.0 - 1.0. */
+ /* The range in input color space can be determined by denormalizing */
+ /* the values 0.0 - 1.0. */
+ for (i = 0; i < wo->inputChan; i++) /* Input tables */
+ for (j = 0; j < wo->inputEnt; j++)
+ wo->inputTable[i * wo->inputEnt + j] = rand_16f();
+
+ /* Lut */
+ /* The multidimentional lut has a normalized index range */
+ /* of 0.0 - 1.0 in each dimension. Its entry values are also */
+ /* normalized values in the range 0.0 - 1.0. */
+ for (i = 0; i < wo->clutPoints; i++) /* Input chan 0 - slow changing */
+ for (j = 0; j < wo->clutPoints; j++) /* Input chan 1 - faster changing */
+ for (k = 0; k < wo->outputChan; k++) /* Output chans */
+ wo->clutTable[(i * wo->clutPoints + j) * wo->outputChan + k] = rand_16f();
+
+ /* The output color space values should be normalized to the */
+ /* range 0.0 - 1.0 for use as output table entry values. */
+ for (i = 0; i < wo->outputChan; i++) /* Output tables */
+ for (j = 0; j < wo->outputEnt; j++)
+ wo->outputTable[i * wo->outputEnt + j] = rand_16f();
+
+ } else {
+ icmLut *ro;
+ unsigned int size;
+ unsigned int i, j;
+
+ /* Try and read the tag from the file */
+ ro = (icmLut *)rd_icco->read_tag(rd_icco, icSigAToB0Tag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigLut16Type)
+ return 1;
+
+ /* Now check it out */
+ rv |= (ro->inputChan != wo->inputChan);
+ rv |= (ro->outputChan != wo->outputChan);
+ rv |= (ro->clutPoints != wo->clutPoints);
+ rv |= (ro->inputEnt != wo->inputEnt);
+ rv |= (ro->outputEnt != wo->outputEnt);
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ rv |= dcomp(ro->e[i][j], wo->e[i][j]);
+
+ size = (wo->inputChan * wo->inputEnt);
+ for (i = 0; i < size; i++)
+ rv |= dcomp(ro->inputTable[i], wo->inputTable[i]);
+
+ size = wo->outputChan;
+ for (i = 0; i < wo->inputChan; i++)
+ size *= wo->clutPoints;
+ for (i = 0; i < size; i++)
+ rv |= dcomp(ro->clutTable[i], wo->clutTable[i]);
+
+ size = (wo->outputChan * wo->outputEnt);
+ for (i = 0; i < size; i++)
+ rv |= dcomp(ro->outputTable[i], wo->outputTable[i]);
+ if (rv)
+ error ("Lut16 verify failed");
+ }
+ }
+ /* ------------------ */
+ /* 16 bit lut - link: */
+ {
+ static icmLut *wo;
+ if (mode == 0) {
+ /* Just link to the existing LUT. This is often used when there */
+ /* is no distinction between intents, and saves file and memory space. */
+ if ((wo = (icmLut *)wr_icco->link_tag(
+ wr_icco, icSigAToB1Tag, icSigAToB0Tag)) == NULL)
+ return 1;
+ } else {
+ icmLut *ro;
+ unsigned int size;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmLut *)rd_icco->read_tag(rd_icco, icSigAToB1Tag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigLut16Type)
+ return 1;
+
+ /* Now check it out */
+ rv |= (ro->inputChan != wo->inputChan);
+ rv |= (ro->outputChan != wo->outputChan);
+ rv |= (ro->clutPoints != wo->clutPoints);
+ rv |= (ro->inputEnt != wo->inputEnt);
+ rv |= (ro->outputEnt != wo->outputEnt);
+
+ size = (wo->inputChan * wo->inputEnt);
+ for (i = 0; i < size; i++)
+ rv |= (ro->inputTable[i] != wo->inputTable[i]);
+
+ size = wo->outputChan;
+ for (i = 0; i < wo->inputChan; i++)
+ size *= wo->clutPoints;
+ for (i = 0; i < size; i++)
+ rv |= (ro->clutTable[i] != wo->clutTable[i]);
+
+ size = (wo->outputChan * wo->outputEnt);
+ for (i = 0; i < size; i++)
+ rv |= (ro->outputTable[i] != wo->outputTable[i]);
+ if (rv)
+ error ("Lut16 link verify failed");
+ }
+ }
+ /* ---------- */
+ /* 8 bit lut: */
+ {
+ static icmLut *wo;
+ if (mode == 0) {
+ unsigned int i, j, m, k;
+ if ((wo = (icmLut *)wr_icco->add_tag(
+ wr_icco, icSigAToB2Tag, icSigLut8Type)) == NULL)
+ return 1;
+
+ wo->inputChan = 3;
+ wo->outputChan = 2;
+ wo->clutPoints = 4;
+ wo->inputEnt = 256; /* Must be 256 for Lut8 */
+ wo->outputEnt = 256;
+ wo->allocate((icmBase *)wo);/* Allocate space */
+
+ for (i = 0; i < 3; i++) /* Matrix */
+ for (j = 0; j < 3; j++)
+ wo->e[i][j] = rand_s15f16();
+
+ for (i = 0; i < wo->inputChan; i++) /* Input tables */
+ for (j = 0; j < wo->inputEnt; j++)
+ wo->inputTable[i * wo->inputEnt + j] = rand_8f();
+
+ /* Lut */
+ for (i = 0; i < wo->clutPoints; i++) /* Input chan 0 */
+ for (j = 0; j < wo->clutPoints; j++) /* Input chan 1 */
+ for (m = 0; m < wo->clutPoints; m++) /* Input chan 2 */
+ for (k = 0; k < wo->outputChan; k++) { /* Output chans */
+ int idx = ((i * wo->clutPoints + j)
+ * wo->clutPoints + m)
+ * wo->outputChan + k;
+ wo->clutTable[idx] = rand_8f();
+ }
+
+ for (i = 0; i < wo->outputChan; i++) /* Output tables */
+ for (j = 0; j < wo->outputEnt; j++)
+ wo->outputTable[i * wo->outputEnt + j] = rand_8f();
+
+ } else {
+ icmLut *ro;
+ unsigned int size;
+ unsigned int i, j;
+
+ /* Try and read the tag from the file */
+ ro = (icmLut *)rd_icco->read_tag(rd_icco, icSigAToB2Tag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigLut8Type)
+ return 1;
+
+ /* Now check it out */
+ rv |= (ro->inputChan != wo->inputChan);
+ rv |= (ro->outputChan != wo->outputChan);
+ rv |= (ro->clutPoints != wo->clutPoints);
+ rv |= (ro->inputEnt != wo->inputEnt);
+ rv |= (ro->outputEnt != wo->outputEnt);
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ rv |= dcomp(ro->e[i][j], wo->e[i][j]);
+
+ size = (wo->inputChan * wo->inputEnt);
+ for (i = 0; i < size; i++)
+ rv |= dcomp(ro->inputTable[i], wo->inputTable[i]);
+
+ size = wo->outputChan;
+ for (i = 0; i < wo->inputChan; i++)
+ size *= wo->clutPoints;
+ for (i = 0; i < size; i++)
+ rv |= dcomp(ro->clutTable[i], wo->clutTable[i]);
+
+ size = (wo->outputChan * wo->outputEnt);
+ for (i = 0; i < size; i++)
+ rv |= dcomp(ro->outputTable[i], wo->outputTable[i]);
+ if (rv)
+ error ("Lut8 verify failed");
+ }
+ }
+ /* ----------------- */
+ /* Measurement: */
+ {
+ static icmMeasurement *wo;
+ if (mode == 0) {
+ if ((wo = (icmMeasurement *)wr_icco->add_tag(
+ wr_icco, icSigMeasurementTag, icSigMeasurementType)) == NULL)
+ return 1;
+
+ /* Standard observer */
+ switch(rand_int(0,2)) {
+ case 0:
+ wo->observer = icStdObsUnknown;
+ break;
+ case 1:
+ wo->observer = icStdObs1931TwoDegrees;
+ break;
+ case 2:
+ wo->observer = icStdObs1964TenDegrees;
+ break;
+ }
+
+ /* XYZ for backing color */
+ wo->backing.X = rand_XYZ16();
+ wo->backing.Y = rand_XYZ16();
+ wo->backing.Z = rand_XYZ16();
+
+ /* Measurement geometry */
+ switch(rand_int(0,2)) {
+ case 0:
+ wo->geometry = icGeometryUnknown;
+ break;
+ case 1:
+ wo->geometry = icGeometry045or450;
+ break;
+ case 2:
+ wo->geometry = icGeometry0dord0;
+ break;
+ }
+
+ /* Measurement flare */
+ wo->flare = rand_u16f16();
+
+ /* Illuminant */
+ switch(rand_int(0,8)) {
+ case 0:
+ wo->illuminant = icIlluminantUnknown;
+ break;
+ case 1:
+ wo->illuminant = icIlluminantD50;
+ break;
+ case 2:
+ wo->illuminant = icIlluminantD65;
+ break;
+ case 3:
+ wo->illuminant = icIlluminantD93;
+ break;
+ case 4:
+ wo->illuminant = icIlluminantF2;
+ break;
+ case 5:
+ wo->illuminant = icIlluminantD55;
+ break;
+ case 6:
+ wo->illuminant = icIlluminantA;
+ break;
+ case 7:
+ wo->illuminant = icIlluminantEquiPowerE;
+ break;
+ case 8:
+ wo->illuminant = icIlluminantF8;
+ break;
+ }
+ } else {
+ icmMeasurement *ro;
+
+ /* Try and read the tag from the file */
+ ro = (icmMeasurement *)rd_icco->read_tag(rd_icco, icSigMeasurementTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigMeasurementType)
+ return 1;
+
+ /* Now check it out */
+ rv |= (ro->observer != wo->observer);
+ rv |= dcomp(ro->backing.X, wo->backing.X);
+ rv |= dcomp(ro->backing.Y, wo->backing.Y);
+ rv |= dcomp(ro->backing.Z, wo->backing.Z);
+ rv |= (ro->geometry != wo->geometry);
+ rv |= dcomp(ro->flare, wo->flare);
+ rv |= (ro->illuminant != wo->illuminant);
+
+ if (rv)
+ error ("Measurement verify failed");
+ }
+ }
+ /* ----------------- */
+ /* Old style NamedColor: */
+ {
+ static icmNamedColor *wo;
+ if (mode == 0) {
+ unsigned int i;
+ if ((wo = (icmNamedColor *)wr_icco->add_tag(
+ wr_icco, icSigNamedColorTag, icSigNamedColorType)) == NULL)
+ return 1;
+
+ wo->vendorFlag = rand_int(0,65535) << 16; /* Bottom 16 bits for IC use */
+ wo->count = 3; /* Count of named colors */
+ strcpy(wo->prefix,"Prefix"); /* Prefix for each color name, max 32, null terminated */
+ strcpy(wo->suffix,"Suffix"); /* Suffix for each color name, max 32, null terminated */
+
+ wo->allocate((icmBase *)wo); /* Allocate named color structures */
+
+ for (i = 0; i < wo->count; i++) {
+ unsigned int j;
+ sprintf(wo->data[i].root,"Color %d",i); /* Root name, max 32, null terminated */
+ for (j = 0; j < wo->nDeviceCoords; j++) /* nDeviceCoords defaults appropriately */
+ wo->data[i].deviceCoords[j] = rand_8f(); /* Device coords of color */
+ }
+ } else {
+ icmNamedColor *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmNamedColor *)rd_icco->read_tag(rd_icco, icSigNamedColorTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigNamedColorType)
+ return 1;
+
+ /* Now check it out */
+ rv |= (ro->vendorFlag != wo->vendorFlag);
+ rv |= (ro->count != wo->count);
+ rv |= (ro->nDeviceCoords != wo->nDeviceCoords);
+ rv |= strcmp(ro->prefix, wo->prefix);
+ rv |= strcmp(ro->suffix, wo->suffix);
+
+ if (rv)
+ error ("NamedColor verify failed");
+
+ for (i = 0; i < wo->count; i++) {
+ unsigned int j;
+ rv |= strcmp(ro->data[i].root, wo->data[i].root);
+ for (j = 0; j < wo->nDeviceCoords; j++)
+ rv |= dcomp(ro->data[i].deviceCoords[j], wo->data[i].deviceCoords[j]);
+ }
+
+ if (rv)
+ error ("NamedColor verify failed");
+ }
+ }
+ /* ----------------- */
+ /* NamedColor2: */
+ {
+ static icmNamedColor *wo; /* Shares same machine specific structure */
+ if (mode == 0) {
+ unsigned int i;
+ if ((wo = (icmNamedColor *)wr_icco->add_tag(
+ wr_icco, icSigNamedColor2Tag, icSigNamedColor2Type)) == NULL)
+ return 1;
+
+ wo->vendorFlag = rand_int(0,65535) << 16; /* Bottom 16 bits for ICC use */
+ wo->count = 4; /* Count of named colors */
+ wo->nDeviceCoords = 3; /* Num of device coordinates */
+ /* Could set this different to that implied by wr_icco->header->colorSpace */
+ strcpy(wo->prefix,"Prefix-ix"); /* Prefix for each color name, max 32, null terminated */
+ strcpy(wo->suffix,"Suffix-ixix"); /* Suffix for each color name, max 32, null terminated */
+
+ wo->allocate((icmBase *)wo); /* Allocate named color structures */
+
+ for (i = 0; i < wo->count; i++) {
+ unsigned int j;
+ sprintf(wo->data[i].root,"Pigment %d",i); /* Root name, max 32, null terminated */
+ for (j = 0; j < wo->nDeviceCoords; j++)
+ wo->data[i].deviceCoords[j] = rand_8f(); /* Device coords of color */
+ switch(wo->icp->header->pcs) {
+ case icSigXYZData:
+ wo->data[i].pcsCoords[0] = rand_XYZ16();
+ wo->data[i].pcsCoords[1] = rand_XYZ16();
+ wo->data[i].pcsCoords[2] = rand_XYZ16();
+ break;
+ case icSigLabData:
+ wo->data[i].pcsCoords[0] = rand_L16();
+ wo->data[i].pcsCoords[1] = rand_ab16();
+ wo->data[i].pcsCoords[2] = rand_ab16();
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ icmNamedColor *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmNamedColor *)rd_icco->read_tag(rd_icco, icSigNamedColor2Tag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigNamedColor2Type)
+ return 1;
+
+ /* Now check it out */
+ rv |= (ro->vendorFlag != wo->vendorFlag);
+ rv |= (ro->count != wo->count);
+ rv |= (ro->nDeviceCoords != wo->nDeviceCoords);
+ rv |= strcmp(ro->prefix, wo->prefix);
+ rv |= strcmp(ro->suffix, wo->suffix);
+
+ if (rv)
+ error ("NamedColor2 verify failed");
+
+ for (i = 0; i < wo->count; i++) {
+ unsigned int j;
+ rv |= strcmp(ro->data[i].root, wo->data[i].root);
+ for (j = 0; j < wo->nDeviceCoords; j++)
+ rv |= dcomp(ro->data[i].deviceCoords[j], wo->data[i].deviceCoords[j]);
+ for (j = 0; j < 3; j++) {
+ rv |= dcomp(ro->data[i].pcsCoords[j], wo->data[i].pcsCoords[j]);
+ }
+ }
+
+ if (rv)
+ error ("NamedColor2 verify failed");
+ }
+ }
+ /* ----------------- */
+ /* ColorantTable: */
+ {
+ static icmColorantTable *wo;
+ if (mode == 0) {
+ unsigned int i;
+ if ((wo = (icmColorantTable *)wr_icco->add_tag(
+ wr_icco, icSigColorantTableTag, icSigColorantTableType)) == NULL)
+ return 1;
+
+ wo->count = 4; /* Count of colorants - should be same as implied by device space */
+ wo->allocate((icmBase *)wo); /* Allocate ColorantTable structures */
+
+ for (i = 0; i < wo->count; i++) {
+ sprintf(wo->data[i].name,"Color %d",i); /* Colorant name, max 32, null terminated */
+ switch(wo->icp->header->pcs) {
+ case icSigXYZData:
+ wo->data[i].pcsCoords[0] = rand_XYZ16();
+ wo->data[i].pcsCoords[1] = rand_XYZ16();
+ wo->data[i].pcsCoords[2] = rand_XYZ16();
+ break;
+ case icSigLabData:
+ wo->data[i].pcsCoords[0] = rand_L16();
+ wo->data[i].pcsCoords[1] = rand_ab16();
+ wo->data[i].pcsCoords[2] = rand_ab16();
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ icmColorantTable *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmColorantTable *)rd_icco->read_tag(rd_icco, icSigColorantTableTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigColorantTableType)
+ return 1;
+
+ /* Now check it out */
+ rv |= (ro->count != wo->count);
+
+ if (rv)
+ error ("ColorantTable verify failed");
+
+ for (i = 0; i < wo->count; i++) {
+ int j;
+ rv |= strcmp(ro->data[i].name, wo->data[i].name);
+ for (j = 0; j < 3; j++) {
+ rv |= dcomp(ro->data[i].pcsCoords[j], wo->data[i].pcsCoords[j]);
+ }
+ }
+
+ if (rv)
+ error ("ColorantTable verify failed");
+ }
+ }
+ /* ----------------- */
+ /* ProfileSequenceDescTag: */
+ {
+ unsigned short ts2a[29] = {'T','h','i','s',' ','i','s',' ','a',' ','d','e','v','i','c','e',
+ ' ','d','e','s','c','r','i','p','t','i','o','n',0x0000};
+ unsigned short ts2b[28] = {'T','h','i','s',' ','i','s',' ','a',' ','m','o','d','e','l',
+ ' ','d','e','s','c','r','i','p','t','i','o','n',0x0000};
+ char *ts3a = "This is a device description";
+ char *ts3b = "This is a model description";
+ static icmProfileSequenceDesc*wo;
+ if (mode == 0) {
+ unsigned int i;
+ if ((wo = (icmProfileSequenceDesc *)wr_icco->add_tag(
+ wr_icco, icSigProfileSequenceDescTag, icSigProfileSequenceDescType)) == NULL)
+ return 1;
+
+ wo->count = 3; /* Number of descriptions in sequence */
+ wo->allocate((icmBase *)wo); /* Allocate space for all the DescStructures */
+
+ /* Fill in each description structure in sequence */
+ for (i = 0; i < wo->count; i++) {
+ char ts1[100];
+ wo->data[i].deviceMfg = str2tag("mfg7");
+ wo->data[i].deviceModel = str2tag("2345");
+ wo->data[i].attributes.l = icTransparency | icMatte;
+ wo->data[i].attributes.h = 0x98765432;
+ wo->data[i].technology = rand_TechnologySignature();
+
+ /* device Text description */
+ sprintf(ts1,"This is device descrption %d",i);
+ wo->data[i].device.size = strlen(ts1)+1;
+ wo->data[i].allocate(&wo->data[i]); /* Allocate space */
+ strcpy(wo->data[i].device.desc, ts1); /* Copy the string in */
+
+ /* We'll fudge up the Unicode string */
+ wo->data[i].device.ucLangCode = 8765; /* UniCode language code */
+ wo->data[i].device.ucSize = 29; /* Size in chars inc null */
+ wo->data[i].allocate(&wo->data[i]); /* Allocate space */
+ memmove(wo->data[i].device.ucDesc, ts2a, 2 * 29); /* Copy string in */
+
+ wo->data[i].device.scCode = 67; /* Fudge scriptCode code */
+ wo->data[i].device.scSize = strlen(ts3a)+1; /* Used size of scDesc in bytes, inc null */
+ if (wo->data[i].device.scSize > 67)
+ error("ScriptCode string longer than 67");
+ strcpy((char *)wo->data[i].device.scDesc, ts3a); /* Copy the string in */
+
+ /* model Text description */
+ sprintf(ts1,"This is model descrption %d",i);
+ wo->data[i].model.size = strlen(ts1)+1;
+ wo->data[i].allocate(&wo->data[i]); /* Allocate space */
+ strcpy(wo->data[i].model.desc, ts1); /* Copy the string in */
+
+ /* We'll fudge up the Unicode string */
+ wo->data[i].model.ucLangCode = 7856; /* UniCode language code */
+ wo->data[i].model.ucSize = 28; /* Size in chars inc null */
+ wo->data[i].allocate(&wo->data[i]); /* Allocate space */
+ memmove(wo->data[i].model.ucDesc, ts2b, 2 * 28); /* Copy string in */
+
+ wo->data[i].model.scCode = 67; /* Fudge scriptCode code */
+ wo->data[i].model.scSize = strlen(ts3b)+1; /* Used size of scDesc in bytes, inc null */
+ if (wo->data[i].model.scSize > 67)
+ error("ScriptCode string longer than 67");
+ strcpy((char *)wo->data[i].model.scDesc, ts3b); /* Copy the string in */
+ }
+ } else {
+ icmProfileSequenceDesc *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmProfileSequenceDesc *)rd_icco->read_tag(rd_icco, icSigProfileSequenceDescTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigProfileSequenceDescType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->count != wo->count)
+ error ("ProfileSequenceDesc count doesn't match");
+
+ for (i = 0; i < wo->count; i++) {
+ rv |= (ro->data[i].deviceMfg != wo->data[i].deviceMfg);
+ rv |= (ro->data[i].deviceModel != wo->data[i].deviceModel);
+ rv |= (ro->data[i].attributes.l != wo->data[i].attributes.l);
+ rv |= (ro->data[i].attributes.h != wo->data[i].attributes.h);
+ rv |= (ro->data[i].technology != wo->data[i].technology);
+
+ /* device Text description */
+ rv |= (ro->data[i].device.size != wo->data[i].device.size);
+ rv |= strcmp(ro->data[i].device.desc, wo->data[i].device.desc);
+
+ rv |= (ro->data[i].device.ucLangCode != wo->data[i].device.ucLangCode);
+ rv |= (ro->data[i].device.ucSize != wo->data[i].device.ucSize);
+ rv |= memcmp(ro->data[i].device.ucDesc, wo->data[i].device.ucDesc, wo->data[i].device.ucSize * 2);
+
+ rv |= (ro->data[i].device.scCode != wo->data[i].device.scCode);
+ rv |= (ro->data[i].device.scSize != wo->data[i].device.scSize);
+ rv |= strcmp((char *)ro->data[i].device.scDesc, (char *)wo->data[i].device.scDesc);
+
+ /* model Text description */
+ rv |= (ro->data[i].model.size != wo->data[i].model.size);
+ rv |= strcmp(ro->data[i].model.desc, wo->data[i].model.desc);
+
+ rv |= (ro->data[i].model.ucLangCode != wo->data[i].model.ucLangCode);
+ rv |= (ro->data[i].model.ucSize != wo->data[i].model.ucSize);
+ rv |= memcmp(ro->data[i].model.ucDesc, wo->data[i].model.ucDesc, wo->data[i].model.ucSize * 2);
+
+ rv |= (ro->data[i].model.scCode != wo->data[i].model.scCode);
+ rv |= (ro->data[i].model.scSize != wo->data[i].model.scSize);
+ rv |= strcmp((char *)ro->data[i].model.scDesc, (char *)wo->data[i].model.scDesc);
+ }
+
+ if (rv)
+ error ("ProfileSequenceDesc verify failed");
+ }
+ }
+ /* ----------------- */
+ /* S15Fixed16Array: */
+ {
+ static icmS15Fixed16Array *wo;
+ if (mode == 0) {
+ unsigned int i;
+ /* There is no standard Tag that uses icSigS15Fixed16ArrayType, so use a 'custom' tag */
+ if ((wo = (icmS15Fixed16Array *)wr_icco->add_tag(
+ wr_icco, str2tag("sf32"), icSigS15Fixed16ArrayType)) == NULL)
+ return 1;
+
+ wo->size = rand_int(0,17); /* Number in array */
+ wo->allocate((icmBase *)wo); /* Allocate space */
+ for (i = 0; i < wo->size; i++) {
+ wo->data[i] = rand_s15f16(); /* Set numbers value */
+ }
+ } else {
+ icmS15Fixed16Array *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmS15Fixed16Array *)rd_icco->read_tag(rd_icco, str2tag("sf32"));
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigS15Fixed16ArrayType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->size != wo->size)
+ error ("S15Fixed16Array size doesn't match");
+
+ for (i = 0; i < wo->size; i++) {
+ rv |= dcomp(ro->data[i], wo->data[i]);
+ }
+
+ if (rv)
+ error ("S15Fixed16Array verify failed");
+ }
+ }
+ /* ----------------- */
+ /* Screening: */
+ {
+ static icmScreening *wo;
+ if (mode == 0) {
+ unsigned int i;
+ if ((wo = (icmScreening *)wr_icco->add_tag(
+ wr_icco, icSigScreeningTag, icSigScreeningType)) == NULL)
+ return 1;
+
+ wo->screeningFlag = rand_ScreenEncodings();
+ wo->channels = rand_int(1,4); /* Number of channels */
+ wo->allocate((icmBase *)wo); /* Allocate space */
+ for (i = 0; i < wo->channels; i++) {
+ wo->data[i].frequency = rand_s15f16(); /* Set screening frequency */
+ wo->data[i].angle = rand_s15f16(); /* Set screening angle */
+ wo->data[i].spotShape = rand_SpotShape(); /* Set spot shape */
+ }
+ } else {
+ icmScreening *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmScreening *)rd_icco->read_tag(rd_icco, icSigScreeningTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigScreeningType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->channels != wo->channels)
+ error ("Screening channels doesn't match");
+
+ rv |= (ro->screeningFlag != wo->screeningFlag);
+
+ for (i = 0; i < wo->channels; i++) {
+ rv |= dcomp(ro->data[i].frequency, wo->data[i].frequency);
+ rv |= dcomp(ro->data[i].angle, wo->data[i].angle);
+ rv |= (ro->data[i].spotShape != wo->data[i].spotShape);
+ }
+
+ if (rv)
+ error ("Screening verify failed");
+ }
+ }
+ /* ----------------- */
+ /* Signature: */
+ {
+ static icmSignature *wo;
+ if (mode == 0) {
+ if ((wo = (icmSignature *)wr_icco->add_tag(
+ wr_icco, icSigTechnologyTag, icSigSignatureType)) == NULL)
+ return 1;
+
+ wo->sig = rand_TechnologySignature();
+ } else {
+ icmSignature *ro;
+
+ /* Try and read the tag from the file */
+ ro = (icmSignature *)rd_icco->read_tag(rd_icco, icSigTechnologyTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigSignatureType)
+ return 1;
+
+ /* Now check it out */
+ rv |= (ro->sig != wo->sig);
+
+ if (rv)
+ error ("Signature verify failed");
+ }
+ }
+ /* ----------------- */
+ /* Text Description: */
+ {
+ static icmTextDescription *wo;
+ char *ts1 = "This is a test description";
+ unsigned short ts2[27] = {'T','h','i','s',' ','i','s',' ','a',' ','t','e','s','t',
+ ' ','d','e','s','c','r','i','p','t','i','o','n',0x0000};
+ char *ts3 = "This is a test3 description";
+ if (mode == 0) {
+ if ((wo = (icmTextDescription *)wr_icco->add_tag(
+ wr_icco, icSigProfileDescriptionTag, icSigTextDescriptionType)) == NULL)
+ return 1;
+
+ /* Data in tag type wojects is always allocated and freed by the woject */
+ wo->size = strlen(ts1)+1; /* Allocated and used size of desc, inc null */
+ wo->allocate((icmBase *)wo);/* Allocate space */
+ strcpy(wo->desc, ts1); /* Copy the string in */
+
+ /* We'll fudge up the Unicode string */
+ wo->ucLangCode = 1234; /* UniCode language code */
+ wo->ucSize = 27; /* Allocated and used size of ucDesc in characters, inc null */
+ wo->allocate((icmBase *)wo);/* Allocate space */
+ memmove(wo->ucDesc, ts2, 2 * 27); /* Copy string in */
+
+ /* Don't really know anything about scriptCode, but fudge some values */
+ wo->scCode = 23; /* ScriptCode code */
+ wo->scSize = strlen(ts3)+1; /* Used size of scDesc in bytes, inc null */
+ /* No allocations, since this has a fixed max of 67 bytes */
+ if (wo->scSize > 67)
+ error("ScriptCode string longer than 67");
+ strcpy((char *)wo->scDesc, ts3); /* Copy the string in */
+ } else {
+ icmTextDescription *ro;
+
+ /* Try and read the tag from the file */
+ ro = (icmTextDescription *)rd_icco->read_tag(rd_icco, icSigProfileDescriptionTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ /* We could have left it icmBase, switched on ro->ttype, & then cast appropriately. */
+ if (ro->ttype != icSigTextDescriptionType)
+ return 1;
+
+ /* Now check it out */
+ rv |= (ro->size != wo->size);
+ rv |= strcmp(ro->desc, wo->desc);
+
+ rv |= (ro->ucLangCode != wo->ucLangCode);
+ rv |= (ro->ucSize != wo->ucSize);
+ rv |= memcmp(ro->ucDesc, wo->ucDesc, wo->ucSize * 2);
+
+ rv |= (ro->scCode != wo->scCode);
+ rv |= (ro->scSize != wo->scSize);
+ rv |= strcmp((char *)ro->scDesc, (char *)wo->scDesc);
+ if (rv)
+ error ("Text Description verify failed4");
+ }
+ }
+ /* ----- */
+ /* Text: */
+ {
+ static icmText *wo;
+ char *ts1 = "This is Copyright by me!";
+ if (mode == 0) {
+ if ((wo = (icmText *)wr_icco->add_tag(
+ wr_icco, icSigCopyrightTag, icSigTextType)) == NULL)
+ return 1;
+
+ wo->size = strlen(ts1)+1; /* Allocated and used size of text, inc null */
+ wo->allocate((icmBase *)wo);/* Allocate space */
+ strcpy(wo->data, ts1); /* Copy the text in */
+ } else {
+ icmText *ro;
+
+ /* Try and read the tag from the file */
+ ro = (icmText *)rd_icco->read_tag(rd_icco, icSigCopyrightTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigTextType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->size != wo->size)
+ error ("Text size doesn't match");
+
+ rv |= strcmp(ro->data, wo->data);
+
+ if (rv)
+ error ("Text verify failed");
+ }
+ }
+ /* ---------------- */
+ /* U16Fixed16Array: */
+ {
+ static icmU16Fixed16Array *wo;
+ if (mode == 0) {
+ unsigned int i;
+ /* There is no standard Tag that uses icSigU16Fixed16ArrayType, so use a 'custom' tag */
+ if ((wo = (icmU16Fixed16Array *)wr_icco->add_tag(
+ wr_icco, str2tag("uf32"), icSigU16Fixed16ArrayType)) == NULL)
+ return 1;
+
+ wo->size = rand_int(0,17); /* Number in array */
+ wo->allocate((icmBase *)wo); /* Allocate space */
+ for (i = 0; i < wo->size; i++) {
+ wo->data[i] = rand_u16f16(); /* Set numbers value */
+ }
+ } else {
+ icmU16Fixed16Array *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmU16Fixed16Array *)rd_icco->read_tag(rd_icco, str2tag("uf32"));
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigU16Fixed16ArrayType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->size != wo->size)
+ error ("U16Fixed16Array size doesn't match");
+
+ for (i = 0; i < wo->size; i++) {
+ rv |= dcomp(ro->data[i], wo->data[i]);
+ }
+
+ if (rv)
+ error ("U16Fixed16Array verify failed");
+ }
+ }
+ /* ------------------- */
+ /* UcrBg - full curve: */
+ {
+ static icmUcrBg *wo;
+ char *ts1 = "UcrBg - full curve info";
+ if (mode == 0) {
+ unsigned int i;
+ if ((wo = (icmUcrBg *)wr_icco->add_tag(
+ wr_icco, icSigUcrBgTag, icSigUcrBgType)) == NULL)
+ return 1;
+
+ wo->UCRcount = rand_int(2,55); /* Number in UCR curve */
+ wo->BGcount = rand_int(2,32); /* Number in BG array */
+ wo->allocate((icmBase *)wo); /* Allocate space for both curves */
+ for (i = 0; i < wo->UCRcount; i++)
+ wo->UCRcurve[i] = rand_16f(); /* Set numbers value */
+ for (i = 0; i < wo->BGcount; i++)
+ wo->BGcurve[i] = rand_16f(); /* Set numbers value */
+ wo->size = strlen(ts1)+1; /* Allocated and used size of text, inc null */
+ wo->allocate((icmBase *)wo); /* Allocate space */
+ strcpy(wo->string, ts1); /* Copy the text in */
+ } else {
+ icmUcrBg *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmUcrBg *)rd_icco->read_tag(rd_icco, icSigUcrBgTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigUcrBgType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->UCRcount != wo->UCRcount)
+ error ("UcrBg UCRcount doesn't match");
+
+ if (ro->BGcount != wo->BGcount)
+ error ("UcrBg BGcount doesn't match");
+
+ for (i = 0; i < wo->UCRcount; i++)
+ rv |= dcomp(ro->UCRcurve[i], wo->UCRcurve[i]);
+
+ for (i = 0; i < wo->BGcount; i++)
+ rv |= dcomp(ro->BGcurve[i], wo->BGcurve[i]);
+
+ if (ro->size != wo->size)
+ error ("Text size doesn't match");
+
+ rv |= strcmp(ro->string, wo->string);
+
+ if (rv)
+ error ("UcrBg verify failed");
+ }
+ }
+ /* ------------------- */
+ /* UcrBg - percentage: */
+ {
+ static icmUcrBg *wo;
+ char *ts1 = "UcrBg - percentage info";
+ if (mode == 0) {
+ if ((wo = (icmUcrBg *)wr_icco->add_tag(
+ wr_icco, str2tag("bfd%"), icSigUcrBgType)) == NULL)
+ return 1;
+
+ wo->UCRcount = 1; /* 1 == UCR percentage */
+ wo->BGcount = 1; /* 1 == BG percentage */
+ wo->allocate((icmBase *)wo);/* Allocate space */
+ wo->UCRcurve[0] = (double) rand_int(0,65535);
+ wo->BGcurve[0] = (double) rand_int(0,65535);
+ wo->size = strlen(ts1)+1; /* Allocated and used size of text, inc null */
+ wo->allocate((icmBase *)wo);/* Allocate space */
+ strcpy(wo->string, ts1); /* Copy the text in */
+ } else {
+ icmUcrBg *ro;
+
+ /* Try and read the tag from the file */
+ ro = (icmUcrBg *)rd_icco->read_tag(rd_icco, str2tag("bfd%"));
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigUcrBgType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->UCRcount != wo->UCRcount)
+ error ("UcrBg UCRcount doesn't match");
+
+ if (ro->BGcount != wo->BGcount)
+ error ("UcrBg BGcount doesn't match");
+
+ rv |= (ro->UCRcurve[0] != wo->UCRcurve[0]);
+ rv |= (ro->BGcurve[0] != wo->BGcurve[0]);
+
+ if (ro->size != wo->size)
+ error ("Text size doesn't match");
+
+ rv |= strcmp(ro->string, wo->string);
+
+ if (rv)
+ error ("UcrBg verify failed");
+ }
+ }
+ /* ------------ */
+ /* UInt16Array: */
+ {
+ static icmUInt16Array *wo;
+ if (mode == 0) {
+ unsigned int i;
+ /* There is no standard Tag that uses icSigUInt16ArrayType, so use a 'custom' tag */
+ if ((wo = (icmUInt16Array *)wr_icco->add_tag(
+ wr_icco, str2tag("ui16"), icSigUInt16ArrayType)) == NULL)
+ return 1;
+
+ wo->size = rand_int(0,17); /* Number in array */
+ wo->allocate((icmBase *)wo); /* Allocate space */
+ for (i = 0; i < wo->size; i++) {
+ wo->data[i] = rand_o16(); /* Set numbers value */
+ }
+ } else {
+ icmUInt16Array *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmUInt16Array *)rd_icco->read_tag(rd_icco, str2tag("ui16"));
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigUInt16ArrayType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->size != wo->size)
+ error ("UInt16Array size doesn't match");
+
+ for (i = 0; i < wo->size; i++) {
+ rv |= (ro->data[i] != wo->data[i]);
+ }
+
+ if (rv)
+ error ("UInt16Array verify failed");
+ }
+ }
+ /* ------------ */
+ /* UInt32Array: */
+ {
+ static icmUInt32Array *wo;
+ if (mode == 0) {
+ unsigned int i;
+ /* There is no standard Tag that uses icSigUInt32ArrayType, so use a 'custom' tag */
+ if ((wo = (icmUInt32Array *)wr_icco->add_tag(
+ wr_icco, str2tag("ui32"), icSigUInt32ArrayType)) == NULL)
+ return 1;
+
+ wo->size = rand_int(0,18); /* Number in array */
+ wo->allocate((icmBase *)wo); /* Allocate space */
+ for (i = 0; i < wo->size; i++) {
+ wo->data[i] = rand_o32(); /* Set numbers value */
+ }
+ } else {
+ icmUInt32Array *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmUInt32Array *)rd_icco->read_tag(rd_icco, str2tag("ui32"));
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigUInt32ArrayType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->size != wo->size)
+ error ("UInt32Array size doesn't match");
+
+ for (i = 0; i < wo->size; i++) {
+ rv |= (ro->data[i] != wo->data[i]);
+ }
+
+ if (rv)
+ error ("UInt32Array verify failed");
+ }
+ }
+ /* ------------ */
+ /* UInt64Array: */
+ {
+ static icmUInt64Array *wo;
+ if (mode == 0) {
+ unsigned int i;
+ /* There is no standard Tag that uses icSigUInt64ArrayType, so use a 'custom' tag */
+ if ((wo = (icmUInt64Array *)wr_icco->add_tag(
+ wr_icco, str2tag("ui64"), icSigUInt64ArrayType)) == NULL)
+ return 1;
+
+ wo->size = rand_int(0,19); /* Number in array */
+ wo->allocate((icmBase *)wo); /* Allocate space */
+ for (i = 0; i < wo->size; i++) {
+ wo->data[i].l = rand_o32(); /* Set numbers value - low 32 bits */
+ wo->data[i].h = rand_o32(); /* Set numbers value - low 32 bits */
+ }
+ } else {
+ icmUInt64Array *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmUInt64Array *)rd_icco->read_tag(rd_icco, str2tag("ui64"));
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigUInt64ArrayType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->size != wo->size)
+ error ("UInt64Array size doesn't match");
+
+ for (i = 0; i < wo->size; i++) {
+ rv |= (ro->data[i].l != wo->data[i].l);
+ rv |= (ro->data[i].h != wo->data[i].h);
+ }
+
+ if (rv)
+ error ("UInt64Array verify failed");
+ }
+ }
+ /* ----------- */
+ /* UInt8Array: */
+ {
+ static icmUInt8Array *wo;
+ if (mode == 0) {
+ unsigned int i;
+ /* There is no standard Tag that uses icSigUInt8ArrayType, so use a 'custom' tag */
+ if ((wo = (icmUInt8Array *)wr_icco->add_tag(
+ wr_icco, str2tag("ui08"), icSigUInt8ArrayType)) == NULL)
+ return 1;
+
+ wo->size = rand_int(0,18); /* Number in array */
+ wo->allocate((icmBase *)wo); /* Allocate space */
+ for (i = 0; i < wo->size; i++) {
+ wo->data[i] = rand_o8(); /* Set numbers value */
+ }
+ } else {
+ icmUInt8Array *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmUInt8Array *)rd_icco->read_tag(rd_icco, str2tag("ui08"));
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigUInt8ArrayType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->size != wo->size)
+ error ("UInt8Array size doesn't match");
+
+ for (i = 0; i < wo->size; i++) {
+ rv |= (ro->data[i] != wo->data[i]);
+ }
+
+ if (rv)
+ error ("UInt8Array verify failed");
+ }
+ }
+ /* --------------- */
+ /* VideoCardGamma: (ColorSync specific) */
+ {
+ static icmVideoCardGamma *wo;
+ if (mode == 0) {
+ int i;
+ if ((wo = (icmVideoCardGamma *)wr_icco->add_tag(
+ wr_icco, icSigVideoCardGammaTag, icSigVideoCardGammaType)) == NULL)
+ return 1;
+
+ wo->tagType = icmVideoCardGammaTableType;
+ wo->u.table.channels = rand_int(1,3);
+ wo->u.table.entryCount = rand_int(2,1024);
+ wo->u.table.entrySize = rand_int(1,2);
+ wo->allocate((icmBase *)wo);
+ if (wo->u.table.entrySize == 1) {
+ unsigned char *cp = wo->u.table.data;
+ for (i=0; i<wo->u.table.channels*wo->u.table.entryCount;i++,cp++)
+ *cp = (unsigned char)rand_int(0,255);
+ } else {
+ unsigned short *sp = wo->u.table.data;
+ for (i=0; i<wo->u.table.channels*wo->u.table.entryCount;i++,sp++)
+ *sp = (unsigned short)rand_int(0,65535);
+ }
+ } else {
+ icmVideoCardGamma *ro;
+ int i;
+
+ /* Try and read tag from the file */
+ ro = (icmVideoCardGamma *)rd_icco->read_tag(rd_icco, icSigVideoCardGammaTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate */
+ if (ro->ttype != icSigVideoCardGammaType)
+ return 1;
+
+ /* Now check it out */
+ rv |= (ro->tagType != wo->tagType);
+ rv |= (ro->u.table.channels != wo->u.table.channels);
+ rv |= (ro->u.table.entryCount != wo->u.table.entryCount);
+ rv |= (ro->u.table.entrySize != wo->u.table.entrySize);
+ for (i=0; i<ro->u.table.channels*ro->u.table.entryCount*ro->u.table.entrySize; i++) {
+ rv |= (((char*)ro->u.table.data)[i] != ((char*)wo->u.table.data)[i]);
+ if (rv) break;
+ }
+ if (rv)
+ error ("VideoCardGamma verify failed");
+ }
+ }
+ /* ------------------ */
+ /* ViewingConditions: */
+ {
+ static icmViewingConditions *wo;
+ if (mode == 0) {
+ if ((wo = (icmViewingConditions *)wr_icco->add_tag(
+ wr_icco, icSigViewingConditionsTag, icSigViewingConditionsType)) == NULL)
+ return 1;
+
+ wo->illuminant.X = rand_XYZ16(); /* XYZ of illuminant in cd/m^2 */
+ wo->illuminant.Y = rand_XYZ16();
+ wo->illuminant.Z = rand_XYZ16();
+ wo->surround.X = rand_XYZ16(); /* XYZ of surround in cd/m^2 */
+ wo->surround.Y = rand_XYZ16();
+ wo->surround.Z = rand_XYZ16();
+ wo->stdIlluminant = rand_Illuminant(); /* Standard illuminent type */
+ } else {
+ icmViewingConditions *ro;
+
+ /* Try and read the tag from the file */
+ ro = (icmViewingConditions *)rd_icco->read_tag(rd_icco, icSigViewingConditionsTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigViewingConditionsType)
+ return 1;
+
+ /* Now check it out */
+ rv |= dcomp(ro->illuminant.X, wo->illuminant.X);
+ rv |= dcomp(ro->illuminant.Y, wo->illuminant.Y);
+ rv |= dcomp(ro->illuminant.Z, wo->illuminant.Z);
+ rv |= dcomp(ro->surround.X , wo->surround.X);
+ rv |= dcomp(ro->surround.Y , wo->surround.Y);
+ rv |= dcomp(ro->surround.Z , wo->surround.Z);
+ rv |= (ro->stdIlluminant != wo->stdIlluminant);
+
+ if (rv)
+ error ("ViewingConditions verify failed");
+ }
+ }
+ /* ---------- */
+ /* XYZ array: */
+ {
+ static icmXYZArray *wo;
+ if (mode == 0) {
+ unsigned int i;
+ /* Note that tag types icSigXYZType and icSigXYZArrayType are identical */
+ if ((wo = (icmXYZArray *)wr_icco->add_tag(
+ wr_icco, icSigMediaWhitePointTag, icSigXYZArrayType)) == NULL)
+ return 1;
+
+ wo->size = rand_int(1,7); /* Should be one XYZ number, but test more */
+ wo->allocate((icmBase *)wo); /* Allocate space */
+ for (i = 0; i < wo->size; i++) {
+ wo->data[i].X = rand_XYZ16(); /* Set numbers value */
+ wo->data[i].Y = rand_XYZ16();
+ wo->data[i].Z = rand_XYZ16();
+ }
+ } else {
+ icmXYZArray *ro;
+ unsigned int i;
+
+ /* Try and read the tag from the file */
+ ro = (icmXYZArray *)rd_icco->read_tag(rd_icco, icSigMediaWhitePointTag);
+ if (ro == NULL)
+ return 1;
+
+ /* Need to check that the cast is appropriate. */
+ if (ro->ttype != icSigXYZArrayType)
+ return 1;
+
+ /* Now check it out */
+ if (ro->size != wo->size)
+ error ("XYZArray size doesn't match");
+
+ for (i = 0; i < wo->size; i++) {
+ rv |= dcomp(ro->data[i].X, wo->data[i].X);
+ rv |= dcomp(ro->data[i].Y, wo->data[i].Y);
+ rv |= dcomp(ro->data[i].Z, wo->data[i].Z);
+ }
+
+ if (rv)
+ error ("XYZArray verify failed");
+ }
+ }
+
+ return 0;
+}
+
+/* ------------------------------------------------ */
+/* Floating point random number generators */
+/* These are appropriate for the underlying integer */
+/* representations in the icc format. */
+/* This is simply as a convenience so that we can */
+/* test the full range of representation, and */
+/* get away with exact verification. */
+
+/* 32 bit pseudo random sequencer */
+static unsigned int seed = 0x12345678;
+
+/* #define PSRAND(S) ((S) * 1103515245 + 12345) */
+#define PSRAND(S) (((S) & 0x80000000) ? (((S) << 1) ^ 0xa398655d) : ((S) << 1))
+
+unsigned int rand_o8() {
+ ORD32 o32;
+ seed = PSRAND(seed);
+ o32 = seed & 0xff;
+ return o32;
+}
+
+unsigned int rand_o16() {
+ ORD32 o32;
+ seed = PSRAND(seed);
+ o32 = seed & 0xffff;
+ return o32;
+}
+
+unsigned int rand_o32() {
+ ORD32 o32;
+ o32 = seed = PSRAND(seed);
+ return o32;
+}
+
+int rand_int(int low, int high) {
+ int i;
+ seed = PSRAND(seed);
+ i = seed % (high - low + 1);
+ return i + low;
+}
+
+double rand_u8f8() {
+ ORD32 o32;
+ seed = PSRAND(seed);
+ o32 = seed & 0xffff;
+ return (double)o32/256.0;
+}
+
+double rand_u16f16() {
+ ORD32 o32;
+ seed = PSRAND(seed);
+ o32 = seed;
+ return (double)o32/65536.0;
+}
+
+double rand_s15f16() {
+ INR32 i32;
+ seed = PSRAND(seed);
+ i32 = seed;
+ return (double)i32/65536.0;
+}
+
+double rand_XYZ16() {
+ ORD32 o32;
+ seed = PSRAND(seed);
+ o32 = seed & 0xffff;
+ return (double)o32/32768.0;
+}
+
+double rand_L8() {
+ ORD32 o32;
+ seed = PSRAND(seed);
+ o32 = seed & 0xff;
+ return (double)o32/2.550;
+}
+
+double rand_ab8() {
+ ORD32 o32;
+ seed = PSRAND(seed);
+ o32 = seed & 0xff;
+ return (double)o32-128.0;
+}
+
+double rand_L16() {
+ ORD32 o32;
+ seed = PSRAND(seed);
+ o32 = seed & 0xffff;
+ return (double)o32/652.800; /* 0xff00/100.0 */
+}
+
+double rand_ab16() {
+ ORD32 o32;
+ seed = PSRAND(seed);
+ o32 = seed & 0xffff;
+ return ((double)o32/256.0)-128.0;
+}
+
+double rand_8f() {
+ unsigned int rv;
+ seed = PSRAND(seed);
+ rv = seed & 0xff;
+ return (double)rv/255.0;
+}
+
+double rand_16f() {
+ unsigned int rv;
+ seed = PSRAND(seed);
+ rv = seed & 0xffff;
+ return (double)rv/65535.0;
+}
+
+/* Random selectors for ICC flags and enumerayions */
+
+unsigned int rand_ScreenEncodings() {
+ unsigned int flags = 0;
+
+ if (rand_int(0,1) == 0)
+ flags |= icPrtrDefaultScreensTrue;
+
+ if (rand_int(0,1) == 0)
+ flags |= icLinesPerInch;
+
+ return flags;
+}
+
+/* Device attributes */
+unsigned int rand_DeviceAttributes() {
+ unsigned int flags = 0;
+
+ if (rand_int(0,1) == 0)
+ flags |= icTransparency;
+
+ if (rand_int(0,1) == 0)
+ flags |= icMatte;
+
+ return flags;
+}
+
+/* Profile header flags */
+unsigned int rand_ProfileHeaderFlags() {
+ unsigned int flags = 0;
+
+ if (rand_int(0,1) == 0)
+ flags |= icEmbeddedProfileTrue;
+
+ if (rand_int(0,1) == 0)
+ flags |= icUseWithEmbeddedDataOnly;
+
+ return flags;
+}
+
+
+unsigned int rand_AsciiOrBinaryData() {
+ unsigned int flags = 0;
+
+ if (rand_int(0,1) == 0)
+ flags |= icBinaryData;
+
+ return flags;
+}
+
+icColorSpaceSignature rand_ColorSpaceSignature() {
+ switch(rand_int(0,25)) {
+ case 0:
+ return icSigXYZData;
+ case 1:
+ return icSigLabData;
+ case 2:
+ return icSigLuvData;
+ case 3:
+ return icSigYCbCrData;
+ case 4:
+ return icSigYxyData;
+ case 5:
+ return icSigRgbData;
+ case 6:
+ return icSigGrayData;
+ case 7:
+ return icSigHsvData;
+ case 8:
+ return icSigHlsData;
+ case 9:
+ return icSigCmykData;
+ case 10:
+ return icSigCmyData;
+ case 11:
+ return icSigMch6Data;
+ case 12:
+ return icSig2colorData;
+ case 13:
+ return icSig3colorData;
+ case 14:
+ return icSig4colorData;
+ case 15:
+ return icSig5colorData;
+ case 16:
+ return icSig6colorData;
+ case 17:
+ return icSig7colorData;
+ case 18:
+ return icSig8colorData;
+ case 19:
+ return icSig9colorData;
+ case 20:
+ return icSig10colorData;
+ case 21:
+ return icSig11colorData;
+ case 22:
+ return icSig12colorData;
+ case 23:
+ return icSig13colorData;
+ case 24:
+ return icSig14colorData;
+ case 25:
+ return icSig15colorData;
+ }
+ return icMaxEnumData;
+}
+
+icColorSpaceSignature rand_PCS() {
+ switch(rand_int(0,1)) {
+ case 0:
+ return icSigXYZData;
+ case 1:
+ return icSigLabData;
+ }
+ return icMaxEnumData;
+}
+
+icTechnologySignature rand_TechnologySignature() {
+ switch(rand_int(0,21)) {
+ case 0:
+ return icSigDigitalCamera;
+ case 1:
+ return icSigFilmScanner;
+ case 2:
+ return icSigReflectiveScanner;
+ case 3:
+ return icSigInkJetPrinter;
+ case 4:
+ return icSigThermalWaxPrinter;
+ case 5:
+ return icSigElectrophotographicPrinter;
+ case 6:
+ return icSigElectrostaticPrinter;
+ case 7:
+ return icSigDyeSublimationPrinter;
+ case 8:
+ return icSigPhotographicPaperPrinter;
+ case 9:
+ return icSigFilmWriter;
+ case 10:
+ return icSigVideoMonitor;
+ case 11:
+ return icSigVideoCamera;
+ case 12:
+ return icSigProjectionTelevision;
+ case 13:
+ return icSigCRTDisplay;
+ case 14:
+ return icSigPMDisplay;
+ case 15:
+ return icSigAMDisplay;
+ case 16:
+ return icSigPhotoCD;
+ case 17:
+ return icSigPhotoImageSetter;
+ case 18:
+ return icSigGravure;
+ case 19:
+ return icSigOffsetLithography;
+ case 20:
+ return icSigSilkscreen;
+ case 21:
+ return icSigFlexography;
+ }
+ return icMaxEnumTechnology;
+}
+
+icProfileClassSignature rand_ProfileClassSignature() {
+ switch(rand_int(0,6)) {
+ case 0:
+ return icSigInputClass;
+ case 1:
+ return icSigDisplayClass;
+ case 2:
+ return icSigOutputClass;
+ case 3:
+ return icSigLinkClass;
+ case 4:
+ return icSigAbstractClass;
+ case 5:
+ return icSigColorSpaceClass;
+ case 6:
+ return icSigNamedColorClass;
+ }
+ return icMaxEnumClass;
+}
+
+icPlatformSignature rand_PlatformSignature() {
+ switch(rand_int(0,4)) {
+ case 0:
+ return icSigMacintosh;
+ case 1:
+ return icSigMicrosoft;
+ case 2:
+ return icSigSolaris;
+ case 3:
+ return icSigSGI;
+ case 4:
+ return icSigTaligent;
+ }
+ return icMaxEnumPlatform;
+}
+
+icMeasurementFlare rand_MeasurementFlare() {
+ switch(rand_int(0,1)) {
+ case 0:
+ return icFlare0;
+ case 1:
+ return icFlare100;
+ }
+ return icMaxFlare;
+}
+
+icMeasurementGeometry rand_MeasurementGeometry() {
+ switch(rand_int(0,2)) {
+ case 0:
+ return icGeometryUnknown;
+ case 1:
+ return icGeometry045or450;
+ case 2:
+ return icGeometry0dord0;
+ }
+ return icMaxGeometry;
+}
+
+icRenderingIntent rand_RenderingIntent() {
+ switch(rand_int(0,3)) {
+ case 0:
+ return icPerceptual;
+ case 1:
+ return icRelativeColorimetric;
+ case 2:
+ return icSaturation;
+ case 3:
+ return icAbsoluteColorimetric;
+ }
+ return icMaxEnumIntent;
+}
+
+icSpotShape rand_SpotShape() {
+ switch(rand_int(0,7)) {
+ case 0:
+ return icSpotShapeUnknown;
+ case 1:
+ return icSpotShapePrinterDefault;
+ case 2:
+ return icSpotShapeRound;
+ case 3:
+ return icSpotShapeDiamond;
+ case 4:
+ return icSpotShapeEllipse;
+ case 5:
+ return icSpotShapeLine;
+ case 6:
+ return icSpotShapeSquare;
+ case 7:
+ return icSpotShapeCross;
+ }
+ return icMaxEnumSpot;
+}
+
+icStandardObserver rand_StandardObserver() {
+ switch(rand_int(0,2)) {
+ case 0:
+ return icStdObsUnknown;
+ case 1:
+ return icStdObs1931TwoDegrees;
+ case 2:
+ return icStdObs1964TenDegrees;
+ }
+ return icMaxStdObs;
+}
+
+icIlluminant rand_Illuminant() {
+ switch(rand_int(0,8)) {
+ case 0:
+ return icIlluminantUnknown;
+ case 1:
+ return icIlluminantD50;
+ case 2:
+ return icIlluminantD65;
+ case 3:
+ return icIlluminantD93;
+ case 4:
+ return icIlluminantF2;
+ case 5:
+ return icIlluminantD55;
+ case 6:
+ return icIlluminantA;
+ case 7:
+ return icIlluminantEquiPowerE;
+ case 8:
+ return icIlluminantF8;
+ }
+ return icMaxEnumIlluminant;
+}
+
+/* Compare doubles with a margine to allow */
+/* for floating point handling funnies */
+int dcomp(double a, double b) {
+ double dif = fabs(a - b);
+ double mag = fabs(a) + fabs(b);
+
+ return dif > (mag * 1e-10) ? 1 : 0;
+}
+
+/* ------------------------------------------------ */
+/* Basic printf type error() and warning() routines */
+
+void
+error(char *fmt, ...)
+{
+ va_list args;
+
+ fprintf(stderr,"icctest: Error - ");
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ exit (-1);
+}
+
+void
+warning(char *fmt, ...)
+{
+ va_list args;
+
+ fprintf(stderr,"icctest: Warning - ");
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+}