static jpc_tsfbnode_t *jpc_tsfbnode_create() { jpc_tsfbnode_t *node; if (!(node = jas_malloc(sizeof(jpc_tsfbnode_t)))) { return 0; } node->numhchans = 0; node->numvchans = 0; node->numchildren = 0; node->maxchildren = 0; node->hqmfb = 0; node->vqmfb = 0; node->parent = 0; return node; }
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; }
/* Create a marker segment of the specified type. */ jpc_ms_t *jpc_ms_create(int type) { jpc_ms_t *ms; jpc_mstabent_t *mstabent; if (!(ms = jas_malloc(sizeof(jpc_ms_t)))) { return 0; } ms->id = type; ms->len = 0; mstabent = jpc_mstab_lookup(ms->id); ms->ops = &mstabent->ops; memset(&ms->parms, 0, sizeof(jpc_msparms_t)); return ms; }
static jp2_dec_t* jp2_dec_create(void) { jp2_dec_t* dec; if (!(dec = jas_malloc(sizeof(jp2_dec_t)))) { return 0; } dec->ihdr = 0; dec->bpcc = 0; dec->cdef = 0; dec->pclr = 0; dec->image = 0; dec->chantocmptlut = 0; dec->cmap = 0; dec->colr = 0; return dec; }
int jpc_atoaf(char *s, int *numvalues, double **values) { static char delim[] = ", \t\n"; char buf[4096]; int n; double *vs; char *cp; strncpy(buf, s, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; n = 0; if ((cp = strtok(buf, delim))) { ++n; while ((cp = strtok(0, delim))) { if (*cp != '\0') { // SGI fix, was cp != '\0' ++n; } } } if (n) { if (!(vs = jas_malloc(n * sizeof(double)))) { return -1; } strncpy(buf, s, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; n = 0; if ((cp = strtok(buf, delim))) { vs[n] = atof(cp); ++n; while ((cp = strtok(0, delim))) { if (*cp != '\0') { // SGI fix, was cp != '\0' vs[n] = atof(cp); ++n; } } } } else { vs = 0; } *numvalues = n; *values = vs; return 0; }
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 int jpc_siz_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in) { jpc_siz_t *siz = &ms->parms.siz; unsigned int i; uint_fast8_t tmp; /* Eliminate compiler warning about unused variables. */ cstate = 0; if (jpc_getuint16(in, &siz->caps) || jpc_getuint32(in, &siz->width) || jpc_getuint32(in, &siz->height) || jpc_getuint32(in, &siz->xoff) || jpc_getuint32(in, &siz->yoff) || jpc_getuint32(in, &siz->tilewidth) || jpc_getuint32(in, &siz->tileheight) || jpc_getuint32(in, &siz->tilexoff) || jpc_getuint32(in, &siz->tileyoff) || jpc_getuint16(in, &siz->numcomps)) { return -1; } if (!siz->width || !siz->height || !siz->tilewidth || !siz->tileheight || !siz->numcomps) { return -1; } if (!(siz->comps = jas_malloc(siz->numcomps * sizeof(jpc_sizcomp_t)))) { return -1; } for (i = 0; i < siz->numcomps; ++i) { if (jpc_getuint8(in, &tmp) || jpc_getuint8(in, &siz->comps[i].hsamp) || jpc_getuint8(in, &siz->comps[i].vsamp)) { jas_free(siz->comps); return -1; } siz->comps[i].sgnd = (tmp >> 7) & 1; siz->comps[i].prec = (tmp & 0x7f) + 1; } if (jas_stream_eof(in)) { jas_free(siz->comps); return -1; } return 0; }
static jas_stream_t *jas_stream_create() { 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_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; }
/* Create a MQ decoder. */ jpc_mqdec_t *jpc_mqdec_create(int maxctxs, jas_stream_t *in) { jpc_mqdec_t *mqdec; /* There must be at least one context. */ assert(maxctxs > 0); /* Allocate memory for the MQ decoder. */ if (!(mqdec = jas_malloc(sizeof(jpc_mqdec_t)))) { goto error; } mqdec->in = in; mqdec->maxctxs = maxctxs; /* Allocate memory for the per-context state information. */ if (!(mqdec->ctxs = jas_alloc2(mqdec->maxctxs, sizeof(jpc_mqstate_t *)))) { goto error; } /* Set the current context to the first context. */ mqdec->curctx = mqdec->ctxs; /* If an input stream has been associated with the MQ decoder, initialize the decoder state from the stream. */ if (mqdec->in) { jpc_mqdec_init(mqdec); } /* Initialize the per-context state information. */ jpc_mqdec_setctxs(mqdec, 0, 0); return mqdec; error: /* Oops... Something has gone wrong. */ if (mqdec) { jpc_mqdec_destroy(mqdec); } return 0; }
static jas_stream_t *jas_stream_create() { 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->buftell_ = 0; /* bufstart_ 'tell' */ /* position in the stream is buftell_ + (ptr_ - bufstart_) */ stream->bufsize_ = 0; stream->ptr_ = 0; stream->cnt_ = 0; stream->ops_ = 0; stream->obj_ = 0; stream->rwcnt_ = 0; stream->rwlimit_ = -1; return stream; }
/* Encode a single code block. */ int jpc_enc_enccblk(jpc_enc_t *enc, jas_stream_t *out, jpc_enc_tcmpt_t *tcmpt, jpc_enc_band_t *band, jpc_enc_cblk_t *cblk) { jpc_enc_pass_t *pass; jpc_enc_pass_t *endpasses; int bitpos; int n; int adjust; int ret; int passtype; int t; jpc_bitstream_t *bout; jpc_enc_pass_t *termpass; jpc_enc_rlvl_t *rlvl; int vcausal; int segsym; int termmode; int c; bout = 0; rlvl = band->rlvl; cblk->stream = jas_stream_memopen(0, 0); assert(cblk->stream); cblk->mqenc = jpc_mqenc_create(JPC_NUMCTXS, cblk->stream); assert(cblk->mqenc); jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs); cblk->numpasses = (cblk->numbps > 0) ? (3 * cblk->numbps - 2) : 0; if (cblk->numpasses > 0) { cblk->passes = jas_malloc(cblk->numpasses * sizeof(jpc_enc_pass_t)); assert(cblk->passes); } else { cblk->passes = 0; } endpasses = &cblk->passes[cblk->numpasses]; for (pass = cblk->passes; pass != endpasses; ++pass) { pass->start = 0; pass->end = 0; pass->term = JPC_ISTERMINATED(pass - cblk->passes, 0, cblk->numpasses, (tcmpt->cblksty & JPC_COX_TERMALL) != 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0); pass->type = JPC_SEGTYPE(pass - cblk->passes, 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0); pass->lyrno = -1; if (pass == endpasses - 1) { assert(pass->term == 1); pass->term = 1; } } cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) + 2, jas_matrix_numcols(cblk->data) + 2); assert(cblk->flags); bitpos = cblk->numbps - 1; pass = cblk->passes; n = cblk->numpasses; while (--n >= 0) { if (pass->type == JPC_SEG_MQ) { /* NOP */ } else { assert(pass->type == JPC_SEG_RAW); if (!bout) { bout = jpc_bitstream_sopen(cblk->stream, "w"); assert(bout); } } #if 1 passtype = (pass - cblk->passes + 2) % 3; #else passtype = JPC_PASSTYPE(pass - cblk->passes + 2); #endif pass->start = jas_stream_tell(cblk->stream); #if 0 assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream)); #endif assert(bitpos >= 0); vcausal = (tcmpt->cblksty & JPC_COX_VSC) != 0; segsym = (tcmpt->cblksty & JPC_COX_SEGSYM) != 0; if (pass->term) { termmode = ((tcmpt->cblksty & JPC_COX_PTERM) ? JPC_MQENC_PTERM : JPC_MQENC_DEFTERM) + 1; } else { termmode = 0; } switch (passtype) { case JPC_SIGPASS: ret = (pass->type == JPC_SEG_MQ) ? jpc_encsigpass(cblk->mqenc, bitpos, band->orient, vcausal, cblk->flags, cblk->data, termmode, &pass->nmsedec) : jpc_encrawsigpass(bout, bitpos, vcausal, cblk->flags, cblk->data, termmode, &pass->nmsedec); break; case JPC_REFPASS: ret = (pass->type == JPC_SEG_MQ) ? jpc_encrefpass(cblk->mqenc, bitpos, vcausal, cblk->flags, cblk->data, termmode, &pass->nmsedec) : jpc_encrawrefpass(bout, bitpos, vcausal, cblk->flags, cblk->data, termmode, &pass->nmsedec); break; case JPC_CLNPASS: assert(pass->type == JPC_SEG_MQ); ret = jpc_encclnpass(cblk->mqenc, bitpos, band->orient, vcausal, segsym, cblk->flags, cblk->data, termmode, &pass->nmsedec); break; default: assert(0); break; } if (pass->type == JPC_SEG_MQ) { if (pass->term) { jpc_mqenc_init(cblk->mqenc); } jpc_mqenc_getstate(cblk->mqenc, &pass->mqencstate); pass->end = jas_stream_tell(cblk->stream); if (tcmpt->cblksty & JPC_COX_RESET) { jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs); } } else { if (pass->term) { if (jpc_bitstream_pending(bout)) { jpc_bitstream_outalign(bout, 0x2a); } jpc_bitstream_close(bout); bout = 0; pass->end = jas_stream_tell(cblk->stream); } else { pass->end = jas_stream_tell(cblk->stream) + jpc_bitstream_pending(bout); /* NOTE - This will not work. need to adjust by # of pending output bytes */ } } #if 0 /* XXX - This assertion fails sometimes when various coding modes are used. This seems to be harmless, but why does it happen at all? */ assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream)); #endif pass->wmsedec = jpc_fixtodbl(band->rlvl->tcmpt->synweight) * jpc_fixtodbl(band->rlvl->tcmpt->synweight) * jpc_fixtodbl(band->synweight) * jpc_fixtodbl(band->synweight) * jpc_fixtodbl(band->absstepsize) * jpc_fixtodbl(band->absstepsize) * ((double) (1 << bitpos)) * ((double)(1 << bitpos)) * jpc_fixtodbl(pass->nmsedec); pass->cumwmsedec = pass->wmsedec; if (pass != cblk->passes) { pass->cumwmsedec += pass[-1].cumwmsedec; } if (passtype == JPC_CLNPASS) { --bitpos; } ++pass; } #if 0 dump_passes(cblk->passes, cblk->numpasses, cblk); #endif n = 0; endpasses = &cblk->passes[cblk->numpasses]; for (pass = cblk->passes; pass != endpasses; ++pass) { if (pass->start < n) { pass->start = n; } if (pass->end < n) { pass->end = n; } if (!pass->term) { termpass = pass; while (termpass - pass < cblk->numpasses && !termpass->term) { ++termpass; } if (pass->type == JPC_SEG_MQ) { t = (pass->mqencstate.lastbyte == 0xff) ? 1 : 0; if (pass->mqencstate.ctreg >= 5) { adjust = 4 + t; } else { adjust = 5 + t; } pass->end += adjust; } if (pass->end > termpass->end) { pass->end = termpass->end; } if ((c = getthebyte(cblk->stream, pass->end - 1)) == EOF) { abort(); } if (c == 0xff) { ++pass->end; } n = JAS_MAX(n, pass->end); } else { n = JAS_MAX(n, pass->end); } } #if 0 dump_passes(cblk->passes, cblk->numpasses, cblk); #endif if (bout) { jpc_bitstream_close(bout); } return 0; }
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); //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; } */ // JMW quick hack! if ((obj->zfile = zzip_fopen(filename, "rb")) == NULL) { jas_stream_close(stream); return 0; } /* By default, use full buffering for this type of stream. */ jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); return stream; }
jpc_pi_t *jpc_enc_pi_create(jpc_enc_cp_t *cp, jpc_enc_tile_t *tile) { jpc_pi_t *pi; int compno; jpc_picomp_t *picomp; jpc_pirlvl_t *pirlvl; jpc_enc_tcmpt_t *tcomp; int rlvlno; jpc_enc_rlvl_t *rlvl; int prcno; int *prclyrno; if (!(pi = jpc_pi_create0())) { return 0; } pi->pktno = -1; pi->numcomps = cp->numcmpts; if (!(pi->picomps = jas_malloc(pi->numcomps * sizeof(jpc_picomp_t)))) { jpc_pi_destroy(pi); return 0; } for (compno = 0, picomp = pi->picomps; compno < pi->numcomps; ++compno, ++picomp) { picomp->pirlvls = 0; } for (compno = 0, tcomp = tile->tcmpts, picomp = pi->picomps; compno < pi->numcomps; ++compno, ++tcomp, ++picomp) { picomp->numrlvls = tcomp->numrlvls; if (!(picomp->pirlvls = jas_malloc(picomp->numrlvls * sizeof(jpc_pirlvl_t)))) { jpc_pi_destroy(pi); return 0; } for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno < picomp->numrlvls; ++rlvlno, ++pirlvl) { pirlvl->prclyrnos = 0; } for (rlvlno = 0, pirlvl = picomp->pirlvls, rlvl = tcomp->rlvls; rlvlno < picomp->numrlvls; ++rlvlno, ++pirlvl, ++rlvl) { /* XXX sizeof(long) should be sizeof different type */ pirlvl->numprcs = rlvl->numprcs; if (rlvl->numprcs) { if (!(pirlvl->prclyrnos = jas_malloc(pirlvl->numprcs * sizeof(long)))) { jpc_pi_destroy(pi); return 0; } } else { pirlvl->prclyrnos = 0; } } } pi->maxrlvls = 0; for (compno = 0, tcomp = tile->tcmpts, picomp = pi->picomps; compno < pi->numcomps; ++compno, ++tcomp, ++picomp) { picomp->hsamp = cp->ccps[compno].sampgrdstepx; picomp->vsamp = cp->ccps[compno].sampgrdstepy; for (rlvlno = 0, pirlvl = picomp->pirlvls, rlvl = tcomp->rlvls; rlvlno < picomp->numrlvls; ++rlvlno, ++pirlvl, ++rlvl) { pirlvl->prcwidthexpn = rlvl->prcwidthexpn; pirlvl->prcheightexpn = rlvl->prcheightexpn; for (prcno = 0, prclyrno = pirlvl->prclyrnos; prcno < pirlvl->numprcs; ++prcno, ++prclyrno) { *prclyrno = 0; } pirlvl->numhprcs = rlvl->numhprcs; } if (pi->maxrlvls < tcomp->numrlvls) { pi->maxrlvls = tcomp->numrlvls; } } pi->numlyrs = tile->numlyrs; pi->xstart = tile->tlx; pi->ystart = tile->tly; pi->xend = tile->brx; pi->yend = tile->bry; pi->picomp = 0; pi->pirlvl = 0; pi->x = 0; pi->y = 0; pi->compno = 0; pi->rlvlno = 0; pi->prcno = 0; pi->lyrno = 0; pi->xstep = 0; pi->ystep = 0; pi->pchgno = -1; pi->defaultpchg.prgord = tile->prg; pi->defaultpchg.compnostart = 0; pi->defaultpchg.compnoend = pi->numcomps; pi->defaultpchg.rlvlnostart = 0; pi->defaultpchg.rlvlnoend = pi->maxrlvls; pi->defaultpchg.lyrnoend = pi->numlyrs; pi->pchg = 0; pi->valid = 0; return pi; }
jpc_tagtree_t *jpc_tagtree_create(int numleafsh, int numleafsv) { int nplh[JPC_TAGTREE_MAXDEPTH]; int nplv[JPC_TAGTREE_MAXDEPTH]; jpc_tagtreenode_t *node; jpc_tagtreenode_t *parentnode; jpc_tagtreenode_t *parentnode0; jpc_tagtree_t *tree; int i; int j; int k; int numlvls; int n; assert(numleafsh > 0 && numleafsv > 0); if (!(tree = jpc_tagtree_alloc())) { return 0; } tree->numleafsh_ = numleafsh; tree->numleafsv_ = numleafsv; numlvls = 0; nplh[0] = numleafsh; nplv[0] = numleafsv; do { n = nplh[numlvls] * nplv[numlvls]; nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2; nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2; tree->numnodes_ += n; ++numlvls; } while (n > 1); if (!(tree->nodes_ = jas_malloc(tree->numnodes_ * sizeof(jpc_tagtreenode_t)))) { return 0; } /* Initialize the parent links for all nodes in the tree. */ node = tree->nodes_; parentnode = &tree->nodes_[tree->numleafsh_ * tree->numleafsv_]; parentnode0 = parentnode; for (i = 0; i < numlvls - 1; ++i) { for (j = 0; j < nplv[i]; ++j) { k = nplh[i]; while (--k >= 0) { node->parent_ = parentnode; ++node; if (--k >= 0) { node->parent_ = parentnode; ++node; } ++parentnode; } if ((j & 1) || j == nplv[i] - 1) { parentnode0 = parentnode; } else { parentnode = parentnode0; parentnode0 += nplh[i]; } } } node->parent_ = 0; /* Initialize the data values to something sane. */ jpc_tagtree_reset(tree); return tree; }
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; }
static void jpc_qmfb1d_split(jpc_fix_t *startptr, int startind, int endind, register int step, jpc_fix_t *lstartptr, int lstartind, int lendind, jpc_fix_t *hstartptr, int hstartind, int hendind) { int bufsize = JPC_CEILDIVPOW2(endind - startind, 2); #if !defined(HAVE_VLA) #define QMFB_SPLITBUFSIZE 4096 jpc_fix_t splitbuf[QMFB_SPLITBUFSIZE]; #else jpc_fix_t splitbuf[bufsize]; #endif jpc_fix_t *buf = splitbuf; int llen; int hlen; int twostep; jpc_fix_t *tmpptr; register jpc_fix_t *ptr; register jpc_fix_t *hptr; register jpc_fix_t *lptr; register int n; int state; twostep = step << 1; llen = lendind - lstartind; hlen = hendind - hstartind; #if !defined(HAVE_VLA) /* Get a buffer. */ if (bufsize > QMFB_SPLITBUFSIZE) { if (!(buf = jas_malloc(bufsize * sizeof(jpc_fix_t)))) { /* We have no choice but to commit suicide in this case. */ abort(); } } #endif if (hstartind < lstartind) { /* The first sample in the input signal is to appear in the highpass subband signal. */ /* Copy the appropriate samples into the lowpass subband signal, saving any samples destined for the highpass subband signal as they are overwritten. */ tmpptr = buf; ptr = &startptr[step]; lptr = lstartptr; n = llen; state = 1; while (n-- > 0) { if (state) { *tmpptr = *lptr; ++tmpptr; } *lptr = *ptr; ptr += twostep; lptr += step; state ^= 1; } /* Copy the appropriate samples into the highpass subband signal. */ /* Handle the nonoverwritten samples. */ hptr = &hstartptr[(hlen - 1) * step]; ptr = &startptr[(((llen + hlen - 1) >> 1) << 1) * step]; n = hlen - (tmpptr - buf); while (n-- > 0) { *hptr = *ptr; hptr -= step; ptr -= twostep; } /* Handle the overwritten samples. */ n = tmpptr - buf; while (n-- > 0) { --tmpptr; *hptr = *tmpptr; hptr -= step; } } else {
// Modified version of jas_stream_fopen and jas_stream_memopen from jas_stream.c of JasPer // so that we can use our own file routines. jas_stream_t *iJp2ReadStream() { 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_BINARY; /* We use buffering whether it is from memory or a file. */ jas_stream_initbuf(stream, JAS_STREAM_FULLBUF, 0, 0); /* Select the operations for a memory stream. */ stream->ops_ = &jas_stream_devilops; /* 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; // Shouldn't need any of this. ///* 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_image_t *jp2_decode(jas_stream_t *in, char *optstr) { jp2_box_t *box; int found; jas_image_t *image; jp2_dec_t *dec; bool samedtype; int dtype; unsigned int i; jp2_cmap_t *cmapd; jp2_pclr_t *pclrd; jp2_cdef_t *cdefd; unsigned int channo; int newcmptno; int_fast32_t *lutents; #if 0 jp2_cdefchan_t *cdefent; int cmptno; #endif jp2_cmapent_t *cmapent; jas_icchdr_t icchdr; jas_iccprof_t *iccprof; dec = 0; box = 0; image = 0; if (!(dec = jp2_dec_create())) { goto error; } /* Get the first box. This should be a JP box. */ if (!(box = jp2_box_get(in))) { jas_eprintf("error: cannot get box\n"); goto error; } if (box->type != JP2_BOX_JP) { jas_eprintf("error: expecting signature box\n"); goto error; } if (box->data.jp.magic != JP2_JP_MAGIC) { jas_eprintf("incorrect magic number\n"); goto error; } jp2_box_destroy(box); box = 0; /* Get the second box. This should be a FTYP box. */ if (!(box = jp2_box_get(in))) { goto error; } if (box->type != JP2_BOX_FTYP) { jas_eprintf("expecting file type box\n"); goto error; } jp2_box_destroy(box); box = 0; /* Get more boxes... */ found = 0; while ((box = jp2_box_get(in))) { if (jas_getdbglevel() >= 1) { jas_eprintf("box type %s\n", box->info->name); } switch (box->type) { case JP2_BOX_JP2C: found = 1; break; case JP2_BOX_IHDR: if (!dec->ihdr) { dec->ihdr = box; box = 0; } break; case JP2_BOX_BPCC: if (!dec->bpcc) { dec->bpcc = box; box = 0; } break; case JP2_BOX_CDEF: if (!dec->cdef) { dec->cdef = box; box = 0; } break; case JP2_BOX_PCLR: if (!dec->pclr) { dec->pclr = box; box = 0; } break; case JP2_BOX_CMAP: if (!dec->cmap) { dec->cmap = box; box = 0; } break; case JP2_BOX_COLR: if (!dec->colr) { dec->colr = box; box = 0; } break; } if (box) { jp2_box_destroy(box); box = 0; } if (found) { break; } } if (!found) { jas_eprintf("error: no code stream found\n"); goto error; } if (!(dec->image = jpc_decode(in, optstr))) { jas_eprintf("error: cannot decode code stream\n"); goto error; } /* An IHDR box must be present. */ if (!dec->ihdr) { jas_eprintf("error: missing IHDR box\n"); goto error; } /* Does the number of components indicated in the IHDR box match the value specified in the code stream? */ if (dec->ihdr->data.ihdr.numcmpts != JAS_CAST(uint, jas_image_numcmpts(dec->image))) { jas_eprintf("warning: number of components mismatch\n"); } /* At least one component must be present. */ if (!jas_image_numcmpts(dec->image)) { jas_eprintf("error: no components\n"); goto error; } /* Determine if all components have the same data type. */ samedtype = true; dtype = jas_image_cmptdtype(dec->image, 0); for (i = 1; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) { if (jas_image_cmptdtype(dec->image, i) != dtype) { samedtype = false; break; } } /* Is the component data type indicated in the IHDR box consistent with the data in the code stream? */ if ((samedtype && dec->ihdr->data.ihdr.bpc != JP2_DTYPETOBPC(dtype)) || (!samedtype && dec->ihdr->data.ihdr.bpc != JP2_IHDR_BPCNULL)) { jas_eprintf("warning: component data type mismatch\n"); } /* Is the compression type supported? */ if (dec->ihdr->data.ihdr.comptype != JP2_IHDR_COMPTYPE) { jas_eprintf("error: unsupported compression type\n"); goto error; } if (dec->bpcc) { /* Is the number of components indicated in the BPCC box consistent with the code stream data? */ if (dec->bpcc->data.bpcc.numcmpts != JAS_CAST(uint, jas_image_numcmpts( dec->image))) { jas_eprintf("warning: number of components mismatch\n"); } /* Is the component data type information indicated in the BPCC box consistent with the code stream data? */ if (!samedtype) { for (i = 0; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) { if (jas_image_cmptdtype(dec->image, i) != JP2_BPCTODTYPE(dec->bpcc->data.bpcc.bpcs[i])) { jas_eprintf("warning: component data type mismatch\n"); } } } else { jas_eprintf("warning: superfluous BPCC box\n"); } } /* A COLR box must be present. */ if (!dec->colr) { jas_eprintf("error: no COLR box\n"); goto error; } switch (dec->colr->data.colr.method) { case JP2_COLR_ENUM: jas_image_setclrspc(dec->image, jp2_getcs(&dec->colr->data.colr)); break; case JP2_COLR_ICC: iccprof = jas_iccprof_createfrombuf(dec->colr->data.colr.iccp, dec->colr->data.colr.iccplen); assert(iccprof); jas_iccprof_gethdr(iccprof, &icchdr); jas_eprintf("ICC Profile CS %08x\n", icchdr.colorspc); jas_image_setclrspc(dec->image, fromiccpcs(icchdr.colorspc)); dec->image->cmprof_ = jas_cmprof_createfromiccprof(iccprof); assert(dec->image->cmprof_); jas_iccprof_destroy(iccprof); break; } /* If a CMAP box is present, a PCLR box must also be present. */ if (dec->cmap && !dec->pclr) { jas_eprintf("warning: missing PCLR box or superfluous CMAP box\n"); jp2_box_destroy(dec->cmap); dec->cmap = 0; } /* If a CMAP box is not present, a PCLR box must not be present. */ if (!dec->cmap && dec->pclr) { jas_eprintf("warning: missing CMAP box or superfluous PCLR box\n"); jp2_box_destroy(dec->pclr); dec->pclr = 0; } /* Determine the number of channels (which is essentially the number of components after any palette mappings have been applied). */ dec->numchans = dec->cmap ? dec->cmap->data.cmap.numchans : JAS_CAST(uint, jas_image_numcmpts(dec->image)); /* Perform a basic sanity check on the CMAP box if present. */ if (dec->cmap) { for (i = 0; i < dec->numchans; ++i) { /* Is the component number reasonable? */ if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(uint, jas_image_numcmpts(dec->image))) { jas_eprintf("error: invalid component number in CMAP box\n"); goto error; } /* Is the LUT index reasonable? */ if (dec->cmap->data.cmap.ents[i].pcol >= dec->pclr->data.pclr.numchans) { jas_eprintf("error: invalid CMAP LUT index\n"); goto error; } } } /* Allocate space for the channel-number to component-number LUT. */ if (!(dec->chantocmptlut = jas_malloc(dec->numchans * sizeof(uint_fast16_t)))) { jas_eprintf("error: no memory\n"); goto error; } if (!dec->cmap) { for (i = 0; i < dec->numchans; ++i) { dec->chantocmptlut[i] = i; } } else { cmapd = &dec->cmap->data.cmap; pclrd = &dec->pclr->data.pclr; cdefd = &dec->cdef->data.cdef; for (channo = 0; channo < cmapd->numchans; ++channo) { cmapent = &cmapd->ents[channo]; if (cmapent->map == JP2_CMAP_DIRECT) { dec->chantocmptlut[channo] = channo; } else if (cmapent->map == JP2_CMAP_PALETTE) { lutents = jas_malloc(pclrd->numlutents * sizeof(int_fast32_t)); for (i = 0; i < pclrd->numlutents; ++i) { lutents[i] = pclrd->lutdata[cmapent->pcol + i * pclrd->numchans]; } newcmptno = jas_image_numcmpts(dec->image); jas_image_depalettize(dec->image, cmapent->cmptno, pclrd->numlutents, lutents, JP2_BPCTODTYPE(pclrd->bpc[cmapent->pcol]), newcmptno); dec->chantocmptlut[channo] = newcmptno; jas_free(lutents); #if 0 if (dec->cdef) { cdefent = jp2_cdef_lookup(cdefd, channo); if (!cdefent) { abort(); } jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), cdefent->type, cdefent->assoc)); } else { jas_image_setcmpttype(dec->image, newcmptno, jp2_getct(jas_image_clrspc(dec->image), 0, channo + 1)); } #endif } } } /* Mark all components as being of unknown type. */ for (i = 0; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) { jas_image_setcmpttype(dec->image, i, JAS_IMAGE_CT_UNKNOWN); } /* Determine the type of each component. */ if (dec->cdef) { for (i = 0; i < dec->numchans; ++i) { jas_image_setcmpttype(dec->image, dec->chantocmptlut[dec->cdef->data.cdef.ents[i].channo], jp2_getct(jas_image_clrspc(dec->image), dec->cdef->data.cdef.ents[i].type, dec->cdef->data.cdef.ents[i].assoc)); } } else { for (i = 0; i < dec->numchans; ++i) { jas_image_setcmpttype(dec->image, dec->chantocmptlut[i], jp2_getct(jas_image_clrspc(dec->image), 0, i + 1)); } } /* Delete any components that are not of interest. */ for (i = jas_image_numcmpts(dec->image); i > 0; --i) { if (jas_image_cmpttype(dec->image, i - 1) == JAS_IMAGE_CT_UNKNOWN) { jas_image_delcmpt(dec->image, i - 1); } } /* Ensure that some components survived. */ if (!jas_image_numcmpts(dec->image)) { jas_eprintf("error: no components\n"); goto error; } #if 0 jas_eprintf("no of components is %d\n", jas_image_numcmpts(dec->image)); #endif /* Prevent the image from being destroyed later. */ image = dec->image; dec->image = 0; jp2_dec_destroy(dec); return image; error: if (box) { jp2_box_destroy(box); } if (dec) { jp2_dec_destroy(dec); } return 0; }
int jp2_write_header(jas_image_t *image, jas_stream_t *out) { jp2_box_t *box; jp2_ftyp_t *ftyp; jp2_ihdr_t *ihdr; jas_stream_t *tmpstream; int allcmptssame; jp2_bpcc_t *bpcc; long len; uint_fast16_t cmptno; jp2_colr_t *colr; jp2_cdefchan_t *cdefchanent; jp2_cdef_t *cdef; int i; uint_fast32_t typeasoc; jas_iccprof_t *iccprof; jas_stream_t *iccstream; int pos; int needcdef; int prec; int sgnd; box = 0; tmpstream = 0; allcmptssame = 1; sgnd = jas_image_cmptsgnd(image, 0); prec = jas_image_cmptprec(image, 0); for (i = 1; i < jas_image_numcmpts(image); ++i) { if (jas_image_cmptsgnd(image, i) != sgnd || jas_image_cmptprec(image, i) != prec) { allcmptssame = 0; break; } } /* Output the signature box. */ if (!(box = jp2_box_create(JP2_BOX_JP))) { goto error; } box->data.jp.magic = JP2_JP_MAGIC; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; /* Output the file type box. */ if (!(box = jp2_box_create(JP2_BOX_FTYP))) { goto error; } ftyp = &box->data.ftyp; ftyp->majver = JP2_FTYP_MAJVER; ftyp->minver = JP2_FTYP_MINVER; ftyp->numcompatcodes = 1; ftyp->compatcodes[0] = JP2_FTYP_COMPATCODE; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; /* * Generate the data portion of the JP2 header box. * We cannot simply output the header for this box * since we do not yet know the correct value for the length * field. */ if (!(tmpstream = jas_stream_memopen(0, 0))) { goto error; } /* Generate image header box. */ if (!(box = jp2_box_create(JP2_BOX_IHDR))) { goto error; } ihdr = &box->data.ihdr; ihdr->width = jas_image_width(image); ihdr->height = jas_image_height(image); ihdr->numcmpts = jas_image_numcmpts(image); ihdr->bpc = allcmptssame ? JP2_SPTOBPC(jas_image_cmptsgnd(image, 0), jas_image_cmptprec(image, 0)) : JP2_IHDR_BPCNULL; ihdr->comptype = JP2_IHDR_COMPTYPE; ihdr->csunk = 0; ihdr->ipr = 0; if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; /* Generate bits per component box. */ if (!allcmptssame) { if (!(box = jp2_box_create(JP2_BOX_BPCC))) { goto error; } bpcc = &box->data.bpcc; bpcc->numcmpts = jas_image_numcmpts(image); if (!(bpcc->bpcs = jas_malloc(bpcc->numcmpts * sizeof(uint_fast8_t)))) { goto error; } for (cmptno = 0; cmptno < bpcc->numcmpts; ++cmptno) { bpcc->bpcs[cmptno] = JP2_SPTOBPC(jas_image_cmptsgnd(image, cmptno), jas_image_cmptprec(image, cmptno)); } if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; } /* Generate color specification box. */ if (!(box = jp2_box_create(JP2_BOX_COLR))) { goto error; } colr = &box->data.colr; switch (jas_image_clrspc(image)) { case JAS_CLRSPC_SRGB: case JAS_CLRSPC_SYCBCR: case JAS_CLRSPC_SGRAY: colr->method = JP2_COLR_ENUM; colr->csid = clrspctojp2(jas_image_clrspc(image)); colr->pri = JP2_COLR_PRI; colr->approx = 0; break; default: colr->method = JP2_COLR_ICC; colr->pri = JP2_COLR_PRI; colr->approx = 0; iccprof = jas_iccprof_createfromcmprof(jas_image_cmprof(image)); assert(iccprof); iccstream = jas_stream_memopen(0, 0); assert(iccstream); if (jas_iccprof_save(iccprof, iccstream)) abort(); if ((pos = jas_stream_tell(iccstream)) < 0) abort(); colr->iccplen = pos; colr->iccp = jas_malloc(pos); assert(colr->iccp); jas_stream_rewind(iccstream); if (jas_stream_read(iccstream, colr->iccp, colr->iccplen) != colr->iccplen) abort(); jas_stream_close(iccstream); jas_iccprof_destroy(iccprof); break; } if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; needcdef = 1; switch (jas_clrspc_fam(jas_image_clrspc(image))) { case JAS_CLRSPC_FAM_RGB: if (jas_image_cmpttype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R) && jas_image_cmpttype(image, 1) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G) && jas_image_cmpttype(image, 2) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B)) needcdef = 0; break; case JAS_CLRSPC_FAM_YCBCR: if (jas_image_cmpttype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y) && jas_image_cmpttype(image, 1) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB) && jas_image_cmpttype(image, 2) == JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR)) needcdef = 0; break; case JAS_CLRSPC_FAM_GRAY: if (jas_image_cmpttype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y)) needcdef = 0; break; default: abort(); break; } if (needcdef) { if (!(box = jp2_box_create(JP2_BOX_CDEF))) { goto error; } cdef = &box->data.cdef; cdef->numchans = jas_image_numcmpts(image); cdef->ents = jas_malloc(cdef->numchans * sizeof(jp2_cdefchan_t)); for (i = 0; i < jas_image_numcmpts(image); ++i) { cdefchanent = &cdef->ents[i]; cdefchanent->channo = i; typeasoc = jp2_gettypeasoc(jas_image_clrspc(image), jas_image_cmpttype(image, i)); cdefchanent->type = typeasoc >> 16; cdefchanent->assoc = typeasoc & 0x7fff; } if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; } /* Determine the total length of the JP2 header box. */ len = jas_stream_tell(tmpstream); jas_stream_rewind(tmpstream); /* * Output the JP2 header box and all of the boxes which it contains. */ if (!(box = jp2_box_create(JP2_BOX_JP2H))) { goto error; } box->len = len + JP2_BOX_HDRLEN; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; if (jas_stream_copy(out, tmpstream, len)) { goto error; } jas_stream_close(tmpstream); tmpstream = 0; return 0; abort(); error: if (box) { jp2_box_destroy(box); } if (tmpstream) { jas_stream_close(tmpstream); } return -1; }
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; }
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; }
int jp2_encode(jas_image_t *image, jas_stream_t *out, char *optstr) { jp2_box_t *box; jp2_ftyp_t *ftyp; jp2_ihdr_t *ihdr; jas_stream_t *tmpstream; int allcmptssame; jp2_bpcc_t *bpcc; long len; uint_fast16_t cmptno; jp2_colr_t *colr; char buf[4096]; uint_fast32_t overhead; jp2_cdefchan_t *cdefchanent; jp2_cdef_t *cdef; int i; uint_fast32_t typeasoc; box = 0; tmpstream = 0; /* Output the signature box. */ if (!(box = jp2_box_create(JP2_BOX_JP))) { goto error; } box->data.jp.magic = JP2_JP_MAGIC; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; /* Output the file type box. */ if (!(box = jp2_box_create(JP2_BOX_FTYP))) { goto error; } ftyp = &box->data.ftyp; ftyp->majver = JP2_FTYP_MAJVER; ftyp->minver = JP2_FTYP_MINVER; ftyp->numcompatcodes = 1; ftyp->compatcodes[0] = JP2_FTYP_COMPATCODE; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; /* * Generate the data portion of the JP2 header box. * We cannot simply output the header for this box * since we do not yet know the correct value for the length * field. */ if (!(tmpstream = jas_stream_memopen(0, 0))) { goto error; } /* Generate image header box. */ if (!(box = jp2_box_create(JP2_BOX_IHDR))) { goto error; } ihdr = &box->data.ihdr; ihdr->width = jas_image_width(image); ihdr->height = jas_image_height(image); ihdr->numcmpts = jas_image_numcmpts(image); allcmptssame = 0; ihdr->bpc = allcmptssame ? JP2_SPTOBPC(jas_image_cmptsgnd(image, 0), jas_image_cmptprec(image, 0)) : JP2_IHDR_BPCNULL; ihdr->comptype = JP2_IHDR_COMPTYPE; ihdr->csunk = 0; ihdr->ipr = 0; if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; /* Generate bits per component box. */ if (!allcmptssame) { if (!(box = jp2_box_create(JP2_BOX_BPCC))) { goto error; } bpcc = &box->data.bpcc; bpcc->numcmpts = jas_image_numcmpts(image); if (!(bpcc->bpcs = jas_malloc(bpcc->numcmpts * sizeof(uint_fast8_t)))) { goto error; } for (cmptno = 0; cmptno < bpcc->numcmpts; ++cmptno) { bpcc->bpcs[cmptno] = JP2_SPTOBPC(jas_image_cmptsgnd(image, cmptno), jas_image_cmptprec(image, cmptno)); } if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; } /* Generate color specification box. */ if (!(box = jp2_box_create(JP2_BOX_COLR))) { goto error; } colr = &box->data.colr; colr->method = JP2_COLR_ENUM; colr->pri = JP2_COLR_PRI; colr->approx = 0; colr->csid = (jas_image_colorspace(image) == JAS_IMAGE_CS_RGB) ? JP2_COLR_SRGB : JP2_COLR_SGRAY; if (jp2_box_put(box, tmpstream)) { goto error; } jp2_box_destroy(box); box = 0; if (!(jas_image_colorspace(image) == JAS_IMAGE_CS_RGB && jas_image_numcmpts(image) == 3 && jas_image_getcmptbytype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_R) && jas_image_getcmptbytype(image, 1) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_G) && jas_image_getcmptbytype(image, 2) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_B)) && !(jas_image_colorspace(image) == JAS_IMAGE_CS_YCBCR && jas_image_numcmpts(image) != 3 && jas_image_getcmptbytype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_Y) && jas_image_getcmptbytype(image, 1) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_CB) && jas_image_getcmptbytype(image, 2) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_YCBCR_CR)) && !(jas_image_colorspace(image) == JAS_IMAGE_CS_GRAY && jas_image_numcmpts(image) == 1 && jas_image_getcmptbytype(image, 0) == JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y))) { if (!(box = jp2_box_create(JP2_BOX_CDEF))) { goto error; } cdef = &box->data.cdef; cdef->numchans = jas_image_numcmpts(image); cdef->ents = jas_malloc(cdef->numchans * sizeof(jp2_cdefchan_t)); for (i = 0; i < jas_image_numcmpts(image); ++i) { cdefchanent = &cdef->ents[i]; cdefchanent->channo = i; typeasoc = jp2_gettypeasoc(jas_image_colorspace(image), jas_image_cmpttype(image, i)); cdefchanent->type = typeasoc >> 16; cdefchanent->assoc = typeasoc & 0x7fff; } jp2_box_destroy(box); box = 0; } /* Determine the total length of the JP2 header box. */ len = jas_stream_tell(tmpstream); jas_stream_rewind(tmpstream); /* * Output the JP2 header box and all of the boxes which it contains. */ if (!(box = jp2_box_create(JP2_BOX_JP2H))) { goto error; } box->len = len + JP2_BOX_HDRLEN; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; if (jas_stream_copy(out, tmpstream, len)) { goto error; } jas_stream_close(tmpstream); tmpstream = 0; /* * Output the contiguous code stream box. */ if (!(box = jp2_box_create(JP2_BOX_JP2C))) { goto error; } box->len = 0; if (jp2_box_put(box, out)) { goto error; } jp2_box_destroy(box); box = 0; /* Output the JPEG-2000 code stream. */ overhead = jas_stream_getrwcount(out); sprintf(buf, "%s\n_jp2overhead=%lu\n", (optstr ? optstr : ""), (unsigned long) overhead); if (jpc_encode(image, out, buf)) { goto error; } return 0; abort(); error: if (box) { jp2_box_destroy(box); } if (tmpstream) { jas_stream_close(tmpstream); } return -1; }