From 22f703cab05b7cd368f4de9e03991b7664dc5022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 1 Sep 2014 13:56:46 +0200 Subject: Initial import of argyll version 1.5.1-8 --- icc/icctest.c | 2393 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2393 insertions(+) create mode 100644 icc/icctest.c (limited to 'icc/icctest.c') 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 +#include +#include +#include +#include +#ifdef __sun +#include +#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; iu.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; iu.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; iu.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"); +} -- cgit v1.2.3