diff options
author | scuri <scuri> | 2008-10-17 06:10:15 +0000 |
---|---|---|
committer | scuri <scuri> | 2008-10-17 06:10:15 +0000 |
commit | 5a422aba704c375a307a902bafe658342e209906 (patch) | |
tree | 5005011e086bb863d8fb587ad3319bbec59b2447 /src/libjasper/base |
First commit - moving from LuaForge to SourceForge
Diffstat (limited to 'src/libjasper/base')
-rw-r--r-- | src/libjasper/base/jas_cm.c | 1282 | ||||
-rw-r--r-- | src/libjasper/base/jas_debug.c | 137 | ||||
-rw-r--r-- | src/libjasper/base/jas_getopt.c | 168 | ||||
-rw-r--r-- | src/libjasper/base/jas_icc.c | 1722 | ||||
-rw-r--r-- | src/libjasper/base/jas_iccdata.c | 517 | ||||
-rw-r--r-- | src/libjasper/base/jas_image.c | 1516 | ||||
-rw-r--r-- | src/libjasper/base/jas_init.c | 170 | ||||
-rw-r--r-- | src/libjasper/base/jas_malloc.c | 131 | ||||
-rw-r--r-- | src/libjasper/base/jas_seq.c | 454 | ||||
-rw-r--r-- | src/libjasper/base/jas_stream.c | 1151 | ||||
-rw-r--r-- | src/libjasper/base/jas_string.c | 96 | ||||
-rw-r--r-- | src/libjasper/base/jas_tmr.c | 149 | ||||
-rw-r--r-- | src/libjasper/base/jas_tvp.c | 237 | ||||
-rw-r--r-- | src/libjasper/base/jas_version.c | 67 |
14 files changed, 7797 insertions, 0 deletions
diff --git a/src/libjasper/base/jas_cm.c b/src/libjasper/base/jas_cm.c new file mode 100644 index 0000000..efeec99 --- /dev/null +++ b/src/libjasper/base/jas_cm.c @@ -0,0 +1,1282 @@ +/* + * Copyright (c) 2002-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Color Management + * + * $Id: jas_cm.c,v 1.1 2008/10/17 06:14:59 scuri Exp $ + */ + +#include <jasper/jas_config.h> +#include <math.h> +#include <stdlib.h> +#include <assert.h> +#include <jasper/jas_cm.h> +#include <jasper/jas_icc.h> +#include <jasper/jas_init.h> +#include <jasper/jas_stream.h> +#include <jasper/jas_malloc.h> +#include <jasper/jas_math.h> + +static jas_cmprof_t *jas_cmprof_create(void); +static void jas_cmshapmatlut_cleanup(jas_cmshapmatlut_t *); +static jas_cmreal_t jas_cmshapmatlut_lookup(jas_cmshapmatlut_t *lut, jas_cmreal_t x); + +static void jas_cmpxform_destroy(jas_cmpxform_t *pxform); +static jas_cmpxform_t *jas_cmpxform_copy(jas_cmpxform_t *pxform); + +static void jas_cmshapmat_destroy(jas_cmpxform_t *pxform); +static int jas_cmshapmat_apply(jas_cmpxform_t *pxform, jas_cmreal_t *in, + jas_cmreal_t *out, int cnt); + +static int jas_cmputint(long **bufptr, int sgnd, int prec, long val); +static int jas_cmgetint(long **bufptr, int sgnd, int prec, long *val); +static int jas_cmpxformseq_append(jas_cmpxformseq_t *pxformseq, + jas_cmpxformseq_t *othpxformseq); +static int jas_cmpxformseq_appendcnvt(jas_cmpxformseq_t *pxformseq, + int, int); +static int jas_cmpxformseq_resize(jas_cmpxformseq_t *pxformseq, int n); + +static int mono(jas_iccprof_t *prof, int op, jas_cmpxformseq_t **pxformseq); +static int triclr(jas_iccprof_t *prof, int op, jas_cmpxformseq_t **retpxformseq); + +static void jas_cmpxformseq_destroy(jas_cmpxformseq_t *pxformseq); +static int jas_cmpxformseq_delete(jas_cmpxformseq_t *pxformseq, int i); +static jas_cmpxformseq_t *jas_cmpxformseq_create(void); +static jas_cmpxformseq_t *jas_cmpxformseq_copy(jas_cmpxformseq_t *pxformseq); +static int jas_cmshapmat_invmat(jas_cmreal_t out[3][4], jas_cmreal_t in[3][4]); +static int jas_cmpxformseq_insertpxform(jas_cmpxformseq_t *pxformseq, + int i, jas_cmpxform_t *pxform); + +#define SEQFWD(intent) (intent) +#define SEQREV(intent) (4 + (intent)) +#define SEQSIM(intent) (8 + (intent)) +#define SEQGAM 12 + +#define fwdpxformseq(prof, intent) \ + (((prof)->pxformseqs[SEQFWD(intent)]) ? \ + ((prof)->pxformseqs[SEQFWD(intent)]) : \ + ((prof)->pxformseqs[SEQFWD(0)])) + +#define revpxformseq(prof, intent) \ + (((prof)->pxformseqs[SEQREV(intent)]) ? \ + ((prof)->pxformseqs[SEQREV(intent)]) : \ + ((prof)->pxformseqs[SEQREV(0)])) + +#define simpxformseq(prof, intent) \ + (((prof)->pxformseqs[SEQSIM(intent)]) ? \ + ((prof)->pxformseqs[SEQSIM(intent)]) : \ + ((prof)->pxformseqs[SEQSIM(0)])) + +#define gampxformseq(prof) ((prof)->pxformseqs[SEQGAM]) + +static int icctoclrspc(int iccclrspc, int refflag); +static jas_cmpxform_t *jas_cmpxform_create0(void); +static jas_cmpxform_t *jas_cmpxform_createshapmat(void); +static void jas_cmshapmatlut_init(jas_cmshapmatlut_t *lut); +static int jas_cmshapmatlut_set(jas_cmshapmatlut_t *lut, jas_icccurv_t *curv); + +static jas_cmpxformops_t shapmat_ops = {jas_cmshapmat_destroy, jas_cmshapmat_apply, 0}; +static jas_cmprof_t *jas_cmprof_createsycc(void); + +/******************************************************************************\ +* Color profile class. +\******************************************************************************/ + +jas_cmprof_t *jas_cmprof_createfromclrspc(int clrspc) +{ + jas_iccprof_t *iccprof; + jas_cmprof_t *prof; + + iccprof = 0; + prof = 0; + switch (clrspc) { + case JAS_CLRSPC_SYCBCR: + if (!(prof = jas_cmprof_createsycc())) + goto error; + break; + default: + if (!(iccprof = jas_iccprof_createfromclrspc(clrspc))) + goto error; + if (!(prof = jas_cmprof_createfromiccprof(iccprof))) + goto error; + jas_iccprof_destroy(iccprof); + iccprof = 0; + if (!jas_clrspc_isgeneric(clrspc)) + prof->clrspc = clrspc; + break; + } + return prof; +error: + if (iccprof) + jas_iccprof_destroy(iccprof); + return 0; +} + +static jas_cmprof_t *jas_cmprof_createsycc() +{ + jas_cmprof_t *prof; + jas_cmpxform_t *fwdpxform; + jas_cmpxform_t *revpxform; + jas_cmshapmat_t *fwdshapmat; + jas_cmshapmat_t *revshapmat; + int i; + int j; + + if (!(prof = jas_cmprof_createfromclrspc(JAS_CLRSPC_SRGB))) + goto error; + prof->clrspc = JAS_CLRSPC_SYCBCR; + assert(prof->numchans == 3 && prof->numrefchans == 3); + assert(prof->refclrspc == JAS_CLRSPC_CIEXYZ); + if (!(fwdpxform = jas_cmpxform_createshapmat())) + goto error; + fwdpxform->numinchans = 3; + fwdpxform->numoutchans = 3; + fwdshapmat = &fwdpxform->data.shapmat; + fwdshapmat->mono = 0; + fwdshapmat->order = 0; + fwdshapmat->useluts = 0; + fwdshapmat->usemat = 1; + fwdshapmat->mat[0][0] = 1.0; + fwdshapmat->mat[0][1] = 0.0; + fwdshapmat->mat[0][2] = 1.402; + fwdshapmat->mat[1][0] = 1.0; + fwdshapmat->mat[1][1] = -0.34413; + fwdshapmat->mat[1][2] = -0.71414; + fwdshapmat->mat[2][0] = 1.0; + fwdshapmat->mat[2][1] = 1.772; + fwdshapmat->mat[2][2] = 0.0; + fwdshapmat->mat[0][3] = -0.5 * (1.402); + fwdshapmat->mat[1][3] = -0.5 * (-0.34413 - 0.71414); + fwdshapmat->mat[2][3] = -0.5 * (1.772); + if (!(revpxform = jas_cmpxform_createshapmat())) + goto error; + revpxform->numinchans = 3; + revpxform->numoutchans = 3; + revshapmat = &revpxform->data.shapmat; + revshapmat->mono = 0; + revshapmat->order = 1; + revshapmat->useluts = 0; + revshapmat->usemat = 1; + jas_cmshapmat_invmat(revshapmat->mat, fwdshapmat->mat); + + for (i = 0; i < JAS_CMXFORM_NUMINTENTS; ++i) { + j = SEQFWD(i); + if (prof->pxformseqs[j]) { + if (jas_cmpxformseq_insertpxform(prof->pxformseqs[j], 0, + fwdpxform)) + goto error; + } + j = SEQREV(i); + if (prof->pxformseqs[j]) { + if (jas_cmpxformseq_insertpxform(prof->pxformseqs[j], + -1, revpxform)) + goto error; + } + } + + jas_cmpxform_destroy(fwdpxform); + jas_cmpxform_destroy(revpxform); + return prof; +error: + return 0; +} + +jas_cmprof_t *jas_cmprof_createfromiccprof(jas_iccprof_t *iccprof) +{ + jas_cmprof_t *prof; + jas_icchdr_t icchdr; + jas_cmpxformseq_t *fwdpxformseq; + jas_cmpxformseq_t *revpxformseq; + + prof = 0; + fwdpxformseq = 0; + revpxformseq = 0; + + if (!(prof = jas_cmprof_create())) + goto error; + jas_iccprof_gethdr(iccprof, &icchdr); + if (!(prof->iccprof = jas_iccprof_copy(iccprof))) + goto error; + prof->clrspc = icctoclrspc(icchdr.colorspc, 0); + prof->refclrspc = icctoclrspc(icchdr.refcolorspc, 1); + prof->numchans = jas_clrspc_numchans(prof->clrspc); + prof->numrefchans = jas_clrspc_numchans(prof->refclrspc); + + if (prof->numchans == 1) { + if (mono(prof->iccprof, 0, &fwdpxformseq)) + goto error; + if (mono(prof->iccprof, 1, &revpxformseq)) + goto error; + } else if (prof->numchans == 3) { + if (triclr(prof->iccprof, 0, &fwdpxformseq)) + goto error; + if (triclr(prof->iccprof, 1, &revpxformseq)) + goto error; + } + prof->pxformseqs[SEQFWD(0)] = fwdpxformseq; + prof->pxformseqs[SEQREV(0)] = revpxformseq; + +#if 0 + if (prof->numchans > 1) { + lut(prof->iccprof, 0, PER, &pxformseq); + pxformseqs_set(prof, SEQFWD(PER), pxformseq); + lut(prof->iccprof, 1, PER, &pxformseq); + pxformseqs_set(prof, SEQREV(PER), pxformseq); + lut(prof->iccprof, 0, CLR, &pxformseq); + pxformseqs_set(prof, SEQREV(CLR), pxformseq); + lut(prof->iccprof, 1, CLR, &pxformseq); + pxformseqs_set(prof, SEQREV(CLR), pxformseq); + lut(prof->iccprof, 0, SAT, &pxformseq); + pxformseqs_set(prof, SEQREV(SAT), pxformseq); + lut(prof->iccprof, 1, SAT, &pxformseq); + pxformseqs_set(prof, SEQREV(SAT), pxformseq); + } +#endif + + return prof; + +error: + if (fwdpxformseq) { + jas_cmpxformseq_destroy(fwdpxformseq); + } + if (revpxformseq) { + jas_cmpxformseq_destroy(revpxformseq); + } + if (prof) { + jas_cmprof_destroy(prof); + } + + return 0; +} + +static jas_cmprof_t *jas_cmprof_create() +{ + int i; + jas_cmprof_t *prof; + if (!(prof = jas_malloc(sizeof(jas_cmprof_t)))) + return 0; + memset(prof, 0, sizeof(jas_cmprof_t)); + prof->iccprof = 0; + for (i = 0; i < JAS_CMPROF_NUMPXFORMSEQS; ++i) + prof->pxformseqs[i] = 0; + return prof; +} + +void jas_cmprof_destroy(jas_cmprof_t *prof) +{ + int i; + for (i = 0; i < JAS_CMPROF_NUMPXFORMSEQS; ++i) { + if (prof->pxformseqs[i]) { + jas_cmpxformseq_destroy(prof->pxformseqs[i]); + prof->pxformseqs[i] = 0; + } + } + if (prof->iccprof) + jas_iccprof_destroy(prof->iccprof); + jas_free(prof); +} + +jas_cmprof_t *jas_cmprof_copy(jas_cmprof_t *prof) +{ + jas_cmprof_t *newprof; + int i; + + if (!(newprof = jas_cmprof_create())) + goto error; + newprof->clrspc = prof->clrspc; + newprof->numchans = prof->numchans; + newprof->refclrspc = prof->refclrspc; + newprof->numrefchans = prof->numrefchans; + newprof->iccprof = jas_iccprof_copy(prof->iccprof); + for (i = 0; i < JAS_CMPROF_NUMPXFORMSEQS; ++i) { + if (prof->pxformseqs[i]) { + if (!(newprof->pxformseqs[i] = jas_cmpxformseq_copy(prof->pxformseqs[i]))) + goto error; + } + } + return newprof; +error: + return 0; +} + +/******************************************************************************\ +* Transform class. +\******************************************************************************/ + +jas_cmxform_t *jas_cmxform_create(jas_cmprof_t *inprof, jas_cmprof_t *outprof, + jas_cmprof_t *prfprof, int op, int intent, int optimize) +{ + jas_cmxform_t *xform; + jas_cmpxformseq_t *inpxformseq; + jas_cmpxformseq_t *outpxformseq; + jas_cmpxformseq_t *altoutpxformseq; + jas_cmpxformseq_t *prfpxformseq; + int prfintent; + + /* Avoid compiler warnings about unused parameters. */ + optimize = 0; + + prfintent = intent; + + if (!(xform = jas_malloc(sizeof(jas_cmxform_t)))) + goto error; + if (!(xform->pxformseq = jas_cmpxformseq_create())) + goto error; + + switch (op) { + case JAS_CMXFORM_OP_FWD: + inpxformseq = fwdpxformseq(inprof, intent); + outpxformseq = revpxformseq(outprof, intent); + if (!inpxformseq || !outpxformseq) + goto error; + if (jas_cmpxformseq_append(xform->pxformseq, inpxformseq) || + jas_cmpxformseq_appendcnvt(xform->pxformseq, + inprof->refclrspc, outprof->refclrspc) || + jas_cmpxformseq_append(xform->pxformseq, outpxformseq)) + goto error; + xform->numinchans = jas_clrspc_numchans(inprof->clrspc); + xform->numoutchans = jas_clrspc_numchans(outprof->clrspc); + break; + case JAS_CMXFORM_OP_REV: + outpxformseq = fwdpxformseq(outprof, intent); + inpxformseq = revpxformseq(inprof, intent); + if (!outpxformseq || !inpxformseq) + goto error; + if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq) || + jas_cmpxformseq_appendcnvt(xform->pxformseq, + outprof->refclrspc, inprof->refclrspc) || + jas_cmpxformseq_append(xform->pxformseq, inpxformseq)) + goto error; + xform->numinchans = jas_clrspc_numchans(outprof->clrspc); + xform->numoutchans = jas_clrspc_numchans(inprof->clrspc); + break; + case JAS_CMXFORM_OP_PROOF: + assert(prfprof); + inpxformseq = fwdpxformseq(inprof, intent); + prfpxformseq = fwdpxformseq(prfprof, prfintent); + if (!inpxformseq || !prfpxformseq) + goto error; + outpxformseq = simpxformseq(outprof, intent); + altoutpxformseq = 0; + if (!outpxformseq) { + outpxformseq = revpxformseq(outprof, intent); + altoutpxformseq = fwdpxformseq(outprof, intent); + if (!outpxformseq || !altoutpxformseq) + goto error; + } + if (jas_cmpxformseq_append(xform->pxformseq, inpxformseq) || + jas_cmpxformseq_appendcnvt(xform->pxformseq, + inprof->refclrspc, outprof->refclrspc)) + goto error; + if (altoutpxformseq) { + if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq) || + jas_cmpxformseq_append(xform->pxformseq, altoutpxformseq)) + goto error; + } else { + if (jas_cmpxformseq_append(xform->pxformseq, outpxformseq)) + goto error; + } + if (jas_cmpxformseq_appendcnvt(xform->pxformseq, + outprof->refclrspc, inprof->refclrspc) || + jas_cmpxformseq_append(xform->pxformseq, prfpxformseq)) + goto error; + xform->numinchans = jas_clrspc_numchans(inprof->clrspc); + xform->numoutchans = jas_clrspc_numchans(prfprof->clrspc); + break; + case JAS_CMXFORM_OP_GAMUT: + inpxformseq = fwdpxformseq(inprof, intent); + outpxformseq = gampxformseq(outprof); + if (!inpxformseq || !outpxformseq) + goto error; + if (jas_cmpxformseq_append(xform->pxformseq, inpxformseq) || + jas_cmpxformseq_appendcnvt(xform->pxformseq, + inprof->refclrspc, outprof->refclrspc) || + jas_cmpxformseq_append(xform->pxformseq, outpxformseq)) + goto error; + xform->numinchans = jas_clrspc_numchans(inprof->clrspc); + xform->numoutchans = 1; + break; + } + return xform; +error: + return 0; +} + +#define APPLYBUFSIZ 2048 +int jas_cmxform_apply(jas_cmxform_t *xform, jas_cmpixmap_t *in, jas_cmpixmap_t *out) +{ + jas_cmcmptfmt_t *fmt; + jas_cmreal_t buf[2][APPLYBUFSIZ]; + jas_cmpxformseq_t *pxformseq; + int i; + int j; + int width; + int height; + int total; + int n; + jas_cmreal_t *inbuf; + jas_cmreal_t *outbuf; + jas_cmpxform_t *pxform; + long *dataptr; + int maxchans; + int bufmax; + int m; + int bias; + jas_cmreal_t scale; + long v; + jas_cmreal_t *bufptr; + + if (xform->numinchans > in->numcmpts || xform->numoutchans > out->numcmpts) + goto error; + + fmt = &in->cmptfmts[0]; + width = fmt->width; + height = fmt->height; + for (i = 1; i < xform->numinchans; ++i) { + fmt = &in->cmptfmts[i]; + if (fmt->width != width || fmt->height != height) { + goto error; + } + } + for (i = 0; i < xform->numoutchans; ++i) { + fmt = &out->cmptfmts[i]; + if (fmt->width != width || fmt->height != height) { + goto error; + } + } + + maxchans = 0; + pxformseq = xform->pxformseq; + for (i = 0; i < pxformseq->numpxforms; ++i) { + pxform = pxformseq->pxforms[i]; + if (pxform->numinchans > maxchans) { + maxchans = pxform->numinchans; + } + if (pxform->numoutchans > maxchans) { + maxchans = pxform->numoutchans; + } + } + bufmax = APPLYBUFSIZ / maxchans; + assert(bufmax > 0); + + total = width * height; + n = 0; + while (n < total) { + + inbuf = &buf[0][0]; + m = JAS_MIN(total - n, bufmax); + + for (i = 0; i < xform->numinchans; ++i) { + fmt = &in->cmptfmts[i]; + scale = (double)((1 << fmt->prec) - 1); + bias = fmt->sgnd ? (1 << (fmt->prec - 1)) : 0; + dataptr = &fmt->buf[n]; + bufptr = &inbuf[i]; + for (j = 0; j < m; ++j) { + if (jas_cmgetint(&dataptr, fmt->sgnd, fmt->prec, &v)) + goto error; + *bufptr = (v - bias) / scale; + bufptr += xform->numinchans; + } + } + + inbuf = &buf[0][0]; + outbuf = inbuf; + for (i = 0; i < pxformseq->numpxforms; ++i) { + pxform = pxformseq->pxforms[i]; + if (pxform->numoutchans > pxform->numinchans) { + outbuf = (inbuf == &buf[0][0]) ? &buf[1][0] : &buf[0][0]; + } else { + outbuf = inbuf; + } + if ((*pxform->ops->apply)(pxform, inbuf, outbuf, m)) + goto error; + inbuf = outbuf; + } + + for (i = 0; i < xform->numoutchans; ++i) { + fmt = &out->cmptfmts[i]; + scale = (double)((1 << fmt->prec) - 1); + bias = fmt->sgnd ? (1 << (fmt->prec - 1)) : 0; + bufptr = &outbuf[i]; + dataptr = &fmt->buf[n]; + for (j = 0; j < m; ++j) { + v = (*bufptr) * scale + bias; + bufptr += xform->numoutchans; + if (jas_cmputint(&dataptr, fmt->sgnd, fmt->prec, v)) + goto error; + } + } + + n += m; + } + + return 0; +error: + return -1; +} + +void jas_cmxform_destroy(jas_cmxform_t *xform) +{ + if (xform->pxformseq) + jas_cmpxformseq_destroy(xform->pxformseq); + jas_free(xform); +} + +/******************************************************************************\ +* Primitive transform sequence class. +\******************************************************************************/ + +static jas_cmpxformseq_t *jas_cmpxformseq_create() +{ + jas_cmpxformseq_t *pxformseq; + pxformseq = 0; + if (!(pxformseq = jas_malloc(sizeof(jas_cmpxformseq_t)))) + goto error; + pxformseq->pxforms = 0; + pxformseq->numpxforms = 0; + pxformseq->maxpxforms = 0; + if (jas_cmpxformseq_resize(pxformseq, 16)) + goto error; + return pxformseq; +error: + if (pxformseq) + jas_cmpxformseq_destroy(pxformseq); + return 0; +} + +static jas_cmpxformseq_t *jas_cmpxformseq_copy(jas_cmpxformseq_t *pxformseq) +{ + jas_cmpxformseq_t *newpxformseq; + + if (!(newpxformseq = jas_cmpxformseq_create())) + goto error; + if (jas_cmpxformseq_append(newpxformseq, pxformseq)) + goto error; + return newpxformseq; +error: + return 0; +} + +static void jas_cmpxformseq_destroy(jas_cmpxformseq_t *pxformseq) +{ + while (pxformseq->numpxforms > 0) + jas_cmpxformseq_delete(pxformseq, pxformseq->numpxforms - 1); + if (pxformseq->pxforms) + jas_free(pxformseq->pxforms); + jas_free(pxformseq); +} + +static int jas_cmpxformseq_delete(jas_cmpxformseq_t *pxformseq, int i) +{ + assert(i >= 0 && i < pxformseq->numpxforms); + if (i != pxformseq->numpxforms - 1) + abort(); + jas_cmpxform_destroy(pxformseq->pxforms[i]); + pxformseq->pxforms[i] = 0; + --pxformseq->numpxforms; + return 0; +} + +static int jas_cmpxformseq_appendcnvt(jas_cmpxformseq_t *pxformseq, + int dstclrspc, int srcclrspc) +{ + if (dstclrspc == srcclrspc) + return 0; + abort(); + /* Avoid compiler warnings about unused parameters. */ + pxformseq = 0; + return -1; +} + +static int jas_cmpxformseq_insertpxform(jas_cmpxformseq_t *pxformseq, + int i, jas_cmpxform_t *pxform) +{ + jas_cmpxform_t *tmppxform; + int n; + if (i < 0) + i = pxformseq->numpxforms; + assert(i >= 0 && i <= pxformseq->numpxforms); + if (pxformseq->numpxforms >= pxformseq->maxpxforms) { + if (jas_cmpxformseq_resize(pxformseq, pxformseq->numpxforms + + 16)) + goto error; + } + assert(pxformseq->numpxforms < pxformseq->maxpxforms); + if (!(tmppxform = jas_cmpxform_copy(pxform))) + goto error; + n = pxformseq->numpxforms - i; + if (n > 0) { + memmove(&pxformseq->pxforms[i + 1], &pxformseq->pxforms[i], + n * sizeof(jas_cmpxform_t *)); + } + pxformseq->pxforms[i] = tmppxform; + ++pxformseq->numpxforms; + return 0; +error: + return -1; +} + +static int jas_cmpxformseq_append(jas_cmpxformseq_t *pxformseq, + jas_cmpxformseq_t *othpxformseq) +{ + int n; + int i; + jas_cmpxform_t *pxform; + jas_cmpxform_t *othpxform; + n = pxformseq->numpxforms + othpxformseq->numpxforms; + if (n > pxformseq->maxpxforms) { + if (jas_cmpxformseq_resize(pxformseq, n)) + goto error; + } + for (i = 0; i < othpxformseq->numpxforms; ++i) { + othpxform = othpxformseq->pxforms[i]; + if (!(pxform = jas_cmpxform_copy(othpxform))) + goto error; + pxformseq->pxforms[pxformseq->numpxforms] = pxform; + ++pxformseq->numpxforms; + } + return 0; +error: + return -1; +} + +static int jas_cmpxformseq_resize(jas_cmpxformseq_t *pxformseq, int n) +{ + jas_cmpxform_t **p; + assert(n >= pxformseq->numpxforms); + p = (!pxformseq->pxforms) ? jas_malloc(n * sizeof(jas_cmpxform_t *)) : + jas_realloc(pxformseq->pxforms, n * sizeof(jas_cmpxform_t *)); + if (!p) { + return -1; + } + pxformseq->pxforms = p; + pxformseq->maxpxforms = n; + return 0; +} + +/******************************************************************************\ +* Primitive transform class. +\******************************************************************************/ + +static jas_cmpxform_t *jas_cmpxform_create0() +{ + jas_cmpxform_t *pxform; + if (!(pxform = jas_malloc(sizeof(jas_cmpxform_t)))) + return 0; + memset(pxform, 0, sizeof(jas_cmpxform_t)); + pxform->refcnt = 0; + pxform->ops = 0; + return pxform; +} + +static void jas_cmpxform_destroy(jas_cmpxform_t *pxform) +{ + if (--pxform->refcnt <= 0) { + (*pxform->ops->destroy)(pxform); + jas_free(pxform); + } +} + +static jas_cmpxform_t *jas_cmpxform_copy(jas_cmpxform_t *pxform) +{ + ++pxform->refcnt; + return pxform; +} + +/******************************************************************************\ +* Shaper matrix class. +\******************************************************************************/ + +static jas_cmpxform_t *jas_cmpxform_createshapmat() +{ + int i; + int j; + jas_cmpxform_t *pxform; + jas_cmshapmat_t *shapmat; + if (!(pxform = jas_cmpxform_create0())) + return 0; + pxform->ops = &shapmat_ops; + shapmat = &pxform->data.shapmat; + shapmat->mono = 0; + shapmat->order = 0; + shapmat->useluts = 0; + shapmat->usemat = 0; + for (i = 0; i < 3; ++i) + jas_cmshapmatlut_init(&shapmat->luts[i]); + for (i = 0; i < 3; ++i) { + for (j = 0; j < 4; ++j) + shapmat->mat[i][j] = 0.0; + } + ++pxform->refcnt; + return pxform; +} + +static void jas_cmshapmat_destroy(jas_cmpxform_t *pxform) +{ + jas_cmshapmat_t *shapmat = &pxform->data.shapmat; + int i; + for (i = 0; i < 3; ++i) + jas_cmshapmatlut_cleanup(&shapmat->luts[i]); +} + +static int jas_cmshapmat_apply(jas_cmpxform_t *pxform, jas_cmreal_t *in, + jas_cmreal_t *out, int cnt) +{ + jas_cmshapmat_t *shapmat = &pxform->data.shapmat; + jas_cmreal_t *src; + jas_cmreal_t *dst; + jas_cmreal_t a0; + jas_cmreal_t a1; + jas_cmreal_t a2; + jas_cmreal_t b0; + jas_cmreal_t b1; + jas_cmreal_t b2; + src = in; + dst = out; + if (!shapmat->mono) { + while (--cnt >= 0) { + a0 = *src++; + a1 = *src++; + a2 = *src++; + if (!shapmat->order && shapmat->useluts) { + a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0); + a1 = jas_cmshapmatlut_lookup(&shapmat->luts[1], a1); + a2 = jas_cmshapmatlut_lookup(&shapmat->luts[2], a2); + } + if (shapmat->usemat) { + b0 = shapmat->mat[0][0] * a0 + + shapmat->mat[0][1] * a1 + + shapmat->mat[0][2] * a2 + + shapmat->mat[0][3]; + b1 = shapmat->mat[1][0] * a0 + + shapmat->mat[1][1] * a1 + + shapmat->mat[1][2] * a2 + + shapmat->mat[1][3]; + b2 = shapmat->mat[2][0] * a0 + + shapmat->mat[2][1] * a1 + + shapmat->mat[2][2] * a2 + + shapmat->mat[2][3]; + a0 = b0; + a1 = b1; + a2 = b2; + } + if (shapmat->order && shapmat->useluts) { + a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0); + a1 = jas_cmshapmatlut_lookup(&shapmat->luts[1], a1); + a2 = jas_cmshapmatlut_lookup(&shapmat->luts[2], a2); + } + *dst++ = a0; + *dst++ = a1; + *dst++ = a2; + } + } else { + if (!shapmat->order) { + while (--cnt >= 0) { + a0 = *src++; + if (shapmat->useluts) + a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0); + a2 = a0 * shapmat->mat[2][0]; + a1 = a0 * shapmat->mat[1][0]; + a0 = a0 * shapmat->mat[0][0]; + *dst++ = a0; + *dst++ = a1; + *dst++ = a2; + } + } else { +assert(0); + while (--cnt >= 0) { + a0 = *src++; + src++; + src++; + a0 = a0 * shapmat->mat[0][0]; + if (shapmat->useluts) + a0 = jas_cmshapmatlut_lookup(&shapmat->luts[0], a0); + *dst++ = a0; + } + } + } + + return 0; +} + +static void jas_cmshapmatlut_init(jas_cmshapmatlut_t *lut) +{ + lut->data = 0; + lut->size = 0; +} + +static void jas_cmshapmatlut_cleanup(jas_cmshapmatlut_t *lut) +{ + if (lut->data) { + jas_free(lut->data); + lut->data = 0; + } + lut->size = 0; +} + +static double gammafn(double x, double gamma) +{ + if (x == 0.0) + return 0.0; + return pow(x, gamma); +} + +static int jas_cmshapmatlut_set(jas_cmshapmatlut_t *lut, jas_icccurv_t *curv) +{ + jas_cmreal_t gamma; + int i; + gamma = 0; + jas_cmshapmatlut_cleanup(lut); + if (curv->numents == 0) { + lut->size = 2; + if (!(lut->data = jas_malloc(lut->size * sizeof(jas_cmreal_t)))) + goto error; + lut->data[0] = 0.0; + lut->data[1] = 1.0; + } else if (curv->numents == 1) { + lut->size = 256; + if (!(lut->data = jas_malloc(lut->size * sizeof(jas_cmreal_t)))) + goto error; + gamma = curv->ents[0] / 256.0; + for (i = 0; i < lut->size; ++i) { + lut->data[i] = gammafn(i / (double) (lut->size - 1), gamma); + } + } else { + lut->size = curv->numents; + if (!(lut->data = jas_malloc(lut->size * sizeof(jas_cmreal_t)))) + goto error; + for (i = 0; i < lut->size; ++i) { + lut->data[i] = curv->ents[i] / 65535.0; + } + } + return 0; +error: + return -1; +} + +static jas_cmreal_t jas_cmshapmatlut_lookup(jas_cmshapmatlut_t *lut, jas_cmreal_t x) +{ + jas_cmreal_t t; + int lo; + int hi; + t = x * (lut->size - 1); + lo = floor(t); + if (lo < 0) + return lut->data[0]; + hi = ceil(t); + if (hi >= lut->size) + return lut->data[lut->size - 1]; + return lut->data[lo] + (t - lo) * (lut->data[hi] - lut->data[lo]); +} + +static int jas_cmshapmatlut_invert(jas_cmshapmatlut_t *invlut, + jas_cmshapmatlut_t *lut, int n) +{ + int i; + int j; + int k; + jas_cmreal_t ax; + jas_cmreal_t ay; + jas_cmreal_t bx; + jas_cmreal_t by; + jas_cmreal_t sx; + jas_cmreal_t sy; + assert(n >= 2); + if (invlut->data) { + jas_free(invlut->data); + invlut->data = 0; + } + /* The sample values should be nondecreasing. */ + for (i = 1; i < lut->size; ++i) { + if (lut->data[i - 1] > lut->data[i]) { + assert(0); + return -1; + } + } + if (!(invlut->data = jas_malloc(n * sizeof(jas_cmreal_t)))) + return -1; + invlut->size = n; + for (i = 0; i < invlut->size; ++i) { + sy = ((double) i) / (invlut->size - 1); + sx = 1.0; + for (j = 0; j < lut->size; ++j) { + ay = lut->data[j]; + if (sy == ay) { + for (k = j + 1; k < lut->size; ++k) { + by = lut->data[k]; + if (by != sy) + break; +#if 0 +assert(0); +#endif + } + if (k < lut->size) { + --k; + ax = ((double) j) / (lut->size - 1); + bx = ((double) k) / (lut->size - 1); + sx = (ax + bx) / 2.0; + } + break; + } + if (j < lut->size - 1) { + by = lut->data[j + 1]; + if (sy > ay && sy < by) { + ax = ((double) j) / (lut->size - 1); + bx = ((double) j + 1) / (lut->size - 1); + sx = ax + + (sy - ay) / (by - ay) * (bx - ax); + break; + } + } + } + invlut->data[i] = sx; + } +#if 0 +for (i=0;i<lut->size;++i) + jas_eprintf("lut[%d]=%f ", i, lut->data[i]); +for (i=0;i<invlut->size;++i) + jas_eprintf("invlut[%d]=%f ", i, invlut->data[i]); +#endif + return 0; +} + +static int jas_cmshapmat_invmat(jas_cmreal_t out[3][4], jas_cmreal_t in[3][4]) +{ + jas_cmreal_t d; + d = in[0][0] * (in[1][1] * in[2][2] - in[1][2] * in[2][1]) + - in[0][1] * (in[1][0] * in[2][2] - in[1][2] * in[2][0]) + + in[0][2] * (in[1][0] * in[2][1] - in[1][1] * in[2][0]); +#if 0 +jas_eprintf("delta=%f\n", d); +#endif + if (JAS_ABS(d) < 1e-6) + return -1; + out[0][0] = (in[1][1] * in[2][2] - in[1][2] * in[2][1]) / d; + out[1][0] = -(in[1][0] * in[2][2] - in[1][2] * in[2][0]) / d; + out[2][0] = (in[1][0] * in[2][1] - in[1][1] * in[2][0]) / d; + out[0][1] = -(in[0][1] * in[2][2] - in[0][2] * in[2][1]) / d; + out[1][1] = (in[0][0] * in[2][2] - in[0][2] * in[2][0]) / d; + out[2][1] = -(in[0][0] * in[2][1] - in[0][1] * in[2][0]) / d; + out[0][2] = (in[0][1] * in[1][2] - in[0][2] * in[1][1]) / d; + out[1][2] = -(in[0][0] * in[1][2] - in[1][0] * in[0][2]) / d; + out[2][2] = (in[0][0] * in[1][1] - in[0][1] * in[1][0]) / d; + out[0][3] = -in[0][3]; + out[1][3] = -in[1][3]; + out[2][3] = -in[2][3]; +#if 0 +jas_eprintf("[ %f %f %f %f ]\n[ %f %f %f %f ]\n[ %f %f %f %f ]\n", +in[0][0], in[0][1], in[0][2], in[0][3], +in[1][0], in[1][1], in[1][2], in[1][3], +in[2][0], in[2][1], in[2][2], in[2][3]); +jas_eprintf("[ %f %f %f %f ]\n[ %f %f %f %f ]\n[ %f %f %f %f ]\n", +out[0][0], out[0][1], out[0][2], out[0][3], +out[1][0], out[1][1], out[1][2], out[1][3], +out[2][0], out[2][1], out[2][2], out[2][3]); +#endif + return 0; +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static int icctoclrspc(int iccclrspc, int refflag) +{ + if (refflag) { + switch (iccclrspc) { + case JAS_ICC_COLORSPC_XYZ: + return JAS_CLRSPC_CIEXYZ; + case JAS_ICC_COLORSPC_LAB: + return JAS_CLRSPC_CIELAB; + default: + abort(); + break; + } + } else { + switch (iccclrspc) { + case JAS_ICC_COLORSPC_YCBCR: + return JAS_CLRSPC_GENYCBCR; + case JAS_ICC_COLORSPC_RGB: + return JAS_CLRSPC_GENRGB; + case JAS_ICC_COLORSPC_GRAY: + return JAS_CLRSPC_GENGRAY; + default: + abort(); + break; + } + } +} + +static int mono(jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retpxformseq) +{ + jas_iccattrval_t *graytrc; + jas_cmshapmat_t *shapmat; + jas_cmpxform_t *pxform; + jas_cmpxformseq_t *pxformseq; + jas_cmshapmatlut_t lut; + + jas_cmshapmatlut_init(&lut); + if (!(graytrc = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_GRYTRC)) || + graytrc->type != JAS_ICC_TYPE_CURV) + goto error; + if (!(pxform = jas_cmpxform_createshapmat())) + goto error; + shapmat = &pxform->data.shapmat; + if (!(pxformseq = jas_cmpxformseq_create())) + goto error; + if (jas_cmpxformseq_insertpxform(pxformseq, -1, pxform)) + goto error; + + pxform->numinchans = 1; + pxform->numoutchans = 3; + + shapmat->mono = 1; + shapmat->useluts = 1; + shapmat->usemat = 1; + if (!op) { + shapmat->order = 0; + shapmat->mat[0][0] = 0.9642; + shapmat->mat[1][0] = 1.0; + shapmat->mat[2][0] = 0.8249; + if (jas_cmshapmatlut_set(&shapmat->luts[0], &graytrc->data.curv)) + goto error; + } else { + shapmat->order = 1; + shapmat->mat[0][0] = 1.0 / 0.9642; + shapmat->mat[1][0] = 1.0; + shapmat->mat[2][0] = 1.0 / 0.8249; + jas_cmshapmatlut_init(&lut); + if (jas_cmshapmatlut_set(&lut, &graytrc->data.curv)) + goto error; + if (jas_cmshapmatlut_invert(&shapmat->luts[0], &lut, lut.size)) + goto error; + jas_cmshapmatlut_cleanup(&lut); + } + jas_iccattrval_destroy(graytrc); + jas_cmpxform_destroy(pxform); + *retpxformseq = pxformseq; + return 0; +error: + return -1; +} + +static int triclr(jas_iccprof_t *iccprof, int op, jas_cmpxformseq_t **retpxformseq) +{ + int i; + jas_iccattrval_t *trcs[3]; + jas_iccattrval_t *cols[3]; + jas_cmshapmat_t *shapmat; + jas_cmpxform_t *pxform; + jas_cmpxformseq_t *pxformseq; + jas_cmreal_t mat[3][4]; + jas_cmshapmatlut_t lut; + + pxform = 0; + pxformseq = 0; + for (i = 0; i < 3; ++i) { + trcs[i] = 0; + cols[i] = 0; + } + jas_cmshapmatlut_init(&lut); + + if (!(trcs[0] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_REDTRC)) || + !(trcs[1] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_GRNTRC)) || + !(trcs[2] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_BLUTRC)) || + !(cols[0] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_REDMATCOL)) || + !(cols[1] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_GRNMATCOL)) || + !(cols[2] = jas_iccprof_getattr(iccprof, JAS_ICC_TAG_BLUMATCOL))) + goto error; + for (i = 0; i < 3; ++i) { + if (trcs[i]->type != JAS_ICC_TYPE_CURV || + cols[i]->type != JAS_ICC_TYPE_XYZ) + goto error; + } + if (!(pxform = jas_cmpxform_createshapmat())) + goto error; + pxform->numinchans = 3; + pxform->numoutchans = 3; + shapmat = &pxform->data.shapmat; + if (!(pxformseq = jas_cmpxformseq_create())) + goto error; + if (jas_cmpxformseq_insertpxform(pxformseq, -1, pxform)) + goto error; + shapmat->mono = 0; + shapmat->useluts = 1; + shapmat->usemat = 1; + if (!op) { + shapmat->order = 0; + for (i = 0; i < 3; ++i) { + shapmat->mat[0][i] = cols[i]->data.xyz.x / 65536.0; + shapmat->mat[1][i] = cols[i]->data.xyz.y / 65536.0; + shapmat->mat[2][i] = cols[i]->data.xyz.z / 65536.0; + } + for (i = 0; i < 3; ++i) + shapmat->mat[i][3] = 0.0; + for (i = 0; i < 3; ++i) { + if (jas_cmshapmatlut_set(&shapmat->luts[i], &trcs[i]->data.curv)) + goto error; + } + } else { + shapmat->order = 1; + for (i = 0; i < 3; ++i) { + mat[0][i] = cols[i]->data.xyz.x / 65536.0; + mat[1][i] = cols[i]->data.xyz.y / 65536.0; + mat[2][i] = cols[i]->data.xyz.z / 65536.0; + } + for (i = 0; i < 3; ++i) + mat[i][3] = 0.0; + if (jas_cmshapmat_invmat(shapmat->mat, mat)) + goto error; + for (i = 0; i < 3; ++i) { + jas_cmshapmatlut_init(&lut); + if (jas_cmshapmatlut_set(&lut, &trcs[i]->data.curv)) + goto error; + if (jas_cmshapmatlut_invert(&shapmat->luts[i], &lut, lut.size)) + goto error; + jas_cmshapmatlut_cleanup(&lut); + } + } + for (i = 0; i < 3; ++i) { + jas_iccattrval_destroy(trcs[i]); + jas_iccattrval_destroy(cols[i]); + } + jas_cmpxform_destroy(pxform); + *retpxformseq = pxformseq; + return 0; + +error: + + for (i = 0; i < 3; ++i) { + if (trcs[i]) { + jas_iccattrval_destroy(trcs[i]); + } + if (cols[i]) { + jas_iccattrval_destroy(cols[i]); + } + } + if (pxformseq) { + jas_cmpxformseq_destroy(pxformseq); + } + if (pxform) { + jas_cmpxform_destroy(pxform); + } + + return -1; +} + +static int jas_cmgetint(long **bufptr, int sgnd, int prec, long *val) +{ + long v; + int m; + v = **bufptr; + if (sgnd) { + m = (1 << (prec - 1)); + if (v < -m || v >= m) + return -1; + } else { + if (v < 0 || v >= (1 << prec)) + return -1; + } + ++(*bufptr); + *val = v; + return 0; +} + +static int jas_cmputint(long **bufptr, int sgnd, int prec, long val) +{ + int m; + if (sgnd) { + m = (1 << (prec - 1)); + if (val < -m || val >= m) + return -1; + } else { + if (val < 0 || val >= (1 << prec)) + return -1; + } + **bufptr = val; + ++(*bufptr); + return 0; +} + +int jas_clrspc_numchans(int clrspc) +{ + switch (jas_clrspc_fam(clrspc)) { + case JAS_CLRSPC_FAM_XYZ: + case JAS_CLRSPC_FAM_LAB: + case JAS_CLRSPC_FAM_RGB: + case JAS_CLRSPC_FAM_YCBCR: + return 3; + break; + case JAS_CLRSPC_FAM_GRAY: + return 1; + break; + default: + abort(); + break; + } +} + +jas_iccprof_t *jas_iccprof_createfromcmprof(jas_cmprof_t *prof) +{ + return jas_iccprof_copy(prof->iccprof); +} diff --git a/src/libjasper/base/jas_debug.c b/src/libjasper/base/jas_debug.c new file mode 100644 index 0000000..8a762d5 --- /dev/null +++ b/src/libjasper/base/jas_debug.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include <stdarg.h> +#include <stdio.h> + +#include "jasper/jas_types.h" +#include "jasper/jas_debug.h" + +/******************************************************************************\ +* Local data. +\******************************************************************************/ + +static int jas_dbglevel = 0; +/* The debug level. */ + +/******************************************************************************\ +* Code for getting/setting the debug level. +\******************************************************************************/ + +/* Set the library debug level. */ +int jas_setdbglevel(int dbglevel) +{ + int olddbglevel; + + /* Save the old debug level. */ + olddbglevel = jas_dbglevel; + + /* Change the debug level. */ + jas_dbglevel = dbglevel; + + /* Return the old debug level. */ + return olddbglevel; +} + +/* Get the library debug level. */ +int jas_getdbglevel() +{ + return jas_dbglevel; +} + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +/* Perform formatted output to standard error. */ +int jas_eprintf(const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfprintf(stderr, fmt, ap); + va_end(ap); + return ret; +} + +/* Dump memory to a stream. */ +int jas_memdump(FILE *out, void *data, size_t len) +{ + size_t i; + size_t j; + uchar *dp; + dp = data; + for (i = 0; i < len; i += 16) { + fprintf(out, "%04x:", i); + for (j = 0; j < 16; ++j) { + if (i + j < len) { + fprintf(out, " %02x", dp[i + j]); + } + } + fprintf(out, "\n"); + } + return 0; +} diff --git a/src/libjasper/base/jas_getopt.c b/src/libjasper/base/jas_getopt.c new file mode 100644 index 0000000..efb472e --- /dev/null +++ b/src/libjasper/base/jas_getopt.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 1999-2000, Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Command Line Option Parsing Library + * + * $Id: jas_getopt.c,v 1.1 2008/10/17 06:14:59 scuri Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include <stdio.h> +#include <string.h> + +#include "jasper/jas_getopt.h" +#include "jasper/jas_math.h" + +/******************************************************************************\ +* Global data. +\******************************************************************************/ + +int jas_optind = 0; +int jas_opterr = 1; +char *jas_optarg = 0; + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +static jas_opt_t *jas_optlookup(jas_opt_t *opts, char *name) +{ + jas_opt_t *opt; + + for (opt = opts; opt->id >= 0 && opt->name; ++opt) { + if (!strcmp(opt->name, name)) { + return opt; + } + } + return 0; +} + +int jas_getopt(int argc, char **argv, jas_opt_t *opts) +{ + char *cp; + int id; + int hasarg; + jas_opt_t *opt; + char *s; + + if (!jas_optind) { + jas_optind = JAS_MIN(1, argc); + } + while (jas_optind < argc) { + s = cp = argv[jas_optind]; + if (*cp == '-') { + /* We are processing an option. */ + ++jas_optind; + if (*++cp == '-') { + /* We are processing a long option. */ + ++cp; + if (*cp == '\0') { + /* This is the end of the options. */ + return JAS_GETOPT_EOF; + } + if (!(opt = jas_optlookup(opts, cp))) { + if (jas_opterr) { + jas_eprintf("unknown long option %s\n", s); + } + return JAS_GETOPT_ERR; + } + hasarg = (opt->flags & JAS_OPT_HASARG) != 0; + id = opt->id; + } else { + /* We are processing a short option. */ + if (strlen(cp) != 1 || + !(opt = jas_optlookup(opts, cp))) { + if (jas_opterr) { + jas_eprintf("unknown short option %s\n", s); + } + return JAS_GETOPT_ERR; + } + hasarg = (opt->flags & JAS_OPT_HASARG) != 0; + id = opt->id; + } + if (hasarg) { + /* The option has an argument. */ + if (jas_optind >= argc) { + if (jas_opterr) { + jas_eprintf("missing argument for option %s\n", s); + } + return JAS_GETOPT_ERR; + } + jas_optarg = argv[jas_optind]; + ++jas_optind; + } else { + /* The option does not have an argument. */ + jas_optarg = 0; + } + return id; + } else { + /* We are not processing an option. */ + return JAS_GETOPT_EOF; + } + } + return JAS_GETOPT_EOF; +} diff --git a/src/libjasper/base/jas_icc.c b/src/libjasper/base/jas_icc.c new file mode 100644 index 0000000..e5a0a2e --- /dev/null +++ b/src/libjasper/base/jas_icc.c @@ -0,0 +1,1722 @@ +/* + * Copyright (c) 2002-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#include <assert.h> +#include <jasper/jas_config.h> +#include <jasper/jas_types.h> +#include <jasper/jas_malloc.h> +#include <jasper/jas_debug.h> +#include <jasper/jas_icc.h> +#include <jasper/jas_cm.h> +#include <jasper/jas_stream.h> +#include <jasper/jas_string.h> + +#include <stdlib.h> +#include <ctype.h> + +#define jas_iccputuint8(out, val) jas_iccputuint(out, 1, val) +#define jas_iccputuint16(out, val) jas_iccputuint(out, 2, val) +#define jas_iccputsint32(out, val) jas_iccputsint(out, 4, val) +#define jas_iccputuint32(out, val) jas_iccputuint(out, 4, val) +#define jas_iccputuint64(out, val) jas_iccputuint(out, 8, val) + +static jas_iccattrval_t *jas_iccattrval_create0(void); + +static int jas_iccgetuint(jas_stream_t *in, int n, ulonglong *val); +static int jas_iccgetuint8(jas_stream_t *in, jas_iccuint8_t *val); +static int jas_iccgetuint16(jas_stream_t *in, jas_iccuint16_t *val); +static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val); +static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val); +static int jas_iccgetuint64(jas_stream_t *in, jas_iccuint64_t *val); +static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val); +static int jas_iccputsint(jas_stream_t *out, int n, longlong val); +static jas_iccprof_t *jas_iccprof_create(void); +static int jas_iccprof_readhdr(jas_stream_t *in, jas_icchdr_t *hdr); +static int jas_iccprof_writehdr(jas_stream_t *out, jas_icchdr_t *hdr); +static int jas_iccprof_gettagtab(jas_stream_t *in, jas_icctagtab_t *tagtab); +static void jas_iccprof_sorttagtab(jas_icctagtab_t *tagtab); +static int jas_iccattrtab_lookup(jas_iccattrtab_t *attrtab, jas_iccuint32_t name); +static jas_iccattrtab_t *jas_iccattrtab_copy(jas_iccattrtab_t *attrtab); +static jas_iccattrvalinfo_t *jas_iccattrvalinfo_lookup(jas_iccsig_t name); +static int jas_iccgettime(jas_stream_t *in, jas_icctime_t *time); +static int jas_iccgetxyz(jas_stream_t *in, jas_iccxyz_t *xyz); +static int jas_icctagtabent_cmp(const void *src, const void *dst); + +static void jas_icccurv_destroy(jas_iccattrval_t *attrval); +static int jas_icccurv_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval); +static int jas_icccurv_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt); +static int jas_icccurv_getsize(jas_iccattrval_t *attrval); +static int jas_icccurv_output(jas_iccattrval_t *attrval, jas_stream_t *out); +static void jas_icccurv_dump(jas_iccattrval_t *attrval, FILE *out); + +static void jas_icctxtdesc_destroy(jas_iccattrval_t *attrval); +static int jas_icctxtdesc_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval); +static int jas_icctxtdesc_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt); +static int jas_icctxtdesc_getsize(jas_iccattrval_t *attrval); +static int jas_icctxtdesc_output(jas_iccattrval_t *attrval, jas_stream_t *out); +static void jas_icctxtdesc_dump(jas_iccattrval_t *attrval, FILE *out); + +static void jas_icctxt_destroy(jas_iccattrval_t *attrval); +static int jas_icctxt_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval); +static int jas_icctxt_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt); +static int jas_icctxt_getsize(jas_iccattrval_t *attrval); +static int jas_icctxt_output(jas_iccattrval_t *attrval, jas_stream_t *out); +static void jas_icctxt_dump(jas_iccattrval_t *attrval, FILE *out); + +static int jas_iccxyz_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt); +static int jas_iccxyz_getsize(jas_iccattrval_t *attrval); +static int jas_iccxyz_output(jas_iccattrval_t *attrval, jas_stream_t *out); +static void jas_iccxyz_dump(jas_iccattrval_t *attrval, FILE *out); + +static jas_iccattrtab_t *jas_iccattrtab_create(void); +static void jas_iccattrtab_destroy(jas_iccattrtab_t *tab); +static int jas_iccattrtab_resize(jas_iccattrtab_t *tab, int maxents); +static int jas_iccattrtab_add(jas_iccattrtab_t *attrtab, int i, + jas_iccuint32_t name, jas_iccattrval_t *val); +static int jas_iccattrtab_replace(jas_iccattrtab_t *attrtab, int i, + jas_iccuint32_t name, jas_iccattrval_t *val); +static void jas_iccattrtab_delete(jas_iccattrtab_t *attrtab, int i); +static long jas_iccpadtomult(long x, long y); +static int jas_iccattrtab_get(jas_iccattrtab_t *attrtab, int i, + jas_iccattrname_t *name, jas_iccattrval_t **val); +static int jas_iccprof_puttagtab(jas_stream_t *out, jas_icctagtab_t *tagtab); + +static void jas_icclut16_destroy(jas_iccattrval_t *attrval); +static int jas_icclut16_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval); +static int jas_icclut16_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt); +static int jas_icclut16_getsize(jas_iccattrval_t *attrval); +static int jas_icclut16_output(jas_iccattrval_t *attrval, jas_stream_t *out); +static void jas_icclut16_dump(jas_iccattrval_t *attrval, FILE *out); + +static void jas_icclut8_destroy(jas_iccattrval_t *attrval); +static int jas_icclut8_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval); +static int jas_icclut8_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt); +static int jas_icclut8_getsize(jas_iccattrval_t *attrval); +static int jas_icclut8_output(jas_iccattrval_t *attrval, jas_stream_t *out); +static void jas_icclut8_dump(jas_iccattrval_t *attrval, FILE *out); + +static int jas_iccputtime(jas_stream_t *out, jas_icctime_t *ctime); +static int jas_iccputxyz(jas_stream_t *out, jas_iccxyz_t *xyz); + +static long jas_iccpowi(int x, int n); + +static char *jas_iccsigtostr(int sig, char *buf); + + +jas_iccattrvalinfo_t jas_iccattrvalinfos[] = { + {JAS_ICC_TYPE_CURV, {jas_icccurv_destroy, jas_icccurv_copy, + jas_icccurv_input, jas_icccurv_output, jas_icccurv_getsize, + jas_icccurv_dump}}, + {JAS_ICC_TYPE_XYZ, {0, 0, jas_iccxyz_input, jas_iccxyz_output, + jas_iccxyz_getsize, jas_iccxyz_dump}}, + {JAS_ICC_TYPE_TXTDESC, {jas_icctxtdesc_destroy, + jas_icctxtdesc_copy, jas_icctxtdesc_input, jas_icctxtdesc_output, + jas_icctxtdesc_getsize, jas_icctxtdesc_dump}}, + {JAS_ICC_TYPE_TXT, {jas_icctxt_destroy, jas_icctxt_copy, + jas_icctxt_input, jas_icctxt_output, jas_icctxt_getsize, + jas_icctxt_dump}}, + {JAS_ICC_TYPE_LUT8, {jas_icclut8_destroy, jas_icclut8_copy, + jas_icclut8_input, jas_icclut8_output, jas_icclut8_getsize, + jas_icclut8_dump}}, + {JAS_ICC_TYPE_LUT16, {jas_icclut16_destroy, jas_icclut16_copy, + jas_icclut16_input, jas_icclut16_output, jas_icclut16_getsize, + jas_icclut16_dump}}, + {0, {0, 0, 0, 0, 0, 0}} +}; + +typedef struct { + jas_iccuint32_t tag; + char *name; +} jas_icctaginfo_t; + +/******************************************************************************\ +* profile class +\******************************************************************************/ + +static jas_iccprof_t *jas_iccprof_create() +{ + jas_iccprof_t *prof; + prof = 0; + if (!(prof = jas_malloc(sizeof(jas_iccprof_t)))) { + goto error; + } + if (!(prof->attrtab = jas_iccattrtab_create())) + goto error; + memset(&prof->hdr, 0, sizeof(jas_icchdr_t)); + prof->tagtab.numents = 0; + prof->tagtab.ents = 0; + return prof; +error: + if (prof) + jas_iccprof_destroy(prof); + return 0; +} + +jas_iccprof_t *jas_iccprof_copy(jas_iccprof_t *prof) +{ + jas_iccprof_t *newprof; + newprof = 0; + if (!(newprof = jas_iccprof_create())) + goto error; + newprof->hdr = prof->hdr; + newprof->tagtab.numents = 0; + newprof->tagtab.ents = 0; + assert(newprof->attrtab); + jas_iccattrtab_destroy(newprof->attrtab); + if (!(newprof->attrtab = jas_iccattrtab_copy(prof->attrtab))) + goto error; + return newprof; +error: + if (newprof) + jas_iccprof_destroy(newprof); + return 0; +} + +void jas_iccprof_destroy(jas_iccprof_t *prof) +{ + if (prof->attrtab) + jas_iccattrtab_destroy(prof->attrtab); + if (prof->tagtab.ents) + jas_free(prof->tagtab.ents); + jas_free(prof); +} + +void jas_iccprof_dump(jas_iccprof_t *prof, FILE *out) +{ + jas_iccattrtab_dump(prof->attrtab, out); +} + +jas_iccprof_t *jas_iccprof_load(jas_stream_t *in) +{ + jas_iccprof_t *prof; + int numtags; + long curoff; + long reloff; + long prevoff; + jas_iccsig_t type; + jas_iccattrval_t *attrval; + jas_iccattrval_t *prevattrval; + jas_icctagtabent_t *tagtabent; + jas_iccattrvalinfo_t *attrvalinfo; + int i; + int len; + + prof = 0; + attrval = 0; + + if (!(prof = jas_iccprof_create())) { + goto error; + } + + if (jas_iccprof_readhdr(in, &prof->hdr)) { + jas_eprintf("cannot get header\n"); + goto error; + } + if (jas_iccprof_gettagtab(in, &prof->tagtab)) { + jas_eprintf("cannot get tab table\n"); + goto error; + } + jas_iccprof_sorttagtab(&prof->tagtab); + + numtags = prof->tagtab.numents; + curoff = JAS_ICC_HDRLEN + 4 + 12 * numtags; + prevoff = 0; + prevattrval = 0; + for (i = 0; i < numtags; ++i) { + tagtabent = &prof->tagtab.ents[i]; + if (tagtabent->off == JAS_CAST(jas_iccuint32_t, prevoff)) { + if (prevattrval) { + if (!(attrval = jas_iccattrval_clone(prevattrval))) + goto error; + if (jas_iccprof_setattr(prof, tagtabent->tag, attrval)) + goto error; + jas_iccattrval_destroy(attrval); + } else { +#if 0 + jas_eprintf("warning: skipping unknown tag type\n"); +#endif + } + continue; + } + reloff = tagtabent->off - curoff; + if (reloff > 0) { + if (jas_stream_gobble(in, reloff) != reloff) + goto error; + curoff += reloff; + } else if (reloff < 0) { + /* This should never happen since we read the tagged + element data in a single pass. */ + abort(); + } + prevoff = curoff; + if (jas_iccgetuint32(in, &type)) { + goto error; + } + if (jas_stream_gobble(in, 4) != 4) { + goto error; + } + curoff += 8; + if (!(attrvalinfo = jas_iccattrvalinfo_lookup(type))) { +#if 0 + jas_eprintf("warning: skipping unknown tag type\n"); +#endif + prevattrval = 0; + continue; + } + if (!(attrval = jas_iccattrval_create(type))) { + goto error; + } + len = tagtabent->len - 8; + if ((*attrval->ops->input)(attrval, in, len)) { + goto error; + } + curoff += len; + if (jas_iccprof_setattr(prof, tagtabent->tag, attrval)) { + goto error; + } + prevattrval = attrval; /* This is correct, but slimey. */ + jas_iccattrval_destroy(attrval); + attrval = 0; + } + + return prof; + +error: + if (prof) + jas_iccprof_destroy(prof); + if (attrval) + jas_iccattrval_destroy(attrval); + return 0; +} + +int jas_iccprof_save(jas_iccprof_t *prof, jas_stream_t *out) +{ + long curoff; + long reloff; + long newoff; + int i; + int j; + jas_icctagtabent_t *tagtabent; + jas_icctagtabent_t *sharedtagtabent; + jas_icctagtabent_t *tmptagtabent; + jas_iccuint32_t attrname; + jas_iccattrval_t *attrval; + jas_icctagtab_t *tagtab; + + tagtab = &prof->tagtab; + if (!(tagtab->ents = jas_malloc(prof->attrtab->numattrs * + sizeof(jas_icctagtabent_t)))) + goto error; + tagtab->numents = prof->attrtab->numattrs; + curoff = JAS_ICC_HDRLEN + 4 + 12 * tagtab->numents; + for (i = 0; i < JAS_CAST(int, tagtab->numents); ++i) { + tagtabent = &tagtab->ents[i]; + if (jas_iccattrtab_get(prof->attrtab, i, &attrname, &attrval)) + goto error; + assert(attrval->ops->output); + tagtabent->tag = attrname; + tagtabent->data = &attrval->data; + sharedtagtabent = 0; + for (j = 0; j < i; ++j) { + tmptagtabent = &tagtab->ents[j]; + if (tagtabent->data == tmptagtabent->data) { + sharedtagtabent = tmptagtabent; + break; + } + } + if (sharedtagtabent) { + tagtabent->off = sharedtagtabent->off; + tagtabent->len = sharedtagtabent->len; + tagtabent->first = sharedtagtabent; + } else { + tagtabent->off = curoff; + tagtabent->len = (*attrval->ops->getsize)(attrval) + 8; + tagtabent->first = 0; + if (i < JAS_CAST(int, tagtab->numents - 1)) { + curoff = jas_iccpadtomult(curoff + tagtabent->len, 4); + } else { + curoff += tagtabent->len; + } + } + jas_iccattrval_destroy(attrval); + } + prof->hdr.size = curoff; + if (jas_iccprof_writehdr(out, &prof->hdr)) + goto error; + if (jas_iccprof_puttagtab(out, &prof->tagtab)) + goto error; + curoff = JAS_ICC_HDRLEN + 4 + 12 * tagtab->numents; + for (i = 0; i < JAS_CAST(int, tagtab->numents);) { + tagtabent = &tagtab->ents[i]; + assert(curoff == JAS_CAST(long, tagtabent->off)); + if (jas_iccattrtab_get(prof->attrtab, i, &attrname, &attrval)) + goto error; + if (jas_iccputuint32(out, attrval->type) || jas_stream_pad(out, + 4, 0) != 4) + goto error; + if ((*attrval->ops->output)(attrval, out)) + goto error; + jas_iccattrval_destroy(attrval); + curoff += tagtabent->len; + ++i; + while (i < JAS_CAST(int, tagtab->numents) && + tagtab->ents[i].first) + ++i; + newoff = (i < JAS_CAST(int, tagtab->numents)) ? + tagtab->ents[i].off : prof->hdr.size; + reloff = newoff - curoff; + assert(reloff >= 0); + if (reloff > 0) { + if (jas_stream_pad(out, reloff, 0) != reloff) + goto error; + curoff += reloff; + } + } + return 0; +error: + /* XXX - need to free some resources here */ + return -1; +} + +static int jas_iccprof_writehdr(jas_stream_t *out, jas_icchdr_t *hdr) +{ + if (jas_iccputuint32(out, hdr->size) || + jas_iccputuint32(out, hdr->cmmtype) || + jas_iccputuint32(out, hdr->version) || + jas_iccputuint32(out, hdr->clas) || + jas_iccputuint32(out, hdr->colorspc) || + jas_iccputuint32(out, hdr->refcolorspc) || + jas_iccputtime(out, &hdr->ctime) || + jas_iccputuint32(out, hdr->magic) || + jas_iccputuint32(out, hdr->platform) || + jas_iccputuint32(out, hdr->flags) || + jas_iccputuint32(out, hdr->maker) || + jas_iccputuint32(out, hdr->model) || + jas_iccputuint64(out, hdr->attr) || + jas_iccputuint32(out, hdr->intent) || + jas_iccputxyz(out, &hdr->illum) || + jas_iccputuint32(out, hdr->creator) || + jas_stream_pad(out, 44, 0) != 44) + return -1; + return 0; +} + +static int jas_iccprof_puttagtab(jas_stream_t *out, jas_icctagtab_t *tagtab) +{ + int i; + jas_icctagtabent_t *tagtabent; + if (jas_iccputuint32(out, tagtab->numents)) + goto error; + for (i = 0; i < JAS_CAST(int, tagtab->numents); ++i) { + tagtabent = &tagtab->ents[i]; + if (jas_iccputuint32(out, tagtabent->tag) || + jas_iccputuint32(out, tagtabent->off) || + jas_iccputuint32(out, tagtabent->len)) + goto error; + } + return 0; +error: + return -1; +} + +static int jas_iccprof_readhdr(jas_stream_t *in, jas_icchdr_t *hdr) +{ + if (jas_iccgetuint32(in, &hdr->size) || + jas_iccgetuint32(in, &hdr->cmmtype) || + jas_iccgetuint32(in, &hdr->version) || + jas_iccgetuint32(in, &hdr->clas) || + jas_iccgetuint32(in, &hdr->colorspc) || + jas_iccgetuint32(in, &hdr->refcolorspc) || + jas_iccgettime(in, &hdr->ctime) || + jas_iccgetuint32(in, &hdr->magic) || + jas_iccgetuint32(in, &hdr->platform) || + jas_iccgetuint32(in, &hdr->flags) || + jas_iccgetuint32(in, &hdr->maker) || + jas_iccgetuint32(in, &hdr->model) || + jas_iccgetuint64(in, &hdr->attr) || + jas_iccgetuint32(in, &hdr->intent) || + jas_iccgetxyz(in, &hdr->illum) || + jas_iccgetuint32(in, &hdr->creator) || + jas_stream_gobble(in, 44) != 44) + return -1; + return 0; +} + +static int jas_iccprof_gettagtab(jas_stream_t *in, jas_icctagtab_t *tagtab) +{ + int i; + jas_icctagtabent_t *tagtabent; + + if (tagtab->ents) { + jas_free(tagtab->ents); + tagtab->ents = 0; + } + if (jas_iccgetuint32(in, &tagtab->numents)) + goto error; + if (!(tagtab->ents = jas_malloc(tagtab->numents * + sizeof(jas_icctagtabent_t)))) + goto error; + tagtabent = tagtab->ents; + for (i = 0; i < JAS_CAST(long, tagtab->numents); ++i) { + if (jas_iccgetuint32(in, &tagtabent->tag) || + jas_iccgetuint32(in, &tagtabent->off) || + jas_iccgetuint32(in, &tagtabent->len)) + goto error; + ++tagtabent; + } + return 0; +error: + if (tagtab->ents) { + jas_free(tagtab->ents); + tagtab->ents = 0; + } + return -1; +} + +jas_iccattrval_t *jas_iccprof_getattr(jas_iccprof_t *prof, + jas_iccattrname_t name) +{ + int i; + jas_iccattrval_t *attrval; + if ((i = jas_iccattrtab_lookup(prof->attrtab, name)) < 0) + goto error; + if (!(attrval = jas_iccattrval_clone(prof->attrtab->attrs[i].val))) + goto error; + return attrval; +error: + return 0; +} + +int jas_iccprof_setattr(jas_iccprof_t *prof, jas_iccattrname_t name, + jas_iccattrval_t *val) +{ + int i; + if ((i = jas_iccattrtab_lookup(prof->attrtab, name)) >= 0) { + if (val) { + if (jas_iccattrtab_replace(prof->attrtab, i, name, val)) + goto error; + } else { + jas_iccattrtab_delete(prof->attrtab, i); + } + } else { + if (val) { + if (jas_iccattrtab_add(prof->attrtab, -1, name, val)) + goto error; + } else { + /* NOP */ + } + } + return 0; +error: + return -1; +} + +int jas_iccprof_gethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr) +{ + *hdr = prof->hdr; + return 0; +} + +int jas_iccprof_sethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr) +{ + prof->hdr = *hdr; + return 0; +} + +static void jas_iccprof_sorttagtab(jas_icctagtab_t *tagtab) +{ + qsort(tagtab->ents, tagtab->numents, sizeof(jas_icctagtabent_t), + jas_icctagtabent_cmp); +} + +static int jas_icctagtabent_cmp(const void *src, const void *dst) +{ + jas_icctagtabent_t *srctagtabent = JAS_CAST(jas_icctagtabent_t *, src); + jas_icctagtabent_t *dsttagtabent = JAS_CAST(jas_icctagtabent_t *, dst); + if (srctagtabent->off > dsttagtabent->off) { + return 1; + } else if (srctagtabent->off < dsttagtabent->off) { + return -1; + } + return 0; +} + +static jas_iccattrvalinfo_t *jas_iccattrvalinfo_lookup(jas_iccsig_t type) +{ + jas_iccattrvalinfo_t *info; + info = jas_iccattrvalinfos; + for (info = jas_iccattrvalinfos; info->type; ++info) { + if (info->type == type) { + return info; + } + } + return 0; +} + +static int jas_iccgettime(jas_stream_t *in, jas_icctime_t *time) +{ + if (jas_iccgetuint16(in, &time->year) || + jas_iccgetuint16(in, &time->month) || + jas_iccgetuint16(in, &time->day) || + jas_iccgetuint16(in, &time->hour) || + jas_iccgetuint16(in, &time->min) || + jas_iccgetuint16(in, &time->sec)) { + return -1; + } + return 0; +} + +static int jas_iccgetxyz(jas_stream_t *in, jas_iccxyz_t *xyz) +{ + if (jas_iccgetsint32(in, &xyz->x) || + jas_iccgetsint32(in, &xyz->y) || + jas_iccgetsint32(in, &xyz->z)) { + return -1; + } + return 0; +} + +static int jas_iccputtime(jas_stream_t *out, jas_icctime_t *time) +{ + jas_iccputuint16(out, time->year); + jas_iccputuint16(out, time->month); + jas_iccputuint16(out, time->day); + jas_iccputuint16(out, time->hour); + jas_iccputuint16(out, time->min); + jas_iccputuint16(out, time->sec); + return 0; +} + +static int jas_iccputxyz(jas_stream_t *out, jas_iccxyz_t *xyz) +{ + jas_iccputuint32(out, xyz->x); + jas_iccputuint32(out, xyz->y); + jas_iccputuint32(out, xyz->z); + return 0; +} + +/******************************************************************************\ +* attribute table class +\******************************************************************************/ + +static jas_iccattrtab_t *jas_iccattrtab_create() +{ + jas_iccattrtab_t *tab; + tab = 0; + if (!(tab = jas_malloc(sizeof(jas_iccattrtab_t)))) + goto error; + tab->maxattrs = 0; + tab->numattrs = 0; + tab->attrs = 0; + if (jas_iccattrtab_resize(tab, 32)) + goto error; + return tab; +error: + if (tab) + jas_iccattrtab_destroy(tab); + return 0; +} + +static jas_iccattrtab_t *jas_iccattrtab_copy(jas_iccattrtab_t *attrtab) +{ + jas_iccattrtab_t *newattrtab; + int i; + if (!(newattrtab = jas_iccattrtab_create())) + goto error; + for (i = 0; i < attrtab->numattrs; ++i) { + if (jas_iccattrtab_add(newattrtab, i, attrtab->attrs[i].name, + attrtab->attrs[i].val)) + goto error; + } + return newattrtab; +error: + return 0; +} + +static void jas_iccattrtab_destroy(jas_iccattrtab_t *tab) +{ + if (tab->attrs) { + while (tab->numattrs > 0) { + jas_iccattrtab_delete(tab, 0); + } + jas_free(tab->attrs); + } + jas_free(tab); +} + +void jas_iccattrtab_dump(jas_iccattrtab_t *attrtab, FILE *out) +{ + int i; + jas_iccattr_t *attr; + jas_iccattrval_t *attrval; + jas_iccattrvalinfo_t *info; + char buf[16]; + fprintf(out, "numattrs=%d\n", attrtab->numattrs); + fprintf(out, "---\n"); + for (i = 0; i < attrtab->numattrs; ++i) { + attr = &attrtab->attrs[i]; + attrval = attr->val; + info = jas_iccattrvalinfo_lookup(attrval->type); + if (!info) abort(); + fprintf(out, "attrno=%d; attrname=\"%s\"(0x%08x); attrtype=\"%s\"(0x%08x)\n", + i, + jas_iccsigtostr(attr->name, &buf[0]), + attr->name, + jas_iccsigtostr(attrval->type, &buf[8]), + attrval->type + ); + jas_iccattrval_dump(attrval, out); + fprintf(out, "---\n"); + } +} + +static int jas_iccattrtab_resize(jas_iccattrtab_t *tab, int maxents) +{ + jas_iccattr_t *newattrs; + assert(maxents >= tab->numattrs); + newattrs = tab->attrs ? jas_realloc(tab->attrs, maxents * + sizeof(jas_iccattr_t)) : jas_malloc(maxents * sizeof(jas_iccattr_t)); + if (!newattrs) + return -1; + tab->attrs = newattrs; + tab->maxattrs = maxents; + return 0; +} + +static int jas_iccattrtab_add(jas_iccattrtab_t *attrtab, int i, + jas_iccuint32_t name, jas_iccattrval_t *val) +{ + int n; + jas_iccattr_t *attr; + jas_iccattrval_t *tmpattrval; + tmpattrval = 0; + if (i < 0) { + i = attrtab->numattrs; + } + assert(i >= 0 && i <= attrtab->numattrs); + if (attrtab->numattrs >= attrtab->maxattrs) { + if (jas_iccattrtab_resize(attrtab, attrtab->numattrs + 32)) { + goto error; + } + } + if (!(tmpattrval = jas_iccattrval_clone(val))) + goto error; + n = attrtab->numattrs - i; + if (n > 0) + memmove(&attrtab->attrs[i + 1], &attrtab->attrs[i], + n * sizeof(jas_iccattr_t)); + attr = &attrtab->attrs[i]; + attr->name = name; + attr->val = tmpattrval; + ++attrtab->numattrs; + return 0; +error: + if (tmpattrval) + jas_iccattrval_destroy(tmpattrval); + return -1; +} + +static int jas_iccattrtab_replace(jas_iccattrtab_t *attrtab, int i, + jas_iccuint32_t name, jas_iccattrval_t *val) +{ + jas_iccattrval_t *newval; + jas_iccattr_t *attr; + if (!(newval = jas_iccattrval_clone(val))) + goto error; + attr = &attrtab->attrs[i]; + jas_iccattrval_destroy(attr->val); + attr->name = name; + attr->val = newval; + return 0; +error: + return -1; +} + +static void jas_iccattrtab_delete(jas_iccattrtab_t *attrtab, int i) +{ + int n; + jas_iccattrval_destroy(attrtab->attrs[i].val); + if ((n = attrtab->numattrs - i - 1) > 0) + memmove(&attrtab->attrs[i], &attrtab->attrs[i + 1], + n * sizeof(jas_iccattr_t)); + --attrtab->numattrs; +} + +static int jas_iccattrtab_get(jas_iccattrtab_t *attrtab, int i, + jas_iccattrname_t *name, jas_iccattrval_t **val) +{ + jas_iccattr_t *attr; + if (i < 0 || i >= attrtab->numattrs) + goto error; + attr = &attrtab->attrs[i]; + *name = attr->name; + if (!(*val = jas_iccattrval_clone(attr->val))) + goto error; + return 0; +error: + return -1; +} + +static int jas_iccattrtab_lookup(jas_iccattrtab_t *attrtab, + jas_iccuint32_t name) +{ + int i; + jas_iccattr_t *attr; + for (i = 0; i < attrtab->numattrs; ++i) { + attr = &attrtab->attrs[i]; + if (attr->name == name) + return i; + } + return -1; +} + +/******************************************************************************\ +* attribute value class +\******************************************************************************/ + +jas_iccattrval_t *jas_iccattrval_create(jas_iccuint32_t type) +{ + jas_iccattrval_t *attrval; + jas_iccattrvalinfo_t *info; + + if (!(info = jas_iccattrvalinfo_lookup(type))) + goto error; + if (!(attrval = jas_iccattrval_create0())) + goto error; + attrval->ops = &info->ops; + attrval->type = type; + ++attrval->refcnt; + memset(&attrval->data, 0, sizeof(attrval->data)); + return attrval; +error: + return 0; +} + +jas_iccattrval_t *jas_iccattrval_clone(jas_iccattrval_t *attrval) +{ + ++attrval->refcnt; + return attrval; +} + +void jas_iccattrval_destroy(jas_iccattrval_t *attrval) +{ +#if 0 +jas_eprintf("refcnt=%d\n", attrval->refcnt); +#endif + if (--attrval->refcnt <= 0) { + if (attrval->ops->destroy) + (*attrval->ops->destroy)(attrval); + jas_free(attrval); + } +} + +void jas_iccattrval_dump(jas_iccattrval_t *attrval, FILE *out) +{ + char buf[8]; + jas_iccsigtostr(attrval->type, buf); + fprintf(out, "refcnt = %d; type = 0x%08x %s\n", attrval->refcnt, + attrval->type, jas_iccsigtostr(attrval->type, &buf[0])); + if (attrval->ops->dump) { + (*attrval->ops->dump)(attrval, out); + } +} + +int jas_iccattrval_allowmodify(jas_iccattrval_t **attrvalx) +{ + jas_iccattrval_t *newattrval; + jas_iccattrval_t *attrval = *attrvalx; + newattrval = 0; + if (attrval->refcnt > 1) { + if (!(newattrval = jas_iccattrval_create0())) + goto error; + newattrval->ops = attrval->ops; + newattrval->type = attrval->type; + ++newattrval->refcnt; + if (newattrval->ops->copy) { + if ((*newattrval->ops->copy)(newattrval, attrval)) + goto error; + } else { + memcpy(&newattrval->data, &attrval->data, + sizeof(newattrval->data)); + } + *attrvalx = newattrval; + } + return 0; +error: + if (newattrval) { + jas_free(newattrval); + } + return -1; +} + +static jas_iccattrval_t *jas_iccattrval_create0() +{ + jas_iccattrval_t *attrval; + if (!(attrval = jas_malloc(sizeof(jas_iccattrval_t)))) + return 0; + memset(attrval, 0, sizeof(jas_iccattrval_t)); + attrval->refcnt = 0; + attrval->ops = 0; + attrval->type = 0; + return attrval; +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static int jas_iccxyz_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int len) +{ + if (len != 4 * 3) abort(); + return jas_iccgetxyz(in, &attrval->data.xyz); +} + +static int jas_iccxyz_output(jas_iccattrval_t *attrval, jas_stream_t *out) +{ + jas_iccxyz_t *xyz = &attrval->data.xyz; + if (jas_iccputuint32(out, xyz->x) || + jas_iccputuint32(out, xyz->y) || + jas_iccputuint32(out, xyz->z)) + return -1; + return 0; +} + +static int jas_iccxyz_getsize(jas_iccattrval_t *attrval) +{ + /* Avoid compiler warnings about unused parameters. */ + attrval = 0; + + return 12; +} + +static void jas_iccxyz_dump(jas_iccattrval_t *attrval, FILE *out) +{ + jas_iccxyz_t *xyz = &attrval->data.xyz; + fprintf(out, "(%f, %f, %f)\n", xyz->x / 65536.0, xyz->y / 65536.0, xyz->z / 65536.0); +} + +/******************************************************************************\ +* attribute table class +\******************************************************************************/ + +static void jas_icccurv_destroy(jas_iccattrval_t *attrval) +{ + jas_icccurv_t *curv = &attrval->data.curv; + if (curv->ents) + jas_free(curv->ents); +} + +static int jas_icccurv_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval) +{ + /* Avoid compiler warnings about unused parameters. */ + attrval = 0; + othattrval = 0; + + /* Not yet implemented. */ + abort(); + return -1; +} + +static int jas_icccurv_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt) +{ + jas_icccurv_t *curv = &attrval->data.curv; + unsigned int i; + + curv->numents = 0; + curv->ents = 0; + + if (jas_iccgetuint32(in, &curv->numents)) + goto error; + if (!(curv->ents = jas_malloc(curv->numents * sizeof(jas_iccuint16_t)))) + goto error; + for (i = 0; i < curv->numents; ++i) { + if (jas_iccgetuint16(in, &curv->ents[i])) + goto error; + } + + if (JAS_CAST(int, 4 + 2 * curv->numents) != cnt) + goto error; + return 0; + +error: + jas_icccurv_destroy(attrval); + return -1; +} + +static int jas_icccurv_getsize(jas_iccattrval_t *attrval) +{ + jas_icccurv_t *curv = &attrval->data.curv; + return 4 + 2 * curv->numents; +} + +static int jas_icccurv_output(jas_iccattrval_t *attrval, jas_stream_t *out) +{ + jas_icccurv_t *curv = &attrval->data.curv; + unsigned int i; + + if (jas_iccputuint32(out, curv->numents)) + goto error; + for (i = 0; i < curv->numents; ++i) { + if (jas_iccputuint16(out, curv->ents[i])) + goto error; + } + return 0; +error: + return -1; +} + +static void jas_icccurv_dump(jas_iccattrval_t *attrval, FILE *out) +{ + int i; + jas_icccurv_t *curv = &attrval->data.curv; + fprintf(out, "number of entires = %d\n", curv->numents); + if (curv->numents == 1) { + fprintf(out, "gamma = %f\n", curv->ents[0] / 256.0); + } else { + for (i = 0; i < JAS_CAST(int, curv->numents); ++i) { + if (i < 3 || i >= JAS_CAST(int, curv->numents) - 3) { + fprintf(out, "entry[%d] = %f\n", i, curv->ents[i] / 65535.0); + } + } + } +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static void jas_icctxtdesc_destroy(jas_iccattrval_t *attrval) +{ + jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc; + if (txtdesc->ascdata) + jas_free(txtdesc->ascdata); + if (txtdesc->ucdata) + jas_free(txtdesc->ucdata); +} + +static int jas_icctxtdesc_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval) +{ + jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc; + + /* Avoid compiler warnings about unused parameters. */ + attrval = 0; + othattrval = 0; + txtdesc = 0; + + /* Not yet implemented. */ + abort(); + return -1; +} + +static int jas_icctxtdesc_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt) +{ + int n; + int c; + jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc; + txtdesc->ascdata = 0; + txtdesc->ucdata = 0; + if (jas_iccgetuint32(in, &txtdesc->asclen)) + goto error; + if (!(txtdesc->ascdata = jas_malloc(txtdesc->asclen))) + goto error; + if (jas_stream_read(in, txtdesc->ascdata, txtdesc->asclen) != + JAS_CAST(int, txtdesc->asclen)) + goto error; + txtdesc->ascdata[txtdesc->asclen - 1] = '\0'; + if (jas_iccgetuint32(in, &txtdesc->uclangcode) || + jas_iccgetuint32(in, &txtdesc->uclen)) + goto error; + if (!(txtdesc->ucdata = jas_malloc(txtdesc->uclen * 2))) + goto error; + if (jas_stream_read(in, txtdesc->ucdata, txtdesc->uclen * 2) != + JAS_CAST(int, txtdesc->uclen * 2)) + goto error; + if (jas_iccgetuint16(in, &txtdesc->sccode)) + goto error; + if ((c = jas_stream_getc(in)) == EOF) + goto error; + txtdesc->maclen = c; + if (jas_stream_read(in, txtdesc->macdata, 67) != 67) + goto error; + txtdesc->asclen = strlen(txtdesc->ascdata) + 1; +#define WORKAROUND_BAD_PROFILES +#ifdef WORKAROUND_BAD_PROFILES + n = txtdesc->asclen + txtdesc->uclen * 2 + 15 + 67; + if (n > cnt) { + return -1; + } + if (n < cnt) { + if (jas_stream_gobble(in, cnt - n) != cnt - n) + goto error; + } +#else + if (txtdesc->asclen + txtdesc->uclen * 2 + 15 + 67 != cnt) + return -1; +#endif + return 0; +error: + jas_icctxtdesc_destroy(attrval); + return -1; +} + +static int jas_icctxtdesc_getsize(jas_iccattrval_t *attrval) +{ + jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc; + return strlen(txtdesc->ascdata) + 1 + txtdesc->uclen * 2 + 15 + 67; +} + +static int jas_icctxtdesc_output(jas_iccattrval_t *attrval, jas_stream_t *out) +{ + jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc; + if (jas_iccputuint32(out, txtdesc->asclen) || + jas_stream_puts(out, txtdesc->ascdata) || + jas_stream_putc(out, 0) == EOF || + jas_iccputuint32(out, txtdesc->uclangcode) || + jas_iccputuint32(out, txtdesc->uclen) || + jas_stream_write(out, txtdesc->ucdata, txtdesc->uclen * 2) != JAS_CAST(int, txtdesc->uclen * 2) || + jas_iccputuint16(out, txtdesc->sccode) || + jas_stream_putc(out, txtdesc->maclen) == EOF) + goto error; + if (txtdesc->maclen > 0) { + if (jas_stream_write(out, txtdesc->macdata, 67) != 67) + goto error; + } else { + if (jas_stream_pad(out, 67, 0) != 67) + goto error; + } + return 0; +error: + return -1; +} + +static void jas_icctxtdesc_dump(jas_iccattrval_t *attrval, FILE *out) +{ + jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc; + fprintf(out, "ascii = \"%s\"\n", txtdesc->ascdata); + fprintf(out, "uclangcode = %d; uclen = %d\n", txtdesc->uclangcode, + txtdesc->uclen); + fprintf(out, "sccode = %d\n", txtdesc->sccode); + fprintf(out, "maclen = %d\n", txtdesc->maclen); +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static void jas_icctxt_destroy(jas_iccattrval_t *attrval) +{ + jas_icctxt_t *txt = &attrval->data.txt; + if (txt->string) + jas_free(txt->string); +} + +static int jas_icctxt_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval) +{ + jas_icctxt_t *txt = &attrval->data.txt; + jas_icctxt_t *othtxt = &othattrval->data.txt; + if (!(txt->string = jas_strdup(othtxt->string))) + return -1; + return 0; +} + +static int jas_icctxt_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt) +{ + jas_icctxt_t *txt = &attrval->data.txt; + txt->string = 0; + if (!(txt->string = jas_malloc(cnt))) + goto error; + if (jas_stream_read(in, txt->string, cnt) != cnt) + goto error; + txt->string[cnt - 1] = '\0'; + if (JAS_CAST(int, strlen(txt->string)) + 1 != cnt) + goto error; + return 0; +error: + if (txt->string) + jas_free(txt->string); + return -1; +} + +static int jas_icctxt_getsize(jas_iccattrval_t *attrval) +{ + jas_icctxt_t *txt = &attrval->data.txt; + return strlen(txt->string) + 1; +} + +static int jas_icctxt_output(jas_iccattrval_t *attrval, jas_stream_t *out) +{ + jas_icctxt_t *txt = &attrval->data.txt; + if (jas_stream_puts(out, txt->string) || + jas_stream_putc(out, 0) == EOF) + return -1; + return 0; +} + +static void jas_icctxt_dump(jas_iccattrval_t *attrval, FILE *out) +{ + jas_icctxt_t *txt = &attrval->data.txt; + fprintf(out, "string = \"%s\"\n", txt->string); +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static void jas_icclut8_destroy(jas_iccattrval_t *attrval) +{ + jas_icclut8_t *lut8 = &attrval->data.lut8; + if (lut8->clut) + jas_free(lut8->clut); + if (lut8->intabs) + jas_free(lut8->intabs); + if (lut8->intabsbuf) + jas_free(lut8->intabsbuf); + if (lut8->outtabs) + jas_free(lut8->outtabs); + if (lut8->outtabsbuf) + jas_free(lut8->outtabsbuf); +} + +static int jas_icclut8_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval) +{ + jas_icclut8_t *lut8 = &attrval->data.lut8; + /* Avoid compiler warnings about unused parameters. */ + attrval = 0; + othattrval = 0; + lut8 = 0; + abort(); + return -1; +} + +static int jas_icclut8_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt) +{ + int i; + int j; + int clutsize; + jas_icclut8_t *lut8 = &attrval->data.lut8; + lut8->clut = 0; + lut8->intabs = 0; + lut8->intabsbuf = 0; + lut8->outtabs = 0; + lut8->outtabsbuf = 0; + if (jas_iccgetuint8(in, &lut8->numinchans) || + jas_iccgetuint8(in, &lut8->numoutchans) || + jas_iccgetuint8(in, &lut8->clutlen) || + jas_stream_getc(in) == EOF) + goto error; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + if (jas_iccgetsint32(in, &lut8->e[i][j])) + goto error; + } + } + if (jas_iccgetuint16(in, &lut8->numintabents) || + jas_iccgetuint16(in, &lut8->numouttabents)) + goto error; + clutsize = jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans; + if (!(lut8->clut = jas_malloc(clutsize * sizeof(jas_iccuint8_t))) || + !(lut8->intabsbuf = jas_malloc(lut8->numinchans * + lut8->numintabents * sizeof(jas_iccuint8_t))) || + !(lut8->intabs = jas_malloc(lut8->numinchans * + sizeof(jas_iccuint8_t *)))) + goto error; + for (i = 0; i < lut8->numinchans; ++i) + lut8->intabs[i] = &lut8->intabsbuf[i * lut8->numintabents]; + if (!(lut8->outtabsbuf = jas_malloc(lut8->numoutchans * + lut8->numouttabents * sizeof(jas_iccuint8_t))) || + !(lut8->outtabs = jas_malloc(lut8->numoutchans * + sizeof(jas_iccuint8_t *)))) + goto error; + for (i = 0; i < lut8->numoutchans; ++i) + lut8->outtabs[i] = &lut8->outtabsbuf[i * lut8->numouttabents]; + for (i = 0; i < lut8->numinchans; ++i) { + for (j = 0; j < JAS_CAST(int, lut8->numintabents); ++j) { + if (jas_iccgetuint8(in, &lut8->intabs[i][j])) + goto error; + } + } + for (i = 0; i < lut8->numoutchans; ++i) { + for (j = 0; j < JAS_CAST(int, lut8->numouttabents); ++j) { + if (jas_iccgetuint8(in, &lut8->outtabs[i][j])) + goto error; + } + } + for (i = 0; i < clutsize; ++i) { + if (jas_iccgetuint8(in, &lut8->clut[i])) + goto error; + } + if (JAS_CAST(int, 44 + lut8->numinchans * lut8->numintabents + + lut8->numoutchans * lut8->numouttabents + + jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans) != + cnt) + goto error; + return 0; +error: + jas_icclut8_destroy(attrval); + return -1; +} + +static int jas_icclut8_getsize(jas_iccattrval_t *attrval) +{ + jas_icclut8_t *lut8 = &attrval->data.lut8; + return 44 + lut8->numinchans * lut8->numintabents + + lut8->numoutchans * lut8->numouttabents + + jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans; +} + +static int jas_icclut8_output(jas_iccattrval_t *attrval, jas_stream_t *out) +{ + jas_icclut8_t *lut8 = &attrval->data.lut8; + int i; + int j; + int n; + lut8->clut = 0; + lut8->intabs = 0; + lut8->intabsbuf = 0; + lut8->outtabs = 0; + lut8->outtabsbuf = 0; + if (jas_stream_putc(out, lut8->numinchans) == EOF || + jas_stream_putc(out, lut8->numoutchans) == EOF || + jas_stream_putc(out, lut8->clutlen) == EOF || + jas_stream_putc(out, 0) == EOF) + goto error; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + if (jas_iccputsint32(out, lut8->e[i][j])) + goto error; + } + } + if (jas_iccputuint16(out, lut8->numintabents) || + jas_iccputuint16(out, lut8->numouttabents)) + goto error; + n = lut8->numinchans * lut8->numintabents; + for (i = 0; i < n; ++i) { + if (jas_iccputuint8(out, lut8->intabsbuf[i])) + goto error; + } + n = lut8->numoutchans * lut8->numouttabents; + for (i = 0; i < n; ++i) { + if (jas_iccputuint8(out, lut8->outtabsbuf[i])) + goto error; + } + n = jas_iccpowi(lut8->clutlen, lut8->numinchans) * lut8->numoutchans; + for (i = 0; i < n; ++i) { + if (jas_iccputuint8(out, lut8->clut[i])) + goto error; + } + return 0; +error: + return -1; +} + +static void jas_icclut8_dump(jas_iccattrval_t *attrval, FILE *out) +{ + jas_icclut8_t *lut8 = &attrval->data.lut8; + int i; + int j; + fprintf(out, "numinchans=%d, numoutchans=%d, clutlen=%d\n", + lut8->numinchans, lut8->numoutchans, lut8->clutlen); + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + fprintf(out, "e[%d][%d]=%f ", i, j, lut8->e[i][j] / 65536.0); + } + fprintf(out, "\n"); + } + fprintf(out, "numintabents=%d, numouttabents=%d\n", + lut8->numintabents, lut8->numouttabents); +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static void jas_icclut16_destroy(jas_iccattrval_t *attrval) +{ + jas_icclut16_t *lut16 = &attrval->data.lut16; + if (lut16->clut) + jas_free(lut16->clut); + if (lut16->intabs) + jas_free(lut16->intabs); + if (lut16->intabsbuf) + jas_free(lut16->intabsbuf); + if (lut16->outtabs) + jas_free(lut16->outtabs); + if (lut16->outtabsbuf) + jas_free(lut16->outtabsbuf); +} + +static int jas_icclut16_copy(jas_iccattrval_t *attrval, + jas_iccattrval_t *othattrval) +{ + /* Avoid compiler warnings about unused parameters. */ + attrval = 0; + othattrval = 0; + /* Not yet implemented. */ + abort(); + return -1; +} + +static int jas_icclut16_input(jas_iccattrval_t *attrval, jas_stream_t *in, + int cnt) +{ + int i; + int j; + int clutsize; + jas_icclut16_t *lut16 = &attrval->data.lut16; + lut16->clut = 0; + lut16->intabs = 0; + lut16->intabsbuf = 0; + lut16->outtabs = 0; + lut16->outtabsbuf = 0; + if (jas_iccgetuint8(in, &lut16->numinchans) || + jas_iccgetuint8(in, &lut16->numoutchans) || + jas_iccgetuint8(in, &lut16->clutlen) || + jas_stream_getc(in) == EOF) + goto error; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + if (jas_iccgetsint32(in, &lut16->e[i][j])) + goto error; + } + } + if (jas_iccgetuint16(in, &lut16->numintabents) || + jas_iccgetuint16(in, &lut16->numouttabents)) + goto error; + clutsize = jas_iccpowi(lut16->clutlen, lut16->numinchans) * lut16->numoutchans; + if (!(lut16->clut = jas_malloc(clutsize * sizeof(jas_iccuint16_t))) || + !(lut16->intabsbuf = jas_malloc(lut16->numinchans * + lut16->numintabents * sizeof(jas_iccuint16_t))) || + !(lut16->intabs = jas_malloc(lut16->numinchans * + sizeof(jas_iccuint16_t *)))) + goto error; + for (i = 0; i < lut16->numinchans; ++i) + lut16->intabs[i] = &lut16->intabsbuf[i * lut16->numintabents]; + if (!(lut16->outtabsbuf = jas_malloc(lut16->numoutchans * + lut16->numouttabents * sizeof(jas_iccuint16_t))) || + !(lut16->outtabs = jas_malloc(lut16->numoutchans * + sizeof(jas_iccuint16_t *)))) + goto error; + for (i = 0; i < lut16->numoutchans; ++i) + lut16->outtabs[i] = &lut16->outtabsbuf[i * lut16->numouttabents]; + for (i = 0; i < lut16->numinchans; ++i) { + for (j = 0; j < JAS_CAST(int, lut16->numintabents); ++j) { + if (jas_iccgetuint16(in, &lut16->intabs[i][j])) + goto error; + } + } + for (i = 0; i < lut16->numoutchans; ++i) { + for (j = 0; j < JAS_CAST(int, lut16->numouttabents); ++j) { + if (jas_iccgetuint16(in, &lut16->outtabs[i][j])) + goto error; + } + } + for (i = 0; i < clutsize; ++i) { + if (jas_iccgetuint16(in, &lut16->clut[i])) + goto error; + } + if (JAS_CAST(int, 44 + 2 * (lut16->numinchans * lut16->numintabents + + lut16->numoutchans * lut16->numouttabents + + jas_iccpowi(lut16->clutlen, lut16->numinchans) * + lut16->numoutchans)) != cnt) + goto error; + return 0; +error: + jas_icclut16_destroy(attrval); + return -1; +} + +static int jas_icclut16_getsize(jas_iccattrval_t *attrval) +{ + jas_icclut16_t *lut16 = &attrval->data.lut16; + return 44 + 2 * (lut16->numinchans * lut16->numintabents + + lut16->numoutchans * lut16->numouttabents + + jas_iccpowi(lut16->clutlen, lut16->numinchans) * lut16->numoutchans); +} + +static int jas_icclut16_output(jas_iccattrval_t *attrval, jas_stream_t *out) +{ + jas_icclut16_t *lut16 = &attrval->data.lut16; + int i; + int j; + int n; + if (jas_stream_putc(out, lut16->numinchans) == EOF || + jas_stream_putc(out, lut16->numoutchans) == EOF || + jas_stream_putc(out, lut16->clutlen) == EOF || + jas_stream_putc(out, 0) == EOF) + goto error; + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + if (jas_iccputsint32(out, lut16->e[i][j])) + goto error; + } + } + if (jas_iccputuint16(out, lut16->numintabents) || + jas_iccputuint16(out, lut16->numouttabents)) + goto error; + n = lut16->numinchans * lut16->numintabents; + for (i = 0; i < n; ++i) { + if (jas_iccputuint16(out, lut16->intabsbuf[i])) + goto error; + } + n = lut16->numoutchans * lut16->numouttabents; + for (i = 0; i < n; ++i) { + if (jas_iccputuint16(out, lut16->outtabsbuf[i])) + goto error; + } + n = jas_iccpowi(lut16->clutlen, lut16->numinchans) * lut16->numoutchans; + for (i = 0; i < n; ++i) { + if (jas_iccputuint16(out, lut16->clut[i])) + goto error; + } + return 0; +error: + return -1; +} + +static void jas_icclut16_dump(jas_iccattrval_t *attrval, FILE *out) +{ + jas_icclut16_t *lut16 = &attrval->data.lut16; + int i; + int j; + fprintf(out, "numinchans=%d, numoutchans=%d, clutlen=%d\n", + lut16->numinchans, lut16->numoutchans, lut16->clutlen); + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + fprintf(out, "e[%d][%d]=%f ", i, j, lut16->e[i][j] / 65536.0); + } + fprintf(out, "\n"); + } + fprintf(out, "numintabents=%d, numouttabents=%d\n", + lut16->numintabents, lut16->numouttabents); +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static int jas_iccgetuint(jas_stream_t *in, int n, ulonglong *val) +{ + int i; + int c; + ulonglong v; + v = 0; + for (i = n; i > 0; --i) { + if ((c = jas_stream_getc(in)) == EOF) + return -1; + v = (v << 8) | c; + } + *val = v; + return 0; +} + +static int jas_iccgetuint8(jas_stream_t *in, jas_iccuint8_t *val) +{ + int c; + if ((c = jas_stream_getc(in)) == EOF) + return -1; + *val = c; + return 0; +} + +static int jas_iccgetuint16(jas_stream_t *in, jas_iccuint16_t *val) +{ + ulonglong tmp; + if (jas_iccgetuint(in, 2, &tmp)) + return -1; + *val = tmp; + return 0; +} + +static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val) +{ + ulonglong tmp; + if (jas_iccgetuint(in, 4, &tmp)) + return -1; + *val = (tmp & 0x80000000) ? (-JAS_CAST(longlong, (((~tmp) & + 0x7fffffff) + 1))) : JAS_CAST(longlong, tmp); + return 0; +} + +static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val) +{ + ulonglong tmp; + if (jas_iccgetuint(in, 4, &tmp)) + return -1; + *val = tmp; + return 0; +} + +static int jas_iccgetuint64(jas_stream_t *in, jas_iccuint64_t *val) +{ + ulonglong tmp; + if (jas_iccgetuint(in, 8, &tmp)) + return -1; + *val = tmp; + return 0; +} + +static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val) +{ + int i; + int c; + for (i = n; i > 0; --i) { + c = (val >> (8 * (i - 1))) & 0xff; + if (jas_stream_putc(out, c) == EOF) + return -1; + } + return 0; +} + +static int jas_iccputsint(jas_stream_t *out, int n, longlong val) +{ + ulonglong tmp; + tmp = (val < 0) ? (abort(), 0) : val; + return jas_iccputuint(out, n, tmp); +} + +/******************************************************************************\ +* +\******************************************************************************/ + +static char *jas_iccsigtostr(int sig, char *buf) +{ + int n; + int c; + char *bufptr; + bufptr = buf; + for (n = 4; n > 0; --n) { + c = (sig >> 24) & 0xff; + if (isalpha(c) || isdigit(c)) { + *bufptr++ = c; + } + sig <<= 8; + } + *bufptr = '\0'; + return buf; +} + +static long jas_iccpadtomult(long x, long y) +{ + return ((x + y - 1) / y) * y; +} + +static long jas_iccpowi(int x, int n) +{ + long y; + y = 1; + while (--n >= 0) + y *= x; + return y; +} + + +jas_iccprof_t *jas_iccprof_createfrombuf(uchar *buf, int len) +{ + jas_stream_t *in; + jas_iccprof_t *prof; + if (!(in = jas_stream_memopen(JAS_CAST(char *, buf), len))) + goto error; + if (!(prof = jas_iccprof_load(in))) + goto error; + jas_stream_close(in); + return prof; +error: + return 0; +} + +jas_iccprof_t *jas_iccprof_createfromclrspc(int clrspc) +{ + jas_iccprof_t *prof; + switch (clrspc) { + case JAS_CLRSPC_SRGB: + prof = jas_iccprof_createfrombuf(jas_iccprofdata_srgb, + jas_iccprofdata_srgblen); + break; + case JAS_CLRSPC_SGRAY: + prof = jas_iccprof_createfrombuf(jas_iccprofdata_sgray, + jas_iccprofdata_sgraylen); + break; + default: + prof = 0; + break; + } + return prof; +} diff --git a/src/libjasper/base/jas_iccdata.c b/src/libjasper/base/jas_iccdata.c new file mode 100644 index 0000000..bf68bf0 --- /dev/null +++ b/src/libjasper/base/jas_iccdata.c @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2002-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#include <jasper/jas_config.h> +#include <jasper/jas_types.h> + +uchar jas_iccprofdata_srgb[] = +{ + 0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f, + 0x02, 0x10, 0x00, 0x00, 0x6d, 0x6e, 0x74, 0x72, + 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20, + 0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, + 0x00, 0x31, 0x00, 0x00, 0x61, 0x63, 0x73, 0x70, + 0x4d, 0x53, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00, + 0x49, 0x45, 0x43, 0x20, 0x73, 0x52, 0x47, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, + 0x48, 0x50, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x63, 0x70, 0x72, 0x74, + 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x33, + 0x64, 0x65, 0x73, 0x63, 0x00, 0x00, 0x01, 0x84, + 0x00, 0x00, 0x00, 0x6c, 0x77, 0x74, 0x70, 0x74, + 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x14, + 0x62, 0x6b, 0x70, 0x74, 0x00, 0x00, 0x02, 0x04, + 0x00, 0x00, 0x00, 0x14, 0x72, 0x58, 0x59, 0x5a, + 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x00, 0x14, + 0x67, 0x58, 0x59, 0x5a, 0x00, 0x00, 0x02, 0x2c, + 0x00, 0x00, 0x00, 0x14, 0x62, 0x58, 0x59, 0x5a, + 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x14, + 0x64, 0x6d, 0x6e, 0x64, 0x00, 0x00, 0x02, 0x54, + 0x00, 0x00, 0x00, 0x70, 0x64, 0x6d, 0x64, 0x64, + 0x00, 0x00, 0x02, 0xc4, 0x00, 0x00, 0x00, 0x88, + 0x76, 0x75, 0x65, 0x64, 0x00, 0x00, 0x03, 0x4c, + 0x00, 0x00, 0x00, 0x86, 0x76, 0x69, 0x65, 0x77, + 0x00, 0x00, 0x03, 0xd4, 0x00, 0x00, 0x00, 0x24, + 0x6c, 0x75, 0x6d, 0x69, 0x00, 0x00, 0x03, 0xf8, + 0x00, 0x00, 0x00, 0x14, 0x6d, 0x65, 0x61, 0x73, + 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00, 0x00, 0x24, + 0x74, 0x65, 0x63, 0x68, 0x00, 0x00, 0x04, 0x30, + 0x00, 0x00, 0x00, 0x0c, 0x72, 0x54, 0x52, 0x43, + 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, + 0x67, 0x54, 0x52, 0x43, 0x00, 0x00, 0x04, 0x3c, + 0x00, 0x00, 0x08, 0x0c, 0x62, 0x54, 0x52, 0x43, + 0x00, 0x00, 0x04, 0x3c, 0x00, 0x00, 0x08, 0x0c, + 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, + 0x39, 0x38, 0x20, 0x48, 0x65, 0x77, 0x6c, 0x65, + 0x74, 0x74, 0x2d, 0x50, 0x61, 0x63, 0x6b, 0x61, + 0x72, 0x64, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x61, + 0x6e, 0x79, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, + 0x73, 0x52, 0x47, 0x42, 0x20, 0x49, 0x45, 0x43, + 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, 0x2e, + 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x73, 0x52, 0x47, + 0x42, 0x20, 0x49, 0x45, 0x43, 0x36, 0x31, 0x39, + 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf3, 0x51, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x16, 0xcc, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6f, 0xa2, 0x00, 0x00, 0x38, 0xf5, + 0x00, 0x00, 0x03, 0x90, 0x58, 0x59, 0x5a, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x99, + 0x00, 0x00, 0xb7, 0x85, 0x00, 0x00, 0x18, 0xda, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, 0xa0, 0x00, 0x00, 0x0f, 0x84, + 0x00, 0x00, 0xb6, 0xcf, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, + 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, + 0x65, 0x63, 0x2e, 0x63, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x16, 0x49, 0x45, 0x43, 0x20, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, + 0x69, 0x65, 0x63, 0x2e, 0x63, 0x68, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2e, + 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, 0x36, + 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, 0x47, + 0x42, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x75, 0x72, + 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x2d, + 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2e, 0x49, 0x45, 0x43, 0x20, 0x36, 0x31, 0x39, + 0x36, 0x36, 0x2d, 0x32, 0x2e, 0x31, 0x20, 0x44, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x52, + 0x47, 0x42, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x75, + 0x72, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, + 0x2d, 0x20, 0x73, 0x52, 0x47, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, + 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x20, 0x56, 0x69, 0x65, 0x77, 0x69, 0x6e, + 0x67, 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, + 0x45, 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, + 0x32, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x52, + 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x20, 0x56, 0x69, 0x65, 0x77, 0x69, 0x6e, 0x67, + 0x20, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x49, 0x45, + 0x43, 0x36, 0x31, 0x39, 0x36, 0x36, 0x2d, 0x32, + 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x65, 0x77, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa4, 0xfe, + 0x00, 0x14, 0x5f, 0x2e, 0x00, 0x10, 0xcf, 0x14, + 0x00, 0x03, 0xed, 0xcc, 0x00, 0x04, 0x13, 0x0b, + 0x00, 0x03, 0x5c, 0x9e, 0x00, 0x00, 0x00, 0x01, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x4c, 0x09, 0x56, 0x00, 0x50, 0x00, 0x00, + 0x00, 0x57, 0x1f, 0xe7, 0x6d, 0x65, 0x61, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x8f, 0x00, 0x00, 0x00, 0x02, + 0x73, 0x69, 0x67, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x52, 0x54, 0x20, 0x63, 0x75, 0x72, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0f, + 0x00, 0x14, 0x00, 0x19, 0x00, 0x1e, 0x00, 0x23, + 0x00, 0x28, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37, + 0x00, 0x3b, 0x00, 0x40, 0x00, 0x45, 0x00, 0x4a, + 0x00, 0x4f, 0x00, 0x54, 0x00, 0x59, 0x00, 0x5e, + 0x00, 0x63, 0x00, 0x68, 0x00, 0x6d, 0x00, 0x72, + 0x00, 0x77, 0x00, 0x7c, 0x00, 0x81, 0x00, 0x86, + 0x00, 0x8b, 0x00, 0x90, 0x00, 0x95, 0x00, 0x9a, + 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9, 0x00, 0xae, + 0x00, 0xb2, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xc1, + 0x00, 0xc6, 0x00, 0xcb, 0x00, 0xd0, 0x00, 0xd5, + 0x00, 0xdb, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0xeb, + 0x00, 0xf0, 0x00, 0xf6, 0x00, 0xfb, 0x01, 0x01, + 0x01, 0x07, 0x01, 0x0d, 0x01, 0x13, 0x01, 0x19, + 0x01, 0x1f, 0x01, 0x25, 0x01, 0x2b, 0x01, 0x32, + 0x01, 0x38, 0x01, 0x3e, 0x01, 0x45, 0x01, 0x4c, + 0x01, 0x52, 0x01, 0x59, 0x01, 0x60, 0x01, 0x67, + 0x01, 0x6e, 0x01, 0x75, 0x01, 0x7c, 0x01, 0x83, + 0x01, 0x8b, 0x01, 0x92, 0x01, 0x9a, 0x01, 0xa1, + 0x01, 0xa9, 0x01, 0xb1, 0x01, 0xb9, 0x01, 0xc1, + 0x01, 0xc9, 0x01, 0xd1, 0x01, 0xd9, 0x01, 0xe1, + 0x01, 0xe9, 0x01, 0xf2, 0x01, 0xfa, 0x02, 0x03, + 0x02, 0x0c, 0x02, 0x14, 0x02, 0x1d, 0x02, 0x26, + 0x02, 0x2f, 0x02, 0x38, 0x02, 0x41, 0x02, 0x4b, + 0x02, 0x54, 0x02, 0x5d, 0x02, 0x67, 0x02, 0x71, + 0x02, 0x7a, 0x02, 0x84, 0x02, 0x8e, 0x02, 0x98, + 0x02, 0xa2, 0x02, 0xac, 0x02, 0xb6, 0x02, 0xc1, + 0x02, 0xcb, 0x02, 0xd5, 0x02, 0xe0, 0x02, 0xeb, + 0x02, 0xf5, 0x03, 0x00, 0x03, 0x0b, 0x03, 0x16, + 0x03, 0x21, 0x03, 0x2d, 0x03, 0x38, 0x03, 0x43, + 0x03, 0x4f, 0x03, 0x5a, 0x03, 0x66, 0x03, 0x72, + 0x03, 0x7e, 0x03, 0x8a, 0x03, 0x96, 0x03, 0xa2, + 0x03, 0xae, 0x03, 0xba, 0x03, 0xc7, 0x03, 0xd3, + 0x03, 0xe0, 0x03, 0xec, 0x03, 0xf9, 0x04, 0x06, + 0x04, 0x13, 0x04, 0x20, 0x04, 0x2d, 0x04, 0x3b, + 0x04, 0x48, 0x04, 0x55, 0x04, 0x63, 0x04, 0x71, + 0x04, 0x7e, 0x04, 0x8c, 0x04, 0x9a, 0x04, 0xa8, + 0x04, 0xb6, 0x04, 0xc4, 0x04, 0xd3, 0x04, 0xe1, + 0x04, 0xf0, 0x04, 0xfe, 0x05, 0x0d, 0x05, 0x1c, + 0x05, 0x2b, 0x05, 0x3a, 0x05, 0x49, 0x05, 0x58, + 0x05, 0x67, 0x05, 0x77, 0x05, 0x86, 0x05, 0x96, + 0x05, 0xa6, 0x05, 0xb5, 0x05, 0xc5, 0x05, 0xd5, + 0x05, 0xe5, 0x05, 0xf6, 0x06, 0x06, 0x06, 0x16, + 0x06, 0x27, 0x06, 0x37, 0x06, 0x48, 0x06, 0x59, + 0x06, 0x6a, 0x06, 0x7b, 0x06, 0x8c, 0x06, 0x9d, + 0x06, 0xaf, 0x06, 0xc0, 0x06, 0xd1, 0x06, 0xe3, + 0x06, 0xf5, 0x07, 0x07, 0x07, 0x19, 0x07, 0x2b, + 0x07, 0x3d, 0x07, 0x4f, 0x07, 0x61, 0x07, 0x74, + 0x07, 0x86, 0x07, 0x99, 0x07, 0xac, 0x07, 0xbf, + 0x07, 0xd2, 0x07, 0xe5, 0x07, 0xf8, 0x08, 0x0b, + 0x08, 0x1f, 0x08, 0x32, 0x08, 0x46, 0x08, 0x5a, + 0x08, 0x6e, 0x08, 0x82, 0x08, 0x96, 0x08, 0xaa, + 0x08, 0xbe, 0x08, 0xd2, 0x08, 0xe7, 0x08, 0xfb, + 0x09, 0x10, 0x09, 0x25, 0x09, 0x3a, 0x09, 0x4f, + 0x09, 0x64, 0x09, 0x79, 0x09, 0x8f, 0x09, 0xa4, + 0x09, 0xba, 0x09, 0xcf, 0x09, 0xe5, 0x09, 0xfb, + 0x0a, 0x11, 0x0a, 0x27, 0x0a, 0x3d, 0x0a, 0x54, + 0x0a, 0x6a, 0x0a, 0x81, 0x0a, 0x98, 0x0a, 0xae, + 0x0a, 0xc5, 0x0a, 0xdc, 0x0a, 0xf3, 0x0b, 0x0b, + 0x0b, 0x22, 0x0b, 0x39, 0x0b, 0x51, 0x0b, 0x69, + 0x0b, 0x80, 0x0b, 0x98, 0x0b, 0xb0, 0x0b, 0xc8, + 0x0b, 0xe1, 0x0b, 0xf9, 0x0c, 0x12, 0x0c, 0x2a, + 0x0c, 0x43, 0x0c, 0x5c, 0x0c, 0x75, 0x0c, 0x8e, + 0x0c, 0xa7, 0x0c, 0xc0, 0x0c, 0xd9, 0x0c, 0xf3, + 0x0d, 0x0d, 0x0d, 0x26, 0x0d, 0x40, 0x0d, 0x5a, + 0x0d, 0x74, 0x0d, 0x8e, 0x0d, 0xa9, 0x0d, 0xc3, + 0x0d, 0xde, 0x0d, 0xf8, 0x0e, 0x13, 0x0e, 0x2e, + 0x0e, 0x49, 0x0e, 0x64, 0x0e, 0x7f, 0x0e, 0x9b, + 0x0e, 0xb6, 0x0e, 0xd2, 0x0e, 0xee, 0x0f, 0x09, + 0x0f, 0x25, 0x0f, 0x41, 0x0f, 0x5e, 0x0f, 0x7a, + 0x0f, 0x96, 0x0f, 0xb3, 0x0f, 0xcf, 0x0f, 0xec, + 0x10, 0x09, 0x10, 0x26, 0x10, 0x43, 0x10, 0x61, + 0x10, 0x7e, 0x10, 0x9b, 0x10, 0xb9, 0x10, 0xd7, + 0x10, 0xf5, 0x11, 0x13, 0x11, 0x31, 0x11, 0x4f, + 0x11, 0x6d, 0x11, 0x8c, 0x11, 0xaa, 0x11, 0xc9, + 0x11, 0xe8, 0x12, 0x07, 0x12, 0x26, 0x12, 0x45, + 0x12, 0x64, 0x12, 0x84, 0x12, 0xa3, 0x12, 0xc3, + 0x12, 0xe3, 0x13, 0x03, 0x13, 0x23, 0x13, 0x43, + 0x13, 0x63, 0x13, 0x83, 0x13, 0xa4, 0x13, 0xc5, + 0x13, 0xe5, 0x14, 0x06, 0x14, 0x27, 0x14, 0x49, + 0x14, 0x6a, 0x14, 0x8b, 0x14, 0xad, 0x14, 0xce, + 0x14, 0xf0, 0x15, 0x12, 0x15, 0x34, 0x15, 0x56, + 0x15, 0x78, 0x15, 0x9b, 0x15, 0xbd, 0x15, 0xe0, + 0x16, 0x03, 0x16, 0x26, 0x16, 0x49, 0x16, 0x6c, + 0x16, 0x8f, 0x16, 0xb2, 0x16, 0xd6, 0x16, 0xfa, + 0x17, 0x1d, 0x17, 0x41, 0x17, 0x65, 0x17, 0x89, + 0x17, 0xae, 0x17, 0xd2, 0x17, 0xf7, 0x18, 0x1b, + 0x18, 0x40, 0x18, 0x65, 0x18, 0x8a, 0x18, 0xaf, + 0x18, 0xd5, 0x18, 0xfa, 0x19, 0x20, 0x19, 0x45, + 0x19, 0x6b, 0x19, 0x91, 0x19, 0xb7, 0x19, 0xdd, + 0x1a, 0x04, 0x1a, 0x2a, 0x1a, 0x51, 0x1a, 0x77, + 0x1a, 0x9e, 0x1a, 0xc5, 0x1a, 0xec, 0x1b, 0x14, + 0x1b, 0x3b, 0x1b, 0x63, 0x1b, 0x8a, 0x1b, 0xb2, + 0x1b, 0xda, 0x1c, 0x02, 0x1c, 0x2a, 0x1c, 0x52, + 0x1c, 0x7b, 0x1c, 0xa3, 0x1c, 0xcc, 0x1c, 0xf5, + 0x1d, 0x1e, 0x1d, 0x47, 0x1d, 0x70, 0x1d, 0x99, + 0x1d, 0xc3, 0x1d, 0xec, 0x1e, 0x16, 0x1e, 0x40, + 0x1e, 0x6a, 0x1e, 0x94, 0x1e, 0xbe, 0x1e, 0xe9, + 0x1f, 0x13, 0x1f, 0x3e, 0x1f, 0x69, 0x1f, 0x94, + 0x1f, 0xbf, 0x1f, 0xea, 0x20, 0x15, 0x20, 0x41, + 0x20, 0x6c, 0x20, 0x98, 0x20, 0xc4, 0x20, 0xf0, + 0x21, 0x1c, 0x21, 0x48, 0x21, 0x75, 0x21, 0xa1, + 0x21, 0xce, 0x21, 0xfb, 0x22, 0x27, 0x22, 0x55, + 0x22, 0x82, 0x22, 0xaf, 0x22, 0xdd, 0x23, 0x0a, + 0x23, 0x38, 0x23, 0x66, 0x23, 0x94, 0x23, 0xc2, + 0x23, 0xf0, 0x24, 0x1f, 0x24, 0x4d, 0x24, 0x7c, + 0x24, 0xab, 0x24, 0xda, 0x25, 0x09, 0x25, 0x38, + 0x25, 0x68, 0x25, 0x97, 0x25, 0xc7, 0x25, 0xf7, + 0x26, 0x27, 0x26, 0x57, 0x26, 0x87, 0x26, 0xb7, + 0x26, 0xe8, 0x27, 0x18, 0x27, 0x49, 0x27, 0x7a, + 0x27, 0xab, 0x27, 0xdc, 0x28, 0x0d, 0x28, 0x3f, + 0x28, 0x71, 0x28, 0xa2, 0x28, 0xd4, 0x29, 0x06, + 0x29, 0x38, 0x29, 0x6b, 0x29, 0x9d, 0x29, 0xd0, + 0x2a, 0x02, 0x2a, 0x35, 0x2a, 0x68, 0x2a, 0x9b, + 0x2a, 0xcf, 0x2b, 0x02, 0x2b, 0x36, 0x2b, 0x69, + 0x2b, 0x9d, 0x2b, 0xd1, 0x2c, 0x05, 0x2c, 0x39, + 0x2c, 0x6e, 0x2c, 0xa2, 0x2c, 0xd7, 0x2d, 0x0c, + 0x2d, 0x41, 0x2d, 0x76, 0x2d, 0xab, 0x2d, 0xe1, + 0x2e, 0x16, 0x2e, 0x4c, 0x2e, 0x82, 0x2e, 0xb7, + 0x2e, 0xee, 0x2f, 0x24, 0x2f, 0x5a, 0x2f, 0x91, + 0x2f, 0xc7, 0x2f, 0xfe, 0x30, 0x35, 0x30, 0x6c, + 0x30, 0xa4, 0x30, 0xdb, 0x31, 0x12, 0x31, 0x4a, + 0x31, 0x82, 0x31, 0xba, 0x31, 0xf2, 0x32, 0x2a, + 0x32, 0x63, 0x32, 0x9b, 0x32, 0xd4, 0x33, 0x0d, + 0x33, 0x46, 0x33, 0x7f, 0x33, 0xb8, 0x33, 0xf1, + 0x34, 0x2b, 0x34, 0x65, 0x34, 0x9e, 0x34, 0xd8, + 0x35, 0x13, 0x35, 0x4d, 0x35, 0x87, 0x35, 0xc2, + 0x35, 0xfd, 0x36, 0x37, 0x36, 0x72, 0x36, 0xae, + 0x36, 0xe9, 0x37, 0x24, 0x37, 0x60, 0x37, 0x9c, + 0x37, 0xd7, 0x38, 0x14, 0x38, 0x50, 0x38, 0x8c, + 0x38, 0xc8, 0x39, 0x05, 0x39, 0x42, 0x39, 0x7f, + 0x39, 0xbc, 0x39, 0xf9, 0x3a, 0x36, 0x3a, 0x74, + 0x3a, 0xb2, 0x3a, 0xef, 0x3b, 0x2d, 0x3b, 0x6b, + 0x3b, 0xaa, 0x3b, 0xe8, 0x3c, 0x27, 0x3c, 0x65, + 0x3c, 0xa4, 0x3c, 0xe3, 0x3d, 0x22, 0x3d, 0x61, + 0x3d, 0xa1, 0x3d, 0xe0, 0x3e, 0x20, 0x3e, 0x60, + 0x3e, 0xa0, 0x3e, 0xe0, 0x3f, 0x21, 0x3f, 0x61, + 0x3f, 0xa2, 0x3f, 0xe2, 0x40, 0x23, 0x40, 0x64, + 0x40, 0xa6, 0x40, 0xe7, 0x41, 0x29, 0x41, 0x6a, + 0x41, 0xac, 0x41, 0xee, 0x42, 0x30, 0x42, 0x72, + 0x42, 0xb5, 0x42, 0xf7, 0x43, 0x3a, 0x43, 0x7d, + 0x43, 0xc0, 0x44, 0x03, 0x44, 0x47, 0x44, 0x8a, + 0x44, 0xce, 0x45, 0x12, 0x45, 0x55, 0x45, 0x9a, + 0x45, 0xde, 0x46, 0x22, 0x46, 0x67, 0x46, 0xab, + 0x46, 0xf0, 0x47, 0x35, 0x47, 0x7b, 0x47, 0xc0, + 0x48, 0x05, 0x48, 0x4b, 0x48, 0x91, 0x48, 0xd7, + 0x49, 0x1d, 0x49, 0x63, 0x49, 0xa9, 0x49, 0xf0, + 0x4a, 0x37, 0x4a, 0x7d, 0x4a, 0xc4, 0x4b, 0x0c, + 0x4b, 0x53, 0x4b, 0x9a, 0x4b, 0xe2, 0x4c, 0x2a, + 0x4c, 0x72, 0x4c, 0xba, 0x4d, 0x02, 0x4d, 0x4a, + 0x4d, 0x93, 0x4d, 0xdc, 0x4e, 0x25, 0x4e, 0x6e, + 0x4e, 0xb7, 0x4f, 0x00, 0x4f, 0x49, 0x4f, 0x93, + 0x4f, 0xdd, 0x50, 0x27, 0x50, 0x71, 0x50, 0xbb, + 0x51, 0x06, 0x51, 0x50, 0x51, 0x9b, 0x51, 0xe6, + 0x52, 0x31, 0x52, 0x7c, 0x52, 0xc7, 0x53, 0x13, + 0x53, 0x5f, 0x53, 0xaa, 0x53, 0xf6, 0x54, 0x42, + 0x54, 0x8f, 0x54, 0xdb, 0x55, 0x28, 0x55, 0x75, + 0x55, 0xc2, 0x56, 0x0f, 0x56, 0x5c, 0x56, 0xa9, + 0x56, 0xf7, 0x57, 0x44, 0x57, 0x92, 0x57, 0xe0, + 0x58, 0x2f, 0x58, 0x7d, 0x58, 0xcb, 0x59, 0x1a, + 0x59, 0x69, 0x59, 0xb8, 0x5a, 0x07, 0x5a, 0x56, + 0x5a, 0xa6, 0x5a, 0xf5, 0x5b, 0x45, 0x5b, 0x95, + 0x5b, 0xe5, 0x5c, 0x35, 0x5c, 0x86, 0x5c, 0xd6, + 0x5d, 0x27, 0x5d, 0x78, 0x5d, 0xc9, 0x5e, 0x1a, + 0x5e, 0x6c, 0x5e, 0xbd, 0x5f, 0x0f, 0x5f, 0x61, + 0x5f, 0xb3, 0x60, 0x05, 0x60, 0x57, 0x60, 0xaa, + 0x60, 0xfc, 0x61, 0x4f, 0x61, 0xa2, 0x61, 0xf5, + 0x62, 0x49, 0x62, 0x9c, 0x62, 0xf0, 0x63, 0x43, + 0x63, 0x97, 0x63, 0xeb, 0x64, 0x40, 0x64, 0x94, + 0x64, 0xe9, 0x65, 0x3d, 0x65, 0x92, 0x65, 0xe7, + 0x66, 0x3d, 0x66, 0x92, 0x66, 0xe8, 0x67, 0x3d, + 0x67, 0x93, 0x67, 0xe9, 0x68, 0x3f, 0x68, 0x96, + 0x68, 0xec, 0x69, 0x43, 0x69, 0x9a, 0x69, 0xf1, + 0x6a, 0x48, 0x6a, 0x9f, 0x6a, 0xf7, 0x6b, 0x4f, + 0x6b, 0xa7, 0x6b, 0xff, 0x6c, 0x57, 0x6c, 0xaf, + 0x6d, 0x08, 0x6d, 0x60, 0x6d, 0xb9, 0x6e, 0x12, + 0x6e, 0x6b, 0x6e, 0xc4, 0x6f, 0x1e, 0x6f, 0x78, + 0x6f, 0xd1, 0x70, 0x2b, 0x70, 0x86, 0x70, 0xe0, + 0x71, 0x3a, 0x71, 0x95, 0x71, 0xf0, 0x72, 0x4b, + 0x72, 0xa6, 0x73, 0x01, 0x73, 0x5d, 0x73, 0xb8, + 0x74, 0x14, 0x74, 0x70, 0x74, 0xcc, 0x75, 0x28, + 0x75, 0x85, 0x75, 0xe1, 0x76, 0x3e, 0x76, 0x9b, + 0x76, 0xf8, 0x77, 0x56, 0x77, 0xb3, 0x78, 0x11, + 0x78, 0x6e, 0x78, 0xcc, 0x79, 0x2a, 0x79, 0x89, + 0x79, 0xe7, 0x7a, 0x46, 0x7a, 0xa5, 0x7b, 0x04, + 0x7b, 0x63, 0x7b, 0xc2, 0x7c, 0x21, 0x7c, 0x81, + 0x7c, 0xe1, 0x7d, 0x41, 0x7d, 0xa1, 0x7e, 0x01, + 0x7e, 0x62, 0x7e, 0xc2, 0x7f, 0x23, 0x7f, 0x84, + 0x7f, 0xe5, 0x80, 0x47, 0x80, 0xa8, 0x81, 0x0a, + 0x81, 0x6b, 0x81, 0xcd, 0x82, 0x30, 0x82, 0x92, + 0x82, 0xf4, 0x83, 0x57, 0x83, 0xba, 0x84, 0x1d, + 0x84, 0x80, 0x84, 0xe3, 0x85, 0x47, 0x85, 0xab, + 0x86, 0x0e, 0x86, 0x72, 0x86, 0xd7, 0x87, 0x3b, + 0x87, 0x9f, 0x88, 0x04, 0x88, 0x69, 0x88, 0xce, + 0x89, 0x33, 0x89, 0x99, 0x89, 0xfe, 0x8a, 0x64, + 0x8a, 0xca, 0x8b, 0x30, 0x8b, 0x96, 0x8b, 0xfc, + 0x8c, 0x63, 0x8c, 0xca, 0x8d, 0x31, 0x8d, 0x98, + 0x8d, 0xff, 0x8e, 0x66, 0x8e, 0xce, 0x8f, 0x36, + 0x8f, 0x9e, 0x90, 0x06, 0x90, 0x6e, 0x90, 0xd6, + 0x91, 0x3f, 0x91, 0xa8, 0x92, 0x11, 0x92, 0x7a, + 0x92, 0xe3, 0x93, 0x4d, 0x93, 0xb6, 0x94, 0x20, + 0x94, 0x8a, 0x94, 0xf4, 0x95, 0x5f, 0x95, 0xc9, + 0x96, 0x34, 0x96, 0x9f, 0x97, 0x0a, 0x97, 0x75, + 0x97, 0xe0, 0x98, 0x4c, 0x98, 0xb8, 0x99, 0x24, + 0x99, 0x90, 0x99, 0xfc, 0x9a, 0x68, 0x9a, 0xd5, + 0x9b, 0x42, 0x9b, 0xaf, 0x9c, 0x1c, 0x9c, 0x89, + 0x9c, 0xf7, 0x9d, 0x64, 0x9d, 0xd2, 0x9e, 0x40, + 0x9e, 0xae, 0x9f, 0x1d, 0x9f, 0x8b, 0x9f, 0xfa, + 0xa0, 0x69, 0xa0, 0xd8, 0xa1, 0x47, 0xa1, 0xb6, + 0xa2, 0x26, 0xa2, 0x96, 0xa3, 0x06, 0xa3, 0x76, + 0xa3, 0xe6, 0xa4, 0x56, 0xa4, 0xc7, 0xa5, 0x38, + 0xa5, 0xa9, 0xa6, 0x1a, 0xa6, 0x8b, 0xa6, 0xfd, + 0xa7, 0x6e, 0xa7, 0xe0, 0xa8, 0x52, 0xa8, 0xc4, + 0xa9, 0x37, 0xa9, 0xa9, 0xaa, 0x1c, 0xaa, 0x8f, + 0xab, 0x02, 0xab, 0x75, 0xab, 0xe9, 0xac, 0x5c, + 0xac, 0xd0, 0xad, 0x44, 0xad, 0xb8, 0xae, 0x2d, + 0xae, 0xa1, 0xaf, 0x16, 0xaf, 0x8b, 0xb0, 0x00, + 0xb0, 0x75, 0xb0, 0xea, 0xb1, 0x60, 0xb1, 0xd6, + 0xb2, 0x4b, 0xb2, 0xc2, 0xb3, 0x38, 0xb3, 0xae, + 0xb4, 0x25, 0xb4, 0x9c, 0xb5, 0x13, 0xb5, 0x8a, + 0xb6, 0x01, 0xb6, 0x79, 0xb6, 0xf0, 0xb7, 0x68, + 0xb7, 0xe0, 0xb8, 0x59, 0xb8, 0xd1, 0xb9, 0x4a, + 0xb9, 0xc2, 0xba, 0x3b, 0xba, 0xb5, 0xbb, 0x2e, + 0xbb, 0xa7, 0xbc, 0x21, 0xbc, 0x9b, 0xbd, 0x15, + 0xbd, 0x8f, 0xbe, 0x0a, 0xbe, 0x84, 0xbe, 0xff, + 0xbf, 0x7a, 0xbf, 0xf5, 0xc0, 0x70, 0xc0, 0xec, + 0xc1, 0x67, 0xc1, 0xe3, 0xc2, 0x5f, 0xc2, 0xdb, + 0xc3, 0x58, 0xc3, 0xd4, 0xc4, 0x51, 0xc4, 0xce, + 0xc5, 0x4b, 0xc5, 0xc8, 0xc6, 0x46, 0xc6, 0xc3, + 0xc7, 0x41, 0xc7, 0xbf, 0xc8, 0x3d, 0xc8, 0xbc, + 0xc9, 0x3a, 0xc9, 0xb9, 0xca, 0x38, 0xca, 0xb7, + 0xcb, 0x36, 0xcb, 0xb6, 0xcc, 0x35, 0xcc, 0xb5, + 0xcd, 0x35, 0xcd, 0xb5, 0xce, 0x36, 0xce, 0xb6, + 0xcf, 0x37, 0xcf, 0xb8, 0xd0, 0x39, 0xd0, 0xba, + 0xd1, 0x3c, 0xd1, 0xbe, 0xd2, 0x3f, 0xd2, 0xc1, + 0xd3, 0x44, 0xd3, 0xc6, 0xd4, 0x49, 0xd4, 0xcb, + 0xd5, 0x4e, 0xd5, 0xd1, 0xd6, 0x55, 0xd6, 0xd8, + 0xd7, 0x5c, 0xd7, 0xe0, 0xd8, 0x64, 0xd8, 0xe8, + 0xd9, 0x6c, 0xd9, 0xf1, 0xda, 0x76, 0xda, 0xfb, + 0xdb, 0x80, 0xdc, 0x05, 0xdc, 0x8a, 0xdd, 0x10, + 0xdd, 0x96, 0xde, 0x1c, 0xde, 0xa2, 0xdf, 0x29, + 0xdf, 0xaf, 0xe0, 0x36, 0xe0, 0xbd, 0xe1, 0x44, + 0xe1, 0xcc, 0xe2, 0x53, 0xe2, 0xdb, 0xe3, 0x63, + 0xe3, 0xeb, 0xe4, 0x73, 0xe4, 0xfc, 0xe5, 0x84, + 0xe6, 0x0d, 0xe6, 0x96, 0xe7, 0x1f, 0xe7, 0xa9, + 0xe8, 0x32, 0xe8, 0xbc, 0xe9, 0x46, 0xe9, 0xd0, + 0xea, 0x5b, 0xea, 0xe5, 0xeb, 0x70, 0xeb, 0xfb, + 0xec, 0x86, 0xed, 0x11, 0xed, 0x9c, 0xee, 0x28, + 0xee, 0xb4, 0xef, 0x40, 0xef, 0xcc, 0xf0, 0x58, + 0xf0, 0xe5, 0xf1, 0x72, 0xf1, 0xff, 0xf2, 0x8c, + 0xf3, 0x19, 0xf3, 0xa7, 0xf4, 0x34, 0xf4, 0xc2, + 0xf5, 0x50, 0xf5, 0xde, 0xf6, 0x6d, 0xf6, 0xfb, + 0xf7, 0x8a, 0xf8, 0x19, 0xf8, 0xa8, 0xf9, 0x38, + 0xf9, 0xc7, 0xfa, 0x57, 0xfa, 0xe7, 0xfb, 0x77, + 0xfc, 0x07, 0xfc, 0x98, 0xfd, 0x29, 0xfd, 0xba, + 0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff +}; + +int jas_iccprofdata_srgblen = sizeof(jas_iccprofdata_srgb); + +uchar jas_iccprofdata_sgray[] = { + 0x00, 0x00, 0x01, 0x8a, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x20, 0x00, 0x00, 0x73, 0x63, 0x6e, 0x72, + 0x47, 0x52, 0x41, 0x59, 0x58, 0x59, 0x5a, 0x20, + 0x07, 0xd3, 0x00, 0x01, 0x00, 0x1f, 0x00, 0x0d, + 0x00, 0x35, 0x00, 0x21, 0x61, 0x63, 0x73, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x4b, 0x4f, 0x44, 0x41, 0x73, 0x47, 0x72, 0x79, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xd6, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d, + 0x4a, 0x50, 0x45, 0x47, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x86, + 0x63, 0x70, 0x72, 0x74, 0x00, 0x00, 0x01, 0x3c, + 0x00, 0x00, 0x00, 0x2b, 0x77, 0x74, 0x70, 0x74, + 0x00, 0x00, 0x01, 0x68, 0x00, 0x00, 0x00, 0x14, + 0x6b, 0x54, 0x52, 0x43, 0x00, 0x00, 0x01, 0x7c, + 0x00, 0x00, 0x00, 0x0e, 0x64, 0x65, 0x73, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, + 0x52, 0x65, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, + 0x65, 0x64, 0x20, 0x49, 0x43, 0x43, 0x20, 0x70, + 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x62, 0x69, 0x6e, + 0x67, 0x20, 0x73, 0x52, 0x47, 0x42, 0x2d, 0x67, + 0x72, 0x65, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x32, 0x30, + 0x30, 0x33, 0x20, 0x73, 0x52, 0x47, 0x42, 0x2d, + 0x67, 0x72, 0x65, 0x79, 0x20, 0x52, 0x65, 0x66, + 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x00, 0x00, + 0x58, 0x59, 0x5a, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf3, 0x54, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x16, 0xcf, 0x63, 0x75, 0x72, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x01, 0xcd +}; + +int jas_iccprofdata_sgraylen = sizeof(jas_iccprofdata_sgray); diff --git a/src/libjasper/base/jas_image.c b/src/libjasper/base/jas_image.c new file mode 100644 index 0000000..3f5af8c --- /dev/null +++ b/src/libjasper/base/jas_image.c @@ -0,0 +1,1516 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + + GeoJasper revision: dima <dima@dimin.net> + 11/07/2003 15:00 - dima - aux_buf added for j_image_t + 22/09/2003 14:40 - dima - small correction in jas_image_writecmpt + 2007-04-23 12:23 - dima - updated for a vector of metadata boxes + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Image Library + * + * $Id: jas_image.c,v 1.1 2008/10/17 06:14:59 scuri Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <ctype.h> + +#include "jasper/jas_math.h" +#include "jasper/jas_image.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_string.h" + +/******************************************************************************\ +* GeoJasper: dima - progress functions +\******************************************************************************/ + +#if !defined( JAS_PROGRESS_PROC_DEFINED ) + #define JAS_PROGRESS_PROC_DEFINED + jas_progress_proc_t progress_proc = NULL; + jas_test_abort_proc_t test_abort_proc = NULL; +#endif + +void jas_set_progress_proc( jas_progress_proc_t new_proc ) { + progress_proc = new_proc; +} + +void jas_do_progress( int done, int total, char *descr ) { + if (progress_proc != NULL) progress_proc( done, total, descr ); +} + +void jas_set_test_abort_proc( jas_test_abort_proc_t new_proc ) { + test_abort_proc = new_proc; +} + +int jas_test_abort( ) { + if (test_abort_proc != NULL) return test_abort_proc(); + else return 0; +} + +/******************************************************************************\ +* Types. +\******************************************************************************/ + +#define FLOORDIV(x, y) ((x) / (y)) + +/******************************************************************************\ +* Local prototypes. +\******************************************************************************/ + +static jas_image_cmpt_t *jas_image_cmpt_create0(void); +static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt); +static jas_image_cmpt_t *jas_image_cmpt_create(uint_fast32_t tlx, uint_fast32_t tly, + uint_fast32_t hstep, uint_fast32_t vstep, uint_fast32_t width, uint_fast32_t + height, uint_fast16_t depth, bool sgnd, uint_fast32_t inmem); +static void jas_image_setbbox(jas_image_t *image); +static jas_image_cmpt_t *jas_image_cmpt_copy(jas_image_cmpt_t *cmpt); +static int jas_image_growcmpts(jas_image_t *image, int maxcmpts); +static uint_fast32_t inttobits(jas_seqent_t v, int prec, bool sgnd); +static jas_seqent_t bitstoint(uint_fast32_t v, int prec, bool sgnd); +static int putint(jas_stream_t *out, int sgnd, int prec, long val); +static int getint(jas_stream_t *in, int sgnd, int prec, long *val); +static void jas_image_calcbbox2(jas_image_t *image, jas_image_coord_t *tlx, + jas_image_coord_t *tly, jas_image_coord_t *brx, jas_image_coord_t *bry); +static long uptomult(long x, long y); +static long downtomult(long x, long y); +static long convert(long val, int oldsgnd, int oldprec, int newsgnd, + int newprec); +static void jas_image_calcbbox2(jas_image_t *image, jas_image_coord_t *tlx, + jas_image_coord_t *tly, jas_image_coord_t *brx, jas_image_coord_t *bry); + +/******************************************************************************\ +* Global data. +\******************************************************************************/ + +static int jas_image_numfmts = 0; +static jas_image_fmtinfo_t jas_image_fmtinfos[JAS_IMAGE_MAXFMTS]; + +/******************************************************************************\ +* Create and destroy operations. +\******************************************************************************/ + +jas_image_t *jas_image_create(int numcmpts, jas_image_cmptparm_t *cmptparms, + int clrspc) +{ + jas_image_t *image; + uint_fast32_t rawsize; + uint_fast32_t inmem; + int cmptno; + jas_image_cmptparm_t *cmptparm; + + if (!(image = jas_image_create0())) { + return 0; + } + + image->clrspc_ = clrspc; + image->maxcmpts_ = numcmpts; + image->inmem_ = true; + + /* Allocate memory for the per-component information. */ + if (!(image->cmpts_ = jas_malloc(image->maxcmpts_ * + sizeof(jas_image_cmpt_t *)))) { + jas_image_destroy(image); + return 0; + } + /* Initialize in case of failure. */ + for (cmptno = 0; cmptno < image->maxcmpts_; ++cmptno) { + image->cmpts_[cmptno] = 0; + } + + /* Compute the approximate raw size of the image. */ + rawsize = 0; + for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno, + ++cmptparm) { + rawsize += cmptparm->width * cmptparm->height * + (cmptparm->prec + 7) / 8; + } + /* Decide whether to buffer the image data in memory, based on the + raw size of the image. */ + inmem = (rawsize < JAS_IMAGE_INMEMTHRESH); + + /* Create the individual image components. */ + for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno, + ++cmptparm) { + if (!(image->cmpts_[cmptno] = jas_image_cmpt_create(cmptparm->tlx, + cmptparm->tly, cmptparm->hstep, cmptparm->vstep, + cmptparm->width, cmptparm->height, cmptparm->prec, + cmptparm->sgnd, inmem))) { + jas_image_destroy(image); + return 0; + } + ++image->numcmpts_; + } + + /* Determine the bounding box for all of the components on the + reference grid (i.e., the image area) */ + jas_image_setbbox(image); + + return image; +} + +// GeoJasper: begin - dima - metadata box buffer utils +jas_metadata_box_t jas_box_init( void ) { + jas_metadata_box_t box; + memset( (void *)box.id, 0, 16 ); + box.size = 0; + box.buf = NULL; + return box; +} + +bool jas_box_alloc ( jas_metadata_box_t *box, unsigned long size ) { + if (box == NULL) return false; + *box = jas_box_init(); + if ( box->buf = (uint_fast8_t *) jas_malloc( size ) ) + box->size = size; + return (bool) box->buf; +} + +void jas_box_free( jas_metadata_box_t *box ) { + if (box == NULL) return; + if ( (box->size != 0) && (box->buf != NULL) ) + jas_free(box->buf); + *box = jas_box_init(); +} +// GeoJasper: end - dima - metadata box buffer utils + +jas_image_t *jas_image_create0() +{ + jas_image_t *image; + + if (!(image = jas_malloc(sizeof(jas_image_t)))) { + return 0; + } + + image->tlx_ = 0; + image->tly_ = 0; + image->brx_ = 0; + image->bry_ = 0; + image->clrspc_ = JAS_CLRSPC_UNKNOWN; + image->numcmpts_ = 0; + image->maxcmpts_ = 0; + image->cmpts_ = 0; + image->inmem_ = true; + image->cmprof_ = 0; + + // GeoJasper: begin - dima - buffer defines + { + int i; + image->metadata.count = JAS_IMAGE_NUM_BOXES; + for (i=0; i<image->metadata.count; ++i) + image->metadata.boxes[i] = jas_box_init(); + } + // GeoJasper: end - dima - buffer defines + + return image; +} + +jas_image_t *jas_image_copy(jas_image_t *image) +{ + jas_image_t *newimage; + int cmptno; + + newimage = jas_image_create0(); + if (jas_image_growcmpts(newimage, image->numcmpts_)) { + goto error; + } + for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) { + if (!(newimage->cmpts_[cmptno] = jas_image_cmpt_copy(image->cmpts_[cmptno]))) { + goto error; + } + ++newimage->numcmpts_; + } + + jas_image_setbbox(newimage); + + if (image->cmprof_) { + if (!(newimage->cmprof_ = jas_cmprof_copy(image->cmprof_))) + goto error; + } + + return newimage; +error: + if (newimage) { + jas_image_destroy(newimage); + } + return 0; +} + +static jas_image_cmpt_t *jas_image_cmpt_create0() +{ + jas_image_cmpt_t *cmpt; + if (!(cmpt = jas_malloc(sizeof(jas_image_cmpt_t)))) { + return 0; + } + memset(cmpt, 0, sizeof(jas_image_cmpt_t)); + cmpt->type_ = JAS_IMAGE_CT_UNKNOWN; + return cmpt; +} + +static jas_image_cmpt_t *jas_image_cmpt_copy(jas_image_cmpt_t *cmpt) +{ + jas_image_cmpt_t *newcmpt; + + if (!(newcmpt = jas_image_cmpt_create0())) { + return 0; + } + newcmpt->tlx_ = cmpt->tlx_; + newcmpt->tly_ = cmpt->tly_; + newcmpt->hstep_ = cmpt->hstep_; + newcmpt->vstep_ = cmpt->vstep_; + newcmpt->width_ = cmpt->width_; + newcmpt->height_ = cmpt->height_; + newcmpt->prec_ = cmpt->prec_; + newcmpt->sgnd_ = cmpt->sgnd_; + newcmpt->cps_ = cmpt->cps_; + newcmpt->type_ = cmpt->type_; + if (!(newcmpt->stream_ = jas_stream_memopen(0, 0))) { + return 0; + } + if (jas_stream_seek(cmpt->stream_, 0, SEEK_SET)) { + return 0; + } + if (jas_stream_copy(newcmpt->stream_, cmpt->stream_, -1)) { + return 0; + } + if (jas_stream_seek(newcmpt->stream_, 0, SEEK_SET)) { + return 0; + } + return newcmpt; +} + +void jas_image_destroy(jas_image_t *image) +{ + int i; + + // GeoJasper: begin - dima - free buffers + for (i=0; i<image->metadata.count; ++i) + jas_box_free( &image->metadata.boxes[i] ); + // GeoJasper: end - dima - free buffers + + if (image->cmpts_) { + for (i = 0; i < image->numcmpts_; ++i) { + jas_image_cmpt_destroy(image->cmpts_[i]); + image->cmpts_[i] = 0; + } + jas_free(image->cmpts_); + } + if (image->cmprof_) + jas_cmprof_destroy(image->cmprof_); + jas_free(image); +} + +static jas_image_cmpt_t *jas_image_cmpt_create(uint_fast32_t tlx, uint_fast32_t tly, + uint_fast32_t hstep, uint_fast32_t vstep, uint_fast32_t width, uint_fast32_t + height, uint_fast16_t depth, bool sgnd, uint_fast32_t inmem) +{ + jas_image_cmpt_t *cmpt; + long size; + + if (!(cmpt = jas_malloc(sizeof(jas_image_cmpt_t)))) { + return 0; + } + + cmpt->type_ = JAS_IMAGE_CT_UNKNOWN; + cmpt->tlx_ = tlx; + cmpt->tly_ = tly; + cmpt->hstep_ = hstep; + cmpt->vstep_ = vstep; + cmpt->width_ = width; + cmpt->height_ = height; + cmpt->prec_ = depth; + cmpt->sgnd_ = sgnd; + cmpt->stream_ = 0; + cmpt->cps_ = (depth + 7) / 8; + + size = cmpt->width_ * cmpt->height_ * cmpt->cps_; + cmpt->stream_ = (inmem) ? jas_stream_memopen(0, size) : jas_stream_tmpfile(); + if (!cmpt->stream_) { + jas_image_cmpt_destroy(cmpt); + return 0; + } + + /* Zero the component data. This isn't necessary, but it is + convenient for debugging purposes. */ + if (jas_stream_seek(cmpt->stream_, size - 1, SEEK_SET) < 0 || + jas_stream_putc(cmpt->stream_, 0) == EOF || + jas_stream_seek(cmpt->stream_, 0, SEEK_SET) < 0) { + jas_image_cmpt_destroy(cmpt); + return 0; + } + + return cmpt; +} + +static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt) +{ + if (cmpt->stream_) { + jas_stream_close(cmpt->stream_); + } + jas_free(cmpt); +} + +/******************************************************************************\ +* Load and save operations. +\******************************************************************************/ + +jas_image_t *jas_image_decode(jas_stream_t *in, int fmt, char *optstr) +{ + jas_image_fmtinfo_t *fmtinfo; + jas_image_t *image; + + image = 0; + + /* If possible, try to determine the format of the input data. */ + if (fmt < 0) { + if ((fmt = jas_image_getfmt(in)) < 0) + goto error; + } + + /* Is it possible to decode an image represented in this format? */ + if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) + goto error; + if (!fmtinfo->ops.decode) + goto error; + + /* Decode the image. */ + if (!(image = (*fmtinfo->ops.decode)(in, optstr))) + goto error; + + /* Create a color profile if needed. */ + if (!jas_clrspc_isunknown(image->clrspc_) && + !jas_clrspc_isgeneric(image->clrspc_) && !image->cmprof_) { + if (!(image->cmprof_ = + jas_cmprof_createfromclrspc(jas_image_clrspc(image)))) + goto error; + } + + return image; +error: + if (image) + jas_image_destroy(image); + return 0; +} + +int jas_image_encode(jas_image_t *image, jas_stream_t *out, int fmt, char *optstr) +{ + jas_image_fmtinfo_t *fmtinfo; + if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) { + return -1; + } + return (fmtinfo->ops.encode) ? (*fmtinfo->ops.encode)(image, out, + optstr) : (-1); +} + +/******************************************************************************\ +* Component read and write operations. +\******************************************************************************/ + +int jas_image_readcmpt(jas_image_t *image, int cmptno, jas_image_coord_t x, + jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height, + jas_matrix_t *data) +{ + jas_image_cmpt_t *cmpt; + jas_image_coord_t i; + jas_image_coord_t j; + int k; + jas_seqent_t v; + int c; + jas_seqent_t *dr; + jas_seqent_t *d; + int drs; + + if (cmptno < 0 || cmptno >= image->numcmpts_) { + return -1; + } + + cmpt = image->cmpts_[cmptno]; + if (x >= cmpt->width_ || y >= cmpt->height_ || + x + width > cmpt->width_ || + y + height > cmpt->height_) { + return -1; + } + + if (jas_matrix_numrows(data) != height || jas_matrix_numcols(data) != width) { + if (jas_matrix_resize(data, height, width)) { + return -1; + } + } + + dr = jas_matrix_getref(data, 0, 0); + drs = jas_matrix_rowstep(data); + for (i = 0; i < height; ++i, dr += drs) { + d = dr; + if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x) + * cmpt->cps_, SEEK_SET) < 0) { + return -1; + } + for (j = width; j > 0; --j, ++d) { + v = 0; + for (k = cmpt->cps_; k > 0; --k) { + if ((c = jas_stream_getc(cmpt->stream_)) == EOF) { + return -1; + } + v = (v << 8) | (c & 0xff); + } + *d = bitstoint(v, cmpt->prec_, cmpt->sgnd_); + } + } + + return 0; +} + +int jas_image_writecmpt(jas_image_t *image, int cmptno, jas_image_coord_t x, jas_image_coord_t y, jas_image_coord_t width, + jas_image_coord_t height, jas_matrix_t *data) +{ + jas_image_cmpt_t *cmpt; + jas_image_coord_t i; + jas_image_coord_t j; + jas_seqent_t *d; + jas_seqent_t *dr; + int drs; + jas_seqent_t v; + int k; + int c; + + if (cmptno < 0 || cmptno >= image->numcmpts_) { + return -1; + } + + cmpt = image->cmpts_[cmptno]; + if (x >= cmpt->width_ || y >= cmpt->height_ || + x + width > cmpt->width_ || + y + height > cmpt->height_) { + return -1; + } + + if (jas_matrix_numrows(data) < height || jas_matrix_numcols(data) < width) { + return -1; + } // GeoJasper: dima, change != to < + + dr = jas_matrix_getref(data, 0, 0); + drs = jas_matrix_rowstep(data); + for (i = 0; i < height; ++i, dr += drs) { + d = dr; + if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x) + * cmpt->cps_, SEEK_SET) < 0) { + return -1; + } + for (j = width; j > 0; --j, ++d) { + v = inttobits(*d, cmpt->prec_, cmpt->sgnd_); + for (k = cmpt->cps_; k > 0; --k) { + c = (v >> (8 * (cmpt->cps_ - 1))) & 0xff; + if (jas_stream_putc(cmpt->stream_, + (unsigned char) c) == EOF) { + return -1; + } + v <<= 8; + } + } + } + + return 0; +} + +/******************************************************************************\ +* File format operations. +\******************************************************************************/ + +void jas_image_clearfmts() +{ + int i; + jas_image_fmtinfo_t *fmtinfo; + for (i = 0; i < jas_image_numfmts; ++i) { + fmtinfo = &jas_image_fmtinfos[i]; + if (fmtinfo->name) { + jas_free(fmtinfo->name); + fmtinfo->name = 0; + } + if (fmtinfo->ext) { + jas_free(fmtinfo->ext); + fmtinfo->ext = 0; + } + if (fmtinfo->desc) { + jas_free(fmtinfo->desc); + fmtinfo->desc = 0; + } + } + jas_image_numfmts = 0; +} + +int jas_image_addfmt(int id, char *name, char *ext, char *desc, + jas_image_fmtops_t *ops) +{ + jas_image_fmtinfo_t *fmtinfo; + assert(id >= 0 && name && ext && ops); + if (jas_image_numfmts >= JAS_IMAGE_MAXFMTS) { + return -1; + } + fmtinfo = &jas_image_fmtinfos[jas_image_numfmts]; + fmtinfo->id = id; + if (!(fmtinfo->name = jas_strdup(name))) { + return -1; + } + if (!(fmtinfo->ext = jas_strdup(ext))) { + jas_free(fmtinfo->name); + return -1; + } + if (!(fmtinfo->desc = jas_strdup(desc))) { + jas_free(fmtinfo->name); + jas_free(fmtinfo->ext); + return -1; + } + fmtinfo->ops = *ops; + ++jas_image_numfmts; + return 0; +} + +int jas_image_strtofmt(char *name) +{ + jas_image_fmtinfo_t *fmtinfo; + if (!(fmtinfo = jas_image_lookupfmtbyname(name))) { + return -1; + } + return fmtinfo->id; +} + +char *jas_image_fmttostr(int fmt) +{ + jas_image_fmtinfo_t *fmtinfo; + if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) { + return 0; + } + return fmtinfo->name; +} + +int jas_image_getfmt(jas_stream_t *in) +{ + jas_image_fmtinfo_t *fmtinfo; + int found; + int i; + + /* Check for data in each of the supported formats. */ + found = 0; + for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, + ++fmtinfo) { + if (fmtinfo->ops.validate) { + /* Is the input data valid for this format? */ + if (!(*fmtinfo->ops.validate)(in)) { + found = 1; + break; + } + } + } + return found ? fmtinfo->id : (-1); +} + +int jas_image_fmtfromname(char *name) +{ + int i; + char *ext; + jas_image_fmtinfo_t *fmtinfo; + /* Get the file name extension. */ + if (!(ext = strrchr(name, '.'))) { + return -1; + } + ++ext; + /* Try to find a format that uses this extension. */ + for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, + ++fmtinfo) { + /* Do we have a match? */ + if (!strcmp(ext, fmtinfo->ext)) { + return fmtinfo->id; + } + } + return -1; +} + +/******************************************************************************\ +* Miscellaneous operations. +\******************************************************************************/ + +uint_fast32_t jas_image_rawsize(jas_image_t *image) +{ + uint_fast32_t rawsize; + int cmptno; + jas_image_cmpt_t *cmpt; + + rawsize = 0; + for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) { + cmpt = image->cmpts_[cmptno]; + rawsize += (cmpt->width_ * cmpt->height_ * cmpt->prec_ + + 7) / 8; + } + return rawsize; +} + +void jas_image_delcmpt(jas_image_t *image, int cmptno) +{ + if (cmptno >= image->numcmpts_) { + return; + } + jas_image_cmpt_destroy(image->cmpts_[cmptno]); + if (cmptno < image->numcmpts_) { + memmove(&image->cmpts_[cmptno], &image->cmpts_[cmptno + 1], + (image->numcmpts_ - 1 - cmptno) * sizeof(jas_image_cmpt_t *)); + } + --image->numcmpts_; + + jas_image_setbbox(image); +} + +int jas_image_addcmpt(jas_image_t *image, int cmptno, + jas_image_cmptparm_t *cmptparm) +{ + jas_image_cmpt_t *newcmpt; + if (cmptno < 0) + cmptno = image->numcmpts_; + assert(cmptno >= 0 && cmptno <= image->numcmpts_); + if (image->numcmpts_ >= image->maxcmpts_) { + if (jas_image_growcmpts(image, image->maxcmpts_ + 128)) { + return -1; + } + } + if (!(newcmpt = jas_image_cmpt_create(cmptparm->tlx, + cmptparm->tly, cmptparm->hstep, cmptparm->vstep, + cmptparm->width, cmptparm->height, cmptparm->prec, + cmptparm->sgnd, 1))) { + return -1; + } + if (cmptno < image->numcmpts_) { + memmove(&image->cmpts_[cmptno + 1], &image->cmpts_[cmptno], + (image->numcmpts_ - cmptno) * sizeof(jas_image_cmpt_t *)); + } + image->cmpts_[cmptno] = newcmpt; + ++image->numcmpts_; + + jas_image_setbbox(image); + + return 0; +} + +jas_image_fmtinfo_t *jas_image_lookupfmtbyid(int id) +{ + int i; + jas_image_fmtinfo_t *fmtinfo; + + for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, ++fmtinfo) { + if (fmtinfo->id == id) { + return fmtinfo; + } + } + return 0; +} + +jas_image_fmtinfo_t *jas_image_lookupfmtbyname(const char *name) +{ + int i; + jas_image_fmtinfo_t *fmtinfo; + + for (i = 0, fmtinfo = jas_image_fmtinfos; i < jas_image_numfmts; ++i, ++fmtinfo) { + if (!strcmp(fmtinfo->name, name)) { + return fmtinfo; + } + } + return 0; +} + + + + + +static uint_fast32_t inttobits(jas_seqent_t v, int prec, bool sgnd) +{ + uint_fast32_t ret; + ret = ((sgnd && v < 0) ? ((1 << prec) + v) : v) & JAS_ONES(prec); + return ret; +} + +static jas_seqent_t bitstoint(uint_fast32_t v, int prec, bool sgnd) +{ + jas_seqent_t ret; + v &= JAS_ONES(prec); + ret = (sgnd && (v & (1 << (prec - 1)))) ? (v - (1 << prec)) : v; + return ret; +} + +static void jas_image_setbbox(jas_image_t *image) +{ + jas_image_cmpt_t *cmpt; + int cmptno; + int_fast32_t x; + int_fast32_t y; + + if (image->numcmpts_ > 0) { + /* Determine the bounding box for all of the components on the + reference grid (i.e., the image area) */ + cmpt = image->cmpts_[0]; + image->tlx_ = cmpt->tlx_; + image->tly_ = cmpt->tly_; + image->brx_ = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1) + 1; + image->bry_ = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1) + 1; + for (cmptno = 1; cmptno < image->numcmpts_; ++cmptno) { + cmpt = image->cmpts_[cmptno]; + if (image->tlx_ > cmpt->tlx_) { + image->tlx_ = cmpt->tlx_; + } + if (image->tly_ > cmpt->tly_) { + image->tly_ = cmpt->tly_; + } + x = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1) + 1; + if (image->brx_ < x) { + image->brx_ = x; + } + y = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1) + 1; + if (image->bry_ < y) { + image->bry_ = y; + } + } + } else { + image->tlx_ = 0; + image->tly_ = 0; + image->brx_ = 0; + image->bry_ = 0; + } +} + +static int jas_image_growcmpts(jas_image_t *image, int maxcmpts) +{ + jas_image_cmpt_t **newcmpts; + int cmptno; + + newcmpts = (!image->cmpts_) ? jas_malloc(maxcmpts * sizeof(jas_image_cmpt_t *)) : + jas_realloc(image->cmpts_, maxcmpts * sizeof(jas_image_cmpt_t *)); + if (!newcmpts) { + return -1; + } + image->cmpts_ = newcmpts; + image->maxcmpts_ = maxcmpts; + for (cmptno = image->numcmpts_; cmptno < image->maxcmpts_; ++cmptno) { + image->cmpts_[cmptno] = 0; + } + return 0; +} + +int jas_image_copycmpt(jas_image_t *dstimage, int dstcmptno, jas_image_t *srcimage, + int srccmptno) +{ + jas_image_cmpt_t *newcmpt; + if (dstimage->numcmpts_ >= dstimage->maxcmpts_) { + if (jas_image_growcmpts(dstimage, dstimage->maxcmpts_ + 128)) { + return -1; + } + } + if (!(newcmpt = jas_image_cmpt_copy(srcimage->cmpts_[srccmptno]))) { + return -1; + } + if (dstcmptno < dstimage->numcmpts_) { + memmove(&dstimage->cmpts_[dstcmptno + 1], &dstimage->cmpts_[dstcmptno], + (dstimage->numcmpts_ - dstcmptno) * sizeof(jas_image_cmpt_t *)); + } + dstimage->cmpts_[dstcmptno] = newcmpt; + ++dstimage->numcmpts_; + + jas_image_setbbox(dstimage); + return 0; +} + +void jas_image_dump(jas_image_t *image, FILE *out) +{ + long buf[1024]; + int cmptno; + int n; + int i; + int width; + int height; + jas_image_cmpt_t *cmpt; + for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) { + cmpt = image->cmpts_[cmptno]; + fprintf(out, "prec=%d, sgnd=%d, cmpttype=%d\n", cmpt->prec_, + cmpt->sgnd_, cmpt->type_); + width = jas_image_cmptwidth(image, cmptno); + height = jas_image_cmptheight(image, cmptno); + n = JAS_MIN(16, width); + if (jas_image_readcmpt2(image, cmptno, 0, 0, n, 1, buf)) { + abort(); + } + for (i = 0; i < n; ++i) { + fprintf(out, " f(%d,%d)=%ld", i, 0, buf[i]); + } + fprintf(out, "\n"); + if (jas_image_readcmpt2(image, cmptno, width - n, height - 1, n, 1, buf)) { + abort(); + } + for (i = 0; i < n; ++i) { + fprintf(out, " f(%d,%d)=%ld", width - n + i, height - 1, buf[i]); + } + fprintf(out, "\n"); + } +} + +int jas_image_depalettize(jas_image_t *image, int cmptno, int numlutents, + int_fast32_t *lutents, int dtype, int newcmptno) +{ + jas_image_cmptparm_t cmptparms; + int_fast32_t v; + int i; + int j; + jas_image_cmpt_t *cmpt; + + cmpt = image->cmpts_[cmptno]; + cmptparms.tlx = cmpt->tlx_; + cmptparms.tly = cmpt->tly_; + cmptparms.hstep = cmpt->hstep_; + cmptparms.vstep = cmpt->vstep_; + cmptparms.width = cmpt->width_; + cmptparms.height = cmpt->height_; + cmptparms.prec = JAS_IMAGE_CDT_GETPREC(dtype); + cmptparms.sgnd = JAS_IMAGE_CDT_GETSGND(dtype); + + if (jas_image_addcmpt(image, newcmptno, &cmptparms)) { + return -1; + } + if (newcmptno <= cmptno) { + ++cmptno; + cmpt = image->cmpts_[cmptno]; + } + + for (j = 0; j < cmpt->height_; ++j) { + for (i = 0; i < cmpt->width_; ++i) { + v = jas_image_readcmptsample(image, cmptno, i, j); + if (v < 0) { + v = 0; + } else if (v >= numlutents) { + v = numlutents - 1; + } + jas_image_writecmptsample(image, newcmptno, i, j, + lutents[v]); + } + } + return 0; +} + +int jas_image_readcmptsample(jas_image_t *image, int cmptno, int x, int y) +{ + jas_image_cmpt_t *cmpt; + uint_fast32_t v; + int k; + int c; + + cmpt = image->cmpts_[cmptno]; + + if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_, + SEEK_SET) < 0) { + return -1; + } + v = 0; + for (k = cmpt->cps_; k > 0; --k) { + if ((c = jas_stream_getc(cmpt->stream_)) == EOF) { + return -1; + } + v = (v << 8) | (c & 0xff); + } + return bitstoint(v, cmpt->prec_, cmpt->sgnd_); +} + +void jas_image_writecmptsample(jas_image_t *image, int cmptno, int x, int y, + int_fast32_t v) +{ + jas_image_cmpt_t *cmpt; + uint_fast32_t t; + int k; + int c; + + cmpt = image->cmpts_[cmptno]; + + if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * y + x) * cmpt->cps_, + SEEK_SET) < 0) { + return; + } + t = inttobits(v, cmpt->prec_, cmpt->sgnd_); + for (k = cmpt->cps_; k > 0; --k) { + c = (t >> (8 * (cmpt->cps_ - 1))) & 0xff; + if (jas_stream_putc(cmpt->stream_, (unsigned char) c) == EOF) { + return; + } + t <<= 8; + } +} + +int jas_image_getcmptbytype(jas_image_t *image, int ctype) +{ + int cmptno; + + for (cmptno = 0; cmptno < image->numcmpts_; ++cmptno) { + if (image->cmpts_[cmptno]->type_ == ctype) { + return cmptno; + } + } + return -1; +} + + + + + + + + + + + + + + + + +/***********************************************/ +/***********************************************/ +/***********************************************/ +/***********************************************/ + +int jas_image_readcmpt2(jas_image_t *image, int cmptno, jas_image_coord_t x, + jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height, + long *buf) +{ + jas_image_cmpt_t *cmpt; + jas_image_coord_t i; + jas_image_coord_t j; + long v; + long *bufptr; + + if (cmptno < 0 || cmptno >= image->numcmpts_) + goto error; + cmpt = image->cmpts_[cmptno]; + if (x < 0 || x >= cmpt->width_ || y < 0 || y >= cmpt->height_ || + width < 0 || height < 0 || x + width > cmpt->width_ || + y + height > cmpt->height_) + goto error; + + bufptr = buf; + for (i = 0; i < height; ++i) { + if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x) + * cmpt->cps_, SEEK_SET) < 0) + goto error; + for (j = 0; j < width; ++j) { + if (getint(cmpt->stream_, cmpt->sgnd_, cmpt->prec_, &v)) + goto error; + *bufptr++ = v; + } + } + + return 0; +error: + return -1; +} + +int jas_image_writecmpt2(jas_image_t *image, int cmptno, jas_image_coord_t x, + jas_image_coord_t y, jas_image_coord_t width, jas_image_coord_t height, + long *buf) +{ + jas_image_cmpt_t *cmpt; + jas_image_coord_t i; + jas_image_coord_t j; + long v; + long *bufptr; + + if (cmptno < 0 || cmptno >= image->numcmpts_) + goto error; + cmpt = image->cmpts_[cmptno]; + if (x < 0 || x >= cmpt->width_ || y < 0 || y >= cmpt->height_ || + width < 0 || height < 0 || x + width > cmpt->width_ || + y + height > cmpt->height_) + goto error; + + bufptr = buf; + for (i = 0; i < height; ++i) { + if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * (y + i) + x) + * cmpt->cps_, SEEK_SET) < 0) + goto error; + for (j = 0; j < width; ++j) { + v = *bufptr++; + if (putint(cmpt->stream_, cmpt->sgnd_, cmpt->prec_, v)) + goto error; + } + } + + return 0; +error: + return -1; +} + +int jas_image_sampcmpt(jas_image_t *image, int cmptno, int newcmptno, + jas_image_coord_t ho, jas_image_coord_t vo, jas_image_coord_t hs, + jas_image_coord_t vs, int sgnd, int prec) +{ + jas_image_cmpt_t *oldcmpt; + jas_image_cmpt_t *newcmpt; + int width; + int height; + jas_image_coord_t tlx; + jas_image_coord_t tly; + jas_image_coord_t brx; + jas_image_coord_t bry; + int i; + int j; + jas_image_cmptparm_t cmptparm; + jas_image_coord_t ax; + jas_image_coord_t ay; + jas_image_coord_t bx; + jas_image_coord_t by; + jas_image_coord_t d0; + jas_image_coord_t d1; + jas_image_coord_t d2; + jas_image_coord_t d3; + jas_image_coord_t oldx; + jas_image_coord_t oldy; + jas_image_coord_t x; + jas_image_coord_t y; + long v; + jas_image_coord_t cmptbrx; + jas_image_coord_t cmptbry; + + assert(cmptno >= 0 && cmptno < image->numcmpts_); + oldcmpt = image->cmpts_[cmptno]; + assert(oldcmpt->tlx_ == 0 && oldcmpt->tly_ == 0); + jas_image_calcbbox2(image, &tlx, &tly, &brx, &bry); + width = FLOORDIV(brx - ho + hs, hs); + height = FLOORDIV(bry - vo + vs, vs); + cmptparm.tlx = ho; + cmptparm.tly = vo; + cmptparm.hstep = hs; + cmptparm.vstep = vs; + cmptparm.width = width; + cmptparm.height = height; + cmptparm.prec = prec; + cmptparm.sgnd = sgnd; + if (jas_image_addcmpt(image, newcmptno, &cmptparm)) + goto error; +cmptbrx = oldcmpt->tlx_ + (oldcmpt->width_ - 1) * oldcmpt->hstep_; +cmptbry = oldcmpt->tly_ + (oldcmpt->height_ - 1) * oldcmpt->vstep_; + newcmpt = image->cmpts_[newcmptno]; + jas_stream_rewind(newcmpt->stream_); + for (i = 0; i < height; ++i) { + y = newcmpt->tly_ + newcmpt->vstep_ * i; + for (j = 0; j < width; ++j) { + x = newcmpt->tlx_ + newcmpt->hstep_ * j; + ax = downtomult(x - oldcmpt->tlx_, oldcmpt->hstep_) + oldcmpt->tlx_; + ay = downtomult(y - oldcmpt->tly_, oldcmpt->vstep_) + oldcmpt->tly_; + bx = uptomult(x - oldcmpt->tlx_, oldcmpt->hstep_) + oldcmpt->tlx_; + if (bx > cmptbrx) + bx = cmptbrx; + by = uptomult(y - oldcmpt->tly_, oldcmpt->vstep_) + oldcmpt->tly_; + if (by > cmptbry) + by = cmptbry; + d0 = (ax - x) * (ax - x) + (ay - y) * (ay - y); + d1 = (bx - x) * (bx - x) + (ay - y) * (ay - y); + d2 = (bx - x) * (bx - x) + (by - y) * (by - y); + d3 = (ax - x) * (ax - x) + (by - y) * (by - y); + if (d0 <= d1 && d0 <= d2 && d0 <= d3) { + oldx = (ax - oldcmpt->tlx_) / oldcmpt->hstep_; + oldy = (ay - oldcmpt->tly_) / oldcmpt->vstep_; + } else if (d1 <= d0 && d1 <= d2 && d1 <= d3) { + oldx = (bx - oldcmpt->tlx_) / oldcmpt->hstep_; + oldy = (ay - oldcmpt->tly_) / oldcmpt->vstep_; + } else if (d2 <= d0 && d2 <= d1 && d1 <= d3) { + oldx = (bx - oldcmpt->tlx_) / oldcmpt->hstep_; + oldy = (by - oldcmpt->tly_) / oldcmpt->vstep_; + } else { + oldx = (ax - oldcmpt->tlx_) / oldcmpt->hstep_; + oldy = (by - oldcmpt->tly_) / oldcmpt->vstep_; + } + assert(oldx >= 0 && oldx < oldcmpt->width_ && + oldy >= 0 && oldy < oldcmpt->height_); + if (jas_stream_seek(oldcmpt->stream_, oldcmpt->cps_ * + (oldy * oldcmpt->width_ + oldx), SEEK_SET) < 0) + goto error; + if (getint(oldcmpt->stream_, oldcmpt->sgnd_, + oldcmpt->prec_, &v)) + goto error; + if (newcmpt->prec_ != oldcmpt->prec_ || + newcmpt->sgnd_ != oldcmpt->sgnd_) { + v = convert(v, oldcmpt->sgnd_, oldcmpt->prec_, + newcmpt->sgnd_, newcmpt->prec_); + } + if (putint(newcmpt->stream_, newcmpt->sgnd_, + newcmpt->prec_, v)) + goto error; + } + } + return 0; +error: + return -1; +} + +int jas_image_ishomosamp(jas_image_t *image) +{ + jas_image_coord_t hstep; + jas_image_coord_t vstep; + int result; + int i; + hstep = jas_image_cmpthstep(image, 0); + vstep = jas_image_cmptvstep(image, 0); + result = 1; + for (i = 0; i < image->numcmpts_; ++i) { + if (jas_image_cmpthstep(image, i) != hstep || + jas_image_cmptvstep(image, i) != vstep) { + result = 0; + break; + } + } + return result; +} + +/* Note: This function defines a bounding box differently. */ +static void jas_image_calcbbox2(jas_image_t *image, jas_image_coord_t *tlx, + jas_image_coord_t *tly, jas_image_coord_t *brx, jas_image_coord_t *bry) +{ + jas_image_cmpt_t *cmpt; + jas_image_coord_t tmptlx; + jas_image_coord_t tmptly; + jas_image_coord_t tmpbrx; + jas_image_coord_t tmpbry; + jas_image_coord_t t; + int i; + if (image->numcmpts_ > 0) { + cmpt = image->cmpts_[0]; + tmptlx = cmpt->tlx_; + tmptly = cmpt->tly_; + tmpbrx = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1); + tmpbry = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1); + for (i = 0; i < image->numcmpts_; ++i) { + cmpt = image->cmpts_[i]; + if (cmpt->tlx_ < tmptlx) + tmptlx = cmpt->tlx_; + if (cmpt->tly_ < tmptly) + tmptly = cmpt->tly_; + t = cmpt->tlx_ + cmpt->hstep_ * (cmpt->width_ - 1); + if (t > tmpbrx) + tmpbrx = t; + t = cmpt->tly_ + cmpt->vstep_ * (cmpt->height_ - 1); + if (t > tmpbry) + tmpbry = t; + } + } else { + tmptlx = 0; + tmptly = 0; + tmpbrx = -1; + tmpbry = -1; + } + *tlx = tmptlx; + *tly = tmptly; + *brx = tmpbrx; + *bry = tmpbry; +} + + + +static int getint(jas_stream_t *in, int sgnd, int prec, long *val) +{ + long v; + int n; + int c; + n = (prec + 7) / 8; + v = 0; + while (--n >= 0) { + if ((c = jas_stream_getc(in)) == EOF) + return -1; + v = (v << 8) | c; + } + v &= ((1 << prec) - 1); + if (sgnd) { + /* XXX - Do something here. */ + abort(); + } else { + *val = v; + } + return 0; +} + +static int putint(jas_stream_t *out, int sgnd, int prec, long val) +{ + int n; + int c; + if (sgnd) { + /* XXX - Do something here. */ + abort(); + } + val &= (1 << prec) - 1; + n = (prec + 7) / 8; + while (--n >= 0) { + c = (val >> (n * 8)) & 0xff; + if (jas_stream_putc(out, c) != c) + return -1; + } + return 0; +} + +static long convert(long val, int oldsgnd, int oldprec, int newsgnd, + int newprec) +{ + if (newsgnd != oldsgnd) { + } + if (newprec != oldprec) { + if (newprec > oldprec) { + val <<= newprec - oldprec; + } else if (oldprec > newprec) { + val >>= oldprec - newprec; + } + } + return val; +} + +static long downtomult(long x, long y) +{ + assert(x >= 0); + return (x / y) * y; +} + +static long uptomult(long x, long y) +{ + assert(x >= 0); + return ((x + y - 1) / y) * y; +} + +jas_image_t *jas_image_chclrspc(jas_image_t *image, jas_cmprof_t *outprof, + int intent) +{ + jas_image_t *inimage; + int minhstep; + int minvstep; + int i; + int j; + int k; + int n; + int hstep; + int vstep; + int numinauxchans; + int numoutauxchans; + int numinclrchans; + int numoutclrchans; + int prec; + jas_image_t *outimage; + int cmpttype; + int numoutchans; + jas_cmprof_t *inprof; + jas_cmprof_t *tmpprof; + jas_image_cmptparm_t cmptparm; + int width; + int height; + jas_cmxform_t *xform; + jas_cmpixmap_t inpixmap; + jas_cmpixmap_t outpixmap; + jas_cmcmptfmt_t *incmptfmts; + jas_cmcmptfmt_t *outcmptfmts; + +#if 0 +jas_eprintf("IMAGE\n"); +jas_image_dump(image, stderr); +#endif + + if (!(inimage = jas_image_copy(image))) + goto error; + image = 0; + + if (!jas_image_ishomosamp(inimage)) { + minhstep = jas_image_cmpthstep(inimage, 0); + minvstep = jas_image_cmptvstep(inimage, 0); + for (i = 1; i < jas_image_numcmpts(inimage); ++i) { + hstep = jas_image_cmpthstep(inimage, i); + vstep = jas_image_cmptvstep(inimage, i); + if (hstep < minhstep) + minhstep = hstep; + if (vstep < minvstep) + minvstep = vstep; + } + n = jas_image_numcmpts(inimage); + for (i = 0; i < n; ++i) { + cmpttype = jas_image_cmpttype(inimage, i); + if (jas_image_sampcmpt(inimage, i, i + 1, 0, 0, minhstep, minvstep, jas_image_cmptsgnd(inimage, i), jas_image_cmptprec(inimage, i))) + goto error; + jas_image_setcmpttype(inimage, i + 1, cmpttype); + jas_image_delcmpt(inimage, i); + } + } + + width = jas_image_cmptwidth(inimage, 0); + height = jas_image_cmptheight(inimage, 0); + hstep = jas_image_cmpthstep(inimage, 0); + vstep = jas_image_cmptvstep(inimage, 0); + + inprof = jas_image_cmprof(inimage); + assert(inprof); + numinclrchans = jas_clrspc_numchans(jas_cmprof_clrspc(inprof)); + numinauxchans = jas_image_numcmpts(inimage) - numinclrchans; + numoutclrchans = jas_clrspc_numchans(jas_cmprof_clrspc(outprof)); + numoutauxchans = 0; + numoutchans = numoutclrchans + numoutauxchans; + prec = 8; + + if (!(outimage = jas_image_create0())) + goto error; + + /* Create a component for each of the colorants. */ + for (i = 0; i < numoutclrchans; ++i) { + cmptparm.tlx = 0; + cmptparm.tly = 0; + cmptparm.hstep = hstep; + cmptparm.vstep = vstep; + cmptparm.width = width; + cmptparm.height = height; + cmptparm.prec = prec; + cmptparm.sgnd = 0; + if (jas_image_addcmpt(outimage, -1, &cmptparm)) + goto error; + jas_image_setcmpttype(outimage, i, JAS_IMAGE_CT_COLOR(i)); + } +#if 0 + /* Copy the auxiliary components without modification. */ + for (i = 0; i < jas_image_numcmpts(inimage); ++i) { + if (!ISCOLOR(jas_image_cmpttype(inimage, i))) { + jas_image_copycmpt(outimage, -1, inimage, i); +/* XXX - need to specify laydown of component on ref. grid */ + } + } +#endif + + if (!(tmpprof = jas_cmprof_copy(outprof))) + goto error; + assert(!jas_image_cmprof(outimage)); + jas_image_setcmprof(outimage, tmpprof); + tmpprof = 0; + jas_image_setclrspc(outimage, jas_cmprof_clrspc(outprof)); + + if (!(xform = jas_cmxform_create(inprof, outprof, 0, JAS_CMXFORM_OP_FWD, intent, 0))) + goto error; + + inpixmap.numcmpts = numinclrchans; + incmptfmts = malloc(numinclrchans * sizeof(jas_cmcmptfmt_t)); + assert(incmptfmts); + inpixmap.cmptfmts = incmptfmts; + for (i = 0; i < numinclrchans; ++i) { + j = jas_image_getcmptbytype(inimage, JAS_IMAGE_CT_COLOR(i)); + assert(j >= 0); + if (!(incmptfmts[i].buf = malloc(width * sizeof(long)))) + goto error; + incmptfmts[i].prec = jas_image_cmptprec(inimage, j); + incmptfmts[i].sgnd = jas_image_cmptsgnd(inimage, j); + incmptfmts[i].width = width; + incmptfmts[i].height = 1; + } + + outpixmap.numcmpts = numoutclrchans; + outcmptfmts = malloc(numoutclrchans * sizeof(jas_cmcmptfmt_t)); + assert(outcmptfmts); + outpixmap.cmptfmts = outcmptfmts; + + for (i = 0; i < numoutclrchans; ++i) { + j = jas_image_getcmptbytype(outimage, JAS_IMAGE_CT_COLOR(i)); + assert(j >= 0); + if (!(outcmptfmts[i].buf = malloc(width * sizeof(long)))) + goto error; + outcmptfmts[i].prec = jas_image_cmptprec(outimage, j); + outcmptfmts[i].sgnd = jas_image_cmptsgnd(outimage, j); + outcmptfmts[i].width = width; + outcmptfmts[i].height = 1; + } + + for (i = 0; i < height; ++i) { + for (j = 0; j < numinclrchans; ++j) { + k = jas_image_getcmptbytype(inimage, JAS_IMAGE_CT_COLOR(j)); + if (jas_image_readcmpt2(inimage, k, 0, i, width, 1, incmptfmts[j].buf)) + goto error; + } + jas_cmxform_apply(xform, &inpixmap, &outpixmap); + for (j = 0; j < numoutclrchans; ++j) { + k = jas_image_getcmptbytype(outimage, JAS_IMAGE_CT_COLOR(j)); + if (jas_image_writecmpt2(outimage, k, 0, i, width, 1, outcmptfmts[j].buf)) + goto error; + } + } + + for (i = 0; i < numoutclrchans; ++i) + jas_free(outcmptfmts[i].buf); + jas_free(outcmptfmts); + for (i = 0; i < numinclrchans; ++i) + jas_free(incmptfmts[i].buf); + jas_free(incmptfmts); + jas_cmxform_destroy(xform); + jas_image_destroy(inimage); + +#if 0 +jas_eprintf("INIMAGE\n"); +jas_image_dump(inimage, stderr); +jas_eprintf("OUTIMAGE\n"); +jas_image_dump(outimage, stderr); +#endif + return outimage; +error: + return 0; +} diff --git a/src/libjasper/base/jas_init.c b/src/libjasper/base/jas_init.c new file mode 100644 index 0000000..960d1e9 --- /dev/null +++ b/src/libjasper/base/jas_init.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include "jasper/jas_types.h" +#include "jasper/jas_image.h" +#include "jasper/jas_init.h" + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +/* Initialize the image format table. */ +int jas_init() +{ + jas_image_fmtops_t fmtops; + int fmtid; + + fmtid = 0; + +#if !defined(EXCLUDE_MIF_SUPPORT) + fmtops.decode = mif_decode; + fmtops.encode = mif_encode; + fmtops.validate = mif_validate; + jas_image_addfmt(fmtid, "mif", "mif", "My Image Format (MIF)", &fmtops); + ++fmtid; +#endif + +#if !defined(EXCLUDE_PNM_SUPPORT) + fmtops.decode = pnm_decode; + fmtops.encode = pnm_encode; + fmtops.validate = pnm_validate; + jas_image_addfmt(fmtid, "pnm", "pnm", "Portable Graymap/Pixmap (PNM)", + &fmtops); + jas_image_addfmt(fmtid, "pnm", "pgm", "Portable Graymap/Pixmap (PNM)", + &fmtops); + jas_image_addfmt(fmtid, "pnm", "ppm", "Portable Graymap/Pixmap (PNM)", + &fmtops); + ++fmtid; +#endif + +#if !defined(EXCLUDE_BMP_SUPPORT) + fmtops.decode = bmp_decode; + fmtops.encode = bmp_encode; + fmtops.validate = bmp_validate; + jas_image_addfmt(fmtid, "bmp", "bmp", "Microsoft Bitmap (BMP)", &fmtops); + ++fmtid; +#endif + +#if !defined(EXCLUDE_RAS_SUPPORT) + fmtops.decode = ras_decode; + fmtops.encode = ras_encode; + fmtops.validate = ras_validate; + jas_image_addfmt(fmtid, "ras", "ras", "Sun Rasterfile (RAS)", &fmtops); + ++fmtid; +#endif + +#if !defined(EXCLUDE_JP2_SUPPORT) + fmtops.decode = jp2_decode; + fmtops.encode = jp2_encode; + fmtops.validate = jp2_validate; + jas_image_addfmt(fmtid, "jp2", "jp2", + "JPEG-2000 JP2 File Format Syntax (ISO/IEC 15444-1)", &fmtops); + ++fmtid; + fmtops.decode = jpc_decode; + fmtops.encode = jpc_encode; + fmtops.validate = jpc_validate; + jas_image_addfmt(fmtid, "jpc", "jpc", + "JPEG-2000 Code Stream Syntax (ISO/IEC 15444-1)", &fmtops); + ++fmtid; +#endif + +#if !defined(EXCLUDE_JPG_SUPPORT) + fmtops.decode = jpg_decode; + fmtops.encode = jpg_encode; + fmtops.validate = jpg_validate; + jas_image_addfmt(fmtid, "jpg", "jpg", "JPEG (ISO/IEC 10918-1)", &fmtops); + ++fmtid; +#endif + +#if !defined(EXCLUDE_PGX_SUPPORT) + fmtops.decode = pgx_decode; + fmtops.encode = pgx_encode; + fmtops.validate = pgx_validate; + jas_image_addfmt(fmtid, "pgx", "pgx", "JPEG-2000 VM Format (PGX)", &fmtops); + ++fmtid; +#endif + +#if !defined(EXCLUDE_TIFF_SUPPORT) + fmtops.decode = tiff_decode; + fmtops.encode = tiff_encode; + fmtops.validate = tiff_validate; + jas_image_addfmt(fmtid, "tif", "tif", "Tagged Image File (TIFF)", &fmtops); + ++fmtid; +#endif + + /* We must not register the JasPer library exit handler until after + at least one memory allocation is performed. This is desirable + as it ensures that the JasPer exit handler is called before the + debug memory allocator exit handler. */ + atexit(jas_cleanup); + + return 0; +} + +void jas_cleanup() +{ + jas_image_clearfmts(); +} diff --git a/src/libjasper/base/jas_malloc.c b/src/libjasper/base/jas_malloc.c new file mode 100644 index 0000000..77f2bc6 --- /dev/null +++ b/src/libjasper/base/jas_malloc.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Memory Allocator + * + * $Id: jas_malloc.c,v 1.1 2008/10/17 06:14:59 scuri Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> + +/* We need the prototype for memset. */ +#include <string.h> + +#include "jasper/jas_malloc.h" + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +#if defined(DEBUG_MEMALLOC) +#include "../../../local/src/memalloc.c" +#endif + +#if !defined(DEBUG_MEMALLOC) + +#define MEMALLOC_ALIGNMENT 32 +#define MEMALLOC_ALIGN2 +#undef MEMALLOC_ALIGN2 + +void *jas_malloc(size_t size) +{ +#if defined(MEMALLOC_ALIGN2) + void *ptr; +abort(); + if (posix_memalign(&ptr, MEMALLOC_ALIGNMENT, size)) { + return 0; + } + return ptr; +#endif + return malloc(size); +} + +void jas_free(void *ptr) +{ + free(ptr); +} + +void *jas_realloc(void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +void *jas_calloc(size_t nmemb, size_t size) +{ + void *ptr; + size_t n; + n = nmemb * size; + if (!(ptr = jas_malloc(n * sizeof(char)))) { + return 0; + } + memset(ptr, 0, n); + return ptr; +} + +#endif diff --git a/src/libjasper/base/jas_seq.c b/src/libjasper/base/jas_seq.c new file mode 100644 index 0000000..fcf14f0 --- /dev/null +++ b/src/libjasper/base/jas_seq.c @@ -0,0 +1,454 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Sequence/Matrix Library + * + * $Id: jas_seq.c,v 1.1 2008/10/17 06:14:59 scuri Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include <stdlib.h> +#include <assert.h> +#include <math.h> + +#include "jasper/jas_seq.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_math.h" + +/******************************************************************************\ +* Constructors and destructors. +\******************************************************************************/ + +jas_matrix_t *jas_seq2d_create(int xstart, int ystart, int xend, int yend) +{ + jas_matrix_t *matrix; + assert(xstart <= xend && ystart <= yend); + if (!(matrix = jas_matrix_create(yend - ystart, xend - xstart))) { + return 0; + } + matrix->xstart_ = xstart; + matrix->ystart_ = ystart; + matrix->xend_ = xend; + matrix->yend_ = yend; + return matrix; +} + +jas_matrix_t *jas_matrix_create(int numrows, int numcols) +{ + jas_matrix_t *matrix; + int i; + + if (!(matrix = jas_malloc(sizeof(jas_matrix_t)))) { + return 0; + } + matrix->flags_ = 0; + matrix->numrows_ = numrows; + matrix->numcols_ = numcols; + matrix->rows_ = 0; + matrix->maxrows_ = numrows; + matrix->data_ = 0; + matrix->datasize_ = numrows * numcols; + + if (matrix->maxrows_ > 0) { + if (!(matrix->rows_ = jas_malloc(matrix->maxrows_ * + sizeof(jas_seqent_t *)))) { + jas_matrix_destroy(matrix); + return 0; + } + } + + if (matrix->datasize_ > 0) { + if (!(matrix->data_ = jas_malloc(matrix->datasize_ * + sizeof(jas_seqent_t)))) { + jas_matrix_destroy(matrix); + return 0; + } + } + + for (i = 0; i < numrows; ++i) { + matrix->rows_[i] = &matrix->data_[i * matrix->numcols_]; + } + + for (i = 0; i < matrix->datasize_; ++i) { + matrix->data_[i] = 0; + } + + matrix->xstart_ = 0; + matrix->ystart_ = 0; + matrix->xend_ = matrix->numcols_; + matrix->yend_ = matrix->numrows_; + + return matrix; +} + +void jas_matrix_destroy(jas_matrix_t *matrix) +{ + if (matrix->data_) { + assert(!(matrix->flags_ & JAS_MATRIX_REF)); + jas_free(matrix->data_); + matrix->data_ = 0; + } + if (matrix->rows_) { + jas_free(matrix->rows_); + matrix->rows_ = 0; + } + jas_free(matrix); +} + +jas_seq2d_t *jas_seq2d_copy(jas_seq2d_t *x) +{ + jas_matrix_t *y; + int i; + int j; + y = jas_seq2d_create(jas_seq2d_xstart(x), jas_seq2d_ystart(x), jas_seq2d_xend(x), + jas_seq2d_yend(x)); + assert(y); + for (i = 0; i < x->numrows_; ++i) { + for (j = 0; j < x->numcols_; ++j) { + *jas_matrix_getref(y, i, j) = jas_matrix_get(x, i, j); + } + } + return y; +} + +jas_matrix_t *jas_matrix_copy(jas_matrix_t *x) +{ + jas_matrix_t *y; + int i; + int j; + y = jas_matrix_create(x->numrows_, x->numcols_); + for (i = 0; i < x->numrows_; ++i) { + for (j = 0; j < x->numcols_; ++j) { + *jas_matrix_getref(y, i, j) = jas_matrix_get(x, i, j); + } + } + return y; +} + +/******************************************************************************\ +* Bind operations. +\******************************************************************************/ + +void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, int xstart, int ystart, + int xend, int yend) +{ + jas_matrix_bindsub(s, s1, ystart - s1->ystart_, xstart - s1->xstart_, + yend - s1->ystart_ - 1, xend - s1->xstart_ - 1); +} + +void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, int r0, int c0, + int r1, int c1) +{ + int i; + + if (mat0->data_) { + if (!(mat0->flags_ & JAS_MATRIX_REF)) { + jas_free(mat0->data_); + } + mat0->data_ = 0; + mat0->datasize_ = 0; + } + if (mat0->rows_) { + jas_free(mat0->rows_); + mat0->rows_ = 0; + } + mat0->flags_ |= JAS_MATRIX_REF; + mat0->numrows_ = r1 - r0 + 1; + mat0->numcols_ = c1 - c0 + 1; + mat0->maxrows_ = mat0->numrows_; + mat0->rows_ = jas_malloc(mat0->maxrows_ * sizeof(jas_seqent_t *)); + for (i = 0; i < mat0->numrows_; ++i) { + mat0->rows_[i] = mat1->rows_[r0 + i] + c0; + } + + mat0->xstart_ = mat1->xstart_ + c0; + mat0->ystart_ = mat1->ystart_ + r0; + mat0->xend_ = mat0->xstart_ + mat0->numcols_; + mat0->yend_ = mat0->ystart_ + mat0->numrows_; +} + +/******************************************************************************\ +* Arithmetic operations. +\******************************************************************************/ + +int jas_matrix_cmp(jas_matrix_t *mat0, jas_matrix_t *mat1) +{ + int i; + int j; + + if (mat0->numrows_ != mat1->numrows_ || mat0->numcols_ != + mat1->numcols_) { + return 1; + } + for (i = 0; i < mat0->numrows_; i++) { + for (j = 0; j < mat0->numcols_; j++) { + if (jas_matrix_get(mat0, i, j) != jas_matrix_get(mat1, i, j)) { + return 1; + } + } + } + return 0; +} + +void jas_matrix_divpow2(jas_matrix_t *matrix, int n) +{ + int i; + int j; + jas_seqent_t *rowstart; + int rowstep; + jas_seqent_t *data; + + rowstep = jas_matrix_rowstep(matrix); + for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i, + rowstart += rowstep) { + for (j = matrix->numcols_, data = rowstart; j > 0; --j, + ++data) { + *data = (*data >= 0) ? ((*data) >> n) : + (-((-(*data)) >> n)); + } + } +} + +void jas_matrix_clip(jas_matrix_t *matrix, jas_seqent_t minval, jas_seqent_t maxval) +{ + int i; + int j; + jas_seqent_t v; + jas_seqent_t *rowstart; + jas_seqent_t *data; + int rowstep; + + rowstep = jas_matrix_rowstep(matrix); + for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i, + rowstart += rowstep) { + data = rowstart; + for (j = matrix->numcols_, data = rowstart; j > 0; --j, + ++data) { + v = *data; + if (v < minval) { + *data = minval; + } else if (v > maxval) { + *data = maxval; + } + } + } +} + +void jas_matrix_asr(jas_matrix_t *matrix, int n) +{ + int i; + int j; + jas_seqent_t *rowstart; + int rowstep; + jas_seqent_t *data; + + assert(n >= 0); + rowstep = jas_matrix_rowstep(matrix); + for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i, + rowstart += rowstep) { + for (j = matrix->numcols_, data = rowstart; j > 0; --j, + ++data) { + *data >>= n; + } + } +} + +void jas_matrix_asl(jas_matrix_t *matrix, int n) +{ + int i; + int j; + jas_seqent_t *rowstart; + int rowstep; + jas_seqent_t *data; + + rowstep = jas_matrix_rowstep(matrix); + for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i, + rowstart += rowstep) { + for (j = matrix->numcols_, data = rowstart; j > 0; --j, + ++data) { + *data <<= n; + } + } +} + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +int jas_matrix_resize(jas_matrix_t *matrix, int numrows, int numcols) +{ + int size; + int i; + + size = numrows * numcols; + if (size > matrix->datasize_ || numrows > matrix->maxrows_) { + return -1; + } + + matrix->numrows_ = numrows; + matrix->numcols_ = numcols; + + for (i = 0; i < numrows; ++i) { + matrix->rows_[i] = &matrix->data_[numcols * i]; + } + + return 0; +} + +void jas_matrix_setall(jas_matrix_t *matrix, jas_seqent_t val) +{ + int i; + int j; + jas_seqent_t *rowstart; + int rowstep; + jas_seqent_t *data; + + rowstep = jas_matrix_rowstep(matrix); + for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i, + rowstart += rowstep) { + for (j = matrix->numcols_, data = rowstart; j > 0; --j, + ++data) { + *data = val; + } + } +} + +jas_matrix_t *jas_seq2d_input(FILE *in) +{ + jas_matrix_t *matrix; + int i; + int j; + long x; + int numrows; + int numcols; + int xoff; + int yoff; + + if (fscanf(in, "%d %d", &xoff, &yoff) != 2) + return 0; + if (fscanf(in, "%d %d", &numcols, &numrows) != 2) + return 0; + if (!(matrix = jas_seq2d_create(xoff, yoff, xoff + numcols, yoff + numrows))) + return 0; + + if (jas_matrix_numrows(matrix) != numrows || jas_matrix_numcols(matrix) != numcols) { + abort(); + } + + /* Get matrix data. */ + for (i = 0; i < jas_matrix_numrows(matrix); i++) { + for (j = 0; j < jas_matrix_numcols(matrix); j++) { + if (fscanf(in, "%ld", &x) != 1) { + jas_matrix_destroy(matrix); + return 0; + } + jas_matrix_set(matrix, i, j, JAS_CAST(jas_seqent_t, x)); + } + } + + return matrix; +} + +int jas_seq2d_output(jas_matrix_t *matrix, FILE *out) +{ +#define MAXLINELEN 80 + int i; + int j; + jas_seqent_t x; + char buf[MAXLINELEN + 1]; + char sbuf[MAXLINELEN + 1]; + int n; + + fprintf(out, "%d %d\n", jas_seq2d_xstart(matrix), + jas_seq2d_ystart(matrix)); + fprintf(out, "%d %d\n", jas_matrix_numcols(matrix), + jas_matrix_numrows(matrix)); + + buf[0] = '\0'; + for (i = 0; i < jas_matrix_numrows(matrix); ++i) { + for (j = 0; j < jas_matrix_numcols(matrix); ++j) { + x = jas_matrix_get(matrix, i, j); + sprintf(sbuf, "%s%4ld", (strlen(buf) > 0) ? " " : "", + JAS_CAST(long, x)); + n = strlen(buf); + if (n + strlen(sbuf) > MAXLINELEN) { + fputs(buf, out); + fputs("\n", out); + buf[0] = '\0'; + } + strcat(buf, sbuf); + if (j == jas_matrix_numcols(matrix) - 1) { + fputs(buf, out); + fputs("\n", out); + buf[0] = '\0'; + } + } + } + fputs(buf, out); + + return 0; +} diff --git a/src/libjasper/base/jas_stream.c b/src/libjasper/base/jas_stream.c new file mode 100644 index 0000000..f2b6d3a --- /dev/null +++ b/src/libjasper/base/jas_stream.c @@ -0,0 +1,1151 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2003 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * I/O Stream Library + * + * $Id: jas_stream.c,v 1.1 2008/10/17 06:14:59 scuri Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include <assert.h> +#if defined(HAVE_FCNTL_H) +#include <fcntl.h> +#endif +#include <stdlib.h> +#include <stdarg.h> +#include <stdio.h> +#include <ctype.h> +#if defined(HAVE_UNISTD_H) +#include <unistd.h> +#endif +#if defined(WIN32) || defined(HAVE_IO_H) +#include <io.h> +#endif + +#include "jasper/jas_types.h" +#include "jasper/jas_stream.h" +#include "jasper/jas_malloc.h" +#include "jasper/jas_math.h" + +/******************************************************************************\ +* Local function prototypes. +\******************************************************************************/ + +static int jas_strtoopenmode(const char *s); +static void jas_stream_destroy(jas_stream_t *stream); +jas_stream_t *jas_stream_create(void); /* IMLIB - removed static, so it can be used in jas_binfile.c */ +void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf, /* IMLIB - removed static, so it can be used in jas_binfile.c */ + int bufsize); + +static int mem_read(jas_stream_obj_t *obj, char *buf, int cnt); +static int mem_write(jas_stream_obj_t *obj, char *buf, int cnt); +static long mem_seek(jas_stream_obj_t *obj, long offset, int origin); +static int mem_close(jas_stream_obj_t *obj); + +static int sfile_read(jas_stream_obj_t *obj, char *buf, int cnt); +static int sfile_write(jas_stream_obj_t *obj, char *buf, int cnt); +static long sfile_seek(jas_stream_obj_t *obj, long offset, int origin); +static int sfile_close(jas_stream_obj_t *obj); + +static int file_read(jas_stream_obj_t *obj, char *buf, int cnt); +static int file_write(jas_stream_obj_t *obj, char *buf, int cnt); +static long file_seek(jas_stream_obj_t *obj, long offset, int origin); +static int file_close(jas_stream_obj_t *obj); + +/******************************************************************************\ +* Local data. +\******************************************************************************/ + +static jas_stream_ops_t jas_stream_fileops = { + file_read, + file_write, + file_seek, + file_close +}; + +static jas_stream_ops_t jas_stream_sfileops = { + sfile_read, + sfile_write, + sfile_seek, + sfile_close +}; + +static jas_stream_ops_t jas_stream_memops = { + mem_read, + mem_write, + mem_seek, + mem_close +}; + +/******************************************************************************\ +* Code for opening and closing streams. +\******************************************************************************/ + +jas_stream_t *jas_stream_create() /* IMLIB - removed static, so it can be used in jas_binfile.c */ +{ + jas_stream_t *stream; + + if (!(stream = jas_malloc(sizeof(jas_stream_t)))) { + return 0; + } + stream->openmode_ = 0; + stream->bufmode_ = 0; + stream->flags_ = 0; + stream->bufbase_ = 0; + stream->bufstart_ = 0; + stream->bufsize_ = 0; + stream->ptr_ = 0; + stream->cnt_ = 0; + stream->ops_ = 0; + stream->obj_ = 0; + stream->rwcnt_ = 0; + stream->rwlimit_ = -1; + + return stream; +} + +jas_stream_t *jas_stream_memopen(char *buf, int bufsize) +{ + jas_stream_t *stream; + jas_stream_memobj_t *obj; + + if (!(stream = jas_stream_create())) { + return 0; + } + + /* A stream associated with a memory buffer is always opened + for both reading and writing in binary mode. */ + stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY; + + /* Since the stream data is already resident in memory, buffering + is not necessary. */ + /* But... It still may be faster to use buffering anyways. */ + jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); + + /* Select the operations for a memory stream. */ + stream->ops_ = &jas_stream_memops; + + /* Allocate memory for the underlying memory stream object. */ + if (!(obj = jas_malloc(sizeof(jas_stream_memobj_t)))) { + jas_stream_destroy(stream); + return 0; + } + stream->obj_ = (void *) obj; + + /* Initialize a few important members of the memory stream object. */ + obj->myalloc_ = 0; + obj->buf_ = 0; + + /* If the buffer size specified is nonpositive, then the buffer + is allocated internally and automatically grown as needed. */ + if (bufsize <= 0) { + obj->bufsize_ = 1024; + obj->growable_ = 1; + } else { + obj->bufsize_ = bufsize; + obj->growable_ = 0; + } + if (buf) { + obj->buf_ = (unsigned char *) buf; + } else { + obj->buf_ = jas_malloc(obj->bufsize_ * sizeof(char)); + obj->myalloc_ = 1; + } + if (!obj->buf_) { + jas_stream_close(stream); + return 0; + } + + if (bufsize > 0 && buf) { + /* If a buffer was supplied by the caller and its length is positive, + make the associated buffer data appear in the stream initially. */ + obj->len_ = bufsize; + } else { + /* The stream is initially empty. */ + obj->len_ = 0; + } + obj->pos_ = 0; + + return stream; +} + +jas_stream_t *jas_stream_fopen(const char *filename, const char *mode) +{ + jas_stream_t *stream; + jas_stream_fileobj_t *obj; + int openflags; + + /* Allocate a stream object. */ + if (!(stream = jas_stream_create())) { + return 0; + } + + /* Parse the mode string. */ + stream->openmode_ = jas_strtoopenmode(mode); + + /* Determine the correct flags to use for opening the file. */ + if ((stream->openmode_ & JAS_STREAM_READ) && + (stream->openmode_ & JAS_STREAM_WRITE)) { + openflags = O_RDWR; + } else if (stream->openmode_ & JAS_STREAM_READ) { + openflags = O_RDONLY; + } else if (stream->openmode_ & JAS_STREAM_WRITE) { + openflags = O_WRONLY; + } else { + openflags = 0; + } + if (stream->openmode_ & JAS_STREAM_APPEND) { + openflags |= O_APPEND; + } + if (stream->openmode_ & JAS_STREAM_BINARY) { + openflags |= O_BINARY; + } + if (stream->openmode_ & JAS_STREAM_CREATE) { + openflags |= O_CREAT | O_TRUNC; + } + + /* Allocate space for the underlying file stream object. */ + if (!(obj = jas_malloc(sizeof(jas_stream_fileobj_t)))) { + jas_stream_destroy(stream); + return 0; + } + obj->fd = -1; + obj->flags = 0; + //obj->pathname[0] = '\0'; + strncpy(obj->pathname, filename, DIM_MAX_FILE_NAME); // GeoJasper: dima + stream->obj_ = (void *) obj; + + /* Select the operations for a file stream object. */ + stream->ops_ = &jas_stream_fileops; + + /* Open the underlying file. */ + if ((obj->fd = open(filename, openflags, JAS_STREAM_PERMS)) < 0) { + jas_stream_destroy(stream); + return 0; + } + + /* By default, use full buffering for this type of stream. */ + jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); + + return stream; +} + +jas_stream_t *jas_stream_freopen(const char *path, const char *mode, FILE *fp) +{ + jas_stream_t *stream; + int openflags; + + /* Eliminate compiler warning about unused variable. */ + path = 0; + + /* Allocate a stream object. */ + if (!(stream = jas_stream_create())) { + return 0; + } + + /* Parse the mode string. */ + stream->openmode_ = jas_strtoopenmode(mode); + + /* Determine the correct flags to use for opening the file. */ + if ((stream->openmode_ & JAS_STREAM_READ) && + (stream->openmode_ & JAS_STREAM_WRITE)) { + openflags = O_RDWR; + } else if (stream->openmode_ & JAS_STREAM_READ) { + openflags = O_RDONLY; + } else if (stream->openmode_ & JAS_STREAM_WRITE) { + openflags = O_WRONLY; + } else { + openflags = 0; + } + if (stream->openmode_ & JAS_STREAM_APPEND) { + openflags |= O_APPEND; + } + if (stream->openmode_ & JAS_STREAM_BINARY) { + openflags |= O_BINARY; + } + if (stream->openmode_ & JAS_STREAM_CREATE) { + openflags |= O_CREAT | O_TRUNC; + } + + stream->obj_ = JAS_CAST(void *, fp); + + /* Select the operations for a file stream object. */ + stream->ops_ = &jas_stream_sfileops; + + /* By default, use full buffering for this type of stream. */ + jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); + + return stream; +} + +jas_stream_t *jas_stream_tmpfile() +{ + jas_stream_t *stream; + jas_stream_fileobj_t *obj; + + if (!(stream = jas_stream_create())) { + return 0; + } + + /* A temporary file stream is always opened for both reading and + writing in binary mode. */ + stream->openmode_ = JAS_STREAM_READ | JAS_STREAM_WRITE | JAS_STREAM_BINARY; + + /* Allocate memory for the underlying temporary file object. */ + if (!(obj = jas_malloc(sizeof(jas_stream_fileobj_t)))) { + jas_stream_destroy(stream); + return 0; + } + obj->fd = -1; + obj->flags = 0; + obj->pathname[0] = '\0'; + stream->obj_ = obj; + + /* Choose a file name. */ + tmpnam(obj->pathname); + + /* Open the underlying file. */ + if ((obj->fd = open(obj->pathname, O_CREAT | O_EXCL | O_RDWR | O_TRUNC | O_BINARY, + JAS_STREAM_PERMS)) < 0) { + jas_stream_destroy(stream); + return 0; + } + + /* Unlink the file so that it will disappear if the program + terminates abnormally. */ + /* Under UNIX, one can unlink an open file and continue to do I/O + on it. Not all operating systems support this functionality, however. + For example, under Microsoft Windows the unlink operation will fail, + since the file is open. */ + if (unlink(obj->pathname)) { + /* We will try unlinking the file again after it is closed. */ + obj->flags |= JAS_STREAM_FILEOBJ_DELONCLOSE; + } + + /* Use full buffering. */ + jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); + + stream->ops_ = &jas_stream_fileops; + + return stream; +} + +jas_stream_t *jas_stream_fdopen(int fd, const char *mode) +{ + jas_stream_t *stream; + jas_stream_fileobj_t *obj; + + /* Allocate a stream object. */ + if (!(stream = jas_stream_create())) { + return 0; + } + + /* Parse the mode string. */ + stream->openmode_ = jas_strtoopenmode(mode); + +#if defined(WIN32) + /* Argh!!! Someone ought to banish text mode (i.e., O_TEXT) to the + greatest depths of purgatory! */ + /* Ensure that the file descriptor is in binary mode, if the caller + has specified the binary mode flag. Arguably, the caller ought to + take care of this, but text mode is a ugly wart anyways, so we save + the caller some grief by handling this within the stream library. */ + /* This ugliness is mainly for the benefit of those who run the + JasPer software under Windows from shells that insist on opening + files in text mode. For example, in the Cygwin environment, + shells often open files in text mode when I/O redirection is + used. Grr... */ + if (stream->openmode_ & JAS_STREAM_BINARY) { + setmode(fd, O_BINARY); + } +#endif + + /* Allocate space for the underlying file stream object. */ + if (!(obj = jas_malloc(sizeof(jas_stream_fileobj_t)))) { + jas_stream_destroy(stream); + return 0; + } + obj->fd = fd; + obj->flags = 0; + obj->pathname[0] = '\0'; + stream->obj_ = (void *) obj; + + /* Do not close the underlying file descriptor when the stream is + closed. */ + obj->flags |= JAS_STREAM_FILEOBJ_NOCLOSE; + + /* By default, use full buffering for this type of stream. */ + jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); + + /* Select the operations for a file stream object. */ + stream->ops_ = &jas_stream_fileops; + + return stream; +} + +static void jas_stream_destroy(jas_stream_t *stream) +{ + /* If the memory for the buffer was allocated with malloc, free + this memory. */ + if ((stream->bufmode_ & JAS_STREAM_FREEBUF) && stream->bufbase_) { + jas_free(stream->bufbase_); + stream->bufbase_ = 0; + } + jas_free(stream); +} + +int jas_stream_close(jas_stream_t *stream) +{ + /* Flush buffer if necessary. */ + jas_stream_flush(stream); + + /* Close the underlying stream object. */ + (*stream->ops_->close_)(stream->obj_); + + jas_stream_destroy(stream); + + return 0; +} + +/******************************************************************************\ +* Code for reading and writing streams. +\******************************************************************************/ + +int jas_stream_getc_func(jas_stream_t *stream) +{ + assert(stream->ptr_ - stream->bufbase_ <= stream->bufsize_ + + JAS_STREAM_MAXPUTBACK); + return jas_stream_getc_macro(stream); +} + +int jas_stream_putc_func(jas_stream_t *stream, int c) +{ + assert(stream->ptr_ - stream->bufstart_ <= stream->bufsize_); + return jas_stream_putc_macro(stream, c); +} + +int jas_stream_ungetc(jas_stream_t *stream, int c) +{ + if (!stream->ptr_ || stream->ptr_ == stream->bufbase_) { + return -1; + } + + /* Reset the EOF indicator (since we now have at least one character + to read). */ + stream->flags_ &= ~JAS_STREAM_EOF; + + --stream->rwcnt_; + --stream->ptr_; + ++stream->cnt_; + *stream->ptr_ = c; + return 0; +} + +int jas_stream_read(jas_stream_t *stream, void *buf, int cnt) +{ + int n; + int c; + char *bufptr; + + bufptr = buf; + + n = 0; + while (n < cnt) { + if ((c = jas_stream_getc(stream)) == EOF) { + return n; + } + *bufptr++ = c; + ++n; + } + + return n; +} + +int jas_stream_write(jas_stream_t *stream, const void *buf, int cnt) +{ + int n; + const char *bufptr; + + bufptr = buf; + + n = 0; + while (n < cnt) { + if (jas_stream_putc(stream, *bufptr) == EOF) { + return n; + } + ++bufptr; + ++n; + } + + return n; +} + +/* Note: This function uses a fixed size buffer. Therefore, it cannot + handle invocations that will produce more output than can be held + by the buffer. */ +int jas_stream_printf(jas_stream_t *stream, const char *fmt, ...) +{ + va_list ap; + char buf[4096]; + int ret; + + va_start(ap, fmt); + ret = vsprintf(buf, fmt, ap); + jas_stream_puts(stream, buf); + va_end(ap); + return ret; +} + +int jas_stream_puts(jas_stream_t *stream, const char *s) +{ + while (*s != '\0') { + if (jas_stream_putc_macro(stream, *s) == EOF) { + return -1; + } + ++s; + } + return 0; +} + +char *jas_stream_gets(jas_stream_t *stream, char *buf, int bufsize) +{ + int c; + char *bufptr; + assert(bufsize > 0); + + bufptr = buf; + while (bufsize > 1) { + if ((c = jas_stream_getc(stream)) == EOF) { + break; + } + *bufptr++ = c; + --bufsize; + if (c == '\n') { + break; + } + } + *bufptr = '\0'; + return buf; +} + +int jas_stream_gobble(jas_stream_t *stream, int n) +{ + int m; + m = n; + for (m = n; m > 0; --m) { + if (jas_stream_getc(stream) == EOF) { + return n - m; + } + } + return n; +} + +int jas_stream_pad(jas_stream_t *stream, int n, int c) +{ + int m; + m = n; + for (m = n; m > 0; --m) { + if (jas_stream_putc(stream, c) == EOF) + return n - m; + } + return n; +} + +/******************************************************************************\ +* Code for getting and setting the stream position. +\******************************************************************************/ + +int jas_stream_isseekable(jas_stream_t *stream) +{ + if (stream->ops_ == &jas_stream_memops) { + return 1; + } else if (stream->ops_ == &jas_stream_fileops) { + if ((*stream->ops_->seek_)(stream->obj_, 0, SEEK_CUR) < 0) { + return 0; + } + return 1; + } else { + return 0; + } +} + +int jas_stream_rewind(jas_stream_t *stream) +{ + return jas_stream_seek(stream, 0, SEEK_SET); +} + +long jas_stream_seek(jas_stream_t *stream, long offset, int origin) +{ + long newpos; + + /* The buffer cannot be in use for both reading and writing. */ + assert(!((stream->bufmode_ & JAS_STREAM_RDBUF) && (stream->bufmode_ & + JAS_STREAM_WRBUF))); + + /* Reset the EOF indicator (since we may not be at the EOF anymore). */ + stream->flags_ &= ~JAS_STREAM_EOF; + + if (stream->bufmode_ & JAS_STREAM_RDBUF) { + if (origin == SEEK_CUR) { + offset -= stream->cnt_; + } + } else if (stream->bufmode_ & JAS_STREAM_WRBUF) { + if (jas_stream_flush(stream)) { + return -1; + } + } + stream->cnt_ = 0; + stream->ptr_ = stream->bufstart_; + stream->bufmode_ &= ~(JAS_STREAM_RDBUF | JAS_STREAM_WRBUF); + + if ((newpos = (*stream->ops_->seek_)(stream->obj_, offset, origin)) + < 0) { + return -1; + } + + return newpos; +} + +long jas_stream_tell(jas_stream_t *stream) +{ + int adjust; + int offset; + + if (stream->bufmode_ & JAS_STREAM_RDBUF) { + adjust = -stream->cnt_; + } else if (stream->bufmode_ & JAS_STREAM_WRBUF) { + adjust = stream->ptr_ - stream->bufstart_; + } else { + adjust = 0; + } + + if ((offset = (*stream->ops_->seek_)(stream->obj_, 0, SEEK_CUR)) < 0) { + return -1; + } + + return offset + adjust; +} + +/******************************************************************************\ +* Buffer initialization code. +\******************************************************************************/ + +void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf, /* IMLIB - removed static, so it can be used in jas_binfile.c */ + int bufsize) +{ + /* If this function is being called, the buffer should not have been + initialized yet. */ + assert(!stream->bufbase_); + + if (bufmode != JAS_STREAM_UNBUF) { + /* The full- or line-buffered mode is being employed. */ + if (!buf) { + /* The caller has not specified a buffer to employ, so allocate + one. */ + if ((stream->bufbase_ = jas_malloc(JAS_STREAM_BUFSIZE + + JAS_STREAM_MAXPUTBACK))) { + stream->bufmode_ |= JAS_STREAM_FREEBUF; + stream->bufsize_ = JAS_STREAM_BUFSIZE; + } else { + /* The buffer allocation has failed. Resort to unbuffered + operation. */ + stream->bufbase_ = stream->tinybuf_; + stream->bufsize_ = 1; + } + } else { + /* The caller has specified a buffer to employ. */ + /* The buffer must be large enough to accommodate maximum + putback. */ + assert(bufsize > JAS_STREAM_MAXPUTBACK); + stream->bufbase_ = JAS_CAST(uchar *, buf); + stream->bufsize_ = bufsize - JAS_STREAM_MAXPUTBACK; + } + } else { + /* The unbuffered mode is being employed. */ + /* A buffer should not have been supplied by the caller. */ + assert(!buf); + /* Use a trivial one-character buffer. */ + stream->bufbase_ = stream->tinybuf_; + stream->bufsize_ = 1; + } + stream->bufstart_ = &stream->bufbase_[JAS_STREAM_MAXPUTBACK]; + stream->ptr_ = stream->bufstart_; + stream->cnt_ = 0; + stream->bufmode_ |= bufmode & JAS_STREAM_BUFMODEMASK; +} + +/******************************************************************************\ +* Buffer filling and flushing code. +\******************************************************************************/ + +int jas_stream_flush(jas_stream_t *stream) +{ + if (stream->bufmode_ & JAS_STREAM_RDBUF) { + return 0; + } + return jas_stream_flushbuf(stream, EOF); +} + +int jas_stream_fillbuf(jas_stream_t *stream, int getflag) +{ + int c; + + /* The stream must not be in an error or EOF state. */ + if ((stream->flags_ & (JAS_STREAM_ERRMASK)) != 0) { + return EOF; + } + + /* The stream must be open for reading. */ + if ((stream->openmode_ & JAS_STREAM_READ) == 0) { + return EOF; + } + + /* Make a half-hearted attempt to confirm that the buffer is not + currently being used for writing. This check is not intended + to be foolproof! */ + assert((stream->bufmode_ & JAS_STREAM_WRBUF) == 0); + + assert(stream->ptr_ - stream->bufstart_ <= stream->bufsize_); + + /* Mark the buffer as being used for reading. */ + stream->bufmode_ |= JAS_STREAM_RDBUF; + + /* Read new data into the buffer. */ + stream->ptr_ = stream->bufstart_; + if ((stream->cnt_ = (*stream->ops_->read_)(stream->obj_, + (char *) stream->bufstart_, stream->bufsize_)) <= 0) { + if (stream->cnt_ < 0) { + stream->flags_ |= JAS_STREAM_ERR; + } else { + stream->flags_ |= JAS_STREAM_EOF; + } + stream->cnt_ = 0; + return EOF; + } + + assert(stream->cnt_ > 0); + /* Get or peek at the first character in the buffer. */ + c = (getflag) ? jas_stream_getc2(stream) : (*stream->ptr_); + + return c; +} + +int jas_stream_flushbuf(jas_stream_t *stream, int c) +{ + int len; + int n; + + /* The stream should not be in an error or EOF state. */ + if ((stream->flags_ & (JAS_STREAM_ERRMASK)) != 0) { + return EOF; + } + + /* The stream must be open for writing. */ + if ((stream->openmode_ & (JAS_STREAM_WRITE | JAS_STREAM_APPEND)) == 0) { + return EOF; + } + + /* The buffer should not currently be in use for reading. */ + assert(!(stream->bufmode_ & JAS_STREAM_RDBUF)); + + /* Note: Do not use the quantity stream->cnt to determine the number + of characters in the buffer! Depending on how this function was + called, the stream->cnt value may be "off-by-one". */ + len = stream->ptr_ - stream->bufstart_; + if (len > 0) { + n = (*stream->ops_->write_)(stream->obj_, (char *) + stream->bufstart_, len); + if (n != len) { + stream->flags_ |= JAS_STREAM_ERR; + return EOF; + } + } + stream->cnt_ = stream->bufsize_; + stream->ptr_ = stream->bufstart_; + + stream->bufmode_ |= JAS_STREAM_WRBUF; + + if (c != EOF) { + assert(stream->cnt_ > 0); + return jas_stream_putc2(stream, c); + } + + return 0; +} + +/******************************************************************************\ +* Miscellaneous code. +\******************************************************************************/ + +static int jas_strtoopenmode(const char *s) +{ + int openmode = 0; + while (*s != '\0') { + switch (*s) { + case 'r': + openmode |= JAS_STREAM_READ; + break; + case 'w': + openmode |= JAS_STREAM_WRITE | JAS_STREAM_CREATE; + break; + case 'b': + openmode |= JAS_STREAM_BINARY; + break; + case 'a': + openmode |= JAS_STREAM_APPEND; + break; + case '+': + openmode |= JAS_STREAM_READ | JAS_STREAM_WRITE; + break; + default: + break; + } + ++s; + } + return openmode; +} + +int jas_stream_copy(jas_stream_t *out, jas_stream_t *in, int n) +{ + int all; + int c; + int m; + + all = (n < 0) ? 1 : 0; + + m = n; + while (all || m > 0) { + if ((c = jas_stream_getc_macro(in)) == EOF) { + /* The next character of input could not be read. */ + /* Return with an error if an I/O error occured + (not including EOF) or if an explicit copy count + was specified. */ + return (!all || jas_stream_error(in)) ? (-1) : 0; + } + if (jas_stream_putc_macro(out, c) == EOF) { + return -1; + } + --m; + } + return 0; +} + +long jas_stream_setrwcount(jas_stream_t *stream, long rwcnt) +{ + int old; + + old = stream->rwcnt_; + stream->rwcnt_ = rwcnt; + return old; +} + +int jas_stream_display(jas_stream_t *stream, FILE *fp, int n) +{ + unsigned char buf[16]; + int i; + int j; + int m; + int c; + int display; + int cnt; + + cnt = n - (n % 16); + display = 1; + + for (i = 0; i < n; i += 16) { + if (n > 16 && i > 0) { + display = (i >= cnt) ? 1 : 0; + } + if (display) { + fprintf(fp, "%08x:", i); + } + m = JAS_MIN(n - i, 16); + for (j = 0; j < m; ++j) { + if ((c = jas_stream_getc(stream)) == EOF) { + abort(); + return -1; + } + buf[j] = c; + } + if (display) { + for (j = 0; j < m; ++j) { + fprintf(fp, " %02x", buf[j]); + } + fputc(' ', fp); + for (; j < 16; ++j) { + fprintf(fp, " "); + } + for (j = 0; j < m; ++j) { + if (isprint(buf[j])) { + fputc(buf[j], fp); + } else { + fputc(' ', fp); + } + } + fprintf(fp, "\n"); + } + + + } + return 0; +} + +long jas_stream_length(jas_stream_t *stream) +{ + long oldpos; + long pos; + if ((oldpos = jas_stream_tell(stream)) < 0) { + return -1; + } + if (jas_stream_seek(stream, 0, SEEK_END) < 0) { + return -1; + } + if ((pos = jas_stream_tell(stream)) < 0) { + return -1; + } + if (jas_stream_seek(stream, oldpos, SEEK_SET) < 0) { + return -1; + } + return pos; +} + +/******************************************************************************\ +* Memory stream object. +\******************************************************************************/ + +static int mem_read(jas_stream_obj_t *obj, char *buf, int cnt) +{ + int n; + jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj; + n = m->len_ - m->pos_; + cnt = JAS_MIN(n, cnt); + memcpy(buf, &m->buf_[m->pos_], cnt); + m->pos_ += cnt; + return cnt; +} + +static int mem_resize(jas_stream_memobj_t *m, int bufsize) +{ + unsigned char *buf; + + assert(m->buf_); + if (!(buf = jas_realloc(m->buf_, bufsize * sizeof(unsigned char)))) { + return -1; + } + m->buf_ = buf; + m->bufsize_ = bufsize; + return 0; +} + +static int mem_write(jas_stream_obj_t *obj, char *buf, int cnt) +{ + int n; + int ret; + jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj; + long newbufsize; + long newpos; + + newpos = m->pos_ + cnt; + if (newpos > m->bufsize_ && m->growable_) { + newbufsize = m->bufsize_; + while (newbufsize < newpos) { + newbufsize <<= 1; + assert(newbufsize >= 0); + } + if (mem_resize(m, newbufsize)) { + return -1; + } + } + if (m->pos_ > m->len_) { + /* The current position is beyond the end of the file, so + pad the file to the current position with zeros. */ + n = JAS_MIN(m->pos_, m->bufsize_) - m->len_; + if (n > 0) { + memset(&m->buf_[m->len_], 0, n); + m->len_ += n; + } + if (m->pos_ != m->len_) { + /* The buffer is not big enough. */ + return 0; + } + } + n = m->bufsize_ - m->pos_; + ret = JAS_MIN(n, cnt); + if (ret > 0) { + memcpy(&m->buf_[m->pos_], buf, ret); + m->pos_ += ret; + } + if (m->pos_ > m->len_) { + m->len_ = m->pos_; + } +assert(ret == cnt); + return ret; +} + +static long mem_seek(jas_stream_obj_t *obj, long offset, int origin) +{ + jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj; + long newpos; + + switch (origin) { + case SEEK_SET: + newpos = offset; + break; + case SEEK_END: + newpos = m->len_ - offset; + break; + case SEEK_CUR: + newpos = m->pos_ + offset; + break; + default: + abort(); + break; + } + if (newpos < 0) { + return -1; + } + m->pos_ = newpos; + + return m->pos_; +} + +static int mem_close(jas_stream_obj_t *obj) +{ + jas_stream_memobj_t *m = (jas_stream_memobj_t *)obj; + if (m->myalloc_ && m->buf_) { + jas_free(m->buf_); + m->buf_ = 0; + } + jas_free(obj); + return 0; +} + +/******************************************************************************\ +* File stream object. +\******************************************************************************/ + +static int file_read(jas_stream_obj_t *obj, char *buf, int cnt) +{ + jas_stream_fileobj_t *fileobj = JAS_CAST(jas_stream_fileobj_t *, obj); + return read(fileobj->fd, buf, cnt); +} + +static int file_write(jas_stream_obj_t *obj, char *buf, int cnt) +{ + jas_stream_fileobj_t *fileobj = JAS_CAST(jas_stream_fileobj_t *, obj); + return write(fileobj->fd, buf, cnt); +} + +static long file_seek(jas_stream_obj_t *obj, long offset, int origin) +{ + jas_stream_fileobj_t *fileobj = JAS_CAST(jas_stream_fileobj_t *, obj); + return lseek(fileobj->fd, offset, origin); +} + +static int file_close(jas_stream_obj_t *obj) +{ + jas_stream_fileobj_t *fileobj = JAS_CAST(jas_stream_fileobj_t *, obj); + int ret; + ret = close(fileobj->fd); + if (fileobj->flags & JAS_STREAM_FILEOBJ_DELONCLOSE) { + unlink(fileobj->pathname); + } + jas_free(fileobj); + return ret; +} + +/******************************************************************************\ +* Stdio file stream object. +\******************************************************************************/ + +static int sfile_read(jas_stream_obj_t *obj, char *buf, int cnt) +{ + FILE *fp; + fp = JAS_CAST(FILE *, obj); + return fread(buf, 1, cnt, fp); +} + +static int sfile_write(jas_stream_obj_t *obj, char *buf, int cnt) +{ + FILE *fp; + fp = JAS_CAST(FILE *, obj); + return fwrite(buf, 1, cnt, fp); +} + +static long sfile_seek(jas_stream_obj_t *obj, long offset, int origin) +{ + FILE *fp; + fp = JAS_CAST(FILE *, obj); + return fseek(fp, offset, origin); +} + +static int sfile_close(jas_stream_obj_t *obj) +{ + FILE *fp; + fp = JAS_CAST(FILE *, obj); + return fclose(fp); +} diff --git a/src/libjasper/base/jas_string.c b/src/libjasper/base/jas_string.c new file mode 100644 index 0000000..787e703 --- /dev/null +++ b/src/libjasper/base/jas_string.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1999-2000 Image Power, Inc. and the University of + * British Columbia. + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * String Library + * + * $Id: jas_string.c,v 1.1 2008/10/17 06:14:59 scuri Exp $ + */ + +/******************************************************************************\ +* Includes +\******************************************************************************/ + +#include <string.h> + +#include "jasper/jas_malloc.h" +#include "jasper/jas_string.h" + +/******************************************************************************\ +* Miscellaneous Functions +\******************************************************************************/ + +/* This function is equivalent to the popular but non-standard (and + not-always-available) strdup function. */ + +char *jas_strdup(const char *s) +{ + int n; + char *p; + n = strlen(s) + 1; + if (!(p = jas_malloc(n * sizeof(char)))) { + return 0; + } + strcpy(p, s); + return p; +} diff --git a/src/libjasper/base/jas_tmr.c b/src/libjasper/base/jas_tmr.c new file mode 100644 index 0000000..942a083 --- /dev/null +++ b/src/libjasper/base/jas_tmr.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2004 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Timing Routines + * + * $Id: jas_tmr.c,v 1.1 2008/10/17 06:14:59 scuri Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +#include "jasper/jas_tmr.h" + +/******************************************************************************\ +* Code. +\******************************************************************************/ + +#if defined(HAVE_GETTIMEOFDAY) + +void jas_tmr_start(jas_tmr_t *tmr) +{ + if (gettimeofday(&tmr->start, 0)) { + abort(); + } +} + +void jas_tmr_stop(jas_tmr_t *tmr) +{ + if (gettimeofday(&tmr->stop, 0)) { + abort(); + } +} + +double jas_tmr_get(jas_tmr_t *tmr) +{ + double t0; + double t1; + t0 = ((double) tmr->start.tv_sec) + ((double) tmr->start.tv_usec) / 1e6; + t1 = ((double) tmr->stop.tv_sec) + ((double) tmr->stop.tv_usec) / 1e6; + return t1 - t0; +} + +#elif defined(HAVE_GETRUSAGE) + +void jas_tmr_start(jas_tmr_t *tmr) +{ + if (getrusage(RUSAGE_SELF, &tmr->start) < 0) { + abort(); + } +} + +void jas_tmr_stop(jas_tmr_t *tmr) +{ + if (getrusage(RUSAGE_SELF, &tmr->stop) < 0) { + abort(); + } +} + +double jas_tmr_get(jas_tmr_t *tmr) +{ + double t; + t = ((tmr->stop.ru_utime.tv_sec * 1e6 + tmr->stop.ru_utime.tv_usec) - + (tmr->start.ru_utime.tv_sec * 1e6 + tmr->start.ru_utime.tv_usec)) / 1e6; + t += ((tmr->stop.ru_stime.tv_sec * 1e6 + tmr->stop.ru_stime.tv_usec) - + (tmr->start.ru_stime.tv_sec * 1e6 + tmr->start.ru_stime.tv_usec)) / 1e6; + return t; +} + +#else + +void jas_tmr_start(jas_tmr_t *tmr) +{ +} + +void jas_tmr_stop(jas_tmr_t *tmr) +{ +} + +double jas_tmr_get(jas_tmr_t *tmr) +{ + return 0.0; +} + +#endif + diff --git a/src/libjasper/base/jas_tvp.c b/src/libjasper/base/jas_tvp.c new file mode 100644 index 0000000..4c23476 --- /dev/null +++ b/src/libjasper/base/jas_tvp.c @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +/* + * Tag-Value Parser Library + * + * $Id: jas_tvp.c,v 1.1 2008/10/17 06:14:59 scuri Exp $ + */ + +/******************************************************************************\ +* Includes. +\******************************************************************************/ + +#include <assert.h> +#include <stdio.h> +#include <ctype.h> +#include <stdlib.h> + +#include "jasper/jas_malloc.h" +#include "jasper/jas_string.h" +#include "jasper/jas_tvp.h" + +/******************************************************************************\ +* Macros. +\******************************************************************************/ + +/* Is the specified character valid for a tag name? */ +#define JAS_TVP_ISTAG(x) \ + (isalpha(x) || (x) == '_' || isdigit(x)) + +/******************************************************************************\ +* Code for creating and destroying a tag-value parser. +\******************************************************************************/ + +jas_tvparser_t *jas_tvparser_create(const char *s) +{ + jas_tvparser_t *tvp; + if (!(tvp = jas_malloc(sizeof(jas_tvparser_t)))) { + return 0; + } + if (!(tvp->buf = jas_strdup(s))) { + jas_tvparser_destroy(tvp); + return 0; + } + tvp->pos = tvp->buf; + tvp->tag = 0; + tvp->val = 0; + return tvp; +} + +void jas_tvparser_destroy(jas_tvparser_t *tvp) +{ + if (tvp->buf) { + jas_free(tvp->buf); + } + jas_free(tvp); +} + +/******************************************************************************\ +* Main parsing code. +\******************************************************************************/ + +/* Get the next tag-value pair. */ +int jas_tvparser_next(jas_tvparser_t *tvp) +{ + char *p; + char *tag; + char *val; + + /* Skip any leading whitespace. */ + p = tvp->pos; + while (*p != '\0' && isspace(*p)) { + ++p; + } + + /* Has the end of the input data been reached? */ + if (*p == '\0') { + /* No more tags are present. */ + tvp->pos = p; + return 1; + } + + /* Does the tag name begin with a valid character? */ + if (!JAS_TVP_ISTAG(*p)) { + return -1; + } + + /* Remember where the tag name begins. */ + tag = p; + + /* Find the end of the tag name. */ + while (*p != '\0' && JAS_TVP_ISTAG(*p)) { + ++p; + } + + /* Has the end of the input data been reached? */ + if (*p == '\0') { + /* The value field is empty. */ + tvp->tag = tag; + tvp->val = ""; + tvp->pos = p; + return 0; + } + + /* Is a value field not present? */ + if (*p != '=') { + if (*p != '\0' && !isspace(*p)) { + return -1; + } + *p++ = '\0'; + tvp->tag = tag; + tvp->val = ""; + tvp->pos = p; + return 0; + } + + *p++ = '\0'; + + val = p; + while (*p != '\0' && !isspace(*p)) { + ++p; + } + + if (*p != '\0') { + *p++ = '\0'; + } + + tvp->pos = p; + tvp->tag = tag; + tvp->val = val; + + return 0; +} + +/******************************************************************************\ +* Code for querying the current tag/value. +\******************************************************************************/ + +/* Get the current tag. */ +char *jas_tvparser_gettag(jas_tvparser_t *tvp) +{ + return tvp->tag; +} + +/* Get the current value. */ +char *jas_tvparser_getval(jas_tvparser_t *tvp) +{ + return tvp->val; +} + +/******************************************************************************\ +* Miscellaneous code. +\******************************************************************************/ + +/* Lookup a tag by name. */ +jas_taginfo_t *jas_taginfos_lookup(jas_taginfo_t *taginfos, const char *name) +{ + jas_taginfo_t *taginfo; + taginfo = taginfos; + while (taginfo->id >= 0) { + if (!strcmp(taginfo->name, name)) { + return taginfo; + } + ++taginfo; + } + return 0; +} + +/* This function is simply for convenience. */ +/* One can avoid testing for the special case of a null pointer, by + using this function. This function never returns a null pointer. */ +jas_taginfo_t *jas_taginfo_nonull(jas_taginfo_t *taginfo) +{ + static jas_taginfo_t invalidtaginfo = { + -1, 0 + }; + + return taginfo ? taginfo : &invalidtaginfo; +} diff --git a/src/libjasper/base/jas_version.c b/src/libjasper/base/jas_version.c new file mode 100644 index 0000000..f56f253 --- /dev/null +++ b/src/libjasper/base/jas_version.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2001-2002 Michael David Adams. + * All rights reserved. + */ + +/* __START_OF_JASPER_LICENSE__ + * + * JasPer License Version 2.0 + * + * Copyright (c) 2001-2006 Michael David Adams + * Copyright (c) 1999-2000 Image Power, Inc. + * Copyright (c) 1999-2000 The University of British Columbia + * + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person (the + * "User") obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * 1. The above copyright notices and this permission notice (which + * includes the disclaimer below) shall be included in all copies or + * substantial portions of the Software. + * + * 2. The name of a copyright holder shall not be used to endorse or + * promote products derived from the Software without specific prior + * written permission. + * + * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS + * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER + * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS + * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL + * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE + * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE + * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY. + * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS + * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL + * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS + * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE + * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE + * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL + * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES, + * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL + * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH + * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH, + * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH + * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY + * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. + * + * __END_OF_JASPER_LICENSE__ + */ + +#include "jasper/jas_version.h" + +const char *jas_getversion() +{ + return JAS_VERSION; +} |