int getthebyte(jas_stream_t *in, long off) { int c; long oldpos; oldpos = jas_stream_tell(in); assert(oldpos >= 0); jas_stream_seek(in, off, SEEK_SET); c = jas_stream_peekc(in); jas_stream_seek(in, oldpos, SEEK_SET); return c; }
int iJP2ReadLine(jas_image_t *image, int row, int cmpno, T *data) { jas_image_cmpt_t *cmpt = image->cmpts_[cmpno]; if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * row) * cmpt->cps_, SEEK_SET) < 0) return 0; // this offset will convert from signed to unsigned int offset = 0; if (cmpt->sgnd_ && cmpt->prec_ > 1) offset = 1 << (cmpt->prec_-1); for (int j = 0; j < cmpt->width_; j++) { jas_seqent_t v = 0; for (int k = 0; k < cmpt->cps_; k++) { int c = jas_stream_getc(cmpt->stream_); if (c == EOF) return 0; v = (v << 8) | (c & 0xff); } v = iJP2Bits2Int(v, cmpt->prec_, cmpt->sgnd_); *data++ = (T)(v + offset); } return 1; }
fz_error fz_processjpxd(fz_filter *filter, fz_buffer *in, fz_buffer *out) { fz_jpxd *d = (fz_jpxd*)filter; int n, bpc, w, h; int i, x, y; switch (d->stage) { case 0: goto input; case 1: goto decode; case 2: goto output; } input: while (in->rp < in->wp) { n = jas_stream_write(d->stream, in->rp, in->wp - in->rp); in->rp += n; } if (!in->eof) return fz_ioneedin; d->stage = 1; decode: jas_stream_seek(d->stream, 0, SEEK_SET); d->image = jas_image_decode(d->stream, -1, nil); if (!d->image) return fz_throw("jasper error: jas_image_decode()"); d->stage = 2; output: w = jas_image_width(d->image); h = jas_image_height(d->image); n = jas_image_numcmpts(d->image); bpc = jas_image_cmptprec(d->image, 0); /* use precision of first component for all... */ while (d->offset < w * h) { y = d->offset / w; x = d->offset - y * w; /* FIXME bpc != 8 */ if (out->wp + n >= out->ep) return fz_ioneedout; for (i = 0; i < n; i++) *out->wp++ = jas_image_readcmptsample(d->image, i, x, y); d->offset ++; } return fz_iodone; }
/* Write a marker segment to a stream. */ int jpc_putms(jas_stream_t *out, jpc_cstate_t *cstate, jpc_ms_t *ms) { jas_stream_t *tmpstream; int len; /* Output the marker segment type. */ if (jpc_putuint16(out, ms->id)) { return -1; } /* Output the marker segment length and parameters if necessary. */ if (ms->ops->putparms) { /* Create a temporary stream in which to buffer the parameter data. */ if (!(tmpstream = jas_stream_memopen(0, 0))) { return -1; } if ((*ms->ops->putparms)(ms, cstate, tmpstream)) { jas_stream_close(tmpstream); return -1; } /* Get the number of bytes of parameter data written. */ if ((len = jas_stream_tell(tmpstream)) < 0) { jas_stream_close(tmpstream); return -1; } ms->len = len; /* Write the marker segment length and parameter data to the output stream. */ if (jas_stream_seek(tmpstream, 0, SEEK_SET) < 0 || jpc_putuint16(out, (uint_fast16_t)(ms->len + 2)) || jas_stream_copy(out, tmpstream, ms->len) < 0) { jas_stream_close(tmpstream); return -1; } /* Close the temporary stream. */ jas_stream_close(tmpstream); } /* This is a bit of a hack, but I'm not going to define another type of virtual function for this one special case. */ if (ms->id == JPC_MS_SIZ) { cstate->numcomps = ms->parms.siz.numcomps; } /* if (jas_getdbglevel() > 0) { jpc_ms_dump(ms, stderr); } */ return 0; }
int iJP2WriteLine(jas_image_t *image, int row, int cmpno, T *data) { jas_image_cmpt_t *cmpt = image->cmpts_[cmpno]; if (jas_stream_seek(cmpt->stream_, (cmpt->width_ * row) * cmpt->cps_, SEEK_SET) < 0) return 0; for (int j = 0; j < cmpt->width_; j++) { jas_seqent_t v = iJP2Int2Bits(*data++, cmpt->prec_, cmpt->sgnd_); for (int k = 0; k < cmpt->cps_; k++) { int c = (v >> (8 * (cmpt->cps_ - 1))) & 0xff; if (jas_stream_putc(cmpt->stream_, (imbyte)c) == EOF) return 0; v <<= 8; } } return 1; }
int jas_stream_rewind(jas_stream_t *stream) { return jas_stream_seek(stream, 0, SEEK_SET); }
/* Read a marker segment from a stream. */ jpc_ms_t *jpc_getms(jas_stream_t *in, jpc_cstate_t *cstate) { long file_offset = jas_stream_tell(in); long seek_offset = jas_rtc_SkipMarkerSegment(file_offset); if (seek_offset > 0 && jas_stream_seek(in, seek_offset, SEEK_CUR) < 0) return NULL; jpc_ms_t *ms; jpc_mstabent_t *mstabent; jas_stream_t *tmpstream; if (!(ms = jpc_ms_create(0))) { return 0; } /* Get the marker type. */ if (jpc_getuint16(in, &ms->id) || ms->id < JPC_MS_MIN #ifndef __MINGW32__ || ms->id > JPC_MS_MAX #endif ) { jpc_ms_destroy(ms); return 0; } jas_rtc_MarkerSegment(file_offset, ms->id); mstabent = jpc_mstab_lookup(ms->id); ms->ops = &mstabent->ops; /* Get the marker segment length and parameters if present. */ /* Note: It is tacitly assumed that a marker segment cannot have parameters unless it has a length field. That is, there cannot be a parameters field without a length field and vice versa. */ if (JPC_MS_HASPARMS(ms->id)) { /* Get the length of the marker segment. */ if (jpc_getuint16(in, &ms->len) || ms->len < 3) { jpc_ms_destroy(ms); return 0; } /* Calculate the length of the marker segment parameters. */ ms->len -= 2; /* Create and prepare a temporary memory stream from which to read the marker segment parameters. */ /* Note: This approach provides a simple way of ensuring that we never read beyond the end of the marker segment (even if the marker segment length is errantly set too small). */ if (!(tmpstream = jas_stream_memopen(0, 0))) { jpc_ms_destroy(ms); return 0; } if (jas_stream_copy(tmpstream, in, ms->len) || jas_stream_seek(tmpstream, 0, SEEK_SET) < 0) { jas_stream_close(tmpstream); jpc_ms_destroy(ms); return 0; } /* Get the marker segment parameters. */ if ((*ms->ops->getparms)(ms, cstate, tmpstream)) { ms->ops = 0; jpc_ms_destroy(ms); jas_stream_close(tmpstream); return 0; } #if 0 // JMW if (JAS_CAST(ulong, jas_stream_tell(tmpstream)) != ms->len) { fprintf(stderr, "warning: trailing garbage in marker segment (%ld bytes)\n", ms->len - jas_stream_tell(tmpstream)); } #endif /* Close the temporary stream. */ jas_stream_close(tmpstream); } else { /* There are no marker segment parameters. */ ms->len = 0; } /* Update the code stream state information based on the type of marker segment read. */ /* Note: This is a bit of a hack, but I'm not going to define another type of virtual function for this one special case. */ if (ms->id == JPC_MS_SIZ) { cstate->numcomps = ms->parms.siz.numcomps; } return ms; }
/* Read a marker segment from a stream. */ jpc_ms_t *jpc_getms(jas_stream_t *in, jpc_cstate_t *cstate) { jpc_ms_t *ms; jpc_mstabent_t *mstabent; jas_stream_t *tmpstream; if (!(ms = jpc_ms_create(0))) { return 0; } /* Get the marker type. */ if (jpc_getuint16(in, &ms->id) || ms->id < JPC_MS_MIN || ms->id > JPC_MS_MAX) { jpc_ms_destroy(ms); return 0; } mstabent = jpc_mstab_lookup(ms->id); ms->ops = &mstabent->ops; /* Get the marker segment length and parameters if present. */ /* Note: It is tacitly assumed that a marker segment cannot have parameters unless it has a length field. That is, there cannot be a parameters field without a length field and vice versa. */ if (JPC_MS_HASPARMS(ms->id)) { /* Get the length of the marker segment. */ if (jpc_getuint16(in, &ms->len) || ms->len < 3) { jpc_ms_destroy(ms); return 0; } /* Calculate the length of the marker segment parameters. */ ms->len -= 2; /* Create and prepare a temporary memory stream from which to read the marker segment parameters. */ /* Note: This approach provides a simple way of ensuring that we never read beyond the end of the marker segment (even if the marker segment length is errantly set too small). */ if (!(tmpstream = jas_stream_memopen(0, 0))) { jpc_ms_destroy(ms); return 0; } if (jas_stream_copy(tmpstream, in, ms->len) || jas_stream_seek(tmpstream, 0, SEEK_SET) < 0) { jas_stream_close(tmpstream); jpc_ms_destroy(ms); return 0; } /* Get the marker segment parameters. */ if ((*ms->ops->getparms)(ms, cstate, tmpstream)) { ms->ops = 0; jpc_ms_destroy(ms); jas_stream_close(tmpstream); return 0; } if (jas_getdbglevel() > 0) { jpc_ms_dump(ms, stderr); } if (JAS_CAST(unsigned long, jas_stream_tell(tmpstream)) != ms->len) { fprintf(stderr, "warning: trailing garbage in marker segment (%ld bytes)\n", ms->len - jas_stream_tell(tmpstream)); } /* Close the temporary stream. */ jas_stream_close(tmpstream); } else {
int jpc_enc_encpkt(jpc_enc_t *enc, jas_stream_t *out, int compno, int lvlno, int prcno, int lyrno) { jpc_enc_tcmpt_t *comp; jpc_enc_rlvl_t *lvl; jpc_enc_band_t *band; jpc_enc_band_t *endbands; jpc_enc_cblk_t *cblk; jpc_enc_cblk_t *endcblks; jpc_bitstream_t *outb; jpc_enc_pass_t *pass; jpc_enc_pass_t *startpass; jpc_enc_pass_t *lastpass; jpc_enc_pass_t *endpass; jpc_enc_pass_t *endpasses; int i; int included; int ret; jpc_tagtreenode_t *leaf; int n; int t1; int t2; int adjust; int maxadjust; int datalen; int numnewpasses; int passcount; jpc_enc_tile_t *tile; jpc_enc_prc_t *prc; jpc_enc_cp_t *cp; jpc_ms_t *ms; tile = enc->curtile; cp = enc->cp; if (cp->tcp.csty & JPC_COD_SOP) { if (!(ms = jpc_ms_create(JPC_MS_SOP))) { return -1; } ms->parms.sop.seqno = jpc_pi_getind(tile->pi); if (jpc_putms(out, enc->cstate, ms)) { return -1; } jpc_ms_destroy(ms); } outb = jpc_bitstream_sopen(out, "w+"); assert(outb); if (jpc_bitstream_putbit(outb, 1) == EOF) { return -1; } JAS_DBGLOG(10, ("\n")); JAS_DBGLOG(10, ("present. ")); comp = &tile->tcmpts[compno]; lvl = &comp->rlvls[lvlno]; endbands = &lvl->bands[lvl->numbands]; for (band = lvl->bands; band != endbands; ++band) { if (!band->data) { continue; } prc = &band->prcs[prcno]; if (!prc->cblks) { continue; } endcblks = &prc->cblks[prc->numcblks]; for (cblk = prc->cblks; cblk != endcblks; ++cblk) { if (!lyrno) { leaf = jpc_tagtree_getleaf(prc->nlibtree, cblk - prc->cblks); jpc_tagtree_setvalue(prc->nlibtree, leaf, cblk->numimsbs); } pass = cblk->curpass; included = (pass && pass->lyrno == lyrno); if (included && (!cblk->numencpasses)) { assert(pass->lyrno == lyrno); leaf = jpc_tagtree_getleaf(prc->incltree, cblk - prc->cblks); jpc_tagtree_setvalue(prc->incltree, leaf, pass->lyrno); } } endcblks = &prc->cblks[prc->numcblks]; for (cblk = prc->cblks; cblk != endcblks; ++cblk) { pass = cblk->curpass; included = (pass && pass->lyrno == lyrno); if (!cblk->numencpasses) { leaf = jpc_tagtree_getleaf(prc->incltree, cblk - prc->cblks); if (jpc_tagtree_encode(prc->incltree, leaf, lyrno + 1, outb) < 0) { return -1; } } else { if (jpc_bitstream_putbit(outb, included) == EOF) { return -1; } } JAS_DBGLOG(10, ("included=%d ", included)); if (!included) { continue; } if (!cblk->numencpasses) { i = 1; leaf = jpc_tagtree_getleaf(prc->nlibtree, cblk - prc->cblks); for (;;) { if ((ret = jpc_tagtree_encode(prc->nlibtree, leaf, i, outb)) < 0) { return -1; } if (ret) { break; } ++i; } assert(leaf->known_ && i == leaf->value_ + 1); } endpasses = &cblk->passes[cblk->numpasses]; startpass = pass; endpass = startpass; while (endpass != endpasses && endpass->lyrno == lyrno){ ++endpass; } numnewpasses = endpass - startpass; if (jpc_putnumnewpasses(outb, numnewpasses)) { return -1; } JAS_DBGLOG(10, ("numnewpasses=%d ", numnewpasses)); lastpass = endpass - 1; n = startpass->start; passcount = 1; maxadjust = 0; for (pass = startpass; pass != endpass; ++pass) { if (pass->term || pass == lastpass) { datalen = pass->end - n; t1 = jpc_firstone(datalen) + 1; t2 = cblk->numlenbits + jpc_floorlog2(passcount); adjust = JAS_MAX(t1 - t2, 0); maxadjust = JAS_MAX(adjust, maxadjust); n += datalen; passcount = 1; } else { ++passcount; } } if (jpc_putcommacode(outb, maxadjust)) { return -1; } cblk->numlenbits += maxadjust; lastpass = endpass - 1; n = startpass->start; passcount = 1; for (pass = startpass; pass != endpass; ++pass) { if (pass->term || pass == lastpass) { datalen = pass->end - n; assert(jpc_firstone(datalen) < cblk->numlenbits + jpc_floorlog2(passcount)); if (jpc_bitstream_putbits(outb, cblk->numlenbits + jpc_floorlog2(passcount), datalen) == EOF) { return -1; } n += datalen; passcount = 1; } else { ++passcount; } } } } jpc_bitstream_outalign(outb, 0); jpc_bitstream_close(outb); if (cp->tcp.csty & JPC_COD_EPH) { if (!(ms = jpc_ms_create(JPC_MS_EPH))) { return -1; } jpc_putms(out, enc->cstate, ms); jpc_ms_destroy(ms); } comp = &tile->tcmpts[compno]; lvl = &comp->rlvls[lvlno]; endbands = &lvl->bands[lvl->numbands]; for (band = lvl->bands; band != endbands; ++band) { if (!band->data) { continue; } prc = &band->prcs[prcno]; if (!prc->cblks) { continue; } endcblks = &prc->cblks[prc->numcblks]; for (cblk = prc->cblks; cblk != endcblks; ++cblk) { pass = cblk->curpass; if (!pass) { continue; } if (pass->lyrno != lyrno) { assert(pass->lyrno < 0 || pass->lyrno > lyrno); continue; } endpasses = &cblk->passes[cblk->numpasses]; startpass = pass; endpass = startpass; while (endpass != endpasses && endpass->lyrno == lyrno){ ++endpass; } lastpass = endpass - 1; numnewpasses = endpass - startpass; jas_stream_seek(cblk->stream, startpass->start, SEEK_SET); assert(jas_stream_tell(cblk->stream) == startpass->start); if (jas_stream_copy(out, cblk->stream, lastpass->end - startpass->start)) { return -1; } cblk->curpass = (endpass != endpasses) ? endpass : 0; cblk->numencpasses += numnewpasses; } } return 0; }