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

static void cmdinfo()
{
	fprintf(stderr, "Image Information Utility (Version %s).\n",
	  JAS_VERSION);
	fprintf(stderr,
	  "Copyright (c) 2001 Michael David Adams.\n"
	  "All rights reserved.\n"
	  );
}

Project: jasper

static void usage()
{
	cmdinfo();
	fprintf(stderr, "usage:\n");
	fprintf(stderr,"%s ", cmdname);
	fprintf(stderr, "[-f image_file]\n");
	exit(EXIT_FAILURE);
}

Project: jasper

void jas_deprecated(const char *s)
{
	static char message[] =
	"WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!!\n"
	"WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!!\n"
	"WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!!\n"
	"YOUR CODE IS RELYING ON DEPRECATED FUNCTIONALTIY IN THE JASPER LIBRARY.\n"
	"THIS FUNCTIONALITY WILL BE REMOVED IN THE NEAR FUTURE.\n"
	"PLEASE FIX THIS PROBLEM BEFORE YOUR CODE STOPS WORKING!\n"
	;
	jas_eprintf("%s", message);
	jas_eprintf("The specific problem is as follows:\n%s\n", s);
}

Project: jasper
File: jas_debug.c

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

Project: jasper
File: jas_debug.c

int jas_getdbglevel()
{
	return jas_dbglevel;
}

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper

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%08"PRIxFAST32"); attrtype=\"%s\"(0x%08"PRIxFAST32")\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");
	}
}

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper

static int jas_iccattrtab_resize(jas_iccattrtab_t *tab, int maxents)
{
	jas_iccattr_t *newattrs;
	assert(maxents >= tab->numattrs);
	newattrs = tab->attrs ? jas_realloc2(tab->attrs, maxents,
	  sizeof(jas_iccattr_t)) : jas_alloc2(maxents, sizeof(jas_iccattr_t));
	if (!newattrs) {
		return -1;
	}
	tab->attrs = newattrs;
	tab->maxattrs = maxents;
	return 0;
}

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

jas_iccattrval_t *jas_iccattrval_clone(jas_iccattrval_t *attrval)
{
	++attrval->refcnt;
	return attrval;
}

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper

void jas_iccattrval_dump(jas_iccattrval_t *attrval, FILE *out)
{
	char buf[8];
	jas_iccsigtostr(attrval->type, buf);
	fprintf(out, "refcnt = %d; type = 0x%08"PRIxFAST32" %s\n", attrval->refcnt,
	  attrval->type, jas_iccsigtostr(attrval->type, &buf[0]));
	if (attrval->ops->dump) {
		(*attrval->ops->dump)(attrval, out);
	}
}

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper

static void jas_icccurv_destroy(jas_iccattrval_t *attrval)
{
	jas_icccurv_t *curv = &attrval->data.curv;
	if (curv->ents) {
		jas_free(curv->ents);
		curv->ents = 0;
	}
}

Project: jasper

static void jas_icccurv_dump(jas_iccattrval_t *attrval, FILE *out)
{
	int i;
	jas_icccurv_t *curv = &attrval->data.curv;
	fprintf(out, "number of entries = %"PRIuFAST32"\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);
			}
		}
	}
}

Project: jasper

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

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper

static void jas_icclut16_destroy(jas_iccattrval_t *attrval)
{
	jas_icclut16_t *lut16 = &attrval->data.lut16;
	if (lut16->clut) {
		jas_free(lut16->clut);
		lut16->clut = 0;
	}
	if (lut16->intabs) {
		jas_free(lut16->intabs);
		lut16->intabs = 0;
	}
	if (lut16->intabsbuf) {
		jas_free(lut16->intabsbuf);
		lut16->intabsbuf = 0;
	}
	if (lut16->outtabs) {
		jas_free(lut16->outtabs);
		lut16->outtabs = 0;
	}
	if (lut16->outtabsbuf) {
		jas_free(lut16->outtabsbuf);
		lut16->outtabsbuf = 0;
	}
}

Project: jasper

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=%"PRIuFAST16", numouttabents=%"PRIuFAST16"\n",
	  lut16->numintabents, lut16->numouttabents);
}

Project: jasper
File: jas_icc.c

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

Project: jasper

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

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper

static void jas_icclut8_destroy(jas_iccattrval_t *attrval)
{
	jas_icclut8_t *lut8 = &attrval->data.lut8;
	if (lut8->clut) {
		jas_free(lut8->clut);
		lut8->clut = 0;
	}
	if (lut8->intabs) {
		jas_free(lut8->intabs);
		lut8->intabs = 0;
	}
	if (lut8->intabsbuf) {
		jas_free(lut8->intabsbuf);
		lut8->intabsbuf = 0;
	}
	if (lut8->outtabs) {
		jas_free(lut8->outtabs);
		lut8->outtabs = 0;
	}
	if (lut8->outtabsbuf) {
		jas_free(lut8->outtabsbuf);
		lut8->outtabsbuf = 0;
	}
}

Project: jasper

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=%"PRIuFAST16", numouttabents=%"PRIuFAST16"\n",
	  lut8->numintabents, lut8->numouttabents);
}

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

static long jas_iccpadtomult(long x, long y)
{
	return ((x + y - 1) / y) * y;
}

Project: jasper
File: jas_icc.c

static long jas_iccpowi(int x, int n)
{
	long y;
	y = 1;
	while (--n >= 0)
		y *= x;
	return y;
 }

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

void jas_iccprof_dump(jas_iccprof_t *prof, FILE *out)
{
	jas_iccattrtab_dump(prof->attrtab, out);
}

Project: jasper
File: jas_icc.c

int jas_iccprof_gethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr)
{
	*hdr = prof->hdr;
	return 0;
}

Project: jasper

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

Project: jasper

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;
	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);
				attrval = 0;
			} 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 (!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;
}

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper

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

Project: jasper
File: jas_icc.c

int jas_iccprof_sethdr(jas_iccprof_t *prof, jas_icchdr_t *hdr)
{
	prof->hdr = *hdr;
	return 0;
}

Project: jasper
File: jas_icc.c

static void jas_iccprof_sorttagtab(jas_icctagtab_t *tagtab)
{
	qsort(tagtab->ents, tagtab->numents, sizeof(jas_icctagtabent_t),
	  jas_icctagtabent_cmp);
}

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper

static void jas_icctxt_destroy(jas_iccattrval_t *attrval)
{
	jas_icctxt_t *txt = &attrval->data.txt;
	if (txt->string) {
		jas_free(txt->string);
		txt->string = 0;
	}
}

Project: jasper
File: jas_icc.c

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

Project: jasper

static int jas_icctxt_getsize(jas_iccattrval_t *attrval)
{
	jas_icctxt_t *txt = &attrval->data.txt;
	return JAS_CAST(int, strlen(txt->string) + 1);
}

Project: jasper

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:
	jas_icctxt_destroy(attrval);
	return -1;
}

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper

static void jas_icctxtdesc_destroy(jas_iccattrval_t *attrval)
{
	jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
	if (txtdesc->ascdata) {
		jas_free(txtdesc->ascdata);
		txtdesc->ascdata = 0;
	}
	if (txtdesc->ucdata) {
		jas_free(txtdesc->ucdata);
		txtdesc->ucdata = 0;
	}
}

Project: jasper

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 = %"PRIuFAST32"; uclen = %"PRIuFAST32"\n",
	  txtdesc->uclangcode, txtdesc->uclen);
	fprintf(out, "sccode = %"PRIuFAST16"\n", txtdesc->sccode);
	fprintf(out, "maclen = %d\n", txtdesc->maclen);
}

Project: jasper

static int jas_icctxtdesc_getsize(jas_iccattrval_t *attrval)
{
	jas_icctxtdesc_t *txtdesc = &attrval->data.txtdesc;
	return JAS_CAST(int, strlen(txtdesc->ascdata) + 1 + txtdesc->uclen * 2 +
	  15 + 67);
}

Project: jasper

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_alloc2(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 = JAS_CAST(jas_iccuint32_t, 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;
}

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

static int jas_iccxyz_getsize(jas_iccattrval_t *attrval)
{
	/* Avoid compiler warnings about unused parameters. */
	attrval = 0;

	return 12;
}

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_icc.c

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

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

static long downtomult(long x, long y)
{
	assert(x >= 0);
	return (x / y) * y;
}

Project: jasper
File: jas_image.c

static int getint(jas_stream_t *in, int sgnd, int prec, long *val)
{
	long v;
	int n;
	int c;
	assert((!sgnd && prec >= 1) || (sgnd && prec >= 2));
	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) {
		*val = decode_twos_comp(v, prec);
	} else {
		*val = v;
	}
	return 0;
}

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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

	outimage = 0;
	xform = 0;
	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);

	if (!(inprof = jas_image_cmprof(inimage))) {
		abort();
	}
	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;
	if (!(incmptfmts = jas_alloc2(numinclrchans, sizeof(jas_cmcmptfmt_t)))) {
		abort();
	}
	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 = jas_alloc2(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;
	if (!(outcmptfmts = jas_alloc2(numoutclrchans, sizeof(jas_cmcmptfmt_t)))) {
		abort();
	}
	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 = jas_alloc2(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:
	if (xform)
		jas_cmxform_destroy(xform);
	if (inimage)
		jas_image_destroy(inimage);
	if (outimage)
		jas_image_destroy(outimage);
	return 0;
}

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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))) {
		goto error;
	}
	if (jas_stream_seek(cmpt->stream_, 0, SEEK_SET)) {
		goto error;
	}
	if (jas_stream_copy(newcmpt->stream_, cmpt->stream_, -1)) {
		goto error;
	}
	if (jas_stream_seek(newcmpt->stream_, 0, SEEK_SET)) {
		goto error;
	}
	return newcmpt;
error:
	if (newcmpt) {
		jas_image_cmpt_destroy(newcmpt);
	}
	return 0;
}

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt)
{
	if (cmpt->stream_) {
		jas_stream_close(cmpt->stream_);
	}
	jas_free(cmpt);
}

Project: jasper
File: jas_image.c

bool jas_image_cmpt_domains_same(jas_image_t *image)
{
	int cmptno;
	jas_image_cmpt_t *cmpt;
	jas_image_cmpt_t *cmpt0;

	cmpt0 = image->cmpts_[0];
	for (cmptno = 1; cmptno < image->numcmpts_; ++cmptno) {
		cmpt = image->cmpts_[cmptno];
		if (cmpt->tlx_ != cmpt0->tlx_ || cmpt->tly_ != cmpt0->tly_ ||
		  cmpt->hstep_ != cmpt0->hstep_ || cmpt->vstep_ != cmpt0->vstep_ ||
		  cmpt->width_ != cmpt0->width_ || cmpt->height_ != cmpt0->height_) {
			return 0;
		}
	}
	return 1;
}

Project: jasper
File: jas_image.c

jas_image_t *jas_image_copy(jas_image_t *image)
{
	jas_image_t *newimage;
	int cmptno;

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

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

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

void jas_image_destroy(jas_image_t *image)
{
	int i;

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

Project: jasper
File: jas_image.c

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=%"PRIiFAST32"\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");
	}
}

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

char *jas_image_fmttostr(int fmt)
{
	jas_image_fmtinfo_t *fmtinfo;
	if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) {
		return 0;
	}
	return fmtinfo->name;
}

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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? */
			JAS_DBGLOG(20, ("testing for format %s ... ", fmtinfo->name));
			if (!(*fmtinfo->ops.validate)(in)) {
				JAS_DBGLOG(20, ("test succeeded\n"));
				found = 1;
				break;
			}
			JAS_DBGLOG(20, ("test failed\n"));
		}
	}
	return found ? fmtinfo->id : (-1);
}

Project: jasper
File: jas_image.c

static int jas_image_growcmpts(jas_image_t *image, int maxcmpts)
{
	jas_image_cmpt_t **newcmpts;
	int cmptno;

	newcmpts = (!image->cmpts_) ? jas_alloc2(maxcmpts,
	  sizeof(jas_image_cmpt_t *)) :
	  jas_realloc2(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;
}

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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

Project: jasper

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;

	JAS_DBGLOG(10, ("jas_image_readcmpt(%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) {
		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;
}

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

int jas_image_strtofmt(char *name)
{
	jas_image_fmtinfo_t *fmtinfo;
	if (!(fmtinfo = jas_image_lookupfmtbyname(name))) {
		return -1;
	}
	return fmtinfo->id;
}

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_image.c

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

Project: jasper
File: jas_stream.c

static int file_read(jas_stream_obj_t *obj, char *buf, int cnt)
{
	jas_stream_fileobj_t *fileobj;
	JAS_DBGLOG(100, ("file_read(%p, %p, %d)\n", obj, buf, cnt));
	fileobj = JAS_CAST(jas_stream_fileobj_t *, obj);
	return read(fileobj->fd, buf, cnt);
}

Project: jasper
File: jas_stream.c

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

Project: jasper
File: jas_stream.c

static long sfile_seek(jas_stream_obj_t *obj, long offset, int origin)
{
	FILE *fp;
	JAS_DBGLOG(100, ("sfile_seek(%p, %ld, %d)\n", obj, offset, origin));
	fp = JAS_CAST(FILE *, obj);
	return fseek(fp, offset, origin);
}

Project: jasper

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

Project: jasper

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

Project: jasper

double jas_tmr_get(jas_tmr_t *tmr)
{
	return 0.0;
}

Project: jasper

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

Project: jasper

 void jas_tmr_start(jas_tmr_t *tmr)
 {
	if (getrusage(RUSAGE_SELF, &tmr->start) < 0) {
		abort();
	}
}

Project: jasper

void jas_tmr_start(jas_tmr_t *tmr)
{
}

Project: jasper

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

Project: jasper

void jas_tmr_stop(jas_tmr_t *tmr)
{
}

Project: jasper
File: bmp_dec.c

static int bmp_getdata(jas_stream_t *in, bmp_info_t *info, jas_image_t *image)
{
	int i;
	int j;
	int y;
	jas_matrix_t *cmpts[3];
	int numpad;
	int red;
	int grn;
	int blu;
	int ret;
	int numcmpts;
	int cmptno;
	int ind;
	bmp_palent_t *palent;
	int mxind;
	int haspal;

	assert(info->depth == 8 || info->depth == 24);
	assert(info->enctype == BMP_ENC_RGB);

	numcmpts = bmp_numcmpts(info);
	haspal = bmp_haspal(info);

	ret = 0;
	for (i = 0; i < numcmpts; ++i) {
		cmpts[i] = 0;
	}

	/* Create temporary matrices to hold component data. */
	for (i = 0; i < numcmpts; ++i) {
		if (!(cmpts[i] = jas_matrix_create(1, info->width))) {
			ret = -1;
			goto bmp_getdata_done;
		}
	}

	/* Calculate number of padding bytes per row of image data. */
	numpad = (numcmpts * info->width) % 4;
	if (numpad) {
		numpad = 4 - numpad;
	}

	mxind = (1 << info->depth) - 1;
	for (i = 0; i < info->height; ++i) {
		for (j = 0; j < info->width; ++j) {
			if (haspal) {
				if ((ind = jas_stream_getc(in)) == EOF) {
					ret = -1;
					goto bmp_getdata_done;
				}
				if (ind > mxind) {
					ret = -1;
					goto bmp_getdata_done;
				}
				if (ind < info->numcolors) {
					palent = &info->palents[ind];
					red = palent->red;
					grn = palent->grn;
					blu = palent->blu;
				} else {
					red = ind;
					grn = ind;
					blu = ind;
				}
			} else {
				if ((blu = jas_stream_getc(in)) == EOF ||
				  (grn = jas_stream_getc(in)) == EOF ||
				  (red = jas_stream_getc(in)) == EOF) {
					ret = -1;
					goto bmp_getdata_done;
				}
			}
			if (numcmpts == 3) {
				jas_matrix_setv(cmpts[0], j, red);
				jas_matrix_setv(cmpts[1], j, grn);
				jas_matrix_setv(cmpts[2], j, blu);
			} else {
				jas_matrix_setv(cmpts[0], j, red);
			}
		}
		for (j = numpad; j > 0; --j) {
				if (jas_stream_getc(in) == EOF) {
					ret = -1;
					goto bmp_getdata_done;
				}
		}
		for (cmptno = 0; cmptno < numcmpts; ++cmptno) {
			y = info->topdown ? i : (info->height - 1 - i);
			if (jas_image_writecmpt(image, cmptno, 0, y, info->width,
			  1, cmpts[cmptno])) {
				ret = -1;
				goto bmp_getdata_done;
			}
		}
	}

bmp_getdata_done:
	/* Destroy the temporary matrices. */
	for (i = 0; i < numcmpts; ++i) {
		if (cmpts[i]) {
			jas_matrix_destroy(cmpts[i]);
		}
	}

	return ret;
}

Project: jasper
File: bmp_dec.c

static int bmp_gethdr(jas_stream_t *in, bmp_hdr_t *hdr)
{
	if (bmp_getint16(in, &hdr->magic) || hdr->magic != BMP_MAGIC ||
	  bmp_getint32(in, &hdr->siz) || bmp_getint16(in, &hdr->reserved1) ||
	  bmp_getint16(in, &hdr->reserved2) || bmp_getint32(in, &hdr->off)) {
		return -1;
	}
	return 0;
}

Project: jasper
File: bmp_dec.c

static bmp_info_t *bmp_getinfo(jas_stream_t *in)
{
	bmp_info_t *info;
	int i;
	bmp_palent_t *palent;

	if (!(info = bmp_info_create())) {
		return 0;
	}

	if (bmp_getint32(in, &info->len) || info->len != 40 ||
	  bmp_getint32(in, &info->width) || bmp_getint32(in, &info->height) ||
	  bmp_getint16(in, &info->numplanes) ||
	  bmp_getint16(in, &info->depth) || bmp_getint32(in, &info->enctype) ||
	  bmp_getint32(in, &info->siz) ||
	  bmp_getint32(in, &info->hres) || bmp_getint32(in, &info->vres) ||
	  bmp_getint32(in, &info->numcolors) ||
	  bmp_getint32(in, &info->mincolors)) {
		bmp_info_destroy(info);
		return 0;
	}

	if (info->height < 0) {
		info->topdown = 1;
		info->height = -info->height;
	} else {
		info->topdown = 0;
	}

	if (info->width <= 0 || info->height <= 0 || info->numplanes <= 0 ||
	  info->depth <= 0  || info->numcolors < 0 || info->mincolors < 0) {
		bmp_info_destroy(info);
		return 0;
	}

	if (info->enctype != BMP_ENC_RGB) {
		jas_eprintf("unsupported BMP encoding\n");
		bmp_info_destroy(info);
		return 0;
	}

	if (info->numcolors > 0) {
		if (!(info->palents = jas_alloc2(info->numcolors,
		  sizeof(bmp_palent_t)))) {
			bmp_info_destroy(info);
			return 0;
		}
	} else {
		info->palents = 0;
	}

	for (i = 0; i < info->numcolors; ++i) {
		palent = &info->palents[i];
		if ((palent->blu = jas_stream_getc(in)) == EOF ||
		  (palent->grn = jas_stream_getc(in)) == EOF ||
		  (palent->red = jas_stream_getc(in)) == EOF ||
		  (palent->res = jas_stream_getc(in)) == EOF) {
			bmp_info_destroy(info);
			return 0;
		}
	}

	return info;
}

Project: jasper
File: bmp_dec.c

static int bmp_getint16(jas_stream_t *in, int_fast16_t *val)
{
	int lo;
	int hi;
	if ((lo = jas_stream_getc(in)) == EOF || (hi = jas_stream_getc(in)) == EOF) {
		return -1;
	}
	if (val) {
		*val = (hi << 8) | lo;
	}
	return 0;
}

Project: jasper
File: bmp_dec.c

static int bmp_getint32(jas_stream_t *in, int_fast32_t *val)
{
	int n;
	uint_fast32_t v;
	int c;
	for (n = 4, v = 0;;) {
		if ((c = jas_stream_getc(in)) == EOF) {
			return -1;
		}
		v |= (JAS_CAST(uint_fast32_t, c) << 24);
		if (--n <= 0) {
			break;
		}
		v >>= 8;
	}
	if (val) {
		*val = v;
	}
	return 0;
}

Project: jasper
File: bmp_dec.c

static int bmp_gobble(jas_stream_t *in, long n)
{
	while (--n >= 0) {
		if (jas_stream_getc(in) == EOF) {
			return -1;
		}
	}
	return 0;
}

Project: jasper
File: jp2_dec.c

static int fromiccpcs(int cs)
{
	switch (cs) {
	case ICC_CS_RGB:
		return JAS_CLRSPC_GENRGB;
		break;
	case ICC_CS_YCBCR:
		return JAS_CLRSPC_GENYCBCR;
		break;
	case ICC_CS_GRAY:
		return JAS_CLRSPC_GENGRAY;
		break;
	}
	return JAS_CLRSPC_UNKNOWN;
}

Project: jasper
File: jp2_dec.c

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

Project: jasper
File: jp2_dec.c

static void jp2_dec_destroy(jp2_dec_t *dec)
{
	if (dec->ihdr) {
		jp2_box_destroy(dec->ihdr);
	}
	if (dec->bpcc) {
		jp2_box_destroy(dec->bpcc);
	}
	if (dec->cdef) {
		jp2_box_destroy(dec->cdef);
	}
	if (dec->pclr) {
		jp2_box_destroy(dec->pclr);
	}
	if (dec->image) {
		jas_image_destroy(dec->image);
	}
	if (dec->cmap) {
		jp2_box_destroy(dec->cmap);
	}
	if (dec->colr) {
		jp2_box_destroy(dec->colr);
	}
	if (dec->chantocmptlut) {
		jas_free(dec->chantocmptlut);
	}
	jas_free(dec);
}

Project: jasper
File: jp2_dec.c

static int jp2_getcs(jp2_colr_t *colr)
{
	if (colr->method == JP2_COLR_ENUM) {
		switch (colr->csid) {
		case JP2_COLR_SRGB:
			return JAS_CLRSPC_SRGB;
			break;
		case JP2_COLR_SYCC:
			return JAS_CLRSPC_SYCBCR;
			break;
		case JP2_COLR_SGRAY:
			return JAS_CLRSPC_SGRAY;
			break;
		}
	}
	return JAS_CLRSPC_UNKNOWN;
}

Project: jasper
File: jp2_dec.c

static int jp2_getct(int colorspace, int type, int assoc)
{
	if (type == 1 && assoc == 0) {
		return JAS_IMAGE_CT_OPACITY;
	}
	if (type == 0 && assoc >= 1 && assoc <= 65534) {
		switch (colorspace) {
		case JAS_CLRSPC_FAM_RGB:
			switch (assoc) {
			case JP2_CDEF_RGB_R:
				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R);
				break;
			case JP2_CDEF_RGB_G:
				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G);
				break;
			case JP2_CDEF_RGB_B:
				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B);
				break;
			}
			break;
		case JAS_CLRSPC_FAM_YCBCR:
			switch (assoc) {
			case JP2_CDEF_YCBCR_Y:
				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_Y);
				break;
			case JP2_CDEF_YCBCR_CB:
				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CB);
				break;
			case JP2_CDEF_YCBCR_CR:
				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_YCBCR_CR);
				break;
			}
			break;
		case JAS_CLRSPC_FAM_GRAY:
			switch (assoc) {
			case JP2_CDEF_GRAY_Y:
				return JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y);
				break;
			}
			break;
		default:
			return JAS_IMAGE_CT_COLOR(assoc - 1);
			break;
		}
	}
	return JAS_IMAGE_CT_UNKNOWN;
}

Project: jasper
File: jpc_cs.c

static void jpc_coc_destroyparms(jpc_ms_t *ms)
{
	jpc_coc_t *coc = &ms->parms.coc;
	jpc_cox_destroycompparms(&coc->compparms);
}

Project: jasper
File: jpc_cs.c

static int jpc_coc_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_coc_t *coc = &ms->parms.coc;
	fprintf(out, "compno = %"PRIuFAST16"; csty = 0x%02x; numdlvls = %d;\n",
	  coc->compno, coc->compparms.csty, coc->compparms.numdlvls);
	fprintf(out, "cblkwidthval = %d; cblkheightval = %d; "
	  "cblksty = 0x%02x; qmfbid = %d;\n", coc->compparms.cblkwidthval,
	  coc->compparms.cblkheightval, coc->compparms.cblksty, coc->compparms.qmfbid);
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_coc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_coc_t *coc = &ms->parms.coc;
	uint_fast8_t tmp;
	if (cstate->numcomps <= 256) {
		if (jpc_getuint8(in, &tmp)) {
			return -1;
		}
		coc->compno = tmp;
	} else {
		if (jpc_getuint16(in, &coc->compno)) {
			return -1;
		}
	}
	if (jpc_getuint8(in, &coc->compparms.csty)) {
		return -1;
	}
	if (jpc_cox_getcompparms(ms, cstate, in,
	  (coc->compparms.csty & JPC_COX_PRT) != 0, &coc->compparms)) {
		return -1;
	}
	if (jas_stream_eof(in)) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_coc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
{
	jpc_coc_t *coc = &ms->parms.coc;
	assert(coc->compparms.numdlvls <= 32);
	if (cstate->numcomps <= 256) {
		if (jpc_putuint8(out, coc->compno)) {
			return -1;
		}
	} else {
		if (jpc_putuint16(out, coc->compno)) {
			return -1;
		}
	}
	if (jpc_putuint8(out, coc->compparms.csty)) {
		return -1;
	}
	if (jpc_cox_putcompparms(ms, cstate, out,
	  (coc->compparms.csty & JPC_COX_PRT) != 0, &coc->compparms)) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static void jpc_cod_destroyparms(jpc_ms_t *ms)
{
	jpc_cod_t *cod = &ms->parms.cod;
	jpc_cox_destroycompparms(&cod->compparms);
}

Project: jasper
File: jpc_cs.c

static int jpc_cod_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_cod_t *cod = &ms->parms.cod;
	int i;
	fprintf(out, "csty = 0x%02x;\n", cod->compparms.csty);
	fprintf(out, "numdlvls = %d; qmfbid = %d; mctrans = %d\n",
	  cod->compparms.numdlvls, cod->compparms.qmfbid, cod->mctrans);
	fprintf(out, "prg = %d; numlyrs = %"PRIuFAST16";\n",
	  cod->prg, cod->numlyrs);
	fprintf(out, "cblkwidthval = %d; cblkheightval = %d; "
	  "cblksty = 0x%02x;\n", cod->compparms.cblkwidthval, cod->compparms.cblkheightval,
	  cod->compparms.cblksty);
	if (cod->csty & JPC_COX_PRT) {
		for (i = 0; i < cod->compparms.numrlvls; ++i) {
			jas_eprintf("prcwidth[%d] = %d, prcheight[%d] = %d\n",
			  i, cod->compparms.rlvls[i].parwidthval,
			  i, cod->compparms.rlvls[i].parheightval);
		}
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_cod_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_cod_t *cod = &ms->parms.cod;
	if (jpc_getuint8(in, &cod->csty)) {
		return -1;
	}
	if (jpc_getuint8(in, &cod->prg) ||
	  jpc_getuint16(in, &cod->numlyrs) ||
	  jpc_getuint8(in, &cod->mctrans)) {
		return -1;
	}
	if (cod->numlyrs < 1 || cod->numlyrs > 65535) {
		return -1;
	}
	if (jpc_cox_getcompparms(ms, cstate, in,
	  (cod->csty & JPC_COX_PRT) != 0, &cod->compparms)) {
		return -1;
	}
	if (jas_stream_eof(in)) {
		jpc_cod_destroyparms(ms);
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static void jpc_com_destroyparms(jpc_ms_t *ms)
{
	jpc_com_t *com = &ms->parms.com;
	if (com->data) {
		jas_free(com->data);
	}
}

Project: jasper
File: jpc_cs.c

static int jpc_com_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_com_t *com = &ms->parms.com;
	unsigned int i;
	int printable;
	fprintf(out, "regid = %"PRIuFAST16";\n", com->regid);
	printable = 1;
	for (i = 0; i < com->len; ++i) {
		if (!isprint(com->data[i])) {
			printable = 0;
			break;
		}
	}
	if (printable) {
		fprintf(out, "data = ");
		fwrite(com->data, sizeof(char), com->len, out);
		fprintf(out, "\n");
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_com_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_com_t *com = &ms->parms.com;

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

	if (jpc_getuint16(in, &com->regid)) {
		return -1;
	}
	com->len = ms->len - 2;
	if (com->len > 0) {
		if (!(com->data = jas_malloc(com->len))) {
			return -1;
		}
		if (jas_stream_read(in, com->data, com->len) != JAS_CAST(int, com->len)) {
			return -1;
		}
	} else {
		com->data = 0;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_com_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
{
	jpc_com_t *com = &ms->parms.com;

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

	if (jpc_putuint16(out, com->regid)) {
		return -1;
	}
	if (jas_stream_write(out, com->data, com->len) != JAS_CAST(int, com->len)) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static void jpc_cox_destroycompparms(jpc_coxcp_t *compparms)
{
	/* Eliminate compiler warning about unused variables. */
	compparms = 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_cox_getcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate,
  jas_stream_t *in, int prtflag, jpc_coxcp_t *compparms)
{
	uint_fast8_t tmp;
	int i;

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

	if (jpc_getuint8(in, &compparms->numdlvls) ||
	  jpc_getuint8(in, &compparms->cblkwidthval) ||
	  jpc_getuint8(in, &compparms->cblkheightval) ||
	  jpc_getuint8(in, &compparms->cblksty) ||
	  jpc_getuint8(in, &compparms->qmfbid)) {
		return -1;
	}
	if (compparms->numdlvls > 32) {
		goto error;
	}
	compparms->numrlvls = compparms->numdlvls + 1;
	if (compparms->numrlvls > JPC_MAXRLVLS) {
		goto error;
	}
	if (prtflag) {
		for (i = 0; i < compparms->numrlvls; ++i) {
			if (jpc_getuint8(in, &tmp)) {
				goto error;
			}
			compparms->rlvls[i].parwidthval = tmp & 0xf;
			compparms->rlvls[i].parheightval = (tmp >> 4) & 0xf;
		}
		/* Sigh.
		This bit should be in the same field in both COC and COD mrk segs. */
		compparms->csty |= JPC_COX_PRT;
	}
	if (jas_stream_eof(in)) {
		goto error;
	}
	return 0;
error:
	if (compparms) {
		jpc_cox_destroycompparms(compparms);
	}
	return -1;
}

Project: jasper
File: jpc_cs.c

static int jpc_cox_putcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate,
  jas_stream_t *out, int prtflag, jpc_coxcp_t *compparms)
{
	int i;
	assert(compparms->numdlvls <= 32);

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

	if (jpc_putuint8(out, compparms->numdlvls) ||
	  jpc_putuint8(out, compparms->cblkwidthval) ||
	  jpc_putuint8(out, compparms->cblkheightval) ||
	  jpc_putuint8(out, compparms->cblksty) ||
	  jpc_putuint8(out, compparms->qmfbid)) {
		return -1;
	}
	if (prtflag) {
		for (i = 0; i < compparms->numrlvls; ++i) {
			if (jpc_putuint8(out,
			  ((compparms->rlvls[i].parheightval & 0xf) << 4) |
			  (compparms->rlvls[i].parwidthval & 0xf))) {
				return -1;
			}
		}
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static void jpc_crg_destroyparms(jpc_ms_t *ms)
{
	jpc_crg_t *crg = &ms->parms.crg;
	if (crg->comps) {
		jas_free(crg->comps);
	}
}

Project: jasper
File: jpc_cs.c

static int jpc_crg_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_crg_t *crg = &ms->parms.crg;
	int compno;
	jpc_crgcomp_t *comp;
	for (compno = 0, comp = crg->comps; compno < crg->numcomps; ++compno,
	  ++comp) {
		fprintf(out, "hoff[%d] = %"PRIuFAST16"; voff[%d] = %"PRIuFAST16"\n",
		  compno, comp->hoff, compno, comp->voff);
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_crg_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_crg_t *crg = &ms->parms.crg;
	jpc_crgcomp_t *comp;
	uint_fast16_t compno;
	crg->numcomps = cstate->numcomps;
	if (!(crg->comps = jas_alloc2(cstate->numcomps, sizeof(jpc_crgcomp_t)))) {
		return -1;
	}
	for (compno = 0, comp = crg->comps; compno < cstate->numcomps;
	  ++compno, ++comp) {
		if (jpc_getuint16(in, &comp->hoff) ||
		  jpc_getuint16(in, &comp->voff)) {
			jpc_crg_destroyparms(ms);
			return -1;
		}
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_crg_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
{
	jpc_crg_t *crg = &ms->parms.crg;
	int compno;
	jpc_crgcomp_t *comp;

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

	for (compno = 0, comp = crg->comps; compno < crg->numcomps; ++compno,
	  ++comp) {
		if (jpc_putuint16(out, comp->hoff) ||
		  jpc_putuint16(out, comp->voff)) {
			return -1;
		}
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

jpc_cstate_t *jpc_cstate_create()
{
	jpc_cstate_t *cstate;
	if (!(cstate = jas_malloc(sizeof(jpc_cstate_t)))) {
		return 0;
	}
	cstate->numcomps = 0;
	return cstate;
}

Project: jasper
File: jpc_cs.c

void jpc_cstate_destroy(jpc_cstate_t *cstate)
{
	jas_free(cstate);
}

Project: jasper
File: jpc_cs.c

int jpc_getdata(jas_stream_t *in, jas_stream_t *out, long len)
{
	return jas_stream_copy(out, in, len);
}

Project: jasper
File: jpc_cs.c

int jpc_getuint16(jas_stream_t *in, uint_fast16_t *val)
{
	uint_fast16_t v;
	int c;
	if ((c = jas_stream_getc(in)) == EOF) {
		return -1;
	}
	v = c;
	if ((c = jas_stream_getc(in)) == EOF) {
		return -1;
	}
	v = (v << 8) | c;
	if (val) {
		*val = v;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

int jpc_getuint8(jas_stream_t *in, uint_fast8_t *val)
{
	int c;
	if ((c = jas_stream_getc(in)) == EOF) {
		return -1;
	}
	if (val) {
		*val = c;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

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

Project: jasper
File: jpc_cs.c

void jpc_ms_destroy(jpc_ms_t *ms)
{
	if (ms->ops && ms->ops->destroyparms) {
		(*ms->ops->destroyparms)(ms);
	}
	jas_free(ms);
}

Project: jasper
File: jpc_cs.c

void jpc_ms_dump(jpc_ms_t *ms, FILE *out)
{
	jpc_mstabent_t *mstabent;
	mstabent = jpc_mstab_lookup(ms->id);
	fprintf(out, "type = 0x%04"PRIxFAST16" (%s);", ms->id, mstabent->name);
	if (JPC_MS_HASPARMS(ms->id)) {
		fprintf(out, " len = %"PRIuFAST16";", ms->len + 2);
		if (ms->ops->dumpparms) {
			(*ms->ops->dumpparms)(ms, out);
		} else {
			fprintf(out, "\n");
		}
	} else {
		fprintf(out, "\n");
	}
}

Project: jasper
File: jpc_cs.c

static jpc_mstabent_t *jpc_mstab_lookup(int id)
{
	jpc_mstabent_t *mstabent;
	for (mstabent = jpc_mstab;; ++mstabent) {
		if (mstabent->id == id || mstabent->id < 0) {
			return mstabent;
		}
	}
	assert(0);
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_poc_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_poc_t *poc = &ms->parms.poc;
	jpc_pocpchg_t *pchg;
	int pchgno;
	for (pchgno = 0, pchg = poc->pchgs; pchgno < poc->numpchgs;
	  ++pchgno, ++pchg) {
		fprintf(out, "po[%d] = %d; ", pchgno, pchg->prgord);
		fprintf(out, "cs[%d] = %"PRIuFAST16"; ce[%d] = %"PRIuFAST16"; ",
		  pchgno, pchg->compnostart, pchgno, pchg->compnoend);
		fprintf(out, "rs[%d] = %d; re[%d] = %d; ",
		  pchgno, pchg->rlvlnostart, pchgno, pchg->rlvlnoend);
		fprintf(out, "le[%d] = %"PRIuFAST16"\n", pchgno, pchg->lyrnoend);
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_poc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_poc_t *poc = &ms->parms.poc;
	jpc_pocpchg_t *pchg;
	int pchgno;
	uint_fast8_t tmp;
	poc->numpchgs = (cstate->numcomps > 256) ? (ms->len / 9) :
	  (ms->len / 7);
	if (!(poc->pchgs = jas_alloc2(poc->numpchgs, sizeof(jpc_pocpchg_t)))) {
		goto error;
	}
	for (pchgno = 0, pchg = poc->pchgs; pchgno < poc->numpchgs; ++pchgno,
	  ++pchg) {
		if (jpc_getuint8(in, &pchg->rlvlnostart)) {
			goto error;
		}
		if (cstate->numcomps > 256) {
			if (jpc_getuint16(in, &pchg->compnostart)) {
				goto error;
			}
		} else {
			if (jpc_getuint8(in, &tmp)) {
				goto error;
			};
			pchg->compnostart = tmp;
		}
		if (jpc_getuint16(in, &pchg->lyrnoend) ||
		  jpc_getuint8(in, &pchg->rlvlnoend)) {
			goto error;
		}
		if (cstate->numcomps > 256) {
			if (jpc_getuint16(in, &pchg->compnoend)) {
				goto error;
			}
		} else {
			if (jpc_getuint8(in, &tmp)) {
				goto error;
			}
			pchg->compnoend = tmp;
		}
		if (jpc_getuint8(in, &pchg->prgord)) {
			goto error;
		}
		if (pchg->rlvlnostart > pchg->rlvlnoend ||
		  pchg->compnostart > pchg->compnoend) {
			goto error;
		}
	}
	return 0;

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

Project: jasper
File: jpc_cs.c

static int jpc_poc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
{
	jpc_poc_t *poc = &ms->parms.poc;
	jpc_pocpchg_t *pchg;
	int pchgno;
	for (pchgno = 0, pchg = poc->pchgs; pchgno < poc->numpchgs; ++pchgno,
	  ++pchg) {
		if (jpc_putuint8(out, pchg->rlvlnostart) ||
		  ((cstate->numcomps > 256) ?
		  jpc_putuint16(out, pchg->compnostart) :
		  jpc_putuint8(out, pchg->compnostart)) ||
		  jpc_putuint16(out, pchg->lyrnoend) ||
		  jpc_putuint8(out, pchg->rlvlnoend) ||
		  ((cstate->numcomps > 256) ?
		  jpc_putuint16(out, pchg->compnoend) :
		  jpc_putuint8(out, pchg->compnoend)) ||
		  jpc_putuint8(out, pchg->prgord)) {
			return -1;
		}
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static void jpc_ppm_destroyparms(jpc_ms_t *ms)
{
	jpc_ppm_t *ppm = &ms->parms.ppm;
	if (ppm->data) {
		jas_free(ppm->data);
	}
}

Project: jasper
File: jpc_cs.c

static int jpc_ppm_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_ppm_t *ppm = &ms->parms.ppm;
	fprintf(out, "ind=%d; len = %"PRIuFAST16";\n", ppm->ind, ppm->len);
	if (ppm->len > 0) {
		fprintf(out, "data =\n");
		jas_memdump(out, ppm->data, ppm->len);
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_ppt_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_ppt_t *ppt = &ms->parms.ppt;
	fprintf(out, "ind=%d; len = %"PRIuFAST32";\n", ppt->ind, ppt->len);
	if (ppt->len > 0) {
		fprintf(out, "data =\n");
		jas_memdump(out, ppt->data, ppt->len);
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

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

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

	if (jpc_putuint8(out, ppt->ind)) {
		return -1;
	}
	if (jas_stream_write(out, (char *) ppt->data, ppt->len) != JAS_CAST(int, ppt->len)) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

int jpc_putdata(jas_stream_t *out, jas_stream_t *in, long len)
{
	return jas_stream_copy(out, in, len);
}

Project: jasper
File: jpc_cs.c

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

Project: jasper
File: jpc_cs.c

int jpc_putuint16(jas_stream_t *out, uint_fast16_t val)
{
	if (jas_stream_putc(out, (val >> 8) & 0xff) == EOF ||
	  jas_stream_putc(out, val & 0xff) == EOF) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

int jpc_putuint32(jas_stream_t *out, uint_fast32_t val)
{
	if (jas_stream_putc(out, (val >> 24) & 0xff) == EOF ||
	  jas_stream_putc(out, (val >> 16) & 0xff) == EOF ||
	  jas_stream_putc(out, (val >> 8) & 0xff) == EOF ||
	  jas_stream_putc(out, val & 0xff) == EOF) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

int jpc_putuint8(jas_stream_t *out, uint_fast8_t val)
{
	if (jas_stream_putc(out, val & 0xff) == EOF) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static void jpc_qcc_destroyparms(jpc_ms_t *ms)
{
	jpc_qcc_t *qcc = &ms->parms.qcc;
	jpc_qcx_destroycompparms(&qcc->compparms);
}

Project: jasper
File: jpc_cs.c

static int jpc_qcc_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_qcc_t *qcc = &ms->parms.qcc;
	int i;
	fprintf(out, "compno = %"PRIuFAST16"; qntsty = %d; numguard = %d; "
	  "numstepsizes = %d\n", qcc->compno, qcc->compparms.qntsty, qcc->compparms.numguard,
	  qcc->compparms.numstepsizes);
	for (i = 0; i < qcc->compparms.numstepsizes; ++i) {
		fprintf(out, "expn[%d] = 0x%04x; mant[%d] = 0x%04x;\n",
		  i, (unsigned) JPC_QCX_GETEXPN(qcc->compparms.stepsizes[i]),
		  i, (unsigned) JPC_QCX_GETMANT(qcc->compparms.stepsizes[i]));
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_qcc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_qcc_t *qcc = &ms->parms.qcc;
	uint_fast8_t tmp;
	int len;
	len = ms->len;
	if (cstate->numcomps <= 256) {
		if (jpc_getuint8(in, &tmp)) {
			return -1;
		}
		qcc->compno = tmp;
		--len;
	} else {
		if (jpc_getuint16(in, &qcc->compno)) {
			return -1;
		}
		len -= 2;
	}
	if (jpc_qcx_getcompparms(&qcc->compparms, cstate, in, len)) {
		return -1;
	}
	if (jas_stream_eof(in)) {
		jpc_qcc_destroyparms(ms);
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_qcc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
{
	jpc_qcc_t *qcc = &ms->parms.qcc;
	if (cstate->numcomps <= 256) {
		if (jpc_putuint8(out, qcc->compno)) {
			return -1;
		}
	} else {
		if (jpc_putuint16(out, qcc->compno)) {
			return -1;
		}
	}
	if (jpc_qcx_putcompparms(&qcc->compparms, cstate, out)) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_qcd_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_qcxcp_t *compparms = &ms->parms.qcd.compparms;
	return jpc_qcx_getcompparms(compparms, cstate, in, ms->len);
}

Project: jasper
File: jpc_cs.c

static void jpc_qcx_destroycompparms(jpc_qcxcp_t *compparms)
{
	if (compparms->stepsizes) {
		jas_free(compparms->stepsizes);
	}
}

Project: jasper
File: jpc_cs.c

static int jpc_rgn_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_rgn_t *rgn = &ms->parms.rgn;
	uint_fast8_t tmp;
	if (cstate->numcomps <= 256) {
		if (jpc_getuint8(in, &tmp)) {
			return -1;
		}
		rgn->compno = tmp;
	} else {
		if (jpc_getuint16(in, &rgn->compno)) {
			return -1;
		}
	}
	if (jpc_getuint8(in, &rgn->roisty) ||
	  jpc_getuint8(in, &rgn->roishift)) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_rgn_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
{
	jpc_rgn_t *rgn = &ms->parms.rgn;
	if (cstate->numcomps <= 256) {
		if (jpc_putuint8(out, rgn->compno)) {
			return -1;
		}
	} else {
		if (jpc_putuint16(out, rgn->compno)) {
			return -1;
		}
	}
	if (jpc_putuint8(out, rgn->roisty) ||
	  jpc_putuint8(out, rgn->roishift)) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static void jpc_siz_destroyparms(jpc_ms_t *ms)
{
	jpc_siz_t *siz = &ms->parms.siz;
	if (siz->comps) {
		jas_free(siz->comps);
	}
}

Project: jasper
File: jpc_cs.c

static int jpc_siz_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_siz_t *siz = &ms->parms.siz;
	unsigned int i;
	fprintf(out, "caps = 0x%02"PRIxFAST16";\n", siz->caps);
	fprintf(out, "width = %"PRIuFAST32"; height = %"PRIuFAST32"; xoff = %"PRIuFAST32"; yoff = %" PRIuFAST32 ";\n",
	  siz->width, siz->height, siz->xoff, siz->yoff);
	fprintf(out, "tilewidth = %"PRIuFAST32"; tileheight = %"PRIuFAST32"; "
	  "tilexoff = %"PRIuFAST32"; tileyoff = %" PRIuFAST32 ";\n",
	  siz->tilewidth, siz->tileheight, siz->tilexoff, siz->tileyoff);
	fprintf(out, "numcomps = %"PRIuFAST16";\n", siz->numcomps);
	for (i = 0; i < siz->numcomps; ++i) {
		fprintf(out, "prec[%d] = %d; sgnd[%d] = %d; hsamp[%d] = %d; "
		  "vsamp[%d] = %d\n", i, siz->comps[i].prec, i,
		  siz->comps[i].sgnd, i, siz->comps[i].hsamp, i,
		  siz->comps[i].vsamp);
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

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;

	siz->comps = 0;

	/* 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)) {
		goto error;
	}
	if (!siz->width || !siz->height) {
		jas_eprintf("reference grid cannot have zero area\n");
		goto error;
	}
	if (!siz->tilewidth || !siz->tileheight) {
		jas_eprintf("tile cannot have zero area\n");
		goto error;
	}
	if (!siz->numcomps || siz->numcomps > 16384) {
		jas_eprintf("number of components not in permissible range\n");
		goto error;
	}
	if (siz->xoff >= siz->width) {
		jas_eprintf("XOsiz not in permissible range\n");
		goto error;
	}
	if (siz->yoff >= siz->height) {
		jas_eprintf("YOsiz not in permissible range\n");
		goto error;
	}
	if (siz->tilexoff > siz->xoff || siz->tilexoff + siz->tilewidth <= siz->xoff) {
		jas_eprintf("XTOsiz not in permissible range\n");
		goto error;
	}
	if (siz->tileyoff > siz->yoff || siz->tileyoff + siz->tileheight <= siz->yoff) {
		jas_eprintf("YTOsiz not in permissible range\n");
		goto error;
	}

	if (!(siz->comps = jas_alloc2(siz->numcomps, sizeof(jpc_sizcomp_t)))) {
		goto error;
	}
	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)) {
			goto error;
		}
		if (siz->comps[i].hsamp == 0 || siz->comps[i].hsamp > 255) {
			jas_eprintf("invalid XRsiz value %d\n", siz->comps[i].hsamp);
			goto error;
		}
		if (siz->comps[i].vsamp == 0 || siz->comps[i].vsamp > 255) {
			jas_eprintf("invalid YRsiz value %d\n", siz->comps[i].vsamp);
			goto error;
		}
		siz->comps[i].sgnd = (tmp >> 7) & 1;
		siz->comps[i].prec = (tmp & 0x7f) + 1;
	}
	if (jas_stream_eof(in)) {
		goto error;
	}
	return 0;

error:
	if (siz->comps) {
		jas_free(siz->comps);
	}
	return -1;
}

Project: jasper
File: jpc_cs.c

static int jpc_sop_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_sop_t *sop = &ms->parms.sop;
	fprintf(out, "seqno = %"PRIuFAST16";\n", sop->seqno);
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_sop_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_sop_t *sop = &ms->parms.sop;

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

	if (jpc_getuint16(in, &sop->seqno)) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_sop_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
{
	jpc_sop_t *sop = &ms->parms.sop;

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

	if (jpc_putuint16(out, sop->seqno)) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_sot_dumpparms(jpc_ms_t *ms, FILE *out)
{
	jpc_sot_t *sot = &ms->parms.sot;
	fprintf(out,
	  "tileno = %"PRIuFAST16"; len = %"PRIuFAST32"; partno = %d; numparts = %d\n",
	  sot->tileno, sot->len, sot->partno, sot->numparts);
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_sot_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_sot_t *sot = &ms->parms.sot;

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

	if (jpc_getuint16(in, &sot->tileno) ||
	  jpc_getuint32(in, &sot->len) ||
	  jpc_getuint8(in, &sot->partno) ||
	  jpc_getuint8(in, &sot->numparts)) {
		return -1;
	}
	if (sot->tileno > 65534 || sot->len < 12 || sot->partno > 254 ||
	  sot->numparts < 1 || sot->numparts > 255) {
		return -1;
	}
	if (jas_stream_eof(in)) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static int jpc_sot_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
{
	jpc_sot_t *sot = &ms->parms.sot;

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

	if (jpc_putuint16(out, sot->tileno) ||
	  jpc_putuint32(out, sot->len) ||
	  jpc_putuint8(out, sot->partno) ||
	  jpc_putuint8(out, sot->numparts)) {
		return -1;
	}
	return 0;
}

Project: jasper
File: jpc_cs.c

static void jpc_unk_destroyparms(jpc_ms_t *ms)
{
	jpc_unk_t *unk = &ms->parms.unk;
	if (unk->data) {
		jas_free(unk->data);
	}
}

Project: jasper
File: jpc_cs.c

static int jpc_unk_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
{
	jpc_unk_t *unk = &ms->parms.unk;

	unk->data = 0;

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

	if (ms->len > 0) {
		if (!(unk->data = jas_alloc2(ms->len, sizeof(unsigned char)))) {
			return -1;
		}
		if (jas_stream_read(in, (char *) unk->data, ms->len) !=
		  JAS_CAST(int, ms->len)) {
			jas_free(unk->data);
			return -1;
		}
		unk->len = ms->len;
	} else {
		unk->data = 0;
		unk->len = 0;
	}
	return 0;
}

Project: jasper
File: jpc_enc.c

static jpc_enc_band_t *band_create(jpc_enc_band_t *band, jpc_enc_cp_t *cp,
  jpc_enc_rlvl_t *rlvl, jpc_tsfb_band_t *bandinfos)
{
	uint_fast16_t bandno;
	uint_fast16_t gblbandno;
	uint_fast16_t rlvlno;
	jpc_tsfb_band_t *bandinfo;
	jpc_enc_tcmpt_t *tcmpt;
	uint_fast32_t prcno;
	jpc_enc_prc_t *prc;

	tcmpt = rlvl->tcmpt;
	band->data = 0;
	band->prcs = 0;
	band->rlvl = rlvl;

	/* Deduce the resolution level and band number. */
	rlvlno = rlvl - rlvl->tcmpt->rlvls;
	bandno = band - rlvl->bands;
	gblbandno = (!rlvlno) ? 0 : (3 * (rlvlno - 1) + bandno + 1);

	bandinfo = &bandinfos[gblbandno];

if (bandinfo->xstart != bandinfo->xend && bandinfo->ystart != bandinfo->yend) {
	if (!(band->data = jas_seq2d_create(0, 0, 0, 0))) {
		goto error;
	}
	jas_seq2d_bindsub(band->data, tcmpt->data, bandinfo->locxstart,
	  bandinfo->locystart, bandinfo->locxend, bandinfo->locyend);
	jas_seq2d_setshift(band->data, bandinfo->xstart, bandinfo->ystart);
}
	band->orient = bandinfo->orient;
	band->analgain = JPC_NOMINALGAIN(cp->tccp.qmfbid, tcmpt->numrlvls, rlvlno,
	  band->orient);
	band->numbps = 0;
	band->absstepsize = 0;
	band->stepsize = 0;
	band->synweight = bandinfo->synenergywt;

if (band->data) {
	if (!(band->prcs = jas_alloc2(rlvl->numprcs, sizeof(jpc_enc_prc_t)))) {
		goto error;
	}
	for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs; ++prcno,
	  ++prc) {
		prc->cblks = 0;
		prc->incltree = 0;
		prc->nlibtree = 0;
		prc->savincltree = 0;
		prc->savnlibtree = 0;
		prc->band = band;
	}
	for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs; ++prcno,
	  ++prc) {
		if (!prc_create(prc, cp, band)) {
			goto error;
		}
	}
}

	return band;

error:
	band_destroy(band);
	return 0;
}

Project: jasper
File: jpc_enc.c

void calcrdslopes(jpc_enc_cblk_t *cblk)
{
	jpc_enc_pass_t *endpasses;
	jpc_enc_pass_t *pass0;
	jpc_enc_pass_t *pass1;
	jpc_enc_pass_t *pass2;
	jpc_flt_t slope0;
	jpc_flt_t slope;
	jpc_flt_t dd;
	long dr;

	endpasses = &cblk->passes[cblk->numpasses];
	pass2 = cblk->passes;
	slope0 = 0;
	while (pass2 != endpasses) {
		pass0 = 0;
		for (pass1 = cblk->passes; pass1 != endpasses; ++pass1) {
			dd = pass1->cumwmsedec;
			dr = pass1->end;
			if (pass0) {
				dd -= pass0->cumwmsedec;
				dr -= pass0->end;
			}
			if (dd <= 0) {
				pass1->rdslope = JPC_BADRDSLOPE;
				if (pass1 >= pass2) {
					pass2 = &pass1[1];
				}
				continue;
			}
			if (pass1 < pass2 && pass1->rdslope <= 0) {
				continue;
			}
			if (!dr) {
				assert(pass0);
				pass0->rdslope = 0;
				break;
			}
			slope = dd / dr;
			if (pass0 && slope >= slope0) {
				pass0->rdslope = 0;
				break;
			}
			pass1->rdslope = slope;
			if (pass1 >= pass2) {
				pass2 = &pass1[1];
			}
			pass0 = pass1;
			slope0 = slope;
		}
	}

#if 0
	for (pass0 = cblk->passes; pass0 != endpasses; ++pass0) {
if (pass0->rdslope > 0.0) {
		jas_eprintf("pass %02d nmsedec=%lf dec=%lf end=%d %lf\n", pass0 - cblk->passes,
		  fixtodbl(pass0->nmsedec), pass0->wmsedec, pass0->end, pass0->rdslope);
}
	}
#endif
}

Project: jasper
File: jpc_enc.c

static jpc_enc_cblk_t *cblk_create(jpc_enc_cblk_t *cblk, jpc_enc_cp_t *cp, jpc_enc_prc_t *prc)
{
	jpc_enc_band_t *band;
	uint_fast32_t cblktlx;
	uint_fast32_t cblktly;
	uint_fast32_t cblkbrx;
	uint_fast32_t cblkbry;
	jpc_enc_rlvl_t *rlvl;
	uint_fast32_t cblkxind;
	uint_fast32_t cblkyind;
	uint_fast32_t cblkno;
	uint_fast32_t tlcblktlx;
	uint_fast32_t tlcblktly;

	cblkno = cblk - prc->cblks;
	cblkxind = cblkno % prc->numhcblks;
	cblkyind = cblkno / prc->numhcblks;
	rlvl = prc->band->rlvl;
	cblk->prc = prc;

	cblk->numpasses = 0;
	cblk->passes = 0;
	cblk->numencpasses = 0;
	cblk->numimsbs = 0;
	cblk->numlenbits = 0;
	cblk->stream = 0;
	cblk->mqenc = 0;
	cblk->flags = 0;
	cblk->numbps = 0;
	cblk->curpass = 0;
	cblk->data = 0;
	cblk->savedcurpass = 0;
	cblk->savednumlenbits = 0;
	cblk->savednumencpasses = 0;

	band = prc->band;
	tlcblktlx = JPC_FLOORTOMULTPOW2(prc->tlx, rlvl->cblkwidthexpn);
	tlcblktly = JPC_FLOORTOMULTPOW2(prc->tly, rlvl->cblkheightexpn);
	cblktlx = JAS_MAX(tlcblktlx + (cblkxind << rlvl->cblkwidthexpn), prc->tlx);
	cblktly = JAS_MAX(tlcblktly + (cblkyind << rlvl->cblkheightexpn), prc->tly);
	cblkbrx = JAS_MIN(tlcblktlx + ((cblkxind + 1) << rlvl->cblkwidthexpn),
	  prc->brx);
	cblkbry = JAS_MIN(tlcblktly + ((cblkyind + 1) << rlvl->cblkheightexpn),
	  prc->bry);

	assert(cblktlx < cblkbrx && cblktly < cblkbry);
	if (!(cblk->data = jas_seq2d_create(0, 0, 0, 0))) {
		goto error;
	}
	jas_seq2d_bindsub(cblk->data, band->data, cblktlx, cblktly, cblkbrx, cblkbry);

	return cblk;

error:
	cblk_destroy(cblk);
	return 0;
}

Project: jasper

static void cblk_destroy(jpc_enc_cblk_t *cblk)
{
	uint_fast16_t passno;
	jpc_enc_pass_t *pass;
	if (cblk->passes) {
		for (passno = 0, pass = cblk->passes; passno < cblk->numpasses;
		  ++passno, ++pass) {
			pass_destroy(pass);
		}
		jas_free(cblk->passes);
	}
	if (cblk->stream) {
		jas_stream_close(cblk->stream);
	}
	if (cblk->mqenc) {
		jpc_mqenc_destroy(cblk->mqenc);
	}
	if (cblk->data) {
		jas_seq2d_destroy(cblk->data);
	}
	if (cblk->flags) {
		jas_seq2d_destroy(cblk->flags);
	}
}

Project: jasper

static jpc_enc_cp_t *cp_create(char *optstr, jas_image_t *image)
{
	jpc_enc_cp_t *cp;
	jas_tvparser_t *tvp;
	int ret;
	int numilyrrates;
	double *ilyrrates;
	int i;
	int tagid;
	jpc_enc_tcp_t *tcp;
	jpc_enc_tccp_t *tccp;
	jpc_enc_ccp_t *ccp;
	int cmptno;
	uint_fast16_t rlvlno;
	uint_fast16_t prcwidthexpn;
	uint_fast16_t prcheightexpn;
	bool enablemct;
	uint_fast32_t jp2overhead;
	uint_fast16_t lyrno;
	uint_fast32_t hsteplcm;
	uint_fast32_t vsteplcm;
	bool mctvalid;

	tvp = 0;
	cp = 0;
	ilyrrates = 0;
	numilyrrates = 0;

	if (!(cp = jas_malloc(sizeof(jpc_enc_cp_t)))) {
		goto error;
	}

	prcwidthexpn = 15;
	prcheightexpn = 15;
	enablemct = true;
	jp2overhead = 0;

	cp->ccps = 0;
	cp->debug = 0;
	cp->imgareatlx = UINT_FAST32_MAX;
	cp->imgareatly = UINT_FAST32_MAX;
	cp->refgrdwidth = 0;
	cp->refgrdheight = 0;
	cp->tilegrdoffx = UINT_FAST32_MAX;
	cp->tilegrdoffy = UINT_FAST32_MAX;
	cp->tilewidth = 0;
	cp->tileheight = 0;
	cp->numcmpts = jas_image_numcmpts(image);

	hsteplcm = 1;
	vsteplcm = 1;
	for (cmptno = 0; cmptno < jas_image_numcmpts(image); ++cmptno) {
		if (jas_image_cmptbrx(image, cmptno) + jas_image_cmpthstep(image, cmptno) <=
		  jas_image_brx(image) || jas_image_cmptbry(image, cmptno) +
		  jas_image_cmptvstep(image, cmptno) <= jas_image_bry(image)) {
			jas_eprintf("unsupported image type\n");
			goto error;
		}
		/* Note: We ought to be calculating the LCMs here.  Fix some day. */
		hsteplcm *= jas_image_cmpthstep(image, cmptno);
		vsteplcm *= jas_image_cmptvstep(image, cmptno);
	}

	if (!(cp->ccps = jas_alloc2(cp->numcmpts, sizeof(jpc_enc_ccp_t)))) {
		goto error;
	}
	for (cmptno = 0, ccp = cp->ccps; cmptno < JAS_CAST(int, cp->numcmpts); ++cmptno,
	  ++ccp) {
		ccp->sampgrdstepx = jas_image_cmpthstep(image, cmptno);
		ccp->sampgrdstepy = jas_image_cmptvstep(image, cmptno);
		/* XXX - this isn't quite correct for more general image */
		ccp->sampgrdsubstepx = 0;
		ccp->sampgrdsubstepx = 0;
		ccp->prec = jas_image_cmptprec(image, cmptno);
		ccp->sgnd = jas_image_cmptsgnd(image, cmptno);
		ccp->numstepsizes = 0;
		memset(ccp->stepsizes, 0, sizeof(ccp->stepsizes));
	}

	cp->rawsize = jas_image_rawsize(image);
	cp->totalsize = UINT_FAST32_MAX;

	tcp = &cp->tcp;
	tcp->csty = 0;
	tcp->intmode = true;
	tcp->prg = JPC_COD_LRCPPRG;
	tcp->numlyrs = 1;
	tcp->ilyrrates = 0;

	tccp = &cp->tccp;
	tccp->csty = 0;
	tccp->maxrlvls = 6;
	tccp->cblkwidthexpn = 6;
	tccp->cblkheightexpn = 6;
	tccp->cblksty = 0;
	tccp->numgbits = 2;

	if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) {
		goto error;
	}

	while (!(ret = jas_tvparser_next(tvp))) {
		switch (jas_taginfo_nonull(jas_taginfos_lookup(encopts,
		  jas_tvparser_gettag(tvp)))->id) {
		case OPT_DEBUG:
			cp->debug = atoi(jas_tvparser_getval(tvp));
			break;
		case OPT_IMGAREAOFFX:
			cp->imgareatlx = atoi(jas_tvparser_getval(tvp));
			break;
		case OPT_IMGAREAOFFY:
			cp->imgareatly = atoi(jas_tvparser_getval(tvp));
			break;
		case OPT_TILEGRDOFFX:
			cp->tilegrdoffx = atoi(jas_tvparser_getval(tvp));
			break;
		case OPT_TILEGRDOFFY:
			cp->tilegrdoffy = atoi(jas_tvparser_getval(tvp));
			break;
		case OPT_TILEWIDTH:
			cp->tilewidth = atoi(jas_tvparser_getval(tvp));
			break;
		case OPT_TILEHEIGHT:
			cp->tileheight = atoi(jas_tvparser_getval(tvp));
			break;
		case OPT_PRCWIDTH:
			prcwidthexpn = jpc_floorlog2(atoi(jas_tvparser_getval(tvp)));
			break;
		case OPT_PRCHEIGHT:
			prcheightexpn = jpc_floorlog2(atoi(jas_tvparser_getval(tvp)));
			break;
		case OPT_CBLKWIDTH:
			tccp->cblkwidthexpn =
			  jpc_floorlog2(atoi(jas_tvparser_getval(tvp)));
			break;
		case OPT_CBLKHEIGHT:
			tccp->cblkheightexpn =
			  jpc_floorlog2(atoi(jas_tvparser_getval(tvp)));
			break;
		case OPT_MODE:
			if ((tagid = jas_taginfo_nonull(jas_taginfos_lookup(modetab,
			  jas_tvparser_getval(tvp)))->id) < 0) {
				jas_eprintf("ignoring invalid mode %s\n",
				  jas_tvparser_getval(tvp));
			} else {
				tcp->intmode = (tagid == MODE_INT);
			}
			break;
		case OPT_PRG:
			if ((tagid = jas_taginfo_nonull(jas_taginfos_lookup(prgordtab,
			  jas_tvparser_getval(tvp)))->id) < 0) {
				jas_eprintf("ignoring invalid progression order %s\n",
				  jas_tvparser_getval(tvp));
			} else {
				tcp->prg = tagid;
			}
			break;
		case OPT_NOMCT:
			enablemct = false;
			break;
		case OPT_MAXRLVLS:
			tccp->maxrlvls = atoi(jas_tvparser_getval(tvp));
			break;
		case OPT_SOP:
			cp->tcp.csty |= JPC_COD_SOP;
			break;
		case OPT_EPH:
			cp->tcp.csty |= JPC_COD_EPH;
			break;
		case OPT_LAZY:
			tccp->cblksty |= JPC_COX_LAZY;
			break;
		case OPT_TERMALL:
			tccp->cblksty |= JPC_COX_TERMALL;
			break;
		case OPT_SEGSYM:
			tccp->cblksty |= JPC_COX_SEGSYM;
			break;
		case OPT_VCAUSAL:
			tccp->cblksty |= JPC_COX_VSC;
			break;
		case OPT_RESET:
			tccp->cblksty |= JPC_COX_RESET;
			break;
		case OPT_PTERM:
			tccp->cblksty |= JPC_COX_PTERM;
			break;
		case OPT_NUMGBITS:
			cp->tccp.numgbits = atoi(jas_tvparser_getval(tvp));
			break;
		case OPT_RATE:
			if (ratestrtosize(jas_tvparser_getval(tvp), cp->rawsize,
			  &cp->totalsize)) {
				jas_eprintf("ignoring bad rate specifier %s\n",
				  jas_tvparser_getval(tvp));
			}
			break;
		case OPT_ILYRRATES:
			if (jpc_atoaf(jas_tvparser_getval(tvp), &numilyrrates,
			  &ilyrrates)) {
				jas_eprintf("warning: invalid intermediate layer rates specifier ignored (%s)\n",
				  jas_tvparser_getval(tvp));
			}
			break;

		case OPT_JP2OVERHEAD:
			jp2overhead = atoi(jas_tvparser_getval(tvp));
			break;
		default:
			jas_eprintf("warning: ignoring invalid option %s\n",
			 jas_tvparser_gettag(tvp));
			break;
		}
	}

	jas_tvparser_destroy(tvp);
	tvp = 0;

	if (cp->totalsize != UINT_FAST32_MAX) {
		cp->totalsize = (cp->totalsize > jp2overhead) ?
		  (cp->totalsize - jp2overhead) : 0;
	}

	if (cp->imgareatlx == UINT_FAST32_MAX) {
		cp->imgareatlx = 0;
	} else {
		if (hsteplcm != 1) {
			jas_eprintf("warning: overriding imgareatlx value\n");
		}
		cp->imgareatlx *= hsteplcm;
	}
	if (cp->imgareatly == UINT_FAST32_MAX) {
		cp->imgareatly = 0;
	} else {
		if (vsteplcm != 1) {
			jas_eprintf("warning: overriding imgareatly value\n");
		}
		cp->imgareatly *= vsteplcm;
	}
	cp->refgrdwidth = cp->imgareatlx + jas_image_width(image);
	cp->refgrdheight = cp->imgareatly + jas_image_height(image);
	if (cp->tilegrdoffx == UINT_FAST32_MAX) {
		cp->tilegrdoffx = cp->imgareatlx;
	}
	if (cp->tilegrdoffy == UINT_FAST32_MAX) {
		cp->tilegrdoffy = cp->imgareatly;
	}
	if (!cp->tilewidth) {
		cp->tilewidth = cp->refgrdwidth - cp->tilegrdoffx;
	}
	if (!cp->tileheight) {
		cp->tileheight = cp->refgrdheight - cp->tilegrdoffy;
	}

	if (cp->numcmpts == 3) {
		mctvalid = true;
		for (cmptno = 0; cmptno < jas_image_numcmpts(image); ++cmptno) {
			if (jas_image_cmptprec(image, cmptno) != jas_image_cmptprec(image, 0) ||
			  jas_image_cmptsgnd(image, cmptno) != jas_image_cmptsgnd(image, 0) ||
			  jas_image_cmptwidth(image, cmptno) != jas_image_cmptwidth(image, 0) ||
			  jas_image_cmptheight(image, cmptno) != jas_image_cmptheight(image, 0)) {
				mctvalid = false;
			}
		}
	} else {
		mctvalid = false;
	}
	if (mctvalid && enablemct && jas_clrspc_fam(jas_image_clrspc(image)) != JAS_CLRSPC_FAM_RGB) {
		jas_eprintf("warning: color space apparently not RGB\n");
	}
	if (mctvalid && enablemct && jas_clrspc_fam(jas_image_clrspc(image)) == JAS_CLRSPC_FAM_RGB) {
		tcp->mctid = (tcp->intmode) ? (JPC_MCT_RCT) : (JPC_MCT_ICT);
	} else {
		tcp->mctid = JPC_MCT_NONE;
	}
	tccp->qmfbid = (tcp->intmode) ? (JPC_COX_RFT) : (JPC_COX_INS);

	for (rlvlno = 0; rlvlno < tccp->maxrlvls; ++rlvlno) {
		tccp->prcwidthexpns[rlvlno] = prcwidthexpn;
		tccp->prcheightexpns[rlvlno] = prcheightexpn;
	}
	if (prcwidthexpn != 15 || prcheightexpn != 15) {
		tccp->csty |= JPC_COX_PRT;
	}

	/* Ensure that the tile width and height is valid. */
	if (!cp->tilewidth) {
		jas_eprintf("invalid tile width %lu\n", (unsigned long)
		  cp->tilewidth);
		goto error;
	}
	if (!cp->tileheight) {
		jas_eprintf("invalid tile height %lu\n", (unsigned long)
		  cp->tileheight);
		goto error;
	}

	/* Ensure that the tile grid offset is valid. */
	if (cp->tilegrdoffx > cp->imgareatlx ||
	  cp->tilegrdoffy > cp->imgareatly ||
	  cp->tilegrdoffx + cp->tilewidth < cp->imgareatlx ||
	  cp->tilegrdoffy + cp->tileheight < cp->imgareatly) {
		jas_eprintf("invalid tile grid offset (%lu, %lu)\n",
		  (unsigned long) cp->tilegrdoffx, (unsigned long)
		  cp->tilegrdoffy);
		goto error;
	}

	cp->numhtiles = JPC_CEILDIV(cp->refgrdwidth - cp->tilegrdoffx,
	  cp->tilewidth);
	cp->numvtiles = JPC_CEILDIV(cp->refgrdheight - cp->tilegrdoffy,
	  cp->tileheight);
	cp->numtiles = cp->numhtiles * cp->numvtiles;

	if (ilyrrates && numilyrrates > 0) {
		tcp->numlyrs = numilyrrates + 1;
		if (!(tcp->ilyrrates = jas_alloc2((tcp->numlyrs - 1),
		  sizeof(jpc_fix_t)))) {
			goto error;
		}
		for (i = 0; i < JAS_CAST(int, tcp->numlyrs - 1); ++i) {
			tcp->ilyrrates[i] = jpc_dbltofix(ilyrrates[i]);
		}
	}

	/* Ensure that the integer mode is used in the case of lossless
	  coding. */
	if (cp->totalsize == UINT_FAST32_MAX && (!cp->tcp.intmode)) {
		jas_eprintf("cannot use real mode for lossless coding\n");
		goto error;
	}

	/* Ensure that the precinct width is valid. */
	if (prcwidthexpn > 15) {
		jas_eprintf("invalid precinct width\n");
		goto error;
	}

	/* Ensure that the precinct height is valid. */
	if (prcheightexpn > 15) {
		jas_eprintf("invalid precinct height\n");
		goto error;
	}

	/* Ensure that the code block width is valid. */
	if (cp->tccp.cblkwidthexpn < 2 || cp->tccp.cblkwidthexpn > 12) {
		jas_eprintf("invalid code block width %d\n",
		  JPC_POW2(cp->tccp.cblkwidthexpn));
		goto error;
	}

	/* Ensure that the code block height is valid. */
	if (cp->tccp.cblkheightexpn < 2 || cp->tccp.cblkheightexpn > 12) {
		jas_eprintf("invalid code block height %d\n",
		  JPC_POW2(cp->tccp.cblkheightexpn));
		goto error;
	}

	/* Ensure that the code block size is not too large. */
	if (cp->tccp.cblkwidthexpn + cp->tccp.cblkheightexpn > 12) {
		jas_eprintf("code block size too large\n");
		goto error;
	}

	/* Ensure that the number of layers is valid. */
	if (cp->tcp.numlyrs > 16384) {
		jas_eprintf("too many layers\n");
		goto error;
	}

	/* There must be at least one resolution level. */
	if (cp->tccp.maxrlvls < 1) {
		jas_eprintf("must be at least one resolution level\n");
		goto error;
	}

	/* Ensure that the number of guard bits is valid. */
	if (cp->tccp.numgbits > 8) {
		jas_eprintf("invalid number of guard bits\n");
		goto error;
	}

	/* Ensure that the rate is within the legal range. */
	if (cp->totalsize != UINT_FAST32_MAX && cp->totalsize > cp->rawsize) {
		jas_eprintf("warning: specified rate is unreasonably large (%lu > %lu)\n", (unsigned long) cp->totalsize, (unsigned long) cp->rawsize);
	}

	/* Ensure that the intermediate layer rates are valid. */
	if (tcp->numlyrs > 1) {
		/* The intermediate layers rates must increase monotonically. */
		for (lyrno = 0; lyrno + 2 < tcp->numlyrs; ++lyrno) {
			if (tcp->ilyrrates[lyrno] >= tcp->ilyrrates[lyrno + 1]) {
				jas_eprintf("intermediate layer rates must increase monotonically\n");
				goto error;
			}
		}
		/* The intermediate layer rates must be less than the overall rate. */
		if (cp->totalsize != UINT_FAST32_MAX) {
			for (lyrno = 0; lyrno < tcp->numlyrs - 1; ++lyrno) {
				if (jpc_fixtodbl(tcp->ilyrrates[lyrno]) > ((double) cp->totalsize)
				  / cp->rawsize) {
					jas_eprintf("warning: intermediate layer rates must be less than overall rate\n");
					goto error;
				}
			}
		}
	}

	if (ilyrrates) {
		jas_free(ilyrrates);
	}

	return cp;

error:

	if (ilyrrates) {
		jas_free(ilyrrates);
	}
	if (tvp) {
		jas_tvparser_destroy(tvp);
	}
	if (cp) {
		jpc_enc_cp_destroy(cp);
	}
	return 0;
}

Project: jasper
File: jpc_enc.c

void dump_layeringinfo(jpc_enc_t *enc)
{

	jpc_enc_tcmpt_t *tcmpt;
	int tcmptno;
	jpc_enc_rlvl_t *rlvl;
	int rlvlno;
	jpc_enc_band_t *band;
	int bandno;
	jpc_enc_prc_t *prc;
	int prcno;
	jpc_enc_cblk_t *cblk;
	int cblkno;
	jpc_enc_pass_t *pass;
	int passno;
	int lyrno;
	jpc_enc_tile_t *tile;

	tile = enc->curtile;

	for (lyrno = 0; lyrno < tile->numlyrs; ++lyrno) {
		jas_eprintf("lyrno = %02d\n", lyrno);
		for (tcmptno = 0, tcmpt = tile->tcmpts; tcmptno < tile->numtcmpts;
		  ++tcmptno, ++tcmpt) {
			for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
			  ++rlvlno, ++rlvl) {
				if (!rlvl->bands) {
					continue;
				}
				for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
				  ++bandno, ++band) {
					if (!band->data) {
						continue;
					}
					for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs;
					  ++prcno, ++prc) {
						if (!prc->cblks) {
							continue;
						}
						for (cblkno = 0, cblk = prc->cblks; cblkno <
						  prc->numcblks; ++cblkno, ++cblk) {
							for (passno = 0, pass = cblk->passes; passno <
							  cblk->numpasses && pass->lyrno == lyrno;
							  ++passno, ++pass) {
								jas_eprintf("lyrno=%02d cmptno=%02d rlvlno=%02d bandno=%02d prcno=%02d cblkno=%03d passno=%03d\n", lyrno, tcmptno, rlvlno, bandno, prcno, cblkno, passno);
							}
						}
					}
				}
			}
		}
	}
}

Project: jasper
File: jpc_enc.c

int dump_passes(jpc_enc_pass_t *passes, int numpasses, jpc_enc_cblk_t *cblk)
{
	jpc_enc_pass_t *pass;
	int i;
	jas_stream_memobj_t *smo;

	smo = cblk->stream->obj_;

	pass = passes;
	for (i = 0; i < numpasses; ++i) {
		jas_eprintf("start=%d end=%d type=%d term=%d lyrno=%d firstchar=%02x size=%ld pos=%ld\n",
		  (int)pass->start, (int)pass->end, (int)pass->type, (int)pass->term, (int)pass->lyrno,
		  smo->buf_[pass->start], (long)smo->len_, (long)smo->pos_);
#if 0
		jas_memdump(stderr, &smo->buf_[pass->start], pass->end - pass->start);
#endif
		++pass;
	}
	return 0;
}

Project: jasper
File: jpc_enc.c

static uint_fast32_t jpc_abstorelstepsize(jpc_fix_t absdelta, int scaleexpn)
{
	int p;
	uint_fast32_t mant;
	uint_fast32_t expn;
	int n;

	if (absdelta < 0) {
		abort();
	}

	p = jpc_firstone(absdelta) - JPC_FIX_FRACBITS;
	n = 11 - jpc_firstone(absdelta);
	mant = ((n < 0) ? (absdelta >> (-n)) : (absdelta << n)) & 0x7ff;
	expn = scaleexpn - p;
	if (scaleexpn < p) {
		abort();
	}
	return JPC_QCX_EXPN(expn) | JPC_QCX_MANT(mant);
}

Project: jasper
File: jpc_enc.c

static int jpc_calcssexp(jpc_fix_t stepsize)
{
	return jpc_firstone(stepsize) - JPC_FIX_FRACBITS;
}

Project: jasper
File: jpc_enc.c

static int jpc_calcssmant(jpc_fix_t stepsize)
{
	int n;
	int e;
	int m;

	n = jpc_firstone(stepsize);
	e = n - JPC_FIX_FRACBITS;
	if (n >= 11) {
		m = (stepsize >> (n - 11)) & 0x7ff;
	} else {
		m = (stepsize & ((1 << n) - 1)) << (11 - n);
	}
	return m;
}

Project: jasper
File: jpc_enc.c

void jpc_enc_cp_destroy(jpc_enc_cp_t *cp)
{
	if (cp->ccps) {
		if (cp->tcp.ilyrrates) {
			jas_free(cp->tcp.ilyrrates);
		}
		jas_free(cp->ccps);
	}
	jas_free(cp);
}

Project: jasper
File: jpc_enc.c

jpc_enc_t *jpc_enc_create(jpc_enc_cp_t *cp, jas_stream_t *out, jas_image_t *image)
{
	jpc_enc_t *enc;

	enc = 0;

	if (!(enc = jas_malloc(sizeof(jpc_enc_t)))) {
		goto error;
	}

	enc->image = image;
	enc->out = out;
	enc->cp = cp;
	enc->cstate = 0;
	enc->tmpstream = 0;
	enc->mrk = 0;
	enc->curtile = 0;

	if (!(enc->cstate = jpc_cstate_create())) {
		goto error;
	}
	enc->len = 0;
	enc->mainbodysize = 0;

	return enc;

error:

	if (enc) {
		jpc_enc_destroy(enc);
	}
	return 0;
}

Project: jasper
File: jpc_enc.c

void jpc_enc_dump(jpc_enc_t *enc)
{
	jpc_enc_tile_t *tile;
	jpc_enc_tcmpt_t *tcmpt;
	jpc_enc_rlvl_t *rlvl;
	jpc_enc_band_t *band;
	jpc_enc_prc_t *prc;
	jpc_enc_cblk_t *cblk;
	uint_fast16_t cmptno;
	uint_fast16_t rlvlno;
	uint_fast16_t bandno;
	uint_fast32_t prcno;
	uint_fast32_t cblkno;

	tile = enc->curtile;

	for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < tile->numtcmpts; ++cmptno,
	  ++tcmpt) {
		jas_eprintf("  tcmpt %5d %5d %5d %5d\n", jas_seq2d_xstart(tcmpt->data), jas_seq2d_ystart(tcmpt->data), jas_seq2d_xend(tcmpt->data), jas_seq2d_yend(tcmpt->data));
		for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
		  ++rlvlno, ++rlvl) {
			jas_eprintf("    rlvl %5d %5d %5d %5d\n", rlvl->tlx, rlvl->tly, rlvl->brx, rlvl->bry);
			for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
			  ++bandno, ++band) {
				if (!band->data) {
					continue;
				}
				jas_eprintf("      band %5d %5d %5d %5d\n", jas_seq2d_xstart(band->data), jas_seq2d_ystart(band->data), jas_seq2d_xend(band->data), jas_seq2d_yend(band->data));
				for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs;
				  ++prcno, ++prc) {
					jas_eprintf("        prc %5d %5d %5d %5d (%5d %5d)\n", prc->tlx, prc->tly, prc->brx, prc->bry, prc->brx - prc->tlx, prc->bry - prc->tly);
					if (!prc->cblks) {
						continue;
					}
					for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks;
					  ++cblkno, ++cblk) {
						jas_eprintf("         cblk %5d %5d %5d %5d\n", jas_seq2d_xstart(cblk->data), jas_seq2d_ystart(cblk->data), jas_seq2d_xend(cblk->data), jas_seq2d_yend(cblk->data));
					}
				}
			}
		}
	}
}

Project: jasper

static int jpc_enc_encodemainbody(jpc_enc_t *enc)
{
	int tileno;
	int tilex;
	int tiley;
	int i;
	jpc_sot_t *sot;
	jpc_enc_tcmpt_t *comp;
	jpc_enc_tcmpt_t *endcomps;
	jpc_enc_band_t *band;
	jpc_enc_band_t *endbands;
	jpc_enc_rlvl_t *lvl;
	int rlvlno;
	jpc_qcc_t *qcc;
	jpc_cod_t *cod;
	int adjust;
	int j;
	int absbandno;
	long numbytes;
	long tilehdrlen;
	long tilelen;
	jpc_enc_tile_t *tile;
	jpc_enc_cp_t *cp;
	double rho;
	int lyrno;
	int cmptno;
	int samestepsizes;
	jpc_enc_ccp_t *ccps;
	jpc_enc_tccp_t *tccp;
	int bandno;
	uint_fast32_t x;
	uint_fast32_t y;
	int mingbits;
	int actualnumbps;
	jpc_fix_t mxmag;
	jpc_fix_t mag;
	int numgbits;

	cp = enc->cp;

	/* Avoid compile warnings. */
	numbytes = 0;

	for (tileno = 0; tileno < JAS_CAST(int, cp->numtiles); ++tileno) {
		tilex = tileno % cp->numhtiles;
		tiley = tileno / cp->numhtiles;

		if (!(enc->curtile = jpc_enc_tile_create(enc->cp, enc->image, tileno))) {
			abort();
		}

		tile = enc->curtile;

		if (jas_getdbglevel() >= 10) {
			jpc_enc_dump(enc);
		}

		endcomps = &tile->tcmpts[tile->numtcmpts];
		for (cmptno = 0, comp = tile->tcmpts; cmptno < tile->numtcmpts; ++cmptno, ++comp) {
			if (!cp->ccps[cmptno].sgnd) {
				adjust = 1 << (cp->ccps[cmptno].prec - 1);
				for (i = 0; i < jas_matrix_numrows(comp->data); ++i) {
					for (j = 0; j < jas_matrix_numcols(comp->data); ++j) {
						*jas_matrix_getref(comp->data, i, j) -= adjust;
					}
				}
			}
		}

		if (!tile->intmode) {
				endcomps = &tile->tcmpts[tile->numtcmpts];
				for (comp = tile->tcmpts; comp != endcomps; ++comp) {
					jas_matrix_asl(comp->data, JPC_FIX_FRACBITS);
				}
		}

		switch (tile->mctid) {
		case JPC_MCT_RCT:
assert(jas_image_numcmpts(enc->image) == 3);
			jpc_rct(tile->tcmpts[0].data, tile->tcmpts[1].data,
			  tile->tcmpts[2].data);
			break;
		case JPC_MCT_ICT:
assert(jas_image_numcmpts(enc->image) == 3);
			jpc_ict(tile->tcmpts[0].data, tile->tcmpts[1].data,
			  tile->tcmpts[2].data);
			break;
		default:
			break;
		}

		for (i = 0; i < jas_image_numcmpts(enc->image); ++i) {
			comp = &tile->tcmpts[i];
			jpc_tsfb_analyze(comp->tsfb, comp->data);

		}


		endcomps = &tile->tcmpts[tile->numtcmpts];
		for (cmptno = 0, comp = tile->tcmpts; comp != endcomps; ++cmptno, ++comp) {
			mingbits = 0;
			absbandno = 0;
			/* All bands must have a corresponding quantizer step size,
			  even if they contain no samples and are never coded. */
			/* Some bands may not be hit by the loop below, so we must
			  initialize all of the step sizes to a sane value. */
			memset(comp->stepsizes, 0, sizeof(comp->stepsizes));
			for (rlvlno = 0, lvl = comp->rlvls; rlvlno < comp->numrlvls; ++rlvlno, ++lvl) {
				if (!lvl->bands) {
					absbandno += rlvlno ? 3 : 1;
					continue;
				}
				endbands = &lvl->bands[lvl->numbands];
				for (band = lvl->bands; band != endbands; ++band) {
					if (!band->data) {
						++absbandno;
						continue;
					}
					actualnumbps = 0;
					mxmag = 0;
					for (y = 0; y < JAS_CAST(uint_fast32_t, jas_matrix_numrows(band->data)); ++y) {
						for (x = 0; x < JAS_CAST(uint_fast32_t, jas_matrix_numcols(band->data)); ++x) {
							mag = JAS_ABS(jas_matrix_get(band->data, y, x));
							if (mag > mxmag) {
								mxmag = mag;
							}
						}
					}
					if (tile->intmode) {
						actualnumbps = jpc_firstone(mxmag) + 1;
					} else {
						actualnumbps = jpc_firstone(mxmag) + 1 - JPC_FIX_FRACBITS;
					}
					numgbits = actualnumbps - (cp->ccps[cmptno].prec - 1 +
					  band->analgain);
#if 0
jas_eprintf("%d %d mag=%d actual=%d numgbits=%d\n", cp->ccps[cmptno].prec, band->analgain, mxmag, actualnumbps, numgbits);
#endif
					if (numgbits > mingbits) {
						mingbits = numgbits;
					}
					if (!tile->intmode) {
						band->absstepsize = jpc_fix_div(jpc_inttofix(1
						  << (band->analgain + 1)),
						  band->synweight);
					} else {
						band->absstepsize = jpc_inttofix(1);
					}
					band->stepsize = jpc_abstorelstepsize(
					  band->absstepsize, cp->ccps[cmptno].prec +
					  band->analgain);
					band->numbps = cp->tccp.numgbits +
					  JPC_QCX_GETEXPN(band->stepsize) - 1;

					if ((!tile->intmode) && band->data) {
						jpc_quantize(band->data, band->absstepsize);
					}

					comp->stepsizes[absbandno] = band->stepsize;
					++absbandno;
				}
			}

			assert(JPC_FIX_FRACBITS >= JPC_NUMEXTRABITS);
			if (!tile->intmode) {
				jas_matrix_divpow2(comp->data, JPC_FIX_FRACBITS - JPC_NUMEXTRABITS);
			} else {
				jas_matrix_asl(comp->data, JPC_NUMEXTRABITS);
			}

#if 0
jas_eprintf("mingbits %d\n", mingbits);
#endif
			if (mingbits > cp->tccp.numgbits) {
				jas_eprintf("error: too few guard bits (need at least %d)\n",
				  mingbits);
				return -1;
			}
		}

		if (!(enc->tmpstream = jas_stream_memopen(0, 0))) {
			jas_eprintf("cannot open tmp file\n");
			return -1;
		}

		/* Write the tile header. */
		if (!(enc->mrk = jpc_ms_create(JPC_MS_SOT))) {
			return -1;
		}
		sot = &enc->mrk->parms.sot;
		sot->len = 0;
		sot->tileno = tileno;
		sot->partno = 0;
		sot->numparts = 1;
		if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) {
			jas_eprintf("cannot write SOT marker\n");
			return -1;
		}
		jpc_ms_destroy(enc->mrk);
		enc->mrk = 0;

/************************************************************************/
/************************************************************************/
/************************************************************************/

		tccp = &cp->tccp;
		for (cmptno = 0; cmptno < JAS_CAST(int, cp->numcmpts); ++cmptno) {
			comp = &tile->tcmpts[cmptno];
			if (comp->numrlvls != tccp->maxrlvls) {
				if (!(enc->mrk = jpc_ms_create(JPC_MS_COD))) {
					return -1;
				}
/* XXX = this is not really correct. we are using comp #0's precint sizes
and other characteristics */
				comp = &tile->tcmpts[0];
				cod = &enc->mrk->parms.cod;
				cod->compparms.csty = 0;
				cod->compparms.numdlvls = comp->numrlvls - 1;
				cod->prg = tile->prg;
				cod->numlyrs = tile->numlyrs;
				cod->compparms.cblkwidthval = JPC_COX_CBLKSIZEEXPN(comp->cblkwidthexpn);
				cod->compparms.cblkheightval = JPC_COX_CBLKSIZEEXPN(comp->cblkheightexpn);
				cod->compparms.cblksty = comp->cblksty;
				cod->compparms.qmfbid = comp->qmfbid;
				cod->mctrans = (tile->mctid != JPC_MCT_NONE);
				for (i = 0; i < comp->numrlvls; ++i) {
					cod->compparms.rlvls[i].parwidthval = comp->rlvls[i].prcwidthexpn;
					cod->compparms.rlvls[i].parheightval = comp->rlvls[i].prcheightexpn;
				}
				if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) {
					return -1;
				}
				jpc_ms_destroy(enc->mrk);
				enc->mrk = 0;
			}
		}

		for (cmptno = 0, comp = tile->tcmpts; cmptno < JAS_CAST(int,
		  cp->numcmpts); ++cmptno, ++comp) {
			ccps = &cp->ccps[cmptno];
			if (JAS_CAST(int, ccps->numstepsizes) == comp->numstepsizes) {
				samestepsizes = 1;
				for (bandno = 0; bandno < JAS_CAST(int, ccps->numstepsizes);
				  ++bandno) {
					if (ccps->stepsizes[bandno] != comp->stepsizes[bandno]) {
						samestepsizes = 0;
						break;
					}
				}
			} else {
				samestepsizes = 0;
			}
			if (!samestepsizes) {
				if (!(enc->mrk = jpc_ms_create(JPC_MS_QCC))) {
					return -1;
				}
				qcc = &enc->mrk->parms.qcc;
				qcc->compno = cmptno;
				qcc->compparms.numguard = cp->tccp.numgbits;
				qcc->compparms.qntsty = (comp->qmfbid == JPC_COX_INS) ?
				  JPC_QCX_SEQNT : JPC_QCX_NOQNT;
				qcc->compparms.numstepsizes = comp->numstepsizes;
				qcc->compparms.stepsizes = comp->stepsizes;
				if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) {
					return -1;
				}
				qcc->compparms.stepsizes = 0;
				jpc_ms_destroy(enc->mrk);
				enc->mrk = 0;
			}
		}

		/* Write a SOD marker to indicate the end of the tile header. */
		if (!(enc->mrk = jpc_ms_create(JPC_MS_SOD))) {
			return -1;
		}
		if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) {
			jas_eprintf("cannot write SOD marker\n");
			return -1;
		}
		jpc_ms_destroy(enc->mrk);
		enc->mrk = 0;
		tilehdrlen = jas_stream_getrwcount(enc->tmpstream);
		assert(tilehdrlen >= 0);

/************************************************************************/
/************************************************************************/
/************************************************************************/

		if (jpc_enc_enccblks(enc)) {
			abort();
			return -1;
		}

		cp = enc->cp;
		rho = (double) (tile->brx - tile->tlx) * (tile->bry - tile->tly) /
		  ((cp->refgrdwidth - cp->imgareatlx) * (cp->refgrdheight -
		  cp->imgareatly));
		tile->rawsize = cp->rawsize * rho;

		for (lyrno = 0; lyrno < tile->numlyrs - 1; ++lyrno) {
			tile->lyrsizes[lyrno] = tile->rawsize * jpc_fixtodbl(
			  cp->tcp.ilyrrates[lyrno]);
		}
#if !defined(__clang__)
		tile->lyrsizes[tile->numlyrs - 1] =
		  (cp->totalsize != UINT_FAST32_MAX) ?
		  (rho * enc->mainbodysize) : UINT_FAST32_MAX;
#else
		if (cp->totalsize != UINT_FAST32_MAX) {
			tile->lyrsizes[tile->numlyrs - 1] = (rho * enc->mainbodysize);
		} else {
			tile->lyrsizes[tile->numlyrs - 1] = UINT_FAST32_MAX;
		}
#endif
		for (lyrno = 0; lyrno < tile->numlyrs; ++lyrno) {
			if (tile->lyrsizes[lyrno] != UINT_FAST32_MAX) {
				if (JAS_CAST(uint_fast32_t, tilehdrlen) <= tile->lyrsizes[lyrno]) {
					tile->lyrsizes[lyrno] -= tilehdrlen;
				} else {
					tile->lyrsizes[lyrno] = 0;
				}
			}
		}

		if (rateallocate(enc, tile->numlyrs, tile->lyrsizes)) {
			return -1;
		}

#if 0
jas_eprintf("ENCODE TILE DATA\n");
#endif
		if (jpc_enc_encodetiledata(enc)) {
			jas_eprintf("dotile failed\n");
			return -1;
		}

/************************************************************************/
/************************************************************************/
/************************************************************************/

/************************************************************************/
/************************************************************************/
/************************************************************************/

		tilelen = jas_stream_tell(enc->tmpstream);

		if (jas_stream_seek(enc->tmpstream, 6, SEEK_SET) < 0) {
			return -1;
		}
		jpc_putuint32(enc->tmpstream, tilelen);

		if (jas_stream_seek(enc->tmpstream, 0, SEEK_SET) < 0) {
			return -1;
		}
		if (jpc_putdata(enc->out, enc->tmpstream, -1)) {
			return -1;
		}
		enc->len += tilelen;

		jas_stream_close(enc->tmpstream);
		enc->tmpstream = 0;

		jpc_enc_tile_destroy(enc->curtile);
		enc->curtile = 0;

	}

	return 0;
}

Project: jasper
File: jpc_enc.c

int jpc_enc_encodetiledata(jpc_enc_t *enc)
{
assert(enc->tmpstream);
	if (jpc_enc_encpkts(enc, enc->tmpstream)) {
		return -1;
	}
	return 0;
}

Project: jasper

jpc_enc_tile_t *jpc_enc_tile_create(jpc_enc_cp_t *cp, jas_image_t *image, int tileno)
{
	jpc_enc_tile_t *tile;
	uint_fast32_t htileno;
	uint_fast32_t vtileno;
	uint_fast16_t lyrno;
	uint_fast16_t cmptno;
	jpc_enc_tcmpt_t *tcmpt;

	if (!(tile = jas_malloc(sizeof(jpc_enc_tile_t)))) {
		goto error;
	}

	/* Initialize a few members used in error recovery. */
	tile->tcmpts = 0;
	tile->lyrsizes = 0;
	tile->numtcmpts = cp->numcmpts;
	tile->pi = 0;

	tile->tileno = tileno;
	htileno = tileno % cp->numhtiles;
	vtileno = tileno / cp->numhtiles;

	/* Calculate the coordinates of the top-left and bottom-right
	  corners of the tile. */
	tile->tlx = JAS_MAX(cp->tilegrdoffx + htileno * cp->tilewidth,
	  cp->imgareatlx);
	tile->tly = JAS_MAX(cp->tilegrdoffy + vtileno * cp->tileheight,
	  cp->imgareatly);
	tile->brx = JAS_MIN(cp->tilegrdoffx + (htileno + 1) * cp->tilewidth,
	  cp->refgrdwidth);
	tile->bry = JAS_MIN(cp->tilegrdoffy + (vtileno + 1) * cp->tileheight,
	  cp->refgrdheight);

	/* Initialize some tile coding parameters. */
	tile->intmode = cp->tcp.intmode;
	tile->csty = cp->tcp.csty;
	tile->prg = cp->tcp.prg;
	tile->mctid = cp->tcp.mctid;

	tile->numlyrs = cp->tcp.numlyrs;
	if (!(tile->lyrsizes = jas_alloc2(tile->numlyrs,
	  sizeof(uint_fast32_t)))) {
		goto error;
	}
	for (lyrno = 0; lyrno < tile->numlyrs; ++lyrno) {
		tile->lyrsizes[lyrno] = 0;
	}

	/* Allocate an array for the per-tile-component information. */
	if (!(tile->tcmpts = jas_alloc2(cp->numcmpts, sizeof(jpc_enc_tcmpt_t)))) {
		goto error;
	}
	/* Initialize a few members critical for error recovery. */
	for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts;
	  ++cmptno, ++tcmpt) {
		tcmpt->rlvls = 0;
		tcmpt->tsfb = 0;
		tcmpt->data = 0;
	}
	/* Initialize the per-tile-component information. */
	for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts;
	  ++cmptno, ++tcmpt) {
		if (!tcmpt_create(tcmpt, cp, image, tile)) {
			goto error;
		}
	}

	/* Initialize the synthesis weights for the MCT. */
	switch (tile->mctid) {
	case JPC_MCT_RCT:
		tile->tcmpts[0].synweight = jpc_dbltofix(sqrt(3.0));
		tile->tcmpts[1].synweight = jpc_dbltofix(sqrt(0.6875));
		tile->tcmpts[2].synweight = jpc_dbltofix(sqrt(0.6875));
		break;
	case JPC_MCT_ICT:
		tile->tcmpts[0].synweight = jpc_dbltofix(sqrt(3.0000));
		tile->tcmpts[1].synweight = jpc_dbltofix(sqrt(3.2584));
		tile->tcmpts[2].synweight = jpc_dbltofix(sqrt(2.4755));
		break;
	default:
	case JPC_MCT_NONE:
		for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts;
		  ++cmptno, ++tcmpt) {
			tcmpt->synweight = JPC_FIX_ONE;
		}
		break;
	}

	if (!(tile->pi = jpc_enc_pi_create(cp, tile))) {
		goto error;
	}

	return tile;

error:

	if (tile) {
		jpc_enc_tile_destroy(tile);
	}
	return 0;
}

Project: jasper

void jpc_enc_tile_destroy(jpc_enc_tile_t *tile)
{
	jpc_enc_tcmpt_t *tcmpt;
	uint_fast16_t cmptno;

	if (tile->tcmpts) {
		for (cmptno = 0, tcmpt = tile->tcmpts; cmptno <
		  tile->numtcmpts; ++cmptno, ++tcmpt) {
			tcmpt_destroy(tcmpt);
		}
		jas_free(tile->tcmpts);
	}
	if (tile->lyrsizes) {
		jas_free(tile->lyrsizes);
	}
	if (tile->pi) {
		jpc_pi_destroy(tile->pi);
	}
	jas_free(tile);
}

Project: jasper

int jpc_encode(jas_image_t *image, jas_stream_t *out, char *optstr)
{
	jpc_enc_t *enc;
	jpc_enc_cp_t *cp;

	enc = 0;
	cp = 0;

	jpc_initluts();

	if (!(cp = cp_create(optstr, image))) {
		jas_eprintf("invalid JP encoder options\n");
		goto error;
	}

	if (!(enc = jpc_enc_create(cp, out, image))) {
		goto error;
	}
	cp = 0;

	/* Encode the main header. */
	if (jpc_enc_encodemainhdr(enc)) {
		goto error;
	}

	/* Encode the main body.  This constitutes most of the encoding work. */
	if (jpc_enc_encodemainbody(enc)) {
		goto error;
	}

	/* Write EOC marker segment. */
	if (!(enc->mrk = jpc_ms_create(JPC_MS_EOC))) {
		goto error;
	}
	if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
		jas_eprintf("cannot write EOI marker\n");
		goto error;
	}
	jpc_ms_destroy(enc->mrk);
	enc->mrk = 0;

	if (jas_stream_flush(enc->out)) {
		goto error;
	}

	jpc_enc_destroy(enc);

	return 0;

error:
	if (cp) {
		jpc_enc_cp_destroy(cp);
	}
	if (enc) {
		jpc_enc_destroy(enc);
	}
	return -1;
}

Project: jasper
File: jpc_enc.c

void jpc_quantize(jas_matrix_t *data, jpc_fix_t stepsize)
{
	int i;
	int j;
	jpc_fix_t t;

	if (stepsize == jpc_inttofix(1)) {
		return;
	}

	for (i = 0; i < jas_matrix_numrows(data); ++i) {
		for (j = 0; j < jas_matrix_numcols(data); ++j) {
			t = jas_matrix_get(data, i, j);

{
	if (t < 0) {
		t = jpc_fix_neg(jpc_fix_div(jpc_fix_neg(t), stepsize));
	} else {
		t = jpc_fix_div(t, stepsize);
	}
}

			jas_matrix_set(data, i, j, t);
		}
	}
}

Project: jasper
File: jpc_enc.c

static void pass_destroy(jpc_enc_pass_t *pass)
{
	/* XXX - need to free resources here */
}

Project: jasper
File: jpc_enc.c

static jpc_enc_prc_t *prc_create(jpc_enc_prc_t *prc, jpc_enc_cp_t *cp, jpc_enc_band_t *band)
{
	uint_fast32_t prcno;
	uint_fast32_t prcxind;
	uint_fast32_t prcyind;
	uint_fast32_t cbgtlx;
	uint_fast32_t cbgtly;
	uint_fast32_t tlprctlx;
	uint_fast32_t tlprctly;
	uint_fast32_t tlcbgtlx;
	uint_fast32_t tlcbgtly;
	uint_fast16_t rlvlno;
	jpc_enc_rlvl_t *rlvl;
	uint_fast32_t tlcblktlx;
	uint_fast32_t tlcblktly;
	uint_fast32_t brcblkbrx;
	uint_fast32_t brcblkbry;
	uint_fast32_t cblkno;
	jpc_enc_cblk_t *cblk;
	jpc_enc_tcmpt_t *tcmpt;

	prc->cblks = 0;
	prc->incltree = 0;
	prc->savincltree = 0;
	prc->nlibtree = 0;
	prc->savnlibtree = 0;

	rlvl = band->rlvl;
	tcmpt = rlvl->tcmpt;
rlvlno = rlvl - tcmpt->rlvls;
	prcno = prc - band->prcs;
	prcxind = prcno % rlvl->numhprcs;
	prcyind = prcno / rlvl->numhprcs;
	prc->band = band;

tlprctlx = JPC_FLOORTOMULTPOW2(rlvl->tlx, rlvl->prcwidthexpn);
tlprctly = JPC_FLOORTOMULTPOW2(rlvl->tly, rlvl->prcheightexpn);
if (!rlvlno) {
	tlcbgtlx = tlprctlx;
	tlcbgtly = tlprctly;
} else {
	tlcbgtlx = JPC_CEILDIVPOW2(tlprctlx, 1);
	tlcbgtly = JPC_CEILDIVPOW2(tlprctly, 1);
}

	/* Compute the coordinates of the top-left and bottom-right
	  corners of the precinct. */
	cbgtlx = tlcbgtlx + (prcxind << rlvl->cbgwidthexpn);
	cbgtly = tlcbgtly + (prcyind << rlvl->cbgheightexpn);
	prc->tlx = JAS_MAX(jas_seq2d_xstart(band->data), cbgtlx);
	prc->tly = JAS_MAX(jas_seq2d_ystart(band->data), cbgtly);
	prc->brx = JAS_MIN(jas_seq2d_xend(band->data), cbgtlx +
	  (1 << rlvl->cbgwidthexpn));
	prc->bry = JAS_MIN(jas_seq2d_yend(band->data), cbgtly +
	  (1 << rlvl->cbgheightexpn));

	if (prc->tlx < prc->brx && prc->tly < prc->bry) {
		/* The precinct contains at least one code block. */

		tlcblktlx = JPC_FLOORTOMULTPOW2(prc->tlx, rlvl->cblkwidthexpn);
		tlcblktly = JPC_FLOORTOMULTPOW2(prc->tly, rlvl->cblkheightexpn);
		brcblkbrx = JPC_CEILTOMULTPOW2(prc->brx, rlvl->cblkwidthexpn);
		brcblkbry = JPC_CEILTOMULTPOW2(prc->bry, rlvl->cblkheightexpn);
		prc->numhcblks = JPC_FLOORDIVPOW2(brcblkbrx - tlcblktlx,
		  rlvl->cblkwidthexpn);
		prc->numvcblks = JPC_FLOORDIVPOW2(brcblkbry - tlcblktly,
		  rlvl->cblkheightexpn);
		prc->numcblks = prc->numhcblks * prc->numvcblks;

		if (!(prc->incltree = jpc_tagtree_create(prc->numhcblks,
		  prc->numvcblks))) {
			goto error;
		}
		if (!(prc->nlibtree = jpc_tagtree_create(prc->numhcblks,
		  prc->numvcblks))) {
			goto error;
		}
		if (!(prc->savincltree = jpc_tagtree_create(prc->numhcblks,
		  prc->numvcblks))) {
			goto error;
		}
		if (!(prc->savnlibtree = jpc_tagtree_create(prc->numhcblks,
		  prc->numvcblks))) {
			goto error;
		}

		if (!(prc->cblks = jas_alloc2(prc->numcblks, sizeof(jpc_enc_cblk_t)))) {
			goto error;
		}
		for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks;
		  ++cblkno, ++cblk) {
			cblk->passes = 0;
			cblk->stream = 0;
			cblk->mqenc = 0;
			cblk->data = 0;
			cblk->flags = 0;
			cblk->prc = prc;
		}
		for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks;
		  ++cblkno, ++cblk) {
			if (!cblk_create(cblk, cp, prc)) {
				goto error;
			}
		}
	} else {
		/* The precinct does not contain any code blocks. */
		prc->tlx = prc->brx;
		prc->tly = prc->bry;
		prc->numcblks = 0;
		prc->numhcblks = 0;
		prc->numvcblks = 0;
		prc->cblks = 0;
		prc->incltree = 0;
		prc->nlibtree = 0;
		prc->savincltree = 0;
		prc->savnlibtree = 0;
	}

	return prc;

error:
	prc_destroy(prc);
	return 0;
}

Project: jasper

static void prc_destroy(jpc_enc_prc_t *prc)
{
	jpc_enc_cblk_t *cblk;
	uint_fast32_t cblkno;

	if (prc->cblks) {
		for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks;
		  ++cblkno, ++cblk) {
			cblk_destroy(cblk);
		}
		jas_free(prc->cblks);
	}
	if (prc->incltree) {
		jpc_tagtree_destroy(prc->incltree);
	}
	if (prc->nlibtree) {
		jpc_tagtree_destroy(prc->nlibtree);
	}
	if (prc->savincltree) {
		jpc_tagtree_destroy(prc->savincltree);
	}
	if (prc->savnlibtree) {
		jpc_tagtree_destroy(prc->savnlibtree);
	}
}

Project: jasper
File: jpc_enc.c

int rateallocate(jpc_enc_t *enc, int numlyrs, uint_fast32_t *cumlens)
{
	jpc_flt_t lo;
	jpc_flt_t hi;
	jas_stream_t *out;
	uint_fast32_t cumlen;
	int lyrno;
	jpc_flt_t thresh;
	jpc_flt_t goodthresh;
	int success;
	long pos;
	long oldpos;
	int numiters;

	jpc_enc_tcmpt_t *comp;
	jpc_enc_tcmpt_t *endcomps;
	jpc_enc_rlvl_t *lvl;
	jpc_enc_rlvl_t *endlvls;
	jpc_enc_band_t *band;
	jpc_enc_band_t *endbands;
	jpc_enc_cblk_t *cblk;
	jpc_enc_cblk_t *endcblks;
	jpc_enc_pass_t *pass;
	jpc_enc_pass_t *endpasses;
	jpc_enc_pass_t *pass1;
	jpc_flt_t mxrdslope;
	jpc_flt_t mnrdslope;
	jpc_enc_tile_t *tile;
	jpc_enc_prc_t *prc;
	int prcno;

	JAS_DBGLOG(10, ("starting rate allocation\n"));

	tile = enc->curtile;

	for (lyrno = 1; lyrno < numlyrs - 1; ++lyrno) {
		if (cumlens[lyrno - 1] > cumlens[lyrno]) {
			abort();
		}
	}

	if (!(out = jas_stream_memopen(0, 0))) {
		return -1;
	}


	/* Find minimum and maximum R-D slope values. */
	mnrdslope = DBL_MAX;
	mxrdslope = 0;
	endcomps = &tile->tcmpts[tile->numtcmpts];
	for (comp = tile->tcmpts; comp != endcomps; ++comp) {
		endlvls = &comp->rlvls[comp->numrlvls];
		for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
			if (!lvl->bands) {
				continue;
			}
			endbands = &lvl->bands[lvl->numbands];
			for (band = lvl->bands; band != endbands; ++band) {
				if (!band->data) {
					continue;
				}
				for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs;
				  ++prcno, ++prc) {
					if (!prc->cblks) {
						continue;
					}
					endcblks = &prc->cblks[prc->numcblks];
					for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
						calcrdslopes(cblk);
						endpasses = &cblk->passes[cblk->numpasses];
						for (pass = cblk->passes; pass != endpasses; ++pass) {
							if (pass->rdslope > 0) {
								if (pass->rdslope < mnrdslope) {
									mnrdslope = pass->rdslope;
								}
								if (pass->rdslope > mxrdslope) {
									mxrdslope = pass->rdslope;
								}
							}
						}
					}
				}
			}
		}
	}
	JAS_DBGLOG(10, ("min rdslope = %f max rdslope = %f\n", mnrdslope,
	  mxrdslope));

	jpc_init_t2state(enc, 1);

	for (lyrno = 0; lyrno < numlyrs; ++lyrno) {

		lo = mnrdslope;
		hi = mxrdslope;

		success = 0;
		goodthresh = 0;
		numiters = 0;

		do {

			cumlen = cumlens[lyrno];
			if (cumlen == UINT_FAST32_MAX) {
				/* Only the last layer can be free of a rate
				  constraint (e.g., for lossless coding). */
				assert(lyrno == numlyrs - 1);
				goodthresh = -1;
				success = 1;
				break;
			}

			thresh = (lo + hi) / 2;

			/* Save the tier 2 coding state. */
			jpc_save_t2state(enc);
			oldpos = jas_stream_tell(out);
			assert(oldpos >= 0);

			/* Assign all passes with R-D slopes greater than or
			  equal to the current threshold to this layer. */
			endcomps = &tile->tcmpts[tile->numtcmpts];
			for (comp = tile->tcmpts; comp != endcomps; ++comp) {
				endlvls = &comp->rlvls[comp->numrlvls];
				for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
					if (!lvl->bands) {
						continue;
					}
					endbands = &lvl->bands[lvl->numbands];
					for (band = lvl->bands; band != endbands; ++band) {
						if (!band->data) {
							continue;
						}
						for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs;
						  ++prcno, ++prc) {
							if (!prc->cblks) {
								continue;
							}
							endcblks = &prc->cblks[prc->numcblks];
							for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
								if (cblk->curpass) {
									endpasses = &cblk->passes[cblk->numpasses];
									pass1 = cblk->curpass;
									for (pass = cblk->curpass; pass !=
									  endpasses; ++pass) {
										if (pass->rdslope >= thresh) {
											pass1 = &pass[1];
										}
									}
									for (pass = cblk->curpass; pass != pass1;
									  ++pass) {
										pass->lyrno = lyrno;
									}
									for (; pass != endpasses; ++pass) {
										pass->lyrno = -1;
									}
								}
							}
						}
					}
				}
			}

			/* Perform tier 2 coding. */
			endcomps = &tile->tcmpts[tile->numtcmpts];
			for (comp = tile->tcmpts; comp != endcomps; ++comp) {
				endlvls = &comp->rlvls[comp->numrlvls];
				for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
					if (!lvl->bands) {
						continue;
					}
					for (prcno = 0; prcno < lvl->numprcs; ++prcno) {
						if (jpc_enc_encpkt(enc, out, comp - tile->tcmpts,
						  lvl - comp->rlvls, prcno, lyrno)) {
							return -1;
						}
					}
				}
			}

			pos = jas_stream_tell(out);

			/* Check the rate constraint. */
			assert(pos >= 0);
			if (pos > cumlen) {
				/* The rate is too high. */
				lo = thresh;
			} else if (pos <= cumlen) {
				/* The rate is low enough, so try higher. */
				hi = thresh;
				if (!success || thresh < goodthresh) {
					goodthresh = thresh;
					success = 1;
				}
			}

			/* Save the tier 2 coding state. */
			jpc_restore_t2state(enc);
			if (jas_stream_seek(out, oldpos, SEEK_SET) < 0) {
				abort();
			}

			JAS_DBGLOG(10, ("maxlen=%08ld actuallen=%08ld thresh=%f\n",
			  cumlen, pos, thresh));

			++numiters;
		} while (lo < hi - 1e-3 && numiters < 32);

		if (!success) {
			jas_eprintf("warning: empty layer generated\n");
		}

		JAS_DBGLOG(10, ("success %d goodthresh %f\n", success, goodthresh));

		/* Assign all passes with R-D slopes greater than or
		  equal to the selected threshold to this layer. */
		endcomps = &tile->tcmpts[tile->numtcmpts];
		for (comp = tile->tcmpts; comp != endcomps; ++comp) {
			endlvls = &comp->rlvls[comp->numrlvls];
			for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
				if (!lvl->bands) {
					continue;
				}
				endbands = &lvl->bands[lvl->numbands];
				for (band = lvl->bands; band != endbands; ++band) {
					if (!band->data) {
						continue;
					}
					for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs;
					  ++prcno, ++prc) {
						if (!prc->cblks) {
							continue;
						}
						endcblks = &prc->cblks[prc->numcblks];
						for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
							if (cblk->curpass) {
								endpasses = &cblk->passes[cblk->numpasses];
								pass1 = cblk->curpass;
								if (success) {
									for (pass = cblk->curpass; pass !=
									  endpasses; ++pass) {
										if (pass->rdslope >= goodthresh) {
											pass1 = &pass[1];
										}
									}
								}
								for (pass = cblk->curpass; pass != pass1;
								  ++pass) {
									pass->lyrno = lyrno;
								}
								for (; pass != endpasses; ++pass) {
									pass->lyrno = -1;
								}
							}
						}
					}
				}
			}
		}

		/* Perform tier 2 coding. */
		endcomps = &tile->tcmpts[tile->numtcmpts];
		for (comp = tile->tcmpts; comp != endcomps; ++comp) {
			endlvls = &comp->rlvls[comp->numrlvls];
			for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
				if (!lvl->bands) {
					continue;
				}
				for (prcno = 0; prcno < lvl->numprcs; ++prcno) {
					if (jpc_enc_encpkt(enc, out, comp - tile->tcmpts,
					  lvl - comp->rlvls, prcno, lyrno)) {
						return -1;
					}
				}
			}
		}
	}

	if (jas_getdbglevel() >= 5) {
		dump_layeringinfo(enc);
	}

	jas_stream_close(out);

	JAS_DBGLOG(10, ("finished rate allocation\n"));

	return 0;
}

Project: jasper

int ratestrtosize(char *s, uint_fast32_t rawsize, uint_fast32_t *size)
{
	jpc_flt_t f;

	/* Note: This function must not modify output size on failure. */
	if (strchr(s, 'B')) {
		*size = atoi(s);
	} else {
		f = atof(s);
		if (f < 0) {
			*size = 0;
		} else if (f > 1.0) {
			*size = rawsize + 1;
		} else {
			*size = f * rawsize;
		}
	}
	return 0;
}

Project: jasper
File: jpc_enc.c

static jpc_enc_rlvl_t *rlvl_create(jpc_enc_rlvl_t *rlvl, jpc_enc_cp_t *cp,
  jpc_enc_tcmpt_t *tcmpt, jpc_tsfb_band_t *bandinfos)
{
	uint_fast16_t rlvlno;
	uint_fast32_t tlprctlx;
	uint_fast32_t tlprctly;
	uint_fast32_t brprcbrx;
	uint_fast32_t brprcbry;
	uint_fast16_t bandno;
	jpc_enc_band_t *band;

	/* Deduce the resolution level. */
	rlvlno = rlvl - tcmpt->rlvls;

	/* Initialize members required for error recovery. */
	rlvl->bands = 0;
	rlvl->tcmpt = tcmpt;

	/* Compute the coordinates of the top-left and bottom-right
	  corners of the tile-component at this resolution. */
	rlvl->tlx = JPC_CEILDIVPOW2(jas_seq2d_xstart(tcmpt->data), tcmpt->numrlvls -
	  1 - rlvlno);
	rlvl->tly = JPC_CEILDIVPOW2(jas_seq2d_ystart(tcmpt->data), tcmpt->numrlvls -
	  1 - rlvlno);
	rlvl->brx = JPC_CEILDIVPOW2(jas_seq2d_xend(tcmpt->data), tcmpt->numrlvls -
	  1 - rlvlno);
	rlvl->bry = JPC_CEILDIVPOW2(jas_seq2d_yend(tcmpt->data), tcmpt->numrlvls -
	  1 - rlvlno);

	if (rlvl->tlx >= rlvl->brx || rlvl->tly >= rlvl->bry) {
		rlvl->numhprcs = 0;
		rlvl->numvprcs = 0;
		rlvl->numprcs = 0;
		return rlvl;
	}

	rlvl->numbands = (!rlvlno) ? 1 : 3;
	rlvl->prcwidthexpn = cp->tccp.prcwidthexpns[rlvlno];
	rlvl->prcheightexpn = cp->tccp.prcheightexpns[rlvlno];
	if (!rlvlno) {
		rlvl->cbgwidthexpn = rlvl->prcwidthexpn;
		rlvl->cbgheightexpn = rlvl->prcheightexpn;
	} else {
		rlvl->cbgwidthexpn = rlvl->prcwidthexpn - 1;
		rlvl->cbgheightexpn = rlvl->prcheightexpn - 1;
	}
	rlvl->cblkwidthexpn = JAS_MIN(cp->tccp.cblkwidthexpn, rlvl->cbgwidthexpn);
	rlvl->cblkheightexpn = JAS_MIN(cp->tccp.cblkheightexpn, rlvl->cbgheightexpn);

	/* Compute the number of precincts. */
	tlprctlx = JPC_FLOORTOMULTPOW2(rlvl->tlx, rlvl->prcwidthexpn);
	tlprctly = JPC_FLOORTOMULTPOW2(rlvl->tly, rlvl->prcheightexpn);
	brprcbrx = JPC_CEILTOMULTPOW2(rlvl->brx, rlvl->prcwidthexpn);
	brprcbry = JPC_CEILTOMULTPOW2(rlvl->bry, rlvl->prcheightexpn);
	rlvl->numhprcs = JPC_FLOORDIVPOW2(brprcbrx - tlprctlx, rlvl->prcwidthexpn);
	rlvl->numvprcs = JPC_FLOORDIVPOW2(brprcbry - tlprctly, rlvl->prcheightexpn);
	rlvl->numprcs = rlvl->numhprcs * rlvl->numvprcs;

	if (!(rlvl->bands = jas_alloc2(rlvl->numbands, sizeof(jpc_enc_band_t)))) {
		goto error;
	}
	for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
	  ++bandno, ++band) {
		band->prcs = 0;
		band->data = 0;
		band->rlvl = rlvl;
	}
	for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
	  ++bandno, ++band) {
		if (!band_create(band, cp, rlvl, bandinfos)) {
			goto error;
		}
	}

	return rlvl;
error:

	rlvl_destroy(rlvl);
	return 0;
}

Project: jasper

static void tcmpt_destroy(jpc_enc_tcmpt_t *tcmpt)
{
	jpc_enc_rlvl_t *rlvl;
	uint_fast16_t rlvlno;

	if (tcmpt->rlvls) {
		for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
		  ++rlvlno, ++rlvl) {
			rlvl_destroy(rlvl);
		}
		jas_free(tcmpt->rlvls);
	}

	if (tcmpt->data) {
		jas_seq2d_destroy(tcmpt->data);
	}
	if (tcmpt->tsfb) {
		jpc_tsfb_destroy(tcmpt->tsfb);
	}
}

Project: jasper

static int jpg_copystreamtofile(FILE *out, jas_stream_t *in)
{
	int c;

	while ((c = jas_stream_getc(in)) != EOF) {
		if (fputc(c, out) == EOF) {
			return -1;
		}
	}
	if (jas_stream_error(in)) {
		return -1;
	}
	return 0;
}

Project: jasper

static void jpg_finish_output(j_decompress_ptr cinfo, jpg_dest_t *dinfo)
{
	JAS_DBGLOG(10, ("jpg_finish_output(%p, %p)\n", cinfo, dinfo));

	/* Avoid compiler warnings about unused parameters. */
	cinfo = 0;
	dinfo = 0;
}

Project: jasper

static jas_image_t *jpg_mkimage(j_decompress_ptr cinfo)
{
	jas_image_t *image;
	int cmptno;
	jas_image_cmptparm_t cmptparm;
	int numcmpts;

	JAS_DBGLOG(10, ("jpg_mkimage(%p)\n", cinfo));

	image = 0;
	numcmpts = cinfo->output_components;
	if (!(image = jas_image_create0())) {
		goto error;
	}
	for (cmptno = 0; cmptno < numcmpts; ++cmptno) {
		if (cinfo->image_width > JAS_IMAGE_COORD_MAX ||
		  cinfo->image_height > JAS_IMAGE_COORD_MAX) {
			goto error;
		}
		cmptparm.tlx = 0;
		cmptparm.tly = 0;
		cmptparm.hstep = 1;
		cmptparm.vstep = 1;
		cmptparm.width = cinfo->image_width;
		cmptparm.height = cinfo->image_height;
		cmptparm.prec = 8;
		cmptparm.sgnd = false;
		if (jas_image_addcmpt(image, cmptno, &cmptparm)) {
			goto error;
		}
	}

	if (numcmpts == 3) {
		jas_image_setclrspc(image, JAS_CLRSPC_SRGB);
		jas_image_setcmpttype(image, 0,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
		jas_image_setcmpttype(image, 1,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
		jas_image_setcmpttype(image, 2,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
	} else {
		jas_image_setclrspc(image, JAS_CLRSPC_SGRAY);
		jas_image_setcmpttype(image, 0,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
	}

	return image;

error:
	if (image) {
		jas_image_destroy(image);
	}
	return 0;
}

Project: jasper

static void jpg_put_pixel_rows(j_decompress_ptr cinfo, jpg_dest_t *dinfo,
  JDIMENSION rows_supplied)
{
	JSAMPLE *bufptr;
	int cmptno;
	JDIMENSION x;
	uint_fast32_t width;

	JAS_DBGLOG(10, ("jpg_put_pixel_rows(%p, %p)\n", cinfo, dinfo));

	if (dinfo->error) {
		return;
	}

	assert(cinfo->output_components == jas_image_numcmpts(dinfo->image));

	for (cmptno = 0; cmptno < cinfo->output_components; ++cmptno) {
		width = jas_image_cmptwidth(dinfo->image, cmptno);
		bufptr = (dinfo->buffer[0]) + cmptno;
		for (x = 0; x < width; ++x) {
			jas_matrix_set(dinfo->data, 0, x, GETJSAMPLE(*bufptr));
			bufptr += cinfo->output_components;
		}
		JAS_DBGLOG(10, (
		  "jas_image_writecmpt called for component %d row %lu\n", cmptno,
		  JAS_CAST(unsigned long, dinfo->row)));
		if (jas_image_writecmpt(dinfo->image, cmptno, 0, dinfo->row, width, 1,
		  dinfo->data)) {
			dinfo->error = 1;
		}
	}
	dinfo->row += rows_supplied;
}

Project: jasper

static void jpg_start_output(j_decompress_ptr cinfo, jpg_dest_t *dinfo)
{
	/* Avoid compiler warnings about unused parameters. */
	cinfo = 0;

	JAS_DBGLOG(10, ("jpg_start_output(%p, %p)\n", cinfo, dinfo));

	dinfo->row = 0;
}

Project: jasper
File: mif_cod.c

static mif_cmpt_t *mif_cmpt_create()
{
	mif_cmpt_t *cmpt;
	if (!(cmpt = jas_malloc(sizeof(mif_cmpt_t)))) {
		return 0;
	}
	memset(cmpt, 0, sizeof(mif_cmpt_t));
	return cmpt;
}

Project: jasper
File: mif_cod.c

static void mif_cmpt_destroy(mif_cmpt_t *cmpt)
{
	if (cmpt->data) {
		jas_free(cmpt->data);
	}
	jas_free(cmpt);
}

Project: jasper

int mif_encode(jas_image_t *image, jas_stream_t *out, char *optstr)
{
	mif_hdr_t *hdr;
	jas_image_t *tmpimage;
	int fmt;
	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;

	hdr = 0;
	tmpimage = 0;
	data = 0;

	if (optstr && *optstr != '\0') {
		jas_eprintf("warning: ignoring unsupported options\n");
	}

	if ((fmt = jas_image_strtofmt("pnm")) < 0) {
		jas_eprintf("error: PNM support required\n");
		goto error;
	}

	if (!(hdr = mif_makehdrfromimage(image))) {
		goto error;
	}
	if (mif_hdr_put(hdr, out)) {
		goto error;
	}

	/* Output component data. */
	for (cmptno = 0; cmptno < hdr->numcmpts; ++cmptno) {
		cmpt = hdr->cmpts[cmptno];
		if (!cmpt->data) {
			if (!(tmpimage = jas_image_create0())) {
				goto error;
			}	
			cmptparm.tlx = 0;
			cmptparm.tly = 0;
			cmptparm.hstep = cmpt->sampperx;
			cmptparm.vstep = cmpt->samppery;
			cmptparm.width = cmpt->width;
			cmptparm.height = cmpt->height;
			cmptparm.prec = cmpt->prec;
			cmptparm.sgnd = false;
			if (jas_image_addcmpt(tmpimage, jas_image_numcmpts(tmpimage),
			  &cmptparm)) {
				goto error;
			}
			jas_image_setclrspc(tmpimage, JAS_CLRSPC_SGRAY);
			jas_image_setcmpttype(tmpimage, 0,
			  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
			if (!(data = jas_seq2d_create(0, 0, cmpt->width, cmpt->height))) {
				goto error;
			}
			if (jas_image_readcmpt(image, cmptno, 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(tmpimage, 0, 0, 0, cmpt->width,
			  cmpt->height, data)) {
				goto error;
			}
			jas_seq2d_destroy(data);
			data = 0;
			if (jas_image_encode(tmpimage, out, fmt, 0)) {
				goto error;
			}
			jas_image_destroy(tmpimage);
			tmpimage = 0;
		}
	}

	mif_hdr_destroy(hdr);

	return 0;

error:
	if (hdr) {
		mif_hdr_destroy(hdr);
	}
	if (tmpimage) {
		jas_image_destroy(tmpimage);
	}
	if (data) {
		jas_seq2d_destroy(data);
	}
	return -1;
}

Project: jasper

static int mif_getc(jas_stream_t *in)
{
	int c;
	bool done;

	done = false;
	do {
		switch (c = jas_stream_getc(in)) {
		case EOF:
			done = true;
			break;
		case '#':
			for (;;) {
				if ((c = jas_stream_getc(in)) == EOF) {
					done = true;
					break;
				}	
				if (c == '\n') {
					done = true;
					break;
				}
			}
			break;
		case '\\':
			if (jas_stream_peekc(in) == '\n') {
				jas_stream_getc(in);
			}
			break;
		default:
			done = true;
			break;
		}
	} while (!done);

	return c;
}

Project: jasper
File: mif_cod.c

static char *mif_getline(jas_stream_t *stream, char *buf, int bufsize)
{
	int c;
	char *bufptr;
	assert(bufsize > 0);

	bufptr = buf;
	while (bufsize > 1) {
		if ((c = mif_getc(stream)) == EOF) {
			break;
		}
		*bufptr++ = c;
		--bufsize;
		if (c == '\n') {
			break;
		}
	}
	*bufptr = '\0';
	if (!(bufptr = strchr(buf, '\n'))) {
		return 0;
	}
	*bufptr = '\0';
	return buf;
}

Project: jasper
File: mif_cod.c

static int mif_hdr_addcmpt(mif_hdr_t *hdr, int cmptno, mif_cmpt_t *cmpt)
{
	assert(cmptno >= hdr->numcmpts);
	if (hdr->numcmpts >= hdr->maxcmpts) {
		if (mif_hdr_growcmpts(hdr, hdr->numcmpts + 128)) {
			return -1;
		}
	}
	hdr->cmpts[hdr->numcmpts] = cmpt;
	++hdr->numcmpts;
	return 0;
}

Project: jasper
File: mif_cod.c

static mif_hdr_t *mif_hdr_create(int maxcmpts)
{
	mif_hdr_t *hdr;
	if (!(hdr = jas_malloc(sizeof(mif_hdr_t)))) {
		return 0;
	}
	hdr->numcmpts = 0;
	hdr->maxcmpts = 0;
	hdr->cmpts = 0;
	if (mif_hdr_growcmpts(hdr, maxcmpts)) {
		mif_hdr_destroy(hdr);
		return 0;
	}
	return hdr;
}

Project: jasper
File: mif_cod.c

static void mif_hdr_destroy(mif_hdr_t *hdr)
{
	int cmptno;
	if (hdr->cmpts) {
		for (cmptno = 0; cmptno < hdr->numcmpts; ++cmptno) {
			mif_cmpt_destroy(hdr->cmpts[cmptno]);
		}
		jas_free(hdr->cmpts);
	}
	jas_free(hdr);
}

Project: jasper

static int mif_hdr_growcmpts(mif_hdr_t *hdr, int maxcmpts)
{
	int cmptno;
	mif_cmpt_t **newcmpts;
	assert(maxcmpts >= hdr->numcmpts);
	newcmpts = (!hdr->cmpts) ? jas_alloc2(maxcmpts, sizeof(mif_cmpt_t *)) :
	  jas_realloc2(hdr->cmpts, maxcmpts, sizeof(mif_cmpt_t *));
	if (!newcmpts) {
		return -1;
	}
	hdr->maxcmpts = maxcmpts;
	hdr->cmpts = newcmpts;
	for (cmptno = hdr->numcmpts; cmptno < hdr->maxcmpts; ++cmptno) {
		hdr->cmpts[cmptno] = 0;
	}
	return 0;
}

Project: jasper
File: mif_cod.c

static int mif_hdr_put(mif_hdr_t *hdr, jas_stream_t *out)
{
	int cmptno;
	mif_cmpt_t *cmpt;

	/* Output signature. */
	jas_stream_putc(out, (MIF_MAGIC >> 24) & 0xff);
	jas_stream_putc(out, (MIF_MAGIC >> 16) & 0xff);
	jas_stream_putc(out, (MIF_MAGIC >> 8) & 0xff);
	jas_stream_putc(out, MIF_MAGIC & 0xff);

	/* Output component information. */
	for (cmptno = 0; cmptno < hdr->numcmpts; ++cmptno) {
		cmpt = hdr->cmpts[cmptno];
		jas_stream_printf(out, "component tlx=%ld tly=%ld "
		  "sampperx=%ld samppery=%ld width=%ld height=%ld prec=%d sgnd=%d",
		  cmpt->tlx, cmpt->tly, cmpt->sampperx, cmpt->samppery, cmpt->width,
		  cmpt->height, cmpt->prec, cmpt->sgnd);
		if (cmpt->data) {
			jas_stream_printf(out, " data=%s", cmpt->data);
		}
		jas_stream_printf(out, "\n");
	}

	/* Output end of header indicator. */
	jas_stream_printf(out, "end\n");

	return 0;
}

Project: jasper

static mif_hdr_t *mif_makehdrfromimage(jas_image_t *image)
{
	mif_hdr_t *hdr;
	int cmptno;
	mif_cmpt_t *cmpt;

	if (!(hdr = mif_hdr_create(jas_image_numcmpts(image)))) {
		return 0;
	}
	hdr->magic = MIF_MAGIC;
	hdr->numcmpts = jas_image_numcmpts(image);
	for (cmptno = 0; cmptno < hdr->numcmpts; ++cmptno) {
		if (!(hdr->cmpts[cmptno] = jas_malloc(sizeof(mif_cmpt_t)))) {
			goto error;
		}
		cmpt = hdr->cmpts[cmptno];
		cmpt->tlx = jas_image_cmpttlx(image, cmptno);
		cmpt->tly = jas_image_cmpttly(image, cmptno);
		cmpt->width = jas_image_cmptwidth(image, cmptno);
		cmpt->height = jas_image_cmptheight(image, cmptno);
		cmpt->sampperx = jas_image_cmpthstep(image, cmptno);
		cmpt->samppery = jas_image_cmptvstep(image, cmptno);
		cmpt->prec = jas_image_cmptprec(image, cmptno);
		cmpt->sgnd = jas_image_cmptsgnd(image, cmptno);
		cmpt->data = 0;
	}
	return hdr;

error:
	for (cmptno = 0; cmptno < hdr->numcmpts; ++cmptno) {
		if (hdr->cmpts[cmptno]) {
			jas_free(hdr->cmpts[cmptno]);
		}
	}
	if (hdr) {
		jas_free(hdr);
	}
	return 0;
}

Project: jasper

static int mif_process_cmpt(mif_hdr_t *hdr, char *buf)
{
	jas_tvparser_t *tvp;
	mif_cmpt_t *cmpt;
	int id;

	cmpt = 0;
	tvp = 0;

	if (!(cmpt = mif_cmpt_create())) {
		jas_eprintf("cannot create component\n");
		goto error;
	}
	cmpt->tlx = 0;
	cmpt->tly = 0;
	cmpt->sampperx = 0;
	cmpt->samppery = 0;
	cmpt->width = 0;
	cmpt->height = 0;
	cmpt->prec = 0;
	cmpt->sgnd = -1;
	cmpt->data = 0;

	if (!(tvp = jas_tvparser_create(buf))) {
		jas_eprintf("cannot create parser\n");
		goto error;
	}

	if ((id = jas_tvparser_next(tvp))) {
		abort();
	}

	while (!(id = jas_tvparser_next(tvp))) {
		switch (jas_taginfo_nonull(jas_taginfos_lookup(mif_tags,
		  jas_tvparser_gettag(tvp)))->id) {
		case MIF_TLX:
			cmpt->tlx = atoi(jas_tvparser_getval(tvp));
			break;
		case MIF_TLY:
			cmpt->tly = atoi(jas_tvparser_getval(tvp));
			break;
		case MIF_WIDTH:
			cmpt->width = atoi(jas_tvparser_getval(tvp));
			break;
		case MIF_HEIGHT:
			cmpt->height = atoi(jas_tvparser_getval(tvp));
			break;
		case MIF_HSAMP:
			cmpt->sampperx = atoi(jas_tvparser_getval(tvp));
			break;
		case MIF_VSAMP:
			cmpt->samppery = atoi(jas_tvparser_getval(tvp));
			break;
		case MIF_PREC:
			cmpt->prec = atoi(jas_tvparser_getval(tvp));
			break;
		case MIF_SGND:
			cmpt->sgnd = atoi(jas_tvparser_getval(tvp));
			break;
		case MIF_DATA:
			if (!(cmpt->data = jas_strdup(jas_tvparser_getval(tvp)))) {
				goto error;
			}
			break;
		default:
			jas_eprintf("invalid component information: %s\n", buf);
			goto error;
			break;
		}
	}
	if (!cmpt->sampperx || !cmpt->samppery) {
		goto error;
	}
	if (!cmpt->width || !cmpt->height || !cmpt->prec || cmpt->sgnd < 0) {
		goto error;
	}
	if (mif_hdr_addcmpt(hdr, hdr->numcmpts, cmpt)) {
		jas_eprintf("cannot add component\n");
		goto error;
	}
	jas_tvparser_destroy(tvp);
	return 0;

error:
	if (cmpt) {
		mif_cmpt_destroy(cmpt);
	}
	if (tvp) {
		jas_tvparser_destroy(tvp);
	}
	return -1;
}

Project: jasper

jas_image_t *pgx_decode(jas_stream_t *in, char *optstr)
{
	jas_image_t *image;
	pgx_hdr_t hdr;
	jas_image_cmptparm_t cmptparm;

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

	image = 0;

	if (pgx_gethdr(in, &hdr)) {
		jas_eprintf("cannot get header\n");
		goto error;
	}

	if (jas_getdbglevel() >= 10) {
		pgx_dumphdr(stderr, &hdr);
	}

	if (!(image = jas_image_create0())) {
		goto error;
	}
	cmptparm.tlx = 0;
	cmptparm.tly = 0;
	cmptparm.hstep = 1;
	cmptparm.vstep = 1;
	cmptparm.width = hdr.width;
	cmptparm.height = hdr.height;
	cmptparm.prec = hdr.prec;
	cmptparm.sgnd = hdr.sgnd;
	if (jas_image_addcmpt(image, 0, &cmptparm)) {
		goto error;
	}
	if (pgx_getdata(in, &hdr, image)) {
		jas_eprintf("cannot get data\n");
		goto error;
	}

	jas_image_setclrspc(image, JAS_CLRSPC_SGRAY);
	jas_image_setcmpttype(image, 0,
	  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));

	return image;

error:
	if (image) {
		jas_image_destroy(image);
	}
	return 0;
}

Project: jasper

static int pgx_getbyteorder(jas_stream_t *in, bool *bigendian)
{
	int c;
	char buf[2];

	do {
		if ((c = pgx_getc(in)) == EOF) {
			return -1;
		}
	} while (isspace(c));

	buf[0] = c;
	if ((c = pgx_getc(in)) == EOF) {
		goto error;
	}
	buf[1] = c;
	if (buf[0] == 'M' && buf[1] == 'L') {
		*bigendian = true;
	} else if (buf[0] == 'L' && buf[1] == 'M') {
		*bigendian = false;
	} else {
		goto error;
	}

	while ((c = pgx_getc(in)) != EOF && !isspace(c)) {
		;
	}
	if (c == EOF) {
		goto error;
	}
	return 0;

error:
	return -1;
}

Project: jasper

static int pgx_getc(jas_stream_t *in)
{
	int c;
	for (;;) {
		if ((c = jas_stream_getc(in)) == EOF) {
			return -1;
		}
		if (c != '#') {
			return c;
		}
		do {
			if ((c = jas_stream_getc(in)) == EOF) {
				return -1;
			}
		} while (c != '\n' && c != '\r');
	}
}

Project: jasper

static int pgx_getdata(jas_stream_t *in, pgx_hdr_t *hdr, jas_image_t *image)
{
	jas_matrix_t *data;
	uint_fast32_t x;
	uint_fast32_t y;
	uint_fast32_t word;
	int_fast32_t v;

	data = 0;

	if (!(data = jas_matrix_create(1, hdr->width))) {
		goto error;
	}
	for (y = 0; y < hdr->height; ++y) {
		for (x = 0; x < hdr->width; ++x) {
			/* Need to adjust signed value. */
			if ((v = pgx_getword(in, hdr->bigendian, hdr->prec)) < 0) {
				goto error;
			}
			word = v;
			v = pgx_wordtoint(word, hdr->prec, hdr->sgnd);
			jas_matrix_set(data, 0, x, v);
		}
		if (jas_image_writecmpt(image, 0, 0, y, hdr->width, 1, data)) {
			goto error;
		}
	}
	jas_matrix_destroy(data);
	return 0;

error:
	if (data) {
		jas_matrix_destroy(data);
	}
	return -1;
}

Project: jasper

static int pgx_getsgnd(jas_stream_t *in, bool *sgnd)
{
	int c;

	do {
		if ((c = pgx_getc(in)) == EOF) {
			return -1;
		}
	} while (isspace(c));

#if 0
	if (c == '+') {
		*sgnd = false;
	} else if (c == '-') {
		*sgnd = true;
	} else {
		*sgnd = false;
		if (jas_stream_ungetc(in, c)) {
			goto error;
		}
		return 0;
	}

	while ((c = pgx_getc(in)) != EOF && !isspace(c)) {
		;
	}
	if (c == EOF) {
		goto error;
	}
#else
	if (c == '+' || c == '-') {
		*sgnd = (c == '-');
		while ((c = pgx_getc(in)) != EOF && !isspace(c)) {
			;
		}
		if (c == EOF) {
			goto error;
		}
	} else {
		*sgnd = false;
		if (jas_stream_ungetc(in, c)) {
			goto error;
		}
	}
#endif

	return 0;

error:
	return -1;
}

Project: jasper

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

	do {
		if ((c = pgx_getc(in)) == EOF) {
			return -1;
		}
	} while (isspace(c));

	v = 0;
	while (isdigit(c)) {
		v = 10 * v + c - '0';
		if ((c = pgx_getc(in)) < 0) {
			return -1;
		}
	}
	if (!isspace(c)) {
		return -1;
	}
	*val = v;

	return 0;
}

Project: jasper

static int_fast32_t pgx_getword(jas_stream_t *in, bool bigendian, int prec)
{
	uint_fast32_t val;
	int i;
	int j;
	int c;
	int wordsize;

	wordsize = (prec + 7) / 8;

	if (prec > 32) {
		goto error;
	}

	val = 0;
	for (i = 0; i < wordsize; ++i) {
		if ((c = jas_stream_getc(in)) == EOF) {
			goto error;
		}
		j = bigendian ? (wordsize - 1 - i) : i;
		val = val | ((c & 0xff) << (8 * j));
	}
	val &= (1 << prec) - 1;
	return val;

error:
	return -1;
}

Project: jasper

static jas_seqent_t pgx_wordtoint(uint_fast32_t v, int prec, bool sgnd)
{
	jas_seqent_t ret;
	v &= (1 << prec) - 1;
	ret = (sgnd && (v & (1 << (prec - 1)))) ? (v - (1 << prec)) : v;
	return ret;
}

Project: jasper

jas_image_t *pnm_decode(jas_stream_t *in, char *opts)
{
	pnm_hdr_t hdr;
	jas_image_t *image;
	jas_image_cmptparm_t cmptparms[3];
	jas_image_cmptparm_t *cmptparm;
	int i;

	JAS_DBGLOG(10, ("pnm_decode(%p, \"%s\")\n", in, opts ? opts : ""));

	if (opts) {
		jas_eprintf("warning: ignoring options\n");
	}

	/* Read the file header. */
	if (pnm_gethdr(in, &hdr)) {
		return 0;
	}
	JAS_DBGLOG(10, (
	  "magic %lx; width %lu; height %ld; numcmpts %d; maxval %ld; sgnd %d\n",
	  JAS_CAST(unsigned long, hdr.magic), JAS_CAST(long, hdr.width),
	  JAS_CAST(long, hdr.height), hdr.numcmpts, JAS_CAST(long, hdr.maxval),
	  hdr.sgnd)
	  );

	/* Create an image of the correct size. */
	for (i = 0, cmptparm = cmptparms; i < hdr.numcmpts; ++i, ++cmptparm) {
		cmptparm->tlx = 0;
		cmptparm->tly = 0;
		cmptparm->hstep = 1;
		cmptparm->vstep = 1;
		cmptparm->width = hdr.width;
		cmptparm->height = hdr.height;
		cmptparm->prec = pnm_maxvaltodepth(hdr.maxval);
		cmptparm->sgnd = hdr.sgnd;
	}
	if (!(image = jas_image_create(hdr.numcmpts, cmptparms,
	  JAS_CLRSPC_UNKNOWN))) {
		return 0;
	}

	if (hdr.numcmpts == 3) {
		jas_image_setclrspc(image, JAS_CLRSPC_SRGB);
		jas_image_setcmpttype(image, 0,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
		jas_image_setcmpttype(image, 1,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
		jas_image_setcmpttype(image, 2,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
	} else {
		jas_image_setclrspc(image, JAS_CLRSPC_SGRAY);
		jas_image_setcmpttype(image, 0,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
	}

	/* Read image data from stream into image. */
	if (pnm_getdata(in, &hdr, image)) {
		jas_image_destroy(image);
		return 0;
	}

	return image;
}

Project: jasper

static int pnm_getc(jas_stream_t *in)
{
	int c;
	for (;;) {
		if ((c = jas_stream_getc(in)) == EOF) {
			return -1;
		}
		if (c != '#') {
			return c;
		}
		do {
			if ((c = jas_stream_getc(in)) == EOF) {
				return -1;
			}
		} while (c != '\n' && c != '\r');
	}
}

Project: jasper

static int pnm_getdata(jas_stream_t *in, pnm_hdr_t *hdr, jas_image_t *image)
{
	int ret;
#if 0
	int numcmpts;
#endif
	int cmptno;
	int fmt;
	jas_matrix_t *data[3];
	int x;
	int y;
	int_fast64_t v;
	int depth;
	int type;
	int c;
	int n;

	ret = -1;

#if 0
	numcmpts = jas_image_numcmpts(image);
#endif
	fmt = pnm_fmt(hdr->magic);
	type = pnm_type(hdr->magic);
	assert(type != PNM_TYPE_INVALID);
	depth = pnm_maxvaltodepth(hdr->maxval);

	data[0] = 0;
	data[1] = 0;
	data[2] = 0;
	for (cmptno = 0; cmptno < hdr->numcmpts; ++cmptno) {
		if (!(data[cmptno] = jas_matrix_create(1, hdr->width))) {
			goto done;
		}
	}

	for (y = 0; y < hdr->height; ++y) {
		if (type == PNM_TYPE_PBM) {
			if (fmt == PNM_FMT_BIN) {
				for (x = 0; x < hdr->width;) {
					if ((c = jas_stream_getc(in)) == EOF) {
						goto done;
					}
					n = 8;
					while (n > 0 && x < hdr->width) {
						jas_matrix_set(data[0], 0, x, 1 - ((c >> 7) & 1));
						c <<= 1;
						--n;
						++x;
					}
				}
			} else {
				for (x = 0; x < hdr->width; ++x) {
					int uv;
					if (pnm_getbitstr(in, &uv)) {
						goto done;
					}
					jas_matrix_set(data[0], 0, x, 1 - uv);
				}
			}
		} else {
			for (x = 0; x < hdr->width; ++x) {
				for (cmptno = 0; cmptno < hdr->numcmpts; ++cmptno) {
					if (fmt == PNM_FMT_BIN) {
						/* The sample data is in binary format. */
						if (hdr->sgnd) {
							/* The sample data is signed. */
							int_fast32_t sv;
							if (pnm_getsint(in, depth, &sv)) {
								if (!pnm_allowtrunc) {
									goto done;
								}
								jas_eprintf("bad sample data\n");
								sv = 0;
							}
							v = sv;
						} else {
							/* The sample data is unsigned. */
							uint_fast32_t uv;
							if (pnm_getuint(in, depth, &uv)) {
								if (!pnm_allowtrunc) {
									goto done;
								}
								jas_eprintf("bad sample data\n");
								uv = 0;
							}
							v = uv;
						}
					} else {
						/* The sample data is in text format. */
						if (hdr->sgnd) {
							/* The sample data is signed. */
							int_fast32_t sv;
							if (pnm_getsintstr(in, &sv)) {
								if (!pnm_allowtrunc) {
									goto done;
								}
								jas_eprintf("bad sample data\n");
								sv = 0;
							}
							v = sv;
						} else {
							/* The sample data is unsigned. */
							uint_fast32_t uv;
							if (pnm_getuintstr(in, &uv)) {
								if (!pnm_allowtrunc) {
									goto done;
								}
								jas_eprintf("bad sample data\n");
								uv = 0;
							}
							v = uv;
						}
					}
					jas_matrix_set(data[cmptno], 0, x, v);
				}
			}
		}
		for (cmptno = 0; cmptno < hdr->numcmpts; ++cmptno) {
			if (jas_image_writecmpt(image, cmptno, 0, y, hdr->width, 1,
			  data[cmptno])) {
				goto done;
			}
		}
	}

	ret = 0;

done:

	for (cmptno = 0; cmptno < hdr->numcmpts; ++cmptno) {
		if (data[cmptno]) {
			jas_matrix_destroy(data[cmptno]);
		}
	}

	return ret;
}

Project: jasper

static int pnm_gethdr(jas_stream_t *in, pnm_hdr_t *hdr)
{
	int_fast32_t maxval;
	int_fast32_t width;
	int_fast32_t height;
	int type;

	if (pnm_getint16(in, &hdr->magic) || pnm_getsintstr(in, &width) ||
	  pnm_getsintstr(in, &height)) {
		return -1;
	}
	hdr->width = width;
	hdr->height = height;
	if ((type = pnm_type(hdr->magic)) == PNM_TYPE_INVALID) {
		return -1;
	}
	if (type != PNM_TYPE_PBM) {
		if (pnm_getsintstr(in, &maxval)) {
			return -1;
		}
	} else {
		maxval = 1;
	}
	if (maxval < 0) {
		hdr->maxval = -maxval;
		hdr->sgnd = true;
	} else {
		hdr->maxval = maxval;
		hdr->sgnd = false;
	}

	switch (type) {
	case PNM_TYPE_PBM:
	case PNM_TYPE_PGM:
		hdr->numcmpts = 1;
		break;
	case PNM_TYPE_PPM:
		hdr->numcmpts = 3;
		break;
	default:
		abort();
		break;
	}

	return 0;
}

Project: jasper

static int pnm_getsint(jas_stream_t *in, int wordsize, int_fast32_t *val)
{
	uint_fast32_t tmpval;

	if (pnm_getuint(in, wordsize, &tmpval)) {
		return -1;
	}
	if ((tmpval & (1 << (wordsize - 1))) != 0) {
		jas_eprintf("PNM decoder does not fully support signed data\n");
		return -1;
	}
	if (val) {
		*val = tmpval;
	}

	return 0;
}

Project: jasper

static int pnm_getsintstr(jas_stream_t *in, int_fast32_t *val)
{
	int c;
	int s;
	int_fast32_t v;

	/* Discard any leading whitespace. */
	do {
		if ((c = pnm_getc(in)) == EOF) {
			return -1;
		}
	} while (isspace(c));

	/* Get the number, allowing for a negative sign. */
	s = 1;
	if (c == '-') {
		s = -1;
		if ((c = pnm_getc(in)) == EOF) {
			return -1;
		}
	} else if (c == '+') {
		if ((c = pnm_getc(in)) == EOF) {
			return -1;
		}
	}
	v = 0;
	while (isdigit(c)) {
		v = 10 * v + c - '0';
		if ((c = pnm_getc(in)) < 0) {
			return -1;
		}
	}

	/* The number must be followed by whitespace. */
	if (!isspace(c)) {
		return -1;
	}

	if (val) {
		*val = (s >= 0) ? v : (-v);
	}

	return 0;
}

Project: jasper

static int pnm_getuint(jas_stream_t *in, int wordsize, uint_fast32_t *val)
{
	uint_fast32_t tmpval;
	int c;
	int n;

	tmpval = 0;
	n = (wordsize + 7) / 8;
	while (--n >= 0) {
		if ((c = jas_stream_getc(in)) == EOF) {
			return -1;
		}
		tmpval = (tmpval << 8) | c;
	}
	tmpval &= (((uint_fast64_t) 1) << wordsize) - 1;
	if (val) {
		*val = tmpval;
	}

	return 0;
}

Project: jasper

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

	/* Discard any leading whitespace. */
	do {
		if ((c = pnm_getc(in)) == EOF) {
			return -1;
		}
	} while (isspace(c));

	/* Parse the number. */
	v = 0;
	while (isdigit(c)) {
		v = 10 * v + c - '0';
		if ((c = pnm_getc(in)) < 0) {
			return -1;
		}
	}

	/* The number must be followed by whitespace. */
	if (!isspace(c)) {
		return -1;
	}

	if (val) {
		*val = v;
	}
	return 0;
}

Project: jasper

jas_image_t *ras_decode(jas_stream_t *in, char *optstr)
{
	ras_hdr_t hdr;
	ras_cmap_t cmap;
	jas_image_t *image;
	jas_image_cmptparm_t cmptparms[3];
	jas_image_cmptparm_t *cmptparm;
	int clrspc;
	int numcmpts;
	int i;

	JAS_DBGLOG(10, ("ras_decode(%p, %p, \"%s\"\n", in, optstr ? optstr : ""));

	if (optstr) {
		jas_eprintf("warning: ignoring RAS decoder options\n");
	}

	/* Read the header. */
	if (ras_gethdr(in, &hdr)) {
		return 0;
	}

	/* Does the header information look reasonably sane? */
	if (hdr.magic != RAS_MAGIC || hdr.width <= 0 || hdr.height <= 0 ||
	  hdr.depth <= 0 || hdr.depth > 32) {
		return 0;
	}

	/* In the case of the old format, do not rely on the length field
	being properly specified.  Calculate the quantity from scratch. */
	if (hdr.type == RAS_TYPE_OLD) {
		hdr.length = RAS_ROWSIZE(&hdr) * hdr.height;
	}

	/* Calculate some quantities needed for creation of the image
	object. */
	if (RAS_ISRGB(&hdr)) {
		clrspc = JAS_CLRSPC_SRGB;
		numcmpts = 3;
	} else {
		clrspc = JAS_CLRSPC_SGRAY;
		numcmpts = 1;
	}
	for (i = 0, cmptparm = cmptparms; i < numcmpts; ++i, ++cmptparm) {
		cmptparm->tlx = 0;
		cmptparm->tly = 0;
		cmptparm->hstep = 1;
		cmptparm->vstep = 1;
		cmptparm->width = hdr.width;
		cmptparm->height = hdr.height;
		cmptparm->prec = RAS_ISRGB(&hdr) ? 8 : hdr.depth;
		cmptparm->sgnd = false;
	}
	/* Create the image object. */
	if (!(image = jas_image_create(numcmpts, cmptparms, JAS_CLRSPC_UNKNOWN))) {
		return 0;
	}

	/* Read the color map (if there is one). */
	if (ras_getcmap(in, &hdr, &cmap)) {
		jas_image_destroy(image);
		return 0;
	}

	/* Read the pixel data. */
	if (ras_getdata(in, &hdr, &cmap, image)) {
		jas_image_destroy(image);
		return 0;
	}

	jas_image_setclrspc(image, clrspc);
	if (clrspc == JAS_CLRSPC_SRGB) {
		jas_image_setcmpttype(image, 0,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
		jas_image_setcmpttype(image, 1,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
		jas_image_setcmpttype(image, 2,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
	} else {
		jas_image_setcmpttype(image, 0,
		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
	}

	return image;
}

Project: jasper

static int ras_getcmap(jas_stream_t *in, ras_hdr_t *hdr, ras_cmap_t *cmap)
{
	int i;
	int j;
	int x;
	int c;
	int numcolors;
	int actualnumcolors;

	switch (hdr->maptype) {
	case RAS_MT_NONE:
		break;
	case RAS_MT_EQUALRGB:
		{
		jas_eprintf("warning: palettized images not fully supported\n");
		numcolors = 1 << hdr->depth;
		if (numcolors > RAS_CMAP_MAXSIZ) {
			return -1;
		}
		actualnumcolors = hdr->maplength / 3;
		for (i = 0; i < numcolors; i++) {
			cmap->data[i] = 0;
		}
		if ((hdr->maplength % 3) || hdr->maplength < 0 ||
		  hdr->maplength > 3 * numcolors) {
			return -1;
		}
		for (i = 0; i < 3; i++) {
			for (j = 0; j < actualnumcolors; j++) {
				if ((c = jas_stream_getc(in)) == EOF) {
					return -1;
				}
				x = 0;
				switch (i) {
				case 0:
					x = RAS_RED(c);
					break;
				case 1:
					x = RAS_GREEN(c);
					break;
				case 2:
					x = RAS_BLUE(c);
					break;
				}
				cmap->data[j] |= x;
			}
		}
		}
		break;
	default:
		return -1;
		break;
	}

	return 0;
}

Project: jasper

static int ras_getdata(jas_stream_t *in, ras_hdr_t *hdr, ras_cmap_t *cmap,
  jas_image_t *image)
{
	int ret;

	switch (hdr->type) {
	case RAS_TYPE_OLD:
	case RAS_TYPE_STD:
		ret = ras_getdatastd(in, hdr, cmap, image);
		break;
	case RAS_TYPE_RLE:
		jas_eprintf("error: RLE encoding method not supported\n");
		ret = -1;
		break;
	default:
		jas_eprintf("error: encoding method not supported\n");
		ret = -1;
		break;
	}
	return ret;
}

Project: jasper

static int ras_getdatastd(jas_stream_t *in, ras_hdr_t *hdr, ras_cmap_t *cmap,
  jas_image_t *image)
{
	int pad;
	int nz;
	int z;
	int c;
	int y;
	int x;
	int v;
	int i;
	jas_matrix_t *data[3];

/* Note: This function does not properly handle images with a colormap. */
	/* Avoid compiler warnings about unused parameters. */
	cmap = 0;

	assert(jas_image_numcmpts(image) <= 3);

	for (i = 0; i < 3; ++i) {
		data[i] = 0;
	}

	for (i = 0; i < jas_image_numcmpts(image); ++i) {
		if (!(data[i] = jas_matrix_create(1, jas_image_width(image)))) {
			goto error;
		}
	}

	pad = RAS_ROWSIZE(hdr) - (hdr->width * hdr->depth + 7) / 8;

	for (y = 0; y < hdr->height; y++) {
		nz = 0;
		z = 0;
		for (x = 0; x < hdr->width; x++) {
			while (nz < hdr->depth) {
				if ((c = jas_stream_getc(in)) == EOF) {
					goto error;
				}
				z = (z << 8) | c;
				nz += 8;
			}

			v = (z >> (nz - hdr->depth)) & RAS_ONES(hdr->depth);
			z &= RAS_ONES(nz - hdr->depth);
			nz -= hdr->depth;

			if (jas_image_numcmpts(image) == 3) {
				jas_matrix_setv(data[0], x, (RAS_GETRED(v)));
				jas_matrix_setv(data[1], x, (RAS_GETGREEN(v)));
				jas_matrix_setv(data[2], x, (RAS_GETBLUE(v)));
			} else {
				jas_matrix_setv(data[0], x, (v));
			}
		}
		if (pad) {
			if ((c = jas_stream_getc(in)) == EOF) {
				goto error;
			}
		}
		for (i = 0; i < jas_image_numcmpts(image); ++i) {
			if (jas_image_writecmpt(image, i, 0, y, hdr->width, 1,
			  data[i])) {
				goto error;
			}
		}
	}

	for (i = 0; i < jas_image_numcmpts(image); ++i) {
		jas_matrix_destroy(data[i]);
		data[i] = 0;
	}

	return 0;

error:
	for (i = 0; i < 3; ++i) {
		if (data[i]) {
			jas_matrix_destroy(data[i]);
		}
	}
	return -1;
}

Project: jasper

static int ras_gethdr(jas_stream_t *in, ras_hdr_t *hdr)
{
	if (ras_getint(in, &hdr->magic) || ras_getint(in, &hdr->width) ||
	  ras_getint(in, &hdr->height) || ras_getint(in, &hdr->depth) ||
	  ras_getint(in, &hdr->length) || ras_getint(in, &hdr->type) ||
	  ras_getint(in, &hdr->maptype) || ras_getint(in, &hdr->maplength)) {
		return -1;
	}

	if (hdr->magic != RAS_MAGIC) {
		return -1;
	}

	return 0;
}

Project: jasper

static int ras_getint(jas_stream_t *in, int_fast32_t *val)
{
	int_fast32_t x;
	int c;
	int i;

	x = 0;
	for (i = 0; i < 4; i++) {
		if ((c = jas_stream_getc(in)) == EOF) {
			return -1;
		}
		x = (x << 8) | (c & 0xff);
	}

	*val = x;
	return 0;
}