Commit message: The generation of the configuration file jas_config.h has been completely
reworked in order to avoid pollution of the global namespace.

Some problematic types like uchar, ulong, and friends have been replaced
with names with a jas_ prefix.

An option max_samples has been added to the BMP and JPEG decoders to
restrict the maximum size of image that they can decode.  This change
was made as a (possibly temporary) fix to address security concerns.
A max_samples command-line option has also been added to imginfo.

Whether an image component (for jas_image_t) is stored in memory or on
disk is now based on the component size (rather than the image size).

Some debug log message were added.

Some new integer overflow checks were added.

Some new safe integer add/multiply functions were added.

More pre-C99 cruft was removed.  JasPer has numerous "hacks" to
handle pre-C99 compilers.  JasPer now assumes C99 support.  So, this
pre-C99 cruft is unnecessary and can be removed.

The regression jasper-doublefree-mem_close.jpg has been re-enabled.
Theoretically, it should work more predictably now.
CVE: CVE-2015-5203
CWE: CWE-190
Vulnerability description: Double free vulnerability in the jasper_image_stop_load function in JasPer 1.900.17 allows remote attackers to cause a denial of service (crash) via a crafted JPEG 2000 image file.

Project: jasper
File: jas_debug.c

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;
}

Project: jasper
File: jas_icc.c

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;
}

Project: jasper
File: jas_icc.c

static int jas_icccurv_getsize(jas_iccattrval_t *attrval)
{
	jas_icccurv_t *curv = &attrval->data.curv;
	return 4 + 2 * curv->numents;
}

Project: jasper
File: jas_icc.c

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;
}

Project: jasper
File: jas_icc.c

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;
}

Project: jasper

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_alloc2(clutsize, sizeof(jas_iccuint8_t))) ||
	  !(lut8->intabsbuf = jas_alloc3(lut8->numinchans,
	  lut8->numintabents, sizeof(jas_iccuint8_t))) ||
	  !(lut8->intabs = jas_alloc2(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_alloc3(lut8->numoutchans,
	  lut8->numouttabents, sizeof(jas_iccuint8_t))) ||
	  !(lut8->outtabs = jas_alloc2(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;
}

Project: jasper
File: jas_icc.c

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;
}

Project: jasper
File: jas_icc.c

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;
}

Project: jasper
File: jas_icc.c

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;
}

Project: jasper
File: jas_icc.c

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;
}

Project: jasper
File: jas_icc.c

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;
}

Project: jasper
File: jas_icc.c

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;
}

Project: jasper
File: jas_image.c

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;
}

Project: jasper
File: jas_image.c

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;
}

Project: jasper
File: jas_image.c

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;
}

Project: jasper
File: jas_image.c

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;
}

Project: jasper

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;

	JAS_DBGLOG(10, ("jas_image_writecmpt(%p, %d, %ld, %ld, %ld, %ld, %p)\n",
	  image, cmptno, JAS_CAST(long, x), JAS_CAST(long, y),
	  JAS_CAST(long, width), JAS_CAST(long, height), data));

	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) || !jas_matrix_numcols(data)) {
		return -1;
	}

	if (jas_matrix_numrows(data) != height ||
	  jas_matrix_numcols(data) != 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 = 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;
}

Project: jasper

void jas_tmr_stop(jas_tmr_t *tmr)
{
	if (gettimeofday(&tmr->stop, 0)) {
		abort();
	}
}

Project: jasper
File: jp2_dec.c

int jp2_validate(jas_stream_t *in)
{
	char buf[JP2_VALIDATELEN];
	int i;
	int n;
#if 0
	jas_stream_t *tmpstream;
	jp2_box_t *box;
#endif

	assert(JAS_STREAM_MAXPUTBACK >= JP2_VALIDATELEN);

	/* Read the validation data (i.e., the data used for detecting
	  the format). */
	if ((n = jas_stream_read(in, buf, JP2_VALIDATELEN)) < 0) {
		return -1;
	}

	/* Put the validation data back onto the stream, so that the
	  stream position will not be changed. */
	for (i = n - 1; i >= 0; --i) {
		if (jas_stream_ungetc(in, buf[i]) == EOF) {
			return -1;
		}
	}

	/* Did we read enough data? */
	if (n < JP2_VALIDATELEN) {
		return -1;
	}

	/* Is the box type correct? */
	if (((buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]) !=
	  JP2_BOX_JP)
	{
		return -1;
	}

	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_cod_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
{
	jpc_cod_t *cod = &ms->parms.cod;
	assert(cod->numlyrs > 0 && cod->compparms.numdlvls <= 32);
	assert(cod->compparms.numdlvls == cod->compparms.numrlvls - 1);
	if (jpc_putuint8(out, cod->compparms.csty) ||
	  jpc_putuint8(out, cod->prg) ||
	  jpc_putuint16(out, cod->numlyrs) ||
	  jpc_putuint8(out, cod->mctrans)) {
		return -1;
	}
	if (jpc_cox_putcompparms(ms, cstate, out,
	  (cod->csty & JPC_COX_PRT) != 0, &cod->compparms)) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static void jpc_poc_destroyparms(jpc_ms_t *ms)
{
	jpc_poc_t *poc = &ms->parms.poc;
	if (poc->pchgs) {
		jas_free(poc->pchgs);
	}
}

Project: jasper
File: jpc_cs.c

static void jpc_ppt_destroyparms(jpc_ms_t *ms)
{
	jpc_ppt_t *ppt = &ms->parms.ppt;
	if (ppt->data) {
		jas_free(ppt->data);
	}
}

Project: jasper
File: jpc_cs.c

static int jpc_ppt_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_ppt_t *ppt = &ms->parms.ppt;

	/* Eliminate compiler warning about unused variables. */
	cstate = 0;

	ppt->data = 0;

	if (ms->len < 1) {
		goto error;
	}
	if (jpc_getuint8(in, &ppt->ind)) {
		goto error;
	}
	ppt->len = ms->len - 1;
	if (ppt->len > 0) {
		if (!(ppt->data = jas_malloc(ppt->len))) {
			goto error;
		}
		if (jas_stream_read(in, (char *) ppt->data, ppt->len) != JAS_CAST(int, ppt->len)) {
			goto error;
		}
	} else {
		ppt->data = 0;
	}
	return 0;

error:
	jpc_ppt_destroyparms(ms);
	return -1;
}

Project: jasper
File: jpc_cs.c

static void jpc_qcd_destroyparms(jpc_ms_t *ms)
{
	jpc_qcd_t *qcd = &ms->parms.qcd;
	jpc_qcx_destroycompparms(&qcd->compparms);
}

Project: jasper
File: jpc_cs.c

static int jpc_qcd_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
{
	jpc_qcxcp_t *compparms = &ms->parms.qcd.compparms;
	return jpc_qcx_putcompparms(compparms, cstate, out);
}

Project: jasper
File: jpc_cs.c

static int jpc_qcx_getcompparms(jpc_qcxcp_t *compparms, jpc_cstate_t *cstate,
  jas_stream_t *in, uint_fast16_t len)
{
	uint_fast8_t tmp;
	int n;
	int i;

	/* Eliminate compiler warning about unused variables. */
	cstate = 0;

	n = 0;
	if (jpc_getuint8(in, &tmp)) {
		return -1;
	}
	++n;
	compparms->qntsty = tmp & 0x1f;
	compparms->numguard = (tmp >> 5) & 7;
	switch (compparms->qntsty) {
	case JPC_QCX_SIQNT:
		compparms->numstepsizes = 1;
		break;
	case JPC_QCX_NOQNT:
		compparms->numstepsizes = (len - n);
		break;
	case JPC_QCX_SEQNT:
		/* XXX - this is a hack */
		compparms->numstepsizes = (len - n) / 2;
		break;
	}
	/* Ensure that the step size array is sufficiently large. */
	if (compparms->numstepsizes > 3 * JPC_MAXRLVLS + 1) {
		jpc_qcx_destroycompparms(compparms);
		return -1;
	}
	if (compparms->numstepsizes > 0) {
		if (!(compparms->stepsizes = jas_alloc2(compparms->numstepsizes,
		  sizeof(uint_fast16_t)))) {
			abort();
		}
		for (i = 0; i < compparms->numstepsizes; ++i) {
			if (compparms->qntsty == JPC_QCX_NOQNT) {
				if (jpc_getuint8(in, &tmp)) {
					return -1;
				}
				compparms->stepsizes[i] = JPC_QCX_EXPN(tmp >> 3);
			} else {
				if (jpc_getuint16(in, &compparms->stepsizes[i])) {
					return -1;
				}
			}
		}
	} else {
		compparms->stepsizes = 0;
	}
	if (jas_stream_error(in) || jas_stream_eof(in)) {
		jpc_qcx_destroycompparms(compparms);
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_qcx_putcompparms(jpc_qcxcp_t *compparms, jpc_cstate_t *cstate,
  jas_stream_t *out)
{
	int i;

	/* Eliminate compiler warning about unused variables. */
	cstate = 0;

	jpc_putuint8(out, ((compparms->numguard & 7) << 5) | compparms->qntsty);
	for (i = 0; i < compparms->numstepsizes; ++i) {
		if (compparms->qntsty == JPC_QCX_NOQNT) {
			if (jpc_putuint8(out, JPC_QCX_GETEXPN(
			  compparms->stepsizes[i]) << 3)) {
				return -1;
			}
		} else {
			if (jpc_putuint16(out, compparms->stepsizes[i])) {
				return -1;
			}
		}
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_rgn_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_rgn_t *rgn = &ms->parms.rgn;
	fprintf(out, "compno = %"PRIuFAST16"; roisty = %d; roishift = %d\n",
	  rgn->compno, rgn->roisty, rgn->roishift);
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_unk_dumpparms(jpc_ms_t *ms, FILE *out)
{
	unsigned int i;
	jpc_unk_t *unk = &ms->parms.unk;
	for (i = 0; i < unk->len; ++i) {
		fprintf(out, "%02x ", unk->data[i]);
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_unk_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
{
	/* Eliminate compiler warning about unused variables. */
	cstate = 0;
	ms = 0;
	out = 0;

	/* If this function is called, we are trying to write an unsupported
	  type of marker segment.  Return with an error indication.  */
	return -1;
}

Project: jasper
File: jpc_cs.c

int jpc_validate(jas_stream_t *in)
{
	int n;
	int i;
	unsigned char buf[2];

	assert(JAS_STREAM_MAXPUTBACK >= 2);

	if ((n = jas_stream_read(in, (char *) buf, 2)) < 0) {
		return -1;
	}
	for (i = n - 1; i >= 0; --i) {
		if (jas_stream_ungetc(in, buf[i]) == EOF) {
			return -1;
		}
	}
	if (n < 2) {
		return -1;
	}
	if (buf[0] == (JPC_MS_SOC >> 8) && buf[1] == (JPC_MS_SOC & 0xff)) {
		return 0;
	}
	return -1;
}

Project: jasper

static void band_destroy(jpc_enc_band_t *band)
{
	jpc_enc_prc_t *prc;
	jpc_enc_rlvl_t *rlvl;
	uint_fast32_t prcno;

	if (band->prcs) {
		rlvl = band->rlvl;
		for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs;
		  ++prcno, ++prc) {
			prc_destroy(prc);
		}
		jas_free(band->prcs);
	}
	if (band->data) {
		jas_seq2d_destroy(band->data);
	}
}

Project: jasper

static void rlvl_destroy(jpc_enc_rlvl_t *rlvl)
{
	jpc_enc_band_t *band;
	uint_fast16_t bandno;

	if (rlvl->bands) {
		for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
		  ++bandno, ++band) {
			band_destroy(band);
		}
		jas_free(rlvl->bands);
	}
}

Project: jasper
File: jpc_enc.c

static jpc_enc_tcmpt_t *tcmpt_create(jpc_enc_tcmpt_t *tcmpt, jpc_enc_cp_t *cp,
  jas_image_t *image, jpc_enc_tile_t *tile)
{
	uint_fast16_t cmptno;
	uint_fast16_t rlvlno;
	jpc_enc_rlvl_t *rlvl;
	uint_fast32_t tlx;
	uint_fast32_t tly;
	uint_fast32_t brx;
	uint_fast32_t bry;
	uint_fast32_t cmpttlx;
	uint_fast32_t cmpttly;
	jpc_enc_ccp_t *ccp;
	jpc_tsfb_band_t bandinfos[JPC_MAXBANDS];

	tcmpt->tile = tile;
	tcmpt->tsfb = 0;
	tcmpt->data = 0;
	tcmpt->rlvls = 0;

	/* Deduce the component number. */
	cmptno = tcmpt - tile->tcmpts;

	ccp = &cp->ccps[cmptno];

	/* Compute the coordinates of the top-left and bottom-right
	  corners of this tile-component. */
	tlx = JPC_CEILDIV(tile->tlx, ccp->sampgrdstepx);
	tly = JPC_CEILDIV(tile->tly, ccp->sampgrdstepy);
	brx = JPC_CEILDIV(tile->brx, ccp->sampgrdstepx);
	bry = JPC_CEILDIV(tile->bry, ccp->sampgrdstepy);

	/* Create a sequence to hold the tile-component sample data. */
	if (!(tcmpt->data = jas_seq2d_create(tlx, tly, brx, bry))) {
		goto error;
	}

	/* Get the image data associated with this tile-component. */
	cmpttlx = JPC_CEILDIV(cp->imgareatlx, ccp->sampgrdstepx);
	cmpttly = JPC_CEILDIV(cp->imgareatly, ccp->sampgrdstepy);
	if (jas_image_readcmpt(image, cmptno, tlx - cmpttlx, tly - cmpttly,
	  brx - tlx, bry - tly, tcmpt->data)) {
		goto error;
	}

	tcmpt->synweight = 0;
	tcmpt->qmfbid = cp->tccp.qmfbid;
	tcmpt->numrlvls = cp->tccp.maxrlvls;
	tcmpt->numbands = 3 * tcmpt->numrlvls - 2;
	if (!(tcmpt->tsfb = jpc_cod_gettsfb(tcmpt->qmfbid, tcmpt->numrlvls - 1))) {
		goto error;
	}

	for (rlvlno = 0; rlvlno < tcmpt->numrlvls; ++rlvlno) {
		tcmpt->prcwidthexpns[rlvlno] = cp->tccp.prcwidthexpns[rlvlno];
		tcmpt->prcheightexpns[rlvlno] = cp->tccp.prcheightexpns[rlvlno];
	}
	tcmpt->cblkwidthexpn = cp->tccp.cblkwidthexpn;
	tcmpt->cblkheightexpn = cp->tccp.cblkheightexpn;
	tcmpt->cblksty = cp->tccp.cblksty;
	tcmpt->csty = cp->tccp.csty;

	tcmpt->numstepsizes = tcmpt->numbands;
	assert(tcmpt->numstepsizes <= JPC_MAXBANDS);
	memset(tcmpt->stepsizes, 0, tcmpt->numstepsizes * sizeof(uint_fast16_t));

	/* Retrieve information about the various bands. */
	jpc_tsfb_getbands(tcmpt->tsfb, jas_seq2d_xstart(tcmpt->data),
	  jas_seq2d_ystart(tcmpt->data), jas_seq2d_xend(tcmpt->data),
	  jas_seq2d_yend(tcmpt->data), bandinfos);

	if (!(tcmpt->rlvls = jas_alloc2(tcmpt->numrlvls, sizeof(jpc_enc_rlvl_t)))) {
		goto error;
	}
	for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
	  ++rlvlno, ++rlvl) {
		rlvl->bands = 0;
		rlvl->tcmpt = tcmpt;
	}
	for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
	  ++rlvlno, ++rlvl) {
		if (!rlvl_create(rlvl, cp, tcmpt, bandinfos)) {
			goto error;
		}
	}

	return tcmpt;

error:

	tcmpt_destroy(tcmpt);
	return 0;

}

Project: jasper

jas_image_t *mif_decode(jas_stream_t *in, char *optstr)
{
	mif_hdr_t *hdr;
	jas_image_t *image;
	jas_image_t *tmpimage;
	jas_stream_t *tmpstream;
	int cmptno;
	mif_cmpt_t *cmpt;
	jas_image_cmptparm_t cmptparm;
	jas_seq2d_t *data;
	int_fast32_t x;
	int_fast32_t y;
	int bias;

	/* Avoid warnings about unused parameters. */
	optstr = 0;

	hdr = 0;
	image = 0;
	tmpimage = 0;
	tmpstream = 0;
	data = 0;

	if (!(hdr = mif_hdr_get(in))) {
		goto error;
	}

	if (!(image = jas_image_create0())) {
		goto error;
	}

	for (cmptno = 0; cmptno < hdr->numcmpts; ++cmptno) {
		cmpt = hdr->cmpts[cmptno];
		tmpstream = cmpt->data ? jas_stream_fopen(cmpt->data, "rb") : in;
		if (!tmpstream) {
			jas_eprintf("cannot open component file %s\n", cmpt->data);
			goto error;
		}
		if (!(tmpimage = jas_image_decode(tmpstream, -1, 0))) {
			goto error;
		}
		if (tmpstream != in) {
			jas_stream_close(tmpstream);
			tmpstream = 0;
		}
		if (!cmpt->width) {
			cmpt->width = jas_image_cmptwidth(tmpimage, 0);
		}
		if (!cmpt->height) {
			cmpt->height = jas_image_cmptwidth(tmpimage, 0);
		}
		if (!cmpt->prec) {
			cmpt->prec = jas_image_cmptprec(tmpimage, 0);
		}
		if (cmpt->sgnd < 0) {
			cmpt->sgnd = jas_image_cmptsgnd(tmpimage, 0);
		}
		cmptparm.tlx = cmpt->tlx;
		cmptparm.tly = cmpt->tly;
		cmptparm.hstep = cmpt->sampperx;
		cmptparm.vstep = cmpt->samppery;
		cmptparm.width = cmpt->width;
		cmptparm.height = cmpt->height;
		cmptparm.prec = cmpt->prec;
		cmptparm.sgnd = cmpt->sgnd;
		if (jas_image_addcmpt(image, jas_image_numcmpts(image), &cmptparm)) {
			goto error;
		}
		if (!(data = jas_seq2d_create(0, 0, cmpt->width, cmpt->height))) {
			goto error;
		}
		if (jas_image_readcmpt(tmpimage, 0, 0, 0, cmpt->width, cmpt->height,
		  data)) {
			goto error;
		}
		if (cmpt->sgnd) {
			bias = 1 << (cmpt->prec - 1);
			for (y = 0; y < cmpt->height; ++y) {
				for (x = 0; x < cmpt->width; ++x) {
					*jas_seq2d_getref(data, x, y) -= bias;
				}
			}
		}
		if (jas_image_writecmpt(image, jas_image_numcmpts(image) - 1, 0, 0,
		  cmpt->width, cmpt->height, data)) {
			goto error;
		}
		jas_seq2d_destroy(data);
		data = 0;
		jas_image_destroy(tmpimage);
		tmpimage = 0;
	}

	mif_hdr_destroy(hdr);
	hdr = 0;
	return image;

error:
	if (image) {
		jas_image_destroy(image);
	}
	if (hdr) {
		mif_hdr_destroy(hdr);
	}
	if (tmpstream && tmpstream != in) {
		jas_stream_close(tmpstream);
	}
	if (tmpimage) {
		jas_image_destroy(tmpimage);
	}
	if (data) {
		jas_seq2d_destroy(data);
	}
	return 0;
}

Project: jasper

static int pnm_getbitstr(jas_stream_t *in, int *val)
{
	int c;
	int_fast32_t v;
	for (;;) {
		if ((c = pnm_getc(in)) == EOF) {
			return -1;
		}
		if (c == '#') {
			for (;;) {
				if ((c = pnm_getc(in)) == EOF) {
					return -1;
				}
				if (c == '\n') {
					break;
				}
			}
		} else if (c == '0' || c == '1') {
			v = c - '0';
			break;
		}
	}
	if (val) {
		*val = v;
	}
	return 0;
}

Project: jasper

static int pnm_getint16(jas_stream_t *in, int *val)
{
	int v;
	int c;

	if ((c = jas_stream_getc(in)) == EOF) {
		return -1;
	}
	v = c & 0xff;
	if ((c = jas_stream_getc(in)) == EOF) {
		return -1;
	}
	v = (v << 8) | (c & 0xff);
	*val = v;

	return 0;
}