Ejemplo n.º 1
0
/* 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_malloc(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;
}
Ejemplo n.º 2
0
static int jpc_dec_decodecblk(jpc_dec_t *dec, jpc_dec_tile_t *tile, jpc_dec_tcomp_t *tcomp, jpc_dec_band_t *band,
  jpc_dec_cblk_t *cblk, int dopartial, int maxlyrs)
{
	jpc_dec_seg_t *seg;
	int i;
	int bpno;
	int passtype;
	int ret;
	int compno;
	int filldata;
	int fillmask;
	jpc_dec_ccp_t *ccp;

	compno = tcomp - tile->tcomps;

	if (!cblk->flags) {
		/* Note: matrix is assumed to be zeroed */
		if (!(cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) +
		  2, jas_matrix_numcols(cblk->data) + 2))) {
			return -1;
		}
	}

	seg = cblk->segs.head;
	while (seg && (seg != cblk->curseg || dopartial) && (maxlyrs < 0 ||
	  seg->lyrno < maxlyrs)) {
		assert(seg->numpasses >= seg->maxpasses || dopartial);
		assert(seg->stream);
		jas_stream_rewind(seg->stream);
		jas_stream_setrwcount(seg->stream, 0);
		if (seg->type == JPC_SEG_MQ) {
			if (!cblk->mqdec) {
				if (!(cblk->mqdec = jpc_mqdec_create(JPC_NUMCTXS, 0))) {
					return -1;
				}
				jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
			}
			jpc_mqdec_setinput(cblk->mqdec, seg->stream);
			jpc_mqdec_init(cblk->mqdec);
		} else {
			assert(seg->type == JPC_SEG_RAW);
			if (!cblk->nulldec) {
				if (!(cblk->nulldec = jpc_bitstream_sopen(seg->stream, "r"))) {
					assert(0);
				}
			}
		}


		for (i = 0; i < seg->numpasses; ++i) {
			if (cblk->numimsbs > band->numbps) {
				ccp = &tile->cp->ccps[compno];
				if (ccp->roishift <= 0) {
					jas_eprintf("warning: corrupt code stream\n");
				} else {
					if (cblk->numimsbs < ccp->roishift - band->numbps) {
						jas_eprintf("warning: corrupt code stream\n");
					}
				}
			}
			bpno = band->roishift + band->numbps - 1 - (cblk->numimsbs +
			  (seg->passno + i - cblk->firstpassno + 2) / 3);
if (bpno < 0) {
	goto premature_exit;
}
#if 1
			passtype = (seg->passno + i + 2) % 3;
#else
			passtype = JPC_PASSTYPE(seg->passno + i + 2);
#endif
			assert(bpno >= 0 && bpno < 31);
			switch (passtype) {
			case JPC_SIGPASS:
				ret = (seg->type == JPC_SEG_MQ) ? dec_sigpass(dec,
				  cblk->mqdec, bpno, band->orient,
				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
				  cblk->flags, cblk->data) :
				  dec_rawsigpass(dec, cblk->nulldec, bpno,
				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
				  cblk->flags, cblk->data);
				break;
			case JPC_REFPASS:
				ret = (seg->type == JPC_SEG_MQ) ?
				  dec_refpass(dec, cblk->mqdec, bpno,
				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
				  cblk->flags, cblk->data) :
				  dec_rawrefpass(dec, cblk->nulldec, bpno,
				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
				  cblk->flags, cblk->data);
				break;
			case JPC_CLNPASS:
				assert(seg->type == JPC_SEG_MQ);
				ret = dec_clnpass(dec, cblk->mqdec, bpno,
				  band->orient, (tile->cp->ccps[compno].cblkctx &
				  JPC_COX_VSC) != 0, (tile->cp->ccps[compno].cblkctx &
				  JPC_COX_SEGSYM) != 0, cblk->flags,
				  cblk->data);
				break;
			default:
				ret = -1;
				break;
			}
			/* Do we need to reset after each coding pass? */
			if (tile->cp->ccps[compno].cblkctx & JPC_COX_RESET) {
				jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
			}

			if (ret) {
				jas_eprintf("coding pass failed passtype=%d segtype=%d\n", passtype, seg->type);
				return -1;
			}

		}

		if (seg->type == JPC_SEG_MQ) {
/* Note: dont destroy mq decoder because context info will be lost */
		} else {
			assert(seg->type == JPC_SEG_RAW);
			if (tile->cp->ccps[compno].cblkctx & JPC_COX_PTERM) {
				fillmask = 0x7f;
				filldata = 0x2a;
			} else {
				fillmask = 0;
				filldata = 0;
			}
			if ((ret = jpc_bitstream_inalign(cblk->nulldec, fillmask,
			  filldata)) < 0) {
				return -1;
			} else if (ret > 0) {
				jas_eprintf("warning: bad termination pattern detected\n");
			}
			jpc_bitstream_close(cblk->nulldec);
			cblk->nulldec = 0;
		}

		cblk->curseg = seg->next;
		jpc_seglist_remove(&cblk->segs, seg);
		jpc_seg_destroy(seg);
		seg = cblk->curseg;
	}

	assert(dopartial ? (!cblk->curseg) : 1);

premature_exit:
	return 0;
}