CVE-2016-9395: Improper Input Validation (CWE-20)
value: The jas_seq2d_create function in jas_seq.c in JasPer before 1.900.25 allows remote attackers to cause a denial of service (assertion failure) via a crafted file.
CWE description: The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
CVSS v3 base score: 5.5
Published: 2017-03-23T18:59Z
Repository: https://github.com/mdadams/jasper
Language: C
Files changed: .gitignore, configure.ac, src/appl/imginfo.c, src/libjasper/base/jas_debug.c, src/libjasper/base/jas_icc.c, src/libjasper/base/jas_iccdata.c, src/libjasper/base/jas_image.c, src/libjasper/base/jas_seq.c, src/libjasper/base/jas_stream.c, src/libjasper/base/jas_tmr.c, src/libjasper/bmp/bmp_dec.c, src/libjasper/include/jasper/jas_cm.h, src/libjasper/include/jasper/jas_config.h.in, src/libjasper/include/jasper/jas_config2.h, src/libjasper/include/jasper/jas_debug.h, src/libjasper/include/jasper/jas_fix.h, src/libjasper/include/jasper/jas_getopt.h, src/libjasper/include/jasper/jas_icc.h, src/libjasper/include/jasper/jas_image.h, src/libjasper/include/jasper/jas_init.h, src/libjasper/include/jasper/jas_malloc.h, src/libjasper/include/jasper/jas_math.h, src/libjasper/include/jasper/jas_seq.h, src/libjasper/include/jasper/jas_stream.h, src/libjasper/include/jasper/jas_string.h, src/libjasper/include/jasper/jas_tmr.h, src/libjasper/include/jasper/jas_tvp.h, src/libjasper/include/jasper/jas_types.h, src/libjasper/include/jasper/jas_version.h, src/libjasper/include/jasper/jasper.h, src/libjasper/jp2/jp2_dec.c, src/libjasper/jpc/jpc_cs.c, src/libjasper/jpc/jpc_cs.h, src/libjasper/jpc/jpc_dec.c, src/libjasper/jpc/jpc_dec.h, src/libjasper/jpc/jpc_enc.c, src/libjasper/jpc/jpc_mqdec.h, src/libjasper/jpg/jpg_dec.c, src/libjasper/jpg/jpg_val.c, src/libjasper/mif/mif_cod.c, src/libjasper/pgx/pgx_dec.c, src/libjasper/pnm/pnm_dec.c, src/libjasper/ras/ras_dec.c, test/bin/run_test_1
Commit date: 2016-11-11 16:27:34 -0800
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.

Diff: diff --git a/.gitignore b/.gitignore
index 9ef3d79..6fd9859 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,8 +38,9 @@ Makefile.in
 /src/appl/jiv
 /src/appl/tmrdemo
 
 # ./src/libjasper/include/jasper directory
 /src/libjasper/include/jasper/jas_config.h
-/src/libjasper/include/jasper/jas_config.h.in
-/src/libjasper/include/jasper/jas_config.h.in~
+/src/libjasper/include/jasper/jas_pconf.h
+/src/libjasper/include/jasper/jas_pconf.h.in
+/src/libjasper/include/jasper/jas_pconf.h.in~
 /src/libjasper/include/jasper/stamp-h1
diff --git a/configure.ac b/configure.ac
index c83181c..a218b3c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -130,20 +130,10 @@ AH_TOP([
 /* This preprocessor symbol identifies the version of JasPer. */
 #undef	JAS_VERSION
 /* If configure is being used, this symbol will be defined automatically
   at this point in the configuration header file. */
 
-#if defined(__GNUC__) && !defined(__clang__)
-#define JAS_ATTRIBUTE_DISABLE_USAN \
-  __attribute__((no_sanitize_undefined))
-#elif defined(__clang__)
-#define JAS_ATTRIBUTE_DISABLE_USAN \
-  __attribute__((no_sanitize("undefined")))
-#else
-#define JAS_ATTRIBUTE_DISABLE_USAN
-#endif
-
 /* The preprocessor symbol JAS_WIN_MSVC_BUILD should not be defined
   unless the JasPer software is being built under Microsoft Windows
   using Microsoft Visual C. */
 #if !defined(JAS_WIN_MSVC_BUILD)
 /* A configure-based build is being used. */
@@ -151,11 +141,11 @@ AH_TOP([
 ])
 
 AH_BOTTOM([
 #else
 /* A configure-based build is not being used. */
-#include <jasper/jas_config2.h>
+#include <jasper/jas_pconf2.h>
 #endif
 
 #endif
 ])
 
@@ -310,35 +300,86 @@ AC_CHECK_LIB(m, main)
 
 ############################################################
 # Check for header files.
 ############################################################
 
-AC_HEADER_STDC
-AC_CHECK_HEADERS(fcntl.h limits.h unistd.h stdint.h stdbool.h io.h windows.h sys/types.h sys/time.h stdlib.h stddef.h)
+dnl AC_HEADER_STDC
+AC_CHECK_HEADERS(fcntl.h io.h unistd.h windows.h sys/time.h sys/types.h)
+
+# Surely, there must be a better way to do this, but
+# let's just get something working for now.
+
+if test $ac_cv_header_fcntl_h = yes; then
+	AC_SUBST([JAS_HAVE_FCNTL_H], ["#define JAS_HAVE_FCNTL_H 1"])
+else
+	AC_SUBST([JAS_HAVE_FCNTL_H], ["#undef JAS_HAVE_FCNTL_H"])
+fi
+
+if test $ac_cv_header_io_h = yes; then
+	AC_SUBST([JAS_HAVE_IO_H], ["#define JAS_HAVE_IO_H 1"])
+else
+	AC_SUBST([JAS_HAVE_IO_H], ["#undef JAS_HAVE_IO_H"])
+fi
+
+if test $ac_cv_header_unistd_h = yes; then
+	AC_SUBST([JAS_HAVE_UNISTD_H], ["#define JAS_HAVE_UNISTD_H 1"])
+else
+	AC_SUBST([JAS_HAVE_UNISTD_H], ["#undef JAS_HAVE_UNISTD_H"])
+fi
+
+if test $ac_cv_header_windows_h = yes; then
+	AC_SUBST([JAS_HAVE_WINDOWS_H], ["#define JAS_HAVE_WINDOWS_H 1"])
+else
+	AC_SUBST([JAS_HAVE_WINDOWS_H], ["#undef JAS_HAVE_WINDOWS_H"])
+fi
+
+if test $ac_cv_header_sys_time_h = yes; then
+	AC_SUBST([JAS_HAVE_SYS_TIME_H], ["#define JAS_HAVE_SYS_TIME_H 1"])
+else
+	AC_SUBST([JAS_HAVE_SYS_TIME_H], ["#undef JAS_HAVE_SYS_TIME_H"])
+fi
+
+if test $ac_cv_header_sys_types_h = yes; then
+	AC_SUBST([JAS_HAVE_SYS_TYPES_H], ["#define JAS_HAVE_SYS_TYPES_H 1"])
+else
+	AC_SUBST([JAS_HAVE_SYS_TYPES_H], ["#undef JAS_HAVE_SYS_TYPES_H"])
+fi
 
 ############################################################
 # Check for typedefs, structures, and compiler characteristics.
 ############################################################
 
-AC_C_CONST
-AC_C_INLINE
-AC_TYPE_SIZE_T
-AC_CHECK_TYPE(uchar, unsigned char)
-AC_CHECK_TYPE(ushort, unsigned short)
-AC_CHECK_TYPE(uint, unsigned int)
-AC_CHECK_TYPE(ulong, unsigned long)
-AC_CHECK_TYPE(longlong, long long)
-AC_CHECK_TYPE(ulonglong, unsigned long long)
-AC_CHECK_TYPE(ssize_t, int)
+dnl AC_C_CONST
+dnl AC_C_INLINE
+dnl AC_TYPE_SIZE_T
+dnl AC_CHECK_TYPE(uchar, unsigned char)
+dnl AC_CHECK_TYPE(ushort, unsigned short)
+dnl AC_CHECK_TYPE(uint, unsigned int)
+dnl AC_CHECK_TYPE(ulong, unsigned long)
+dnl AC_CHECK_TYPE(longlong, long long)
+dnl AC_CHECK_TYPE(ulonglong, unsigned long long)
+dnl AC_CHECK_TYPE(ssize_t, int)
 AC_CHECK_FUNCS(gettimeofday)
 AC_CHECK_FUNCS(getrusage)
 
+if test $ac_cv_func_gettimeofday = yes; then
+	AC_SUBST([JAS_HAVE_GETTIMEOFDAY], ["#define JAS_HAVE_GETTIMEOFDAY 1"])
+else
+	AC_SUBST([JAS_HAVE_GETTIMEOFDAY], ["#undef JAS_HAVE_GETTIMEOFDAY"])
+fi
+
+if test $ac_cv_func_getrusage = yes; then
+	AC_SUBST([JAS_HAVE_GETRUSAGE], ["#define JAS_HAVE_GETRUSAGE 1"])
+else
+	AC_SUBST([JAS_HAVE_GETRUSAGE], ["#undef JAS_HAVE_GETRUSAGE"])
+fi
+
 ############################################################
 # Checks for library functions.
 ############################################################
 
-AC_FUNC_VPRINTF
+dnl AC_FUNC_VPRINTF
 
 ############################################################
 # Enable memory limit feature.
 ############################################################
 
@@ -430,45 +471,32 @@ no)
 	;;
 esac
 ], [debug=no])
 
 ############################################################
-# Extra stuff for research purposes.
+# Extra stuff
 ############################################################
 
-AC_ARG_ENABLE(special0,
-[  --enable-special0    enable something],
-[
-case "${enableval}" in
-yes)
-	if test "$GCC" = yes; then
-		CFLAGS="-g -O0"
-	fi
-	;;
-no)
-	;;
-*)
-	AC_MSG_ERROR(bad value ${enableval} for --enable-special0)
-	;;
-esac
-], [])
-
 if test -n "$EXTRA_CFLAGS"; then
 	CFLAGS="$CFLAGS $EXTRA_CFLAGS"
 fi
 
 ############################################################
 # Generate the configuration header file.
 ############################################################
 
-AC_CONFIG_HEADERS([src/libjasper/include/jasper/jas_config.h])
+# The private header file generated by AC_CONFIG_HEADERS is not
+# currently used.  This just causes less verbose command lines
+# when make is run.
+AC_CONFIG_HEADERS([src/libjasper/include/jasper/jas_pconf.h])
 
 ############################################################
 # Generate the makefiles.
 ############################################################
 
 AC_CONFIG_FILES([
+src/libjasper/include/jasper/jas_config.h
 Makefile
 src/Makefile
 src/appl/Makefile
 src/libjasper/Makefile
 src/libjasper/base/Makefile
diff --git a/src/appl/imginfo.c b/src/appl/imginfo.c
index 0560bea..160054c 100644
--- a/src/appl/imginfo.c
+++ b/src/appl/imginfo.c
@@ -86,10 +86,11 @@ typedef enum {
 	OPT_HELP,
 	OPT_VERSION,
 	OPT_VERBOSE,
 	OPT_INFILE,
 	OPT_DEBUG,
+	OPT_MAXSAMPLES,
 	OPT_MAXMEM
 } optid_t;
 
 /******************************************************************************\
 *
@@ -106,10 +107,11 @@ static jas_opt_t opts[] = {
 	{OPT_HELP, "help", 0},
 	{OPT_VERSION, "version", 0},
 	{OPT_VERBOSE, "verbose", 0},
 	{OPT_INFILE, "f", JAS_OPT_HASARG},
 	{OPT_DEBUG, "debug-level", JAS_OPT_HASARG},
+	{OPT_MAXSAMPLES, "max-samples", JAS_OPT_HASARG},
 #if defined(JAS_DEFAULT_MAX_MEM_USAGE)
 	{OPT_MAXMEM, "memory-limit", JAS_OPT_HASARG},
 #endif
 	{-1, 0, 0}
 };
@@ -133,17 +135,20 @@ int main(int argc, char **argv)
 	int numcmpts;
 	int verbose;
 	char *fmtname;
 	int debug;
 	size_t max_mem;
+	size_t max_samples;
+	char optstr[32];
 
 	if (jas_init()) {
 		abort();
 	}
 
 	cmdname = argv[0];
 
+	max_samples = 64 * JAS_MEBI;
 	infile = 0;
 	verbose = 0;
 	debug = 0;
 #if defined(JAS_DEFAULT_MAX_MEM_USAGE)
 	max_mem = JAS_DEFAULT_MAX_MEM_USAGE;
@@ -163,10 +168,13 @@ int main(int argc, char **argv)
 			debug = atoi(jas_optarg);
 			break;
 		case OPT_INFILE:
 			infile = jas_optarg;
 			break;
+		case OPT_MAXSAMPLES:
+			max_samples = strtoull(jas_optarg, 0, 10);
+			break;
 		case OPT_MAXMEM:
 			max_mem = strtoull(jas_optarg, 0, 10);
 			break;
 		case OPT_HELP:
 		default:
@@ -197,20 +205,27 @@ int main(int argc, char **argv)
 
 	if ((fmtid = jas_image_getfmt(instream)) < 0) {
 		fprintf(stderr, "unknown image format\n");
 	}
 
+	snprintf(optstr, sizeof(optstr), "max_samples=%-zu", max_samples);
+
 	/* Decode the image. */
-	if (!(image = jas_image_decode(instream, fmtid, 0))) {
+	if (!(image = jas_image_decode(instream, fmtid, optstr))) {
 		jas_stream_close(instream);
 		fprintf(stderr, "cannot load image\n");
 		return EXIT_FAILURE;
 	}
 
 	/* Close the image file. */
 	jas_stream_close(instream);
 
+	if (!(fmtname = jas_image_fmttostr(fmtid))) {
+		jas_eprintf("format name lookup failed\n");
+		return EXIT_FAILURE;
+	}
+
 	if (!(numcmpts = jas_image_numcmpts(image))) {
 		fprintf(stderr, "warning: image has no components\n");
 	}
 	if (numcmpts) {
 		width = jas_image_cmptwidth(image, 0);
@@ -219,14 +234,12 @@ int main(int argc, char **argv)
 	} else {
 		width = 0;
 		height = 0;
 		depth = 0;
 	}
-	if (!(fmtname = jas_image_fmttostr(fmtid))) {
-		abort();
-	}
-	printf("%s %d %d %d %d %ld\n", fmtname, numcmpts, width, height, depth, (long) jas_image_rawsize(image));
+	printf("%s %d %d %d %d %ld\n", fmtname, numcmpts, width, height, depth,
+	  JAS_CAST(long, jas_image_rawsize(image)));
 
 	jas_image_destroy(image);
 	jas_image_clearfmts();
 
 	return EXIT_SUCCESS;
diff --git a/src/libjasper/base/jas_debug.c b/src/libjasper/base/jas_debug.c
index 42a7480..c79992e 100644
--- a/src/libjasper/base/jas_debug.c
+++ b/src/libjasper/base/jas_debug.c
@@ -120,11 +120,11 @@ int jas_eprintf(const char *fmt, ...)
 /* Dump memory to a stream. */
 int jas_memdump(FILE *out, void *data, size_t len)
 {
 	size_t i;
 	size_t j;
-	uchar *dp;
+	jas_uchar *dp;
 	dp = data;
 	for (i = 0; i < len; i += 16) {
 		fprintf(out, "%04zx:", i);
 		for (j = 0; j < 16; ++j) {
 			if (i + j < len) {
diff --git a/src/libjasper/base/jas_icc.c b/src/libjasper/base/jas_icc.c
index c9ca43c..09c6ae2 100644
--- a/src/libjasper/base/jas_icc.c
+++ b/src/libjasper/base/jas_icc.c
@@ -80,18 +80,18 @@
 #define	jas_iccputuint32(out, val)	jas_iccputuint(out, 4, val)
 #define	jas_iccputuint64(out, val)	jas_iccputuint(out, 8, val)
 
 static jas_iccattrval_t *jas_iccattrval_create0(void);
 
-static int jas_iccgetuint(jas_stream_t *in, int n, ulonglong *val);
+static int jas_iccgetuint(jas_stream_t *in, int n, jas_ulonglong *val);
 static int jas_iccgetuint8(jas_stream_t *in, jas_iccuint8_t *val);
 static int jas_iccgetuint16(jas_stream_t *in, jas_iccuint16_t *val);
 static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val);
 static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val);
 static int jas_iccgetuint64(jas_stream_t *in, jas_iccuint64_t *val);
-static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val);
-static int jas_iccputsint(jas_stream_t *out, int n, longlong val);
+static int jas_iccputuint(jas_stream_t *out, int n, jas_ulonglong val);
+static int jas_iccputsint(jas_stream_t *out, int n, jas_longlong val);
 static jas_iccprof_t *jas_iccprof_create(void);
 static int jas_iccprof_readhdr(jas_stream_t *in, jas_icchdr_t *hdr);
 static int jas_iccprof_writehdr(jas_stream_t *out, jas_icchdr_t *hdr);
 static int jas_iccprof_gettagtab(jas_stream_t *in, jas_icctagtab_t *tagtab);
 static void jas_iccprof_sorttagtab(jas_icctagtab_t *tagtab);
@@ -1601,15 +1601,15 @@ static void jas_icclut16_dump(jas_iccattrval_t *attrval, FILE *out)
 
 /******************************************************************************\
 *
 \******************************************************************************/
 
-static int jas_iccgetuint(jas_stream_t *in, int n, ulonglong *val)
+static int jas_iccgetuint(jas_stream_t *in, int n, jas_ulonglong *val)
 {
 	int i;
 	int c;
-	ulonglong v;
+	jas_ulonglong v;
 	v = 0;
 	for (i = n; i > 0; --i) {
 		if ((c = jas_stream_getc(in)) == EOF)
 			return -1;
 		v = (v << 8) | c;
@@ -1627,46 +1627,46 @@ static int jas_iccgetuint8(jas_stream_t *in, jas_iccuint8_t *val)
 	return 0;
 }
 
 static int jas_iccgetuint16(jas_stream_t *in, jas_iccuint16_t *val)
 {
-	ulonglong tmp;
+	jas_ulonglong tmp;
 	if (jas_iccgetuint(in, 2, &tmp))
 		return -1;
 	*val = tmp;
 	return 0;
 }
 
 static int jas_iccgetsint32(jas_stream_t *in, jas_iccsint32_t *val)
 {
-	ulonglong tmp;
+	jas_ulonglong tmp;
 	if (jas_iccgetuint(in, 4, &tmp))
 		return -1;
-	*val = (tmp & 0x80000000) ? (-JAS_CAST(longlong, (((~tmp) &
-	  0x7fffffff) + 1))) : JAS_CAST(longlong, tmp);
+	*val = (tmp & 0x80000000) ? (-JAS_CAST(jas_longlong, (((~tmp) &
+	  0x7fffffff) + 1))) : JAS_CAST(jas_longlong, tmp);
 	return 0;
 }
 
 static int jas_iccgetuint32(jas_stream_t *in, jas_iccuint32_t *val)
 {
-	ulonglong tmp;
+	jas_ulonglong tmp;
 	if (jas_iccgetuint(in, 4, &tmp))
 		return -1;
 	*val = tmp;
 	return 0;
 }
 
 static int jas_iccgetuint64(jas_stream_t *in, jas_iccuint64_t *val)
 {
-	ulonglong tmp;
+	jas_ulonglong tmp;
 	if (jas_iccgetuint(in, 8, &tmp))
 		return -1;
 	*val = tmp;
 	return 0;
 }
 
-static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val)
+static int jas_iccputuint(jas_stream_t *out, int n, jas_ulonglong val)
 {
 	int i;
 	int c;
 	for (i = n; i > 0; --i) {
 		c = (val >> (8 * (i - 1))) & 0xff;
@@ -1674,13 +1674,13 @@ static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val)
 			return -1;
 	}
 	return 0;
 }
 
-static int jas_iccputsint(jas_stream_t *out, int n, longlong val)
+static int jas_iccputsint(jas_stream_t *out, int n, jas_longlong val)
 {
-	ulonglong tmp;
+	jas_ulonglong tmp;
 	tmp = (val < 0) ? (abort(), 0) : val;
 	return jas_iccputuint(out, n, tmp);
 }
 
 /******************************************************************************\
@@ -1717,11 +1717,11 @@ static long jas_iccpowi(int x, int n)
 		y *= x;
 	return y;
 }
 
 
-jas_iccprof_t *jas_iccprof_createfrombuf(uchar *buf, int len)
+jas_iccprof_t *jas_iccprof_createfrombuf(jas_uchar *buf, int len)
 {
 	jas_stream_t *in;
 	jas_iccprof_t *prof;
 	if (!(in = jas_stream_memopen(JAS_CAST(char *, buf), len)))
 		goto error;
diff --git a/src/libjasper/base/jas_iccdata.c b/src/libjasper/base/jas_iccdata.c
index bf68bf0..dcbedf2 100644
--- a/src/libjasper/base/jas_iccdata.c
+++ b/src/libjasper/base/jas_iccdata.c
@@ -60,11 +60,11 @@
  */
 
 #include <jasper/jas_config.h>
 #include <jasper/jas_types.h>
 
-uchar jas_iccprofdata_srgb[] =
+jas_uchar jas_iccprofdata_srgb[] =
 {
 	0x00, 0x00, 0x0c, 0x48, 0x4c, 0x69, 0x6e, 0x6f,
 	0x02, 0x10, 0x00, 0x00, 0x6d, 0x6e, 0x74, 0x72,
 	0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20,
 	0x07, 0xce, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06,
@@ -459,11 +459,11 @@ uchar jas_iccprofdata_srgb[] =
 	0xfe, 0x4b, 0xfe, 0xdc, 0xff, 0x6d, 0xff, 0xff
 };
 
 int jas_iccprofdata_srgblen = sizeof(jas_iccprofdata_srgb);
 
-uchar jas_iccprofdata_sgray[] = {
+jas_uchar jas_iccprofdata_sgray[] = {
 	0x00, 0x00, 0x01, 0x8a, 0x00, 0x00, 0x00, 0x00,
 	0x02, 0x20, 0x00, 0x00, 0x73, 0x63, 0x6e, 0x72,
 	0x47, 0x52, 0x41, 0x59, 0x58, 0x59, 0x5a, 0x20,
 	0x07, 0xd3, 0x00, 0x01, 0x00, 0x1f, 0x00, 0x0d,
 	0x00, 0x35, 0x00, 0x21, 0x61, 0x63, 0x73, 0x70,
diff --git a/src/libjasper/base/jas_image.c b/src/libjasper/base/jas_image.c
index 7b56d17..f6dee96 100644
--- a/src/libjasper/base/jas_image.c
+++ b/src/libjasper/base/jas_image.c
@@ -131,63 +131,80 @@ static jas_image_fmtinfo_t jas_image_fmtinfos[JAS_IMAGE_MAXFMTS];
 
 jas_image_t *jas_image_create(int numcmpts, jas_image_cmptparm_t *cmptparms,
   int clrspc)
 {
 	jas_image_t *image;
-	uint_fast32_t rawsize;
+	size_t rawsize;
 	uint_fast32_t inmem;
 	int cmptno;
 	jas_image_cmptparm_t *cmptparm;
 
+	image = 0;
+
+	JAS_DBGLOG(100, ("jas_image_create(%d, %p, %d)\n", numcmpts, cmptparms,
+	  clrspc));
+
 	if (!(image = jas_image_create0())) {
-		return 0;
+		goto error;
 	}
 
 	image->clrspc_ = clrspc;
 	image->maxcmpts_ = numcmpts;
-	image->inmem_ = true;
+//	image->inmem_ = true;
 
 	/* Allocate memory for the per-component information. */
 	if (!(image->cmpts_ = jas_alloc2(image->maxcmpts_,
 	  sizeof(jas_image_cmpt_t *)))) {
-		jas_image_destroy(image);
-		return 0;
+		goto error;
 	}
 	/* Initialize in case of failure. */
 	for (cmptno = 0; cmptno < image->maxcmpts_; ++cmptno) {
 		image->cmpts_[cmptno] = 0;
 	}
 
+#if 0
 	/* Compute the approximate raw size of the image. */
 	rawsize = 0;
 	for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno,
 	  ++cmptparm) {
 		rawsize += cmptparm->width * cmptparm->height *
 		  (cmptparm->prec + 7) / 8;
 	}
 	/* Decide whether to buffer the image data in memory, based on the
 	  raw size of the image. */
 	inmem = (rawsize < JAS_IMAGE_INMEMTHRESH);
+#endif
 
 	/* Create the individual image components. */
 	for (cmptno = 0, cmptparm = cmptparms; cmptno < numcmpts; ++cmptno,
 	  ++cmptparm) {
+		if (!jas_safe_size_mul3(cmptparm->width, cmptparm->height,
+		  (cmptparm->prec + 7), &rawsize)) {
+			goto error;
+		}
+		rawsize /= 8;
+		inmem = (rawsize < JAS_IMAGE_INMEMTHRESH);
 		if (!(image->cmpts_[cmptno] = jas_image_cmpt_create(cmptparm->tlx,
 		  cmptparm->tly, cmptparm->hstep, cmptparm->vstep,
 		  cmptparm->width, cmptparm->height, cmptparm->prec,
 		  cmptparm->sgnd, inmem))) {
-			jas_image_destroy(image);
-			return 0;
+			goto error;
 		}
 		++image->numcmpts_;
 	}
 
 	/* Determine the bounding box for all of the components on the
 	  reference grid (i.e., the image area) */
 	jas_image_setbbox(image);
 
 	return image;
+
+error:
+	if (image) {
+		jas_image_destroy(image);
+	}
+	return 0;
 }
 
 jas_image_t *jas_image_create0()
 {
 	jas_image_t *image;
@@ -202,11 +219,11 @@ jas_image_t *jas_image_create0()
 	image->bry_ = 0;
 	image->clrspc_ = JAS_CLRSPC_UNKNOWN;
 	image->numcmpts_ = 0;
 	image->maxcmpts_ = 0;
 	image->cmpts_ = 0;
-	image->inmem_ = true;
+//	image->inmem_ = true;
 	image->cmprof_ = 0;
 
 	return image;
 }
 
@@ -314,18 +331,34 @@ static jas_image_cmpt_t *jas_image_cmpt_create(int_fast32_t tlx,
   uint_fast32_t inmem)
 {
 	jas_image_cmpt_t *cmpt;
 	size_t size;
 
+	JAS_DBGLOG(100, (
+	  "jas_image_cmpt_create(%ld, %ld, %ld, %ld, %ld, %ld, %d, %d, %d)\n",
+	  JAS_CAST(long, tlx),
+	  JAS_CAST(long, tly),
+	  JAS_CAST(long, hstep),
+	  JAS_CAST(long, vstep),
+	  JAS_CAST(long, width),
+	  JAS_CAST(long, height),
+	  JAS_CAST(int, depth),
+	  sgnd,
+	  inmem
+	  ));
+
 	cmpt = 0;
 	if (width < 0 || height < 0 || hstep <= 0 || vstep <= 0) {
 		goto error;
 	}
 	if (!jas_safe_intfast32_add(tlx, width, 0) ||
 	  !jas_safe_intfast32_add(tly, height, 0)) {
 		goto error;
 	}
+	if (!jas_safe_intfast32_mul3(width, height, depth, 0)) {
+		goto error;
+	}
 
 	if (!(cmpt = jas_malloc(sizeof(jas_image_cmpt_t)))) {
 		goto error;
 	}
 
@@ -342,12 +375,11 @@ static jas_image_cmpt_t *jas_image_cmpt_create(int_fast32_t tlx,
 	cmpt->cps_ = (depth + 7) / 8;
 
 	// Compute the number of samples in the image component, while protecting
 	// against overflow.
 	// size = cmpt->width_ * cmpt->height_ * cmpt->cps_;
-	if (!jas_safe_size_mul(cmpt->width_, cmpt->height_, &size) ||
-	  !jas_safe_size_mul(size, cmpt->cps_, &size)) {
+	if (!jas_safe_size_mul3(cmpt->width_, cmpt->height_, cmpt->cps_, &size)) {
 		goto error;
 	}
 	cmpt->stream_ = (inmem) ? jas_stream_memopen2(0, size) :
 	  jas_stream_tmpfile();
 	if (!cmpt->stream_) {
@@ -1277,23 +1309,23 @@ static void jas_image_calcbbox2(jas_image_t *image, jas_image_coord_t *tlx,
 	*tly = tmptly;
 	*brx = tmpbrx;
 	*bry = tmpbry;
 }
 
-static inline long decode_twos_comp(ulong c, int prec)
+static inline long decode_twos_comp(jas_ulong c, int prec)
 {
 	long result;
 	assert(prec >= 2);
 	jas_eprintf("warning: support for signed data is untested\n");
 	// NOTE: Is this correct?
 	result = (c & ((1 << (prec - 1)) - 1)) - (c & (1 << (prec - 1)));
 	return result;
 }
 
-static inline ulong encode_twos_comp(long n, int prec)
+static inline jas_ulong encode_twos_comp(long n, int prec)
 {
-	ulong result;
+	jas_ulong result;
 	assert(prec >= 2);
 	jas_eprintf("warning: support for signed data is untested\n");
 	// NOTE: Is this correct?
 	if (n < 0) {
 		result = -n;
@@ -1330,11 +1362,11 @@ static int getint(jas_stream_t *in, int sgnd, int prec, long *val)
 static int putint(jas_stream_t *out, int sgnd, int prec, long val)
 {
 	int n;
 	int c;
 	bool s;
-	ulong tmp;
+	jas_ulong tmp;
 	assert((!sgnd && prec >= 1) || (sgnd && prec >= 2));
 	if (sgnd) {
 		val = encode_twos_comp(val, prec);
 	}
 	assert(val >= 0);
diff --git a/src/libjasper/base/jas_seq.c b/src/libjasper/base/jas_seq.c
index 27a21e9..6c5e163 100644
--- a/src/libjasper/base/jas_seq.c
+++ b/src/libjasper/base/jas_seq.c
@@ -82,11 +82,12 @@
 
 /******************************************************************************\
 * Constructors and destructors.
 \******************************************************************************/
 
-jas_matrix_t *jas_seq2d_create(int xstart, int ystart, int xend, int yend)
+jas_matrix_t *jas_seq2d_create(jas_matind_t xstart, jas_matind_t ystart,
+  jas_matind_t xend, jas_matind_t yend)
 {
 	jas_matrix_t *matrix;
 	assert(xstart <= xend && ystart <= yend);
 	if (!(matrix = jas_matrix_create(yend - ystart, xend - xstart))) {
 		return 0;
@@ -96,14 +97,14 @@ jas_matrix_t *jas_seq2d_create(int xstart, int ystart, int xend, int yend)
 	matrix->xend_ = xend;
 	matrix->yend_ = yend;
 	return matrix;
 }
 
-jas_matrix_t *jas_matrix_create(int numrows, int numcols)
+jas_matrix_t *jas_matrix_create(jas_matind_t numrows, jas_matind_t numcols)
 {
 	jas_matrix_t *matrix;
-	int i;
+	jas_matind_t i;
 	size_t size;
 
 	matrix = 0;
 
 	if (numrows < 0 || numcols < 0) {
@@ -178,12 +179,12 @@ void jas_matrix_destroy(jas_matrix_t *matrix)
 }
 
 jas_seq2d_t *jas_seq2d_copy(jas_seq2d_t *x)
 {
 	jas_matrix_t *y;
-	int i;
-	int j;
+	jas_matind_t i;
+	jas_matind_t j;
 	y = jas_seq2d_create(jas_seq2d_xstart(x), jas_seq2d_ystart(x),
 	  jas_seq2d_xend(x), jas_seq2d_yend(x));
 	assert(y);
 	for (i = 0; i < x->numrows_; ++i) {
 		for (j = 0; j < x->numcols_; ++j) {
@@ -194,12 +195,12 @@ jas_seq2d_t *jas_seq2d_copy(jas_seq2d_t *x)
 }
 
 jas_matrix_t *jas_matrix_copy(jas_matrix_t *x)
 {
 	jas_matrix_t *y;
-	int i;
-	int j;
+	jas_matind_t i;
+	jas_matind_t j;
 	y = jas_matrix_create(x->numrows_, x->numcols_);
 	for (i = 0; i < x->numrows_; ++i) {
 		for (j = 0; j < x->numcols_; ++j) {
 			*jas_matrix_getref(y, i, j) = jas_matrix_get(x, i, j);
 		}
@@ -209,21 +210,21 @@ jas_matrix_t *jas_matrix_copy(jas_matrix_t *x)
 
 /******************************************************************************\
 * Bind operations.
 \******************************************************************************/
 
-void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, int xstart,
-  int ystart, int xend, int yend)
+void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, jas_matind_t xstart,
+  jas_matind_t ystart, jas_matind_t xend, jas_matind_t yend)
 {
 	jas_matrix_bindsub(s, s1, ystart - s1->ystart_, xstart - s1->xstart_,
 	  yend - s1->ystart_ - 1, xend - s1->xstart_ - 1);
 }
 
-void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, int r0,
-  int c0, int r1, int c1)
+void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1,
+  jas_matind_t r0, jas_matind_t c0, jas_matind_t r1, jas_matind_t c1)
 {
-	int i;
+	jas_matind_t i;
 
 	if (mat0->data_) {
 		if (!(mat0->flags_ & JAS_MATRIX_REF)) {
 			jas_free(mat0->data_);
 		}
@@ -263,12 +264,12 @@ void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, int r0,
 * Arithmetic operations.
 \******************************************************************************/
 
 int jas_matrix_cmp(jas_matrix_t *mat0, jas_matrix_t *mat1)
 {
-	int i;
-	int j;
+	jas_matind_t i;
+	jas_matind_t j;
 
 	if (mat0->numrows_ != mat1->numrows_ || mat0->numcols_ !=
 	  mat1->numcols_) {
 		return 1;
 	}
@@ -282,14 +283,14 @@ int jas_matrix_cmp(jas_matrix_t *mat0, jas_matrix_t *mat1)
 	return 0;
 }
 
 void jas_matrix_divpow2(jas_matrix_t *matrix, int n)
 {
-	int i;
-	int j;
+	jas_matind_t i;
+	jas_matind_t j;
 	jas_seqent_t *rowstart;
-	int rowstep;
+	jas_matind_t rowstep;
 	jas_seqent_t *data;
 
 	if (jas_matrix_numrows(matrix) > 0 && jas_matrix_numcols(matrix) > 0) {
 		assert(matrix->rows_);
 		rowstep = jas_matrix_rowstep(matrix);
@@ -305,16 +306,16 @@ void jas_matrix_divpow2(jas_matrix_t *matrix, int n)
 }
 
 void jas_matrix_clip(jas_matrix_t *matrix, jas_seqent_t minval,
   jas_seqent_t maxval)
 {
-	int i;
-	int j;
+	jas_matind_t i;
+	jas_matind_t j;
 	jas_seqent_t v;
 	jas_seqent_t *rowstart;
 	jas_seqent_t *data;
-	int rowstep;
+	jas_matind_t rowstep;
 
 	if (jas_matrix_numrows(matrix) > 0 && jas_matrix_numcols(matrix) > 0) {
 		assert(matrix->rows_);
 		rowstep = jas_matrix_rowstep(matrix);
 		for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i,
@@ -333,14 +334,14 @@ void jas_matrix_clip(jas_matrix_t *matrix, jas_seqent_t minval,
 	}
 }
 
 void jas_matrix_asr(jas_matrix_t *matrix, int n)
 {
-	int i;
-	int j;
+	jas_matind_t i;
+	jas_matind_t j;
 	jas_seqent_t *rowstart;
-	int rowstep;
+	jas_matind_t rowstep;
 	jas_seqent_t *data;
 
 	assert(n >= 0);
 	if (jas_matrix_numrows(matrix) > 0 && jas_matrix_numcols(matrix) > 0) {
 		assert(matrix->rows_);
@@ -356,14 +357,14 @@ void jas_matrix_asr(jas_matrix_t *matrix, int n)
 	}
 }
 
 void jas_matrix_asl(jas_matrix_t *matrix, int n)
 {
-	int i;
-	int j;
+	jas_matind_t i;
+	jas_matind_t j;
 	jas_seqent_t *rowstart;
-	int rowstep;
+	jas_matind_t rowstep;
 	jas_seqent_t *data;
 
 	if (jas_matrix_numrows(matrix) > 0 && jas_matrix_numcols(matrix) > 0) {
 		assert(matrix->rows_);
 		rowstep = jas_matrix_rowstep(matrix);
@@ -380,14 +381,15 @@ void jas_matrix_asl(jas_matrix_t *matrix, int n)
 
 /******************************************************************************\
 * Code.
 \******************************************************************************/
 
-int jas_matrix_resize(jas_matrix_t *matrix, int numrows, int numcols)
+int jas_matrix_resize(jas_matrix_t *matrix, jas_matind_t numrows,
+  jas_matind_t numcols)
 {
-	int size;
-	int i;
+	jas_matind_t size;
+	jas_matind_t i;
 
 	size = numrows * numcols;
 	if (size > matrix->datasize_ || numrows > matrix->maxrows_) {
 		return -1;
 	}
@@ -402,14 +404,14 @@ int jas_matrix_resize(jas_matrix_t *matrix, int numrows, int numcols)
 	return 0;
 }
 
 void jas_matrix_setall(jas_matrix_t *matrix, jas_seqent_t val)
 {
-	int i;
-	int j;
+	jas_matind_t i;
+	jas_matind_t j;
 	jas_seqent_t *rowstart;
-	int rowstep;
+	jas_matind_t rowstep;
 	jas_seqent_t *data;
 
 	if (jas_matrix_numrows(matrix) > 0 && jas_matrix_numcols(matrix) > 0) {
 		assert(matrix->rows_);
 		rowstep = jas_matrix_rowstep(matrix);
@@ -424,24 +426,36 @@ void jas_matrix_setall(jas_matrix_t *matrix, jas_seqent_t val)
 }
 
 jas_matrix_t *jas_seq2d_input(FILE *in)
 {
 	jas_matrix_t *matrix;
-	int i;
-	int j;
+	jas_matind_t i;
+	jas_matind_t j;
 	long x;
-	int numrows;
-	int numcols;
-	int xoff;
-	int yoff;
-
-	if (fscanf(in, "%d %d", &xoff, &yoff) != 2)
+	jas_matind_t numrows;
+	jas_matind_t numcols;
+	jas_matind_t xoff;
+	jas_matind_t yoff;
+	long tmp_xoff;
+	long tmp_yoff;
+	long tmp_numrows;
+	long tmp_numcols;
+
+	if (fscanf(in, "%ld %ld", &tmp_xoff, &tmp_yoff) != 2) {
 		return 0;
-	if (fscanf(in, "%d %d", &numcols, &numrows) != 2)
+	}
+	xoff = tmp_xoff;
+	yoff = tmp_yoff;
+	if (fscanf(in, "%ld %ld", &tmp_numcols, &tmp_numrows) != 2) {
 		return 0;
-	if (!(matrix = jas_seq2d_create(xoff, yoff, xoff + numcols, yoff + numrows)))
+	}
+	numrows = tmp_numrows;
+	numcols = tmp_numcols;
+	if (!(matrix = jas_seq2d_create(xoff, yoff, xoff + numcols,
+	  yoff + numrows))) {
 		return 0;
+	}
 
 	if (jas_matrix_numrows(matrix) != numrows ||
 	  jas_matrix_numcols(matrix) != numcols) {
 		abort();
 	}
@@ -461,12 +475,12 @@ jas_matrix_t *jas_seq2d_input(FILE *in)
 }
 
 int jas_seq2d_output(jas_matrix_t *matrix, FILE *out)
 {
 #define MAXLINELEN	80
-	int i;
-	int j;
+	jas_matind_t i;
+	jas_matind_t j;
 	jas_seqent_t x;
 	char buf[MAXLINELEN + 1];
 	char sbuf[MAXLINELEN + 1];
 	int n;
 
diff --git a/src/libjasper/base/jas_stream.c b/src/libjasper/base/jas_stream.c
index cea4a95..327ee57 100644
--- a/src/libjasper/base/jas_stream.c
+++ b/src/libjasper/base/jas_stream.c
@@ -69,22 +69,25 @@
 
 /******************************************************************************\
 * Includes.
 \******************************************************************************/
 
+/* The configuration header file should be included first. */
+#include "jasper/jas_config.h"
+
 #include <assert.h>
-#if defined(HAVE_FCNTL_H)
+#if defined(JAS_HAVE_FCNTL_H)
 #include <fcntl.h>
 #endif
 #include <stdlib.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <ctype.h>
-#if defined(HAVE_UNISTD_H)
+#if defined(JAS_HAVE_UNISTD_H)
 #include <unistd.h>
 #endif
-#if defined(WIN32) || defined(HAVE_IO_H)
+#if defined(WIN32) || defined(JAS_HAVE_IO_H)
 #include <io.h>
 #endif
 
 #include "jasper/jas_debug.h"
 #include "jasper/jas_types.h"
@@ -907,11 +910,11 @@ static void jas_stream_initbuf(jas_stream_t *stream, int bufmode, char *buf,
 		} else {
 			/* The caller has specified a buffer to employ. */
 			/* The buffer must be large enough to accommodate maximum
 			  putback. */
 			assert(bufsize > JAS_STREAM_MAXPUTBACK);
-			stream->bufbase_ = JAS_CAST(uchar *, buf);
+			stream->bufbase_ = JAS_CAST(jas_uchar *, buf);
 			stream->bufsize_ = bufsize - JAS_STREAM_MAXPUTBACK;
 		}
 	} else {
 		/* The unbuffered mode is being employed. */
 		/* A buffer should not have been supplied by the caller. */
diff --git a/src/libjasper/base/jas_tmr.c b/src/libjasper/base/jas_tmr.c
index babb9fd..b3540d3 100644
--- a/src/libjasper/base/jas_tmr.c
+++ b/src/libjasper/base/jas_tmr.c
@@ -67,21 +67,24 @@
 
 /******************************************************************************\
 * Includes.
 \******************************************************************************/
 
+/* The configuration header file should be included first. */
+#include "jasper/jas_config.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
 
 #include "jasper/jas_tmr.h"
 
 /******************************************************************************\
 * Code.
 \******************************************************************************/
 
-#if defined(HAVE_GETTIMEOFDAY)
+#if defined(JAS_HAVE_GETTIMEOFDAY)
 
 void jas_tmr_start(jas_tmr_t *tmr)
 {
 	if (gettimeofday(&tmr->start, 0)) {
 		abort();
@@ -102,11 +105,11 @@ double jas_tmr_get(jas_tmr_t *tmr)
 	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;
 }
 
-#elif defined(HAVE_GETRUSAGE)
+#elif defined(JAS_HAVE_GETRUSAGE)
 
 void jas_tmr_start(jas_tmr_t *tmr)
 {
 	if (getrusage(RUSAGE_SELF, &tmr->start) < 0) {
 		abort();
diff --git a/src/libjasper/bmp/bmp_dec.c b/src/libjasper/bmp/bmp_dec.c
index d5a903f..6af2216 100644
--- a/src/libjasper/bmp/bmp_dec.c
+++ b/src/libjasper/bmp/bmp_dec.c
@@ -76,13 +76,26 @@
 #include "jasper/jas_types.h"
 #include "jasper/jas_stream.h"
 #include "jasper/jas_image.h"
 #include "jasper/jas_malloc.h"
 #include "jasper/jas_debug.h"
+#include "jasper/jas_tvp.h"
 
 #include "bmp_cod.h"
 
+/******************************************************************************\
+* Local types.
+\******************************************************************************/
+
+typedef struct {
+	size_t max_samples;
+} bmp_dec_importopts_t;
+
+typedef enum {
+	OPT_MAXSIZE,
+} optid_t;
+
 /******************************************************************************\
 * Local prototypes.
 \******************************************************************************/
 
 static int bmp_gethdr(jas_stream_t *in, bmp_hdr_t *hdr);
@@ -90,10 +103,47 @@ static bmp_info_t *bmp_getinfo(jas_stream_t *in);
 static int bmp_getdata(jas_stream_t *in, bmp_info_t *info, jas_image_t *image);
 static int bmp_getint16(jas_stream_t *in, int_fast16_t *val);
 static int bmp_getint32(jas_stream_t *in, int_fast32_t *val);
 static int bmp_gobble(jas_stream_t *in, long n);
 
+/******************************************************************************\
+* Option parsing.
+\******************************************************************************/
+
+static jas_taginfo_t decopts[] = {
+	{OPT_MAXSIZE, "max_samples"},
+	{-1, 0}
+};
+
+static int bmp_dec_parseopts(char *optstr, bmp_dec_importopts_t *opts)
+{
+	jas_tvparser_t *tvp;
+
+	opts->max_samples = 128 * JAS_MEBI;
+
+	if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) {
+		return -1;
+	}
+
+	while (!jas_tvparser_next(tvp)) {
+		switch (jas_taginfo_nonull(jas_taginfos_lookup(decopts,
+		  jas_tvparser_gettag(tvp)))->id) {
+		case OPT_MAXSIZE:
+			opts->max_samples = atoi(jas_tvparser_getval(tvp));
+			break;
+		default:
+			jas_eprintf("warning: ignoring invalid option %s\n",
+			  jas_tvparser_gettag(tvp));
+			break;
+		}
+	}
+
+	jas_tvparser_destroy(tvp);
+
+	return 0;
+}
+
 /******************************************************************************\
 * Interface functions.
 \******************************************************************************/
 
 jas_image_t *bmp_decode(jas_stream_t *in, char *optstr)
@@ -104,16 +154,18 @@ jas_image_t *bmp_decode(jas_stream_t *in, char *optstr)
 	uint_fast16_t cmptno;
 	jas_image_cmptparm_t cmptparms[3];
 	jas_image_cmptparm_t *cmptparm;
 	uint_fast16_t numcmpts;
 	long n;
+	bmp_dec_importopts_t opts;
+	size_t num_samples;
 
 	image = 0;
 	info = 0;
 
-	if (optstr) {
-		jas_eprintf("warning: ignoring BMP decoder options\n");
+	if (bmp_dec_parseopts(optstr, &opts)) {
+		goto error;
 	}
 
 	jas_eprintf(
 	  "THE BMP FORMAT IS NOT FULLY SUPPORTED!\n"
 	  "THAT IS, THE JASPER SOFTWARE CANNOT DECODE ALL TYPES OF BMP DATA.\n"
@@ -123,21 +175,19 @@ jas_image_t *bmp_decode(jas_stream_t *in, char *optstr)
 
 	/* Read the bitmap header. */
 	if (bmp_gethdr(in, &hdr)) {
 		jas_eprintf("cannot get header\n");
 		goto error;
-		//return 0;
 	}
 	JAS_DBGLOG(1, (
 	  "BMP header: magic 0x%x; siz %d; res1 %d; res2 %d; off %d\n",
 	  hdr.magic, hdr.siz, hdr.reserved1, hdr.reserved2, hdr.off
 	  ));
 
 	/* Read the bitmap information. */
 	if (!(info = bmp_getinfo(in))) {
 		jas_eprintf("cannot get info\n");
-		//return 0;
 		goto error;
 	}
 	JAS_DBGLOG(1,
 	  ("BMP information: len %ld; width %ld; height %ld; numplanes %d; "
 	  "depth %d; enctype %ld; siz %ld; hres %ld; vres %ld; numcolors %ld; "
@@ -152,30 +202,37 @@ jas_image_t *bmp_decode(jas_stream_t *in, char *optstr)
 	  info->depth < 0 || info->siz < 0 || info->hres < 0 || info->vres < 0) {
 		jas_eprintf("corrupt bit stream\n");
 		goto error;
 	}
 
+	if (!jas_safe_size_mul3(info->width, info->height, info->numplanes,
+	  &num_samples)) {
+		jas_eprintf("image size too large\n");
+		goto error;
+	}
+
+	if (opts.max_samples > 0 && num_samples > opts.max_samples) {
+		jas_eprintf("maximum number of pixels exceeded (%zu)\n",
+		  opts.max_samples);
+		goto error;
+	}
+
 	/* Ensure that we support this type of BMP file. */
 	if (!bmp_issupported(&hdr, info)) {
 		jas_eprintf("error: unsupported BMP encoding\n");
-		//bmp_info_destroy(info);
-		//return 0;
 		goto error;
 	}
 
 	/* Skip over any useless data between the end of the palette
 	  and start of the bitmap data. */
 	if ((n = hdr.off - (BMP_HDRLEN + BMP_INFOLEN + BMP_PALLEN(info))) < 0) {
 		jas_eprintf("error: possibly bad bitmap offset?\n");
 		goto error;
-		//return 0;
 	}
 	if (n > 0) {
 		jas_eprintf("skipping unknown data in BMP file\n");
 		if (bmp_gobble(in, n)) {
-			//bmp_info_destroy(info);
-			//return 0;
 			goto error;
 		}
 	}
 
 	/* Get the number of components. */
@@ -194,12 +251,10 @@ jas_image_t *bmp_decode(jas_stream_t *in, char *optstr)
 	}
 
 	/* Create image object. */
 	if (!(image = jas_image_create(numcmpts, cmptparms,
 	  JAS_CLRSPC_UNKNOWN))) {
-		//bmp_info_destroy(info);
-		//return 0;
 		goto error;
 	}
 
 	if (numcmpts == 3) {
 		jas_image_setclrspc(image, JAS_CLRSPC_SRGB);
@@ -215,13 +270,10 @@ jas_image_t *bmp_decode(jas_stream_t *in, char *optstr)
 		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
 	}
 
 	/* Read the bitmap data. */
 	if (bmp_getdata(in, info, image)) {
-		//bmp_info_destroy(info);
-		//jas_image_destroy(image);
-		//return 0;
 		goto error;
 	}
 
 	bmp_info_destroy(info);
 
@@ -239,11 +291,11 @@ error:
 
 int bmp_validate(jas_stream_t *in)
 {
 	int n;
 	int i;
-	uchar buf[2];
+	jas_uchar buf[2];
 
 	assert(JAS_STREAM_MAXPUTBACK >= 2);
 
 	/* Read the first two characters that constitute the signature. */
 	if ((n = jas_stream_read(in, (char *) buf, 2)) < 0) {
diff --git a/src/libjasper/include/jasper/jas_cm.h b/src/libjasper/include/jasper/jas_cm.h
index d5cd22e..af785f3 100644
--- a/src/libjasper/include/jasper/jas_cm.h
+++ b/src/libjasper/include/jasper/jas_cm.h
@@ -66,11 +66,13 @@
  */
 
 #ifndef JAS_CM_H
 #define JAS_CM_H
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
+
 #include <jasper/jas_icc.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/src/libjasper/include/jasper/jas_config.h.in b/src/libjasper/include/jasper/jas_config.h.in
new file mode 100644
index 0000000..0c0e86f
--- /dev/null
+++ b/src/libjasper/include/jasper/jas_config.h.in
@@ -0,0 +1,27 @@
+#ifndef JAS_CONFIG_H
+#define JAS_CONFIG_H
+
+/* This preprocessor symbol identifies the version of JasPer. */
+#define	JAS_VERSION "@JAS_VERSION@"
+
+@JAS_HAVE_FCNTL_H@
+@JAS_HAVE_IO_H@
+@JAS_HAVE_UNISTD_H@
+@JAS_HAVE_WINDOWS_H@
+@JAS_HAVE_SYS_TIME_H@
+@JAS_HAVE_SYS_TYPES_H@
+
+@JAS_HAVE_GETTIMEOFDAY@
+@JAS_HAVE_GETRUSAGE@
+
+#if defined(__GNUC__) && !defined(__clang__)
+#define JAS_ATTRIBUTE_DISABLE_USAN \
+  __attribute__((no_sanitize_undefined))
+#elif defined(__clang__)
+#define JAS_ATTRIBUTE_DISABLE_USAN \
+  __attribute__((no_sanitize("undefined")))
+#else
+#define JAS_ATTRIBUTE_DISABLE_USAN
+#endif
+
+#endif
diff --git a/src/libjasper/include/jasper/jas_config2.h b/src/libjasper/include/jasper/jas_config2.h
index f139db0..2666b79 100644
--- a/src/libjasper/include/jasper/jas_config2.h
+++ b/src/libjasper/include/jasper/jas_config2.h
@@ -68,27 +68,14 @@
  * We are not using a configure-based build.
  * Try to compensate for this here, by specifying the preprocessor symbols
  * normally defined by configure.
  */
 
-#define	uchar		unsigned char
-#define	ushort		unsigned short
-#define	uint		unsigned int
-#define	ulong		unsigned long
-#undef longlong
-#define	longlong	long long
-#undef ulonglong
-#define	ulonglong	unsigned long long
-/*#define	ssize_t		int*/
-
 #define	HAVE_FCNTL_H		1
-#define	HAVE_LIMITS_H		1
 #define	HAVE_IO_H		1
 #define	HAVE_WINDOWS_H		1
 #define	HAVE_SYS_TYPES_H	1
-#define	HAVE_STDLIB_H		1
-#define	HAVE_STDDEF_H		1
 
 #ifndef __cplusplus
 #undef inline
 #define inline __inline
 #endif
diff --git a/src/libjasper/include/jasper/jas_debug.h b/src/libjasper/include/jasper/jas_debug.h
index 6b78112..d820d36 100644
--- a/src/libjasper/include/jasper/jas_debug.h
+++ b/src/libjasper/include/jasper/jas_debug.h
@@ -70,13 +70,15 @@
 
 /******************************************************************************\
 * Includes.
 \******************************************************************************/
 
+/* The configuration header file should be included first. */
+#include <jasper/jas_config.h>
+
 #include <stdio.h>
 
-#include <jasper/jas_config.h>
 #include <jasper/jas_types.h>
 #include <jasper/jas_debug.h>
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/src/libjasper/include/jasper/jas_fix.h b/src/libjasper/include/jasper/jas_fix.h
index e9164c7..f75d52a 100644
--- a/src/libjasper/include/jasper/jas_fix.h
+++ b/src/libjasper/include/jasper/jas_fix.h
@@ -72,15 +72,17 @@
 
 /******************************************************************************\
 * Includes.
 \******************************************************************************/
 
+/* The configuration header file should be included first. */
+#include <jasper/jas_config.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 
-#include <jasper/jas_config.h>
 #include <jasper/jas_types.h>
 #include <jasper/jas_debug.h>
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/src/libjasper/include/jasper/jas_getopt.h b/src/libjasper/include/jasper/jas_getopt.h
index 3c7b205..1db2e0f 100644
--- a/src/libjasper/include/jasper/jas_getopt.h
+++ b/src/libjasper/include/jasper/jas_getopt.h
@@ -72,10 +72,11 @@
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
 
 /******************************************************************************\
 * Constants.
 \******************************************************************************/
diff --git a/src/libjasper/include/jasper/jas_icc.h b/src/libjasper/include/jasper/jas_icc.h
index 616a572..668f6f5 100644
--- a/src/libjasper/include/jasper/jas_icc.h
+++ b/src/libjasper/include/jasper/jas_icc.h
@@ -60,11 +60,13 @@
  */
 
 #ifndef JAS_ICC_H
 #define	JAS_ICC_H
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
+
 #include <jasper/jas_types.h>
 #include <jasper/jas_stream.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -250,14 +252,14 @@ typedef struct {
 typedef struct {
 	jas_iccuint32_t asclen;
 	char *ascdata; /* ASCII invariant description */
 	jas_iccuint32_t uclangcode; /* Unicode language code */
 	jas_iccuint32_t uclen; /* Unicode localizable description count */
-	uchar *ucdata; /* Unicode localizable description */
+	jas_uchar *ucdata; /* Unicode localizable description */
 	jas_iccuint16_t sccode; /* ScriptCode code */
 	jas_iccuint8_t maclen; /* Localizable Macintosh description count */
-	uchar macdata[69]; /* Localizable Macintosh description */
+	jas_uchar macdata[69]; /* Localizable Macintosh description */
 } jas_icctxtdesc_t;
 
 /* Text type. */
 typedef struct {
 	char *string;	/* ASCII character string */
@@ -391,15 +393,15 @@ int jas_iccattrval_allowmodify(jas_iccattrval_t **attrval);
 jas_iccattrval_t *jas_iccattrval_clone(jas_iccattrval_t *attrval);
 jas_iccattrval_t *jas_iccattrval_create(jas_iccuint32_t type);
 
 void jas_iccattrtab_dump(jas_iccattrtab_t *attrtab, FILE *out);
 
-extern uchar jas_iccprofdata_srgb[];
+extern jas_uchar jas_iccprofdata_srgb[];
 extern int jas_iccprofdata_srgblen;
-extern uchar jas_iccprofdata_sgray[];
+extern jas_uchar jas_iccprofdata_sgray[];
 extern int jas_iccprofdata_sgraylen;
-jas_iccprof_t *jas_iccprof_createfrombuf(uchar *buf, int len);
+jas_iccprof_t *jas_iccprof_createfrombuf(jas_uchar *buf, int len);
 jas_iccprof_t *jas_iccprof_createfromclrspc(int clrspc);
 
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/libjasper/include/jasper/jas_image.h b/src/libjasper/include/jasper/jas_image.h
index 4dcfcc1..b0594c7 100644
--- a/src/libjasper/include/jasper/jas_image.h
+++ b/src/libjasper/include/jasper/jas_image.h
@@ -72,11 +72,13 @@
 
 /******************************************************************************\
 * Includes.
 \******************************************************************************/
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
+
 #include <jasper/jas_stream.h>
 #include <jasper/jas_seq.h>
 #include <jasper/jas_cm.h>
 #include <stdio.h>
 #include <stdbool.h>
@@ -215,11 +217,11 @@ typedef struct {
 
 	jas_clrspc_t clrspc_;
 
 	jas_cmprof_t *cmprof_;
 
-	bool inmem_;
+//	bool inmem_;
 
 } jas_image_t;
 
 /* Component parameters class. */
 /* This data type exists solely/mainly for the purposes of the
diff --git a/src/libjasper/include/jasper/jas_init.h b/src/libjasper/include/jasper/jas_init.h
index 10301e9..20121f5 100644
--- a/src/libjasper/include/jasper/jas_init.h
+++ b/src/libjasper/include/jasper/jas_init.h
@@ -60,10 +60,11 @@
  */
 
 #ifndef JAS_INIT_H
 #define JAS_INIT_H
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/src/libjasper/include/jasper/jas_malloc.h b/src/libjasper/include/jasper/jas_malloc.h
index f3f9047..7b03933 100644
--- a/src/libjasper/include/jasper/jas_malloc.h
+++ b/src/libjasper/include/jasper/jas_malloc.h
@@ -72,10 +72,11 @@
 
 /******************************************************************************\
 * Includes.
 \******************************************************************************/
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
 
 #include <stdlib.h>
 #include <stdio.h>
 
diff --git a/src/libjasper/include/jasper/jas_math.h b/src/libjasper/include/jasper/jas_math.h
index 88f43ed..723b0fa 100644
--- a/src/libjasper/include/jasper/jas_math.h
+++ b/src/libjasper/include/jasper/jas_math.h
@@ -72,11 +72,13 @@
 
 /******************************************************************************\
 * Includes
 \******************************************************************************/
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
+
 #include <jasper/jas_types.h>
 
 #include <assert.h>
 #include <stdio.h>
 #include <string.h>
@@ -89,10 +91,13 @@ extern "C" {
 
 /******************************************************************************\
 * Macros
 \******************************************************************************/
 
+#define JAS_KIBI	JAS_CAST(size_t, 1024)
+#define JAS_MEBI	(JAS_KIBI * JAS_KIBI)
+
 /* Compute the absolute value. */
 #define	JAS_ABS(x) \
 	(((x) >= 0) ? (x) : (-(x)))
 
 /* Compute the minimum of two values. */
@@ -185,10 +190,24 @@ inline static bool jas_safe_size_mul(size_t x, size_t y, size_t *result)
 		*result = x * y;
 	}
 	return true;
 }
 
+inline static bool jas_safe_size_mul3(size_t a, size_t b, size_t c,
+  size_t *result)
+{
+	size_t tmp;
+	if (!jas_safe_size_mul(a, b, &tmp) ||
+	  !jas_safe_size_mul(tmp, c, &tmp)) {
+		return false;
+	}
+	if (result) {
+		*result = tmp;
+	}
+	return true;
+}
+
 /* Compute the sum of two size_t integer with overflow checking. */
 inline static bool jas_safe_size_add(size_t x, size_t y, size_t *result)
 {
 	if (y > SIZE_MAX - x) {
 		return false;
@@ -209,10 +228,61 @@ inline static bool jas_safe_size_sub(size_t x, size_t y, size_t *result)
 		*result = x - y;
 	}
 	return true;
 }
 
+/* Compute the sum of two size_t integer with overflow checking. */
+inline static bool jas_safe_intfast32_mul(int_fast32_t x, int_fast32_t y,
+  int_fast32_t *result)
+{
+	if (x > 0) {
+		/* x is positive */
+		if (y > 0) {
+			/* x and y are positive */
+			if (x > INT_FAST32_MAX / y) {
+				return false;
+			}
+		} else {
+			/* x positive, y nonpositive */
+			if (y < INT_FAST32_MIN / x) {
+				return false;
+			}
+		}
+	} else {
+		/* x is nonpositive */
+		if (y > 0) {
+			/* x is nonpositive, y is positive */
+			if (x < INT_FAST32_MIN / y) {
+				return false;
+			}
+		} else { /* x and y are nonpositive */
+			if (x != 0 && y < INT_FAST32_MAX / x) {
+				return false;
+			}
+		}
+	}
+
+	if (result) {
+		*result = x * y;
+	}
+	return true;
+}
+
+inline static bool jas_safe_intfast32_mul3(int_fast32_t a, int_fast32_t b,
+  int_fast32_t c, int_fast32_t *result)
+{
+	int_fast32_t tmp;
+	if (!jas_safe_intfast32_mul(a, b, &tmp) ||
+	  !jas_safe_intfast32_mul(tmp, c, &tmp)) {
+		return false;
+	}
+	if (result) {
+		*result = tmp;
+	}
+	return true;
+}
+
 /* Compute the sum of two size_t integer with overflow checking. */
 inline static bool jas_safe_intfast32_add(int_fast32_t x, int_fast32_t y,
   int_fast32_t *result)
 {
 	if ((y > 0 && x > INT_FAST32_MAX - y) ||
diff --git a/src/libjasper/include/jasper/jas_seq.h b/src/libjasper/include/jasper/jas_seq.h
index 02fdebf..3cdc9e5 100644
--- a/src/libjasper/include/jasper/jas_seq.h
+++ b/src/libjasper/include/jasper/jas_seq.h
@@ -72,10 +72,11 @@
 
 /******************************************************************************\
 * Includes.
 \******************************************************************************/
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
 
 #include <jasper/jas_stream.h>
 #include <jasper/jas_types.h>
 
@@ -100,34 +101,36 @@ extern "C" {
 typedef int_fast32_t jas_seqent_t;
 
 /* An element in a matrix. */
 typedef int_fast32_t jas_matent_t;
 
+typedef int_fast32_t jas_matind_t;
+
 /* Matrix. */
 
 typedef struct {
 
 	/* Additional state information. */
 	int flags_;
 
 	/* The starting horizontal index. */
-	int_fast32_t xstart_;
+	jas_matind_t xstart_;
 
 	/* The starting vertical index. */
-	int_fast32_t ystart_;
+	jas_matind_t ystart_;
 
 	/* The ending horizontal index. */
-	int_fast32_t xend_;
+	jas_matind_t xend_;
 
 	/* The ending vertical index. */
-	int_fast32_t yend_;
+	jas_matind_t yend_;
 
 	/* The number of rows in the matrix. */
-	int_fast32_t numrows_;
+	jas_matind_t numrows_;
 
 	/* The number of columns in the matrix. */
-	int_fast32_t numcols_;
+	jas_matind_t numcols_;
 
 	/* Pointers to the start of each row. */
 	jas_seqent_t **rows_;
 
 	/* The allocated size of the rows array. */
@@ -180,29 +183,30 @@ typedef jas_matrix_t jas_seq_t;
 /* Get the address of an element in a matrix. */
 #define	jas_matrix_getref(matrix, i, j) \
 	(&(matrix)->rows_[i][j])
 
 #define	jas_matrix_getvref(matrix, i) \
-	(((matrix)->numrows_ > 1) ? jas_matrix_getref(matrix, i, 0) : jas_matrix_getref(matrix, 0, i))
+	(((matrix)->numrows_ > 1) ? jas_matrix_getref(matrix, i, 0) : \
+	  jas_matrix_getref(matrix, 0, i))
 
 #define jas_matrix_length(matrix) \
 	(max((matrix)->numrows_, (matrix)->numcols_))
 
 /* Create a matrix with the specified dimensions. */
-jas_matrix_t *jas_matrix_create(int numrows, int numcols);
+jas_matrix_t *jas_matrix_create(jas_matind_t numrows, jas_matind_t numcols);
 
 /* Destroy a matrix. */
 void jas_matrix_destroy(jas_matrix_t *matrix);
 
 /* Resize a matrix.  The previous contents of the matrix are lost. */
-int jas_matrix_resize(jas_matrix_t *matrix, int numrows, int numcols);
+int jas_matrix_resize(jas_matrix_t *matrix, jas_matind_t numrows, jas_matind_t numcols);
 
 int jas_matrix_output(jas_matrix_t *matrix, FILE *out);
 
 /* Create a matrix that references part of another matrix. */
-void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, int r0,
-  int c0, int r1, int c1);
+void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, jas_matind_t r0,
+  jas_matind_t c0, jas_matind_t r1, jas_matind_t c1);
 
 /* Create a matrix that is a reference to a row of another matrix. */
 #define jas_matrix_bindrow(mat0, mat1, r) \
   (jas_matrix_bindsub((mat0), (mat1), (r), 0, (r), (mat1)->numcols_ - 1))
 
@@ -248,11 +252,12 @@ jas_matrix_t *jas_matrix_input(FILE *);
 * Functions/macros for 2-D sequence class.
 \******************************************************************************/
 
 jas_seq2d_t *jas_seq2d_copy(jas_seq2d_t *x);
 
-jas_matrix_t *jas_seq2d_create(int xstart, int ystart, int xend, int yend);
+jas_matrix_t *jas_seq2d_create(jas_matind_t xstart, jas_matind_t ystart,
+  jas_matind_t xend, jas_matind_t yend);
 
 #define	jas_seq2d_destroy(s) \
 	jas_matrix_destroy(s)
 
 #define	jas_seq2d_xstart(s) \
@@ -278,12 +283,12 @@ jas_matrix_t *jas_seq2d_create(int xstart, int ystart, int xend, int yend);
 	  (s)->xend_ = (s)->xstart_ + (s)->numcols_, \
 	  (s)->yend_ = (s)->ystart_ + (s)->numrows_)
 #define jas_seq2d_size(s) \
 	(jas_seq2d_width(s) * jas_seq2d_height(s))
 
-void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, int xstart,
-  int ystart, int xend, int yend);
+void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, jas_matind_t xstart,
+  jas_matind_t ystart, jas_matind_t xend, jas_matind_t yend);
 
 /******************************************************************************\
 * Functions/macros for 1-D sequence class.
 \******************************************************************************/
 
diff --git a/src/libjasper/include/jasper/jas_stream.h b/src/libjasper/include/jasper/jas_stream.h
index b9801d8..5badccd 100644
--- a/src/libjasper/include/jasper/jas_stream.h
+++ b/src/libjasper/include/jasper/jas_stream.h
@@ -72,18 +72,19 @@
 
 /******************************************************************************\
 * Includes.
 \******************************************************************************/
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
 
 #include <stdio.h>
-#if defined(HAVE_FCNTL_H)
+#if defined(JAS_HAVE_FCNTL_H)
 #include <fcntl.h>
 #endif
 #include <string.h>
-#if defined(HAVE_UNISTD_H)
+#if defined(JAS_HAVE_UNISTD_H)
 #include <unistd.h>
 #endif
 #include <jasper/jas_types.h>
 
 #ifdef __cplusplus
@@ -206,28 +207,28 @@ typedef struct {
 
 	/* The stream status. */
 	int flags_;
 
 	/* The start of the buffer area to use for reading/writing. */
-	uchar *bufbase_;
+	jas_uchar *bufbase_;
 
 	/* The start of the buffer area excluding the extra initial space for
 	  character putback. */
-	uchar *bufstart_;
+	jas_uchar *bufstart_;
 
 	/* The buffer size. */
 	int bufsize_;
 
 	/* The current position in the buffer. */
-	uchar *ptr_;
+	jas_uchar *ptr_;
 
 	/* The number of characters that must be read/written before
 	the buffer needs to be filled/flushed. */
 	int cnt_;
 
 	/* A trivial buffer to be used for unbuffered operation. */
-	uchar tinybuf_[JAS_STREAM_MAXPUTBACK + 1];
+	jas_uchar tinybuf_[JAS_STREAM_MAXPUTBACK + 1];
 
 	/* The operations for the underlying stream file object. */
 	jas_stream_ops_t *ops_;
 
 	/* The underlying stream file object. */
@@ -262,11 +263,11 @@ typedef struct {
  */
 
 typedef struct {
 
 	/* The data associated with this file. */
-	uchar *buf_;
+	jas_uchar *buf_;
 
 	/* The allocated size of the buffer for holding file data. */
 	size_t bufsize_;
 
 	/* The length of the file. */
@@ -449,11 +450,11 @@ directly, you will die a horrible, miserable, and painful death! */
 	  (((stream)->rwlimit_ >= 0 && (stream)->rwcnt_ >= (stream)->rwlimit_) ? \
 	  (stream->flags_ |= JAS_STREAM_RWLIMIT, EOF) : \
 	  jas_stream_putc2(stream, c)) : EOF)
 #define jas_stream_putc2(stream, c) \
 	(((stream)->bufmode_ |= JAS_STREAM_WRBUF, --(stream)->cnt_ < 0) ? \
-	  jas_stream_flushbuf((stream), (uchar)(c)) : \
+	  jas_stream_flushbuf((stream), (jas_uchar)(c)) : \
 	  (++(stream)->rwcnt_, (int)(*(stream)->ptr_++ = (c))))
 
 /* These prototypes need to be here for the sake of the stream_getc and
 stream_putc macros. */
 int jas_stream_fillbuf(jas_stream_t *stream, int getflag);
diff --git a/src/libjasper/include/jasper/jas_string.h b/src/libjasper/include/jasper/jas_string.h
index f217da2..37fddf3 100644
--- a/src/libjasper/include/jasper/jas_string.h
+++ b/src/libjasper/include/jasper/jas_string.h
@@ -72,11 +72,13 @@
 
 /******************************************************************************\
 * Includes.
 \******************************************************************************/
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
+
 #include <string.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/src/libjasper/include/jasper/jas_tmr.h b/src/libjasper/include/jasper/jas_tmr.h
index 837f2bf..2f645e2 100644
--- a/src/libjasper/include/jasper/jas_tmr.h
+++ b/src/libjasper/include/jasper/jas_tmr.h
@@ -60,28 +60,30 @@
  */
 
 #ifndef JAS_TMR_H
 #define JAS_TMR_H
 
-#include<time.h>
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
-#if defined(HAVE_SYS_TIME_H)
+
+#include<time.h>
+#if defined(JAS_HAVE_SYS_TIME_H)
 #include <sys/time.h>
 #endif
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#if defined(HAVE_GETTIMEOFDAY)
+#if defined(JAS_HAVE_GETTIMEOFDAY)
 
 typedef struct {
 	struct timeval start;
 	struct timeval stop;
 } jas_tmr_t;
 
-#elif defined(HAVE_GETRUSAGE)
+#elif defined(JAS_HAVE_GETRUSAGE)
 
 typedef struct {
 	struct rusage start;
 	struct rusage stop;
 } jas_tmr_t;
diff --git a/src/libjasper/include/jasper/jas_tvp.h b/src/libjasper/include/jasper/jas_tvp.h
index ae4f933..e08402c 100644
--- a/src/libjasper/include/jasper/jas_tvp.h
+++ b/src/libjasper/include/jasper/jas_tvp.h
@@ -70,10 +70,11 @@
 
 /******************************************************************************\
 * Includes.
 \******************************************************************************/
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/src/libjasper/include/jasper/jas_types.h b/src/libjasper/include/jasper/jas_types.h
index 32c541c..bd83ca5 100644
--- a/src/libjasper/include/jasper/jas_types.h
+++ b/src/libjasper/include/jasper/jas_types.h
@@ -68,61 +68,49 @@
  */
 
 #ifndef JAS_TYPES_H
 #define JAS_TYPES_H
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
 
 #if !defined(JAS_CONFIGURE)
 
-#if defined(WIN32) || defined(HAVE_WINDOWS_H)
+#if defined(WIN32) || defined(JAS_HAVE_WINDOWS_H)
+// THIS SHOULD NO LONGER BE NEEDED SINCE MSVC SUPPORTS LONG LONG.
 /*
    We are dealing with Microsoft Windows and most likely Microsoft
    Visual C (MSVC).  (Heaven help us.)  Sadly, MSVC does not correctly
    define some of the standard types specified in ISO/IEC 9899:1999.
    In particular, it does not define the "long long" and "unsigned long
    long" types.  So, we work around this problem by using the "INT64"
    and "UINT64" types that are defined in the header file "windows.h".
  */
 #include <windows.h>
-#undef longlong
-#define	longlong	INT64
-#undef ulonglong
-#define	ulonglong	UINT64
+//#undef longlong
+//#define	longlong	INT64
+//#undef ulonglong
+//#define	ulonglong	UINT64
 #endif
 
 #endif
 
 /* Note: The immediately following header files should eventually be removed. */
 #include <stdlib.h>
 #include <stddef.h>
 #include <stdbool.h>
 #include <stdint.h>
 
-#if defined(HAVE_SYS_TYPES_H)
+#if defined(JAS_HAVE_SYS_TYPES_H)
 #include <sys/types.h>
 #endif
 
-/* Hopefully, these macro definitions will fix more problems than they cause. */
-#if !defined(uchar)
-#define uchar unsigned char
-#endif
-#if !defined(ushort)
-#define ushort unsigned short
-#endif
-#if !defined(uint)
-#define uint unsigned int
-#endif
-#if !defined(ulong)
-#define ulong unsigned long
-#endif
-#if !defined(longlong)
-#define longlong long long
-#endif
-#if !defined(ulonglong)
-#define ulonglong unsigned long long
-#endif
+#define jas_uchar unsigned char
+#define jas_uint unsigned int
+#define jas_ulong unsigned long
+#define jas_longlong long long
+#define jas_ulonglong unsigned long long
 
 /* The below macro is intended to be used for type casts.  By using this
   macro, type casts can be easily located in the source code with
   tools like "grep". */
 #define	JAS_CAST(t, e) \
diff --git a/src/libjasper/include/jasper/jas_version.h b/src/libjasper/include/jasper/jas_version.h
index 14da7a0..ea37ed2 100644
--- a/src/libjasper/include/jasper/jas_version.h
+++ b/src/libjasper/include/jasper/jas_version.h
@@ -66,10 +66,11 @@
  */
 
 #ifndef JAS_VERSION_H
 #define JAS_VERSION_H
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/src/libjasper/include/jasper/jasper.h b/src/libjasper/include/jasper/jasper.h
index eb74ba0..fc544eb 100644
--- a/src/libjasper/include/jasper/jasper.h
+++ b/src/libjasper/include/jasper/jasper.h
@@ -60,11 +60,13 @@
  */
 
 #ifndef JAS_JASPER_H
 #define JAS_JASPER_H
 
+/* The configuration header file should be included first. */
 #include <jasper/jas_config.h>
+
 #include <jasper/jas_types.h>
 #include <jasper/jas_version.h>
 
 #include <jasper/jas_init.h>
 #include <jasper/jas_cm.h>
diff --git a/src/libjasper/jp2/jp2_dec.c b/src/libjasper/jp2/jp2_dec.c
index 2996393..cb5f14f 100644
--- a/src/libjasper/jp2/jp2_dec.c
+++ b/src/libjasper/jp2/jp2_dec.c
@@ -75,10 +75,11 @@
 #include "jasper/jas_stream.h"
 #include "jasper/jas_math.h"
 #include "jasper/jas_debug.h"
 #include "jasper/jas_malloc.h"
 #include "jasper/jas_version.h"
+#include "jasper/jas_types.h"
 
 #include "jp2_cod.h"
 #include "jp2_dec.h"
 
 #define	JP2_VALIDATELEN	(JAS_MIN(JP2_JP_LEN + 16, JAS_STREAM_MAXPUTBACK))
@@ -223,11 +224,11 @@ jas_image_t *jp2_decode(jas_stream_t *in, char *optstr)
 		goto error;
 	}
 
 	/* Does the number of components indicated in the IHDR box match
 	  the value specified in the code stream? */
-	if (dec->ihdr->data.ihdr.numcmpts != JAS_CAST(uint,
+	if (dec->ihdr->data.ihdr.numcmpts != JAS_CAST(jas_uint,
 	  jas_image_numcmpts(dec->image))) {
 		jas_eprintf("warning: number of components mismatch\n");
 	}
 
 	/* At least one component must be present. */
@@ -237,11 +238,11 @@ jas_image_t *jp2_decode(jas_stream_t *in, char *optstr)
 	}
 
 	/* Determine if all components have the same data type. */
 	samedtype = true;
 	dtype = jas_image_cmptdtype(dec->image, 0);
-	for (i = 1; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) {
+	for (i = 1; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); ++i) {
 		if (jas_image_cmptdtype(dec->image, i) != dtype) {
 			samedtype = false;
 			break;
 		}
 	}
@@ -260,18 +261,18 @@ jas_image_t *jp2_decode(jas_stream_t *in, char *optstr)
 	}
 
 	if (dec->bpcc) {
 		/* Is the number of components indicated in the BPCC box
 		  consistent with the code stream data? */
-		if (dec->bpcc->data.bpcc.numcmpts != JAS_CAST(uint, jas_image_numcmpts(
+		if (dec->bpcc->data.bpcc.numcmpts != JAS_CAST(jas_uint, jas_image_numcmpts(
 		  dec->image))) {
 			jas_eprintf("warning: number of components mismatch\n");
 		}
 		/* Is the component data type information indicated in the BPCC
 		  box consistent with the code stream data? */
 		if (!samedtype) {
-			for (i = 0; i < JAS_CAST(uint, jas_image_numcmpts(dec->image));
+			for (i = 0; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image));
 			  ++i) {
 				if (jas_image_cmptdtype(dec->image, i) !=
 				  JP2_BPCTODTYPE(dec->bpcc->data.bpcc.bpcs[i])) {
 					jas_eprintf("warning: component data type mismatch\n");
 				}
@@ -322,17 +323,17 @@ jas_image_t *jp2_decode(jas_stream_t *in, char *optstr)
 	}
 
 	/* Determine the number of channels (which is essentially the number
 	  of components after any palette mappings have been applied). */
 	dec->numchans = dec->cmap ? dec->cmap->data.cmap.numchans :
-	  JAS_CAST(uint, jas_image_numcmpts(dec->image));
+	  JAS_CAST(jas_uint, jas_image_numcmpts(dec->image));
 
 	/* Perform a basic sanity check on the CMAP box if present. */
 	if (dec->cmap) {
 		for (i = 0; i < dec->numchans; ++i) {
 			/* Is the component number reasonable? */
-			if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(uint,
+			if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(jas_uint,
 			  jas_image_numcmpts(dec->image))) {
 				jas_eprintf("error: invalid component number in CMAP box\n");
 				goto error;
 			}
 			/* Is the LUT index reasonable? */
@@ -389,11 +390,11 @@ jas_image_t *jp2_decode(jas_stream_t *in, char *optstr)
 		}
 	}
 
 	/* Mark all components as being of unknown type. */
 
-	for (i = 0; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) {
+	for (i = 0; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); ++i) {
 		jas_image_setcmpttype(dec->image, i, JAS_IMAGE_CT_UNKNOWN);
 	}
 
 	/* Determine the type of each component. */
 	if (dec->cdef) {
diff --git a/src/libjasper/jpc/jpc_cs.c b/src/libjasper/jpc/jpc_cs.c
index e6a5503..cc66ddb 100644
--- a/src/libjasper/jpc/jpc_cs.c
+++ b/src/libjasper/jpc/jpc_cs.c
@@ -287,11 +287,11 @@ jpc_ms_t *jpc_getms(jas_stream_t *in, jpc_cstate_t *cstate)
 
 		if (jas_getdbglevel() > 0) {
 			jpc_ms_dump(ms, stderr);
 		}
 
-		if (JAS_CAST(ulong, jas_stream_tell(tmpstream)) != ms->len) {
+		if (JAS_CAST(jas_ulong, jas_stream_tell(tmpstream)) != ms->len) {
 			jas_eprintf(
 			  "warning: trailing garbage in marker segment (%ld bytes)\n",
 			  ms->len - jas_stream_tell(tmpstream));
 		}
 
@@ -1175,11 +1175,11 @@ static int jpc_ppm_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in
 	ppm->len = ms->len - 1;
 	if (ppm->len > 0) {
 		if (!(ppm->data = jas_malloc(ppm->len))) {
 			goto error;
 		}
-		if (JAS_CAST(uint, jas_stream_read(in, ppm->data, ppm->len)) != ppm->len) {
+		if (JAS_CAST(jas_uint, jas_stream_read(in, ppm->data, ppm->len)) != ppm->len) {
 			goto error;
 		}
 	} else {
 		ppm->data = 0;
 	}
@@ -1195,11 +1195,11 @@ static int jpc_ppm_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *ou
 	jpc_ppm_t *ppm = &ms->parms.ppm;
 
 	/* Eliminate compiler warning about unused variables. */
 	cstate = 0;
 
-	if (JAS_CAST(uint, jas_stream_write(out, (char *) ppm->data, ppm->len)) != ppm->len) {
+	if (JAS_CAST(jas_uint, jas_stream_write(out, (char *) ppm->data, ppm->len)) != ppm->len) {
 		return -1;
 	}
 	return 0;
 }
 
diff --git a/src/libjasper/jpc/jpc_cs.h b/src/libjasper/jpc/jpc_cs.h
index 311986f..f2fbfee 100644
--- a/src/libjasper/jpc/jpc_cs.h
+++ b/src/libjasper/jpc/jpc_cs.h
@@ -488,11 +488,11 @@ typedef struct {
 
 	/* The length. */
 	uint_fast16_t len;
 
 	/* The data. */
-	uchar *data;
+	jas_uchar *data;
 
 } jpc_ppm_t;
 
 /* PPT marker segment parameters. */
 
@@ -527,11 +527,11 @@ typedef struct {
 
 	/* The length of the data in bytes. */
 	uint_fast16_t len;
 
 	/* The data. */
-	uchar *data;
+	jas_uchar *data;
 
 } jpc_com_t;
 
 /**************************************\
 * SOP marker segment parameters.
@@ -575,11 +575,11 @@ typedef struct {
 \**************************************/
 
 typedef struct {
 
 	/* The data. */
-	uchar *data;
+	jas_uchar *data;
 
 	/* The length. */
 	uint_fast16_t len;
 
 } jpc_unk_t;
diff --git a/src/libjasper/jpc/jpc_dec.c b/src/libjasper/jpc/jpc_dec.c
index 28b29fe..58e101d 100644
--- a/src/libjasper/jpc/jpc_dec.c
+++ b/src/libjasper/jpc/jpc_dec.c
@@ -2274,11 +2274,11 @@ int jpc_ppxstab_insert(jpc_ppxstab_t *tab, jpc_ppxstabent_t *ent)
 }
 
 jpc_streamlist_t *jpc_ppmstabtostreams(jpc_ppxstab_t *tab)
 {
 	jpc_streamlist_t *streams;
-	uchar *dataptr;
+	jas_uchar *dataptr;
 	uint_fast32_t datacnt;
 	uint_fast32_t tpcnt;
 	jpc_ppxstabent_t *ent;
 	int entno;
 	jas_stream_t *stream;
diff --git a/src/libjasper/jpc/jpc_dec.h b/src/libjasper/jpc/jpc_dec.h
index 2af98ca..81a1a50 100644
--- a/src/libjasper/jpc/jpc_dec.h
+++ b/src/libjasper/jpc/jpc_dec.h
@@ -97,11 +97,11 @@ typedef struct {
 
 	/* The data length. */
 	uint_fast32_t len;
 
 	/* The data. */
-	uchar *data;
+	jas_uchar *data;
 
 } jpc_ppxstabent_t;
 
 /* PPM/PPT marker segment table. */
 
diff --git a/src/libjasper/jpc/jpc_enc.c b/src/libjasper/jpc/jpc_enc.c
index 0a4c0ce..03a86ed 100644
--- a/src/libjasper/jpc/jpc_enc.c
+++ b/src/libjasper/jpc/jpc_enc.c
@@ -959,11 +959,11 @@ startoff = jas_stream_getrwcount(enc->out);
 	}
 	sprintf(buf, "Creator: JasPer Version %s", jas_getversion());
 	com = &enc->mrk->parms.com;
 	com->len = JAS_CAST(uint_fast16_t, strlen(buf));
 	com->regid = JPC_COM_LATIN;
-	if (!(com->data = JAS_CAST(uchar *, jas_strdup(buf)))) {
+	if (!(com->data = JAS_CAST(jas_uchar *, jas_strdup(buf)))) {
 		abort();
 	}
 	if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
 		jas_eprintf("cannot write COM marker\n");
 		return -1;
diff --git a/src/libjasper/jpc/jpc_mqdec.h b/src/libjasper/jpc/jpc_mqdec.h
index 05bf735..2266769 100644
--- a/src/libjasper/jpc/jpc_mqdec.h
+++ b/src/libjasper/jpc/jpc_mqdec.h
@@ -107,11 +107,11 @@ typedef struct {
 
 	/* The stream from which to read data. */
 	jas_stream_t *in;
 
 	/* The last character read. */
-	uchar inbuffer;
+	jas_uchar inbuffer;
 
 	/* The EOF indicator. */
 	int eof;
 
 } jpc_mqdec_t;
diff --git a/src/libjasper/jpg/jpg_dec.c b/src/libjasper/jpg/jpg_dec.c
index 858f243..c4b3aa2 100644
--- a/src/libjasper/jpg/jpg_dec.c
+++ b/src/libjasper/jpg/jpg_dec.c
@@ -78,10 +78,18 @@
 
 /******************************************************************************\
 * Types.
 \******************************************************************************/
 
+typedef struct {
+	size_t max_samples;
+} jpg_dec_importopts_t;
+
+typedef enum {
+	OPT_MAXSIZE,
+} optid_t;
+
 /* JPEG decoder data sink type. */
 
 typedef struct jpg_dest_s {
 
 	/* Initialize output. */
@@ -125,41 +133,33 @@ static void jpg_put_pixel_rows(j_decompress_ptr cinfo, jpg_dest_t *dinfo,
 static void jpg_finish_output(j_decompress_ptr cinfo, jpg_dest_t *dinfo);
 static int jpg_copystreamtofile(FILE *out, jas_stream_t *in);
 static jas_image_t *jpg_mkimage(j_decompress_ptr cinfo);
 
 /******************************************************************************\
-*
+* Option parsing.
 \******************************************************************************/
 
-typedef struct {
-	size_t max_size;
-} jpg_dec_importopts_t;
-
-typedef enum {
-	OPT_MAXSIZE,
-} optid_t;
-
 static jas_taginfo_t decopts[] = {
-	{OPT_MAXSIZE, "max_size"},
+	{OPT_MAXSIZE, "max_samples"},
 	{-1, 0}
 };
 
 static int jpg_dec_parseopts(char *optstr, jpg_dec_importopts_t *opts)
 {
 	jas_tvparser_t *tvp;
 
-	opts->max_size = 0;
+	opts->max_samples = 64 * JAS_MEBI;
 
 	if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) {
 		return -1;
 	}
 
 	while (!jas_tvparser_next(tvp)) {
 		switch (jas_taginfo_nonull(jas_taginfos_lookup(decopts,
 		  jas_tvparser_gettag(tvp)))->id) {
 		case OPT_MAXSIZE:
-			opts->max_size = atoi(jas_tvparser_getval(tvp));
+			opts->max_samples = atoi(jas_tvparser_getval(tvp));
 			break;
 		default:
 			jas_eprintf("warning: ignoring invalid option %s\n",
 			  jas_tvparser_gettag(tvp));
 			break;
@@ -186,11 +186,13 @@ jas_image_t *jpg_decode(jas_stream_t *in, char *optstr)
 	jpg_dest_t *dest_mgr = &dest_mgr_buf;
 	JDIMENSION num_scanlines;
 	jas_image_t *image;
 	int ret;
 	jpg_dec_importopts_t opts;
-	size_t size;
+	size_t num_samples;
+
+	JAS_DBGLOG(100, ("jpg_decode(%p, \"%s\")\n", in, optstr));
 
 	if (jpg_dec_parseopts(optstr, &opts)) {
 		goto error;
 	}
 
@@ -234,31 +236,31 @@ jas_image_t *jpg_decode(jas_stream_t *in, char *optstr)
 	JAS_DBGLOG(10, (
 	  "header: image_width %d; image_height %d; num_components %d\n",
 	  cinfo.image_width, cinfo.image_height, cinfo.num_components)
 	  );
 
+	if (opts.max_samples > 0) {
+		if (!jas_safe_size_mul3(cinfo.image_width, cinfo.image_height,
+		  cinfo.num_components, &num_samples)) {
+			goto error;
+		}
+		if (num_samples > opts.max_samples) {
+			jas_eprintf("image is too large (%zu > %zu)\n", num_samples,
+			  opts.max_samples);
+			goto error;
+		}
+	}
+
 	/* Start the decompressor. */
 	JAS_DBGLOG(10, ("jpeg_start_decompress(%p)\n", &cinfo));
 	ret = jpeg_start_decompress(&cinfo);
 	JAS_DBGLOG(10, ("jpeg_start_decompress return value %d\n", ret));
 	JAS_DBGLOG(10, (
 	  "header: output_width %d; output_height %d; output_components %d\n",
 	  cinfo.output_width, cinfo.output_height, cinfo.output_components)
 	  );
 
-	if (opts.max_size) {
-		if (!jas_safe_size_mul(cinfo.output_width, cinfo.output_height,
-		  &size) ||
-		  !jas_safe_size_mul(size, cinfo.output_components, &size)) {
-			goto error;
-		}
-		if (size > opts.max_size) {
-			jas_eprintf("image is too large\n");
-			goto error;
-		}
-	}
-
 	/* Create an image object to hold the decoded data. */
 	if (!(image = jpg_mkimage(&cinfo))) {
 		jas_eprintf("jpg_mkimage failed\n");
 		goto error;
 	}
diff --git a/src/libjasper/jpg/jpg_val.c b/src/libjasper/jpg/jpg_val.c
index 338afaf..6222a69 100644
--- a/src/libjasper/jpg/jpg_val.c
+++ b/src/libjasper/jpg/jpg_val.c
@@ -75,11 +75,11 @@
 * Code for validate operation.
 \******************************************************************************/
 
 int jpg_validate(jas_stream_t *in)
 {
-	uchar buf[JPG_MAGICLEN];
+	jas_uchar buf[JPG_MAGICLEN];
 	int i;
 	int n;
 
 	assert(JAS_STREAM_MAXPUTBACK >= JPG_MAGICLEN);
 
diff --git a/src/libjasper/mif/mif_cod.c b/src/libjasper/mif/mif_cod.c
index bfed68a..3303f59 100644
--- a/src/libjasper/mif/mif_cod.c
+++ b/src/libjasper/mif/mif_cod.c
@@ -368,11 +368,11 @@ error:
 * Code for validate operation.
 \******************************************************************************/
 
 int mif_validate(jas_stream_t *in)
 {
-	uchar buf[MIF_MAGICLEN];
+	jas_uchar buf[MIF_MAGICLEN];
 	uint_fast32_t magic;
 	int i;
 	int n;
 
 	assert(JAS_STREAM_MAXPUTBACK >= MIF_MAGICLEN);
@@ -460,11 +460,11 @@ static int mif_hdr_growcmpts(mif_hdr_t *hdr, int maxcmpts)
 	return 0;
 }
 
 static mif_hdr_t *mif_hdr_get(jas_stream_t *in)
 {
-	uchar magicbuf[MIF_MAGICLEN];
+	jas_uchar magicbuf[MIF_MAGICLEN];
 	char buf[4096];
 	mif_hdr_t *hdr;
 	bool done;
 	jas_tvparser_t *tvp;
 	int id;
diff --git a/src/libjasper/pgx/pgx_dec.c b/src/libjasper/pgx/pgx_dec.c
index 5a2e631..f6f8563 100644
--- a/src/libjasper/pgx/pgx_dec.c
+++ b/src/libjasper/pgx/pgx_dec.c
@@ -149,11 +149,11 @@ error:
 * Code for validate operation.
 \******************************************************************************/
 
 int pgx_validate(jas_stream_t *in)
 {
-	uchar buf[PGX_MAGICLEN];
+	jas_uchar buf[PGX_MAGICLEN];
 	uint_fast32_t magic;
 	int i;
 	int n;
 
 	assert(JAS_STREAM_MAXPUTBACK >= PGX_MAGICLEN);
@@ -193,11 +193,11 @@ int pgx_validate(jas_stream_t *in)
 \******************************************************************************/
 
 static int pgx_gethdr(jas_stream_t *in, pgx_hdr_t *hdr)
 {
 	int c;
-	uchar buf[2];
+	jas_uchar buf[2];
 
 	if ((c = jas_stream_getc(in)) == EOF) {
 		goto error;
 	}
 	buf[0] = c;
diff --git a/src/libjasper/pnm/pnm_dec.c b/src/libjasper/pnm/pnm_dec.c
index 78e2b3a..526e10d 100644
--- a/src/libjasper/pnm/pnm_dec.c
+++ b/src/libjasper/pnm/pnm_dec.c
@@ -178,11 +178,11 @@ jas_image_t *pnm_decode(jas_stream_t *in, char *opts)
 * Validation function.
 \******************************************************************************/
 
 int pnm_validate(jas_stream_t *in)
 {
-	uchar buf[2];
+	jas_uchar buf[2];
 	int i;
 	int n;
 
 	assert(JAS_STREAM_MAXPUTBACK >= 2);
 
diff --git a/src/libjasper/ras/ras_dec.c b/src/libjasper/ras/ras_dec.c
index 927883f..8200406 100644
--- a/src/libjasper/ras/ras_dec.c
+++ b/src/libjasper/ras/ras_dec.c
@@ -183,11 +183,11 @@ jas_image_t *ras_decode(jas_stream_t *in, char *optstr)
 	return image;
 }
 
 int ras_validate(jas_stream_t *in)
 {
-	uchar buf[RAS_MAGICLEN];
+	jas_uchar buf[RAS_MAGICLEN];
 	int i;
 	int n;
 	uint_fast32_t magic;
 
 	assert(JAS_STREAM_MAXPUTBACK >= RAS_MAGICLEN);
diff --git a/test/bin/run_test_1 b/test/bin/run_test_1
index 7cc1663..6f38e08 100755
--- a/test/bin/run_test_1
+++ b/test/bin/run_test_1
@@ -52,27 +52,33 @@ echo "############################################################"
 
 for in_file in "${bad_list[@]}"; do
 	name=$(basename "$in_file")
 	echo "############################################################"
 	case "$name" in
-	2_crashes.bmp|jasper-doublefree-mem_close.jpg)
+	2_crashes.bmp)
+		#jasper-doublefree-mem_close.jpg
 		# The file jasper-doublefree-mem_close.jpg must be skipped
 		# since this test could pass or fail depending on the version of
 		# the JPEG library used (and if it passes it will be VERY SLOW).
+		# Thie file 2_crashes.bmp must be skipped since it will try
+		# to allocate a huge palette which can cause an ASAN failure.
 		echo "Skipping $in_file"
 		continue
 		;;
 	esac
 
 	echo "Input file: $in_file"
+	imginfo_opts=()
+	imginfo_opts+=(--max-samples 100000000)
 	special_asan_options=()
 	special_asan_options+=(exitcode=10)
 	special_asan_options+=(allocator_may_return_null=true)
 	special_asan_options+=(detect_leaks=false)
 	#special_asan_options+=(soft_rss_limit_mb=1024)
 	expected_status=1
-	ASAN_OPTIONS="${special_asan_options[*]}" "$imginfo" < "$in_file"
+	ASAN_OPTIONS="${special_asan_options[*]}" \
+	  "$imginfo" "${imginfo_opts[@]}" < "$in_file"
 	status=$?
 	echo "actual exit status: $status"
 	echo "expected exit status: $expected_status"
 	if [ "$status" -ne 1 ]; then
 		echo "imginfo command had unexpected exit status " \

Vulnerable code: /src/libjasper/include/jasper/jas_config.h.in
/src/libjasper/include/jasper/jas_config.h.in~
#if defined(__GNUC__) && !defined(__clang__)
#define JAS_ATTRIBUTE_DISABLE_USAN \
  __attribute__((no_sanitize_undefined))
#elif defined(__clang__)
#define JAS_ATTRIBUTE_DISABLE_USAN \
  __attribute__((no_sanitize("undefined")))
#else
#define JAS_ATTRIBUTE_DISABLE_USAN
#endif

#include <jasper/jas_config2.h>
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h limits.h unistd.h stdint.h stdbool.h io.h windows.h sys/types.h sys/time.h stdlib.h stddef.h)
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
AC_CHECK_TYPE(uchar, unsigned char)
AC_CHECK_TYPE(ushort, unsigned short)
AC_CHECK_TYPE(uint, unsigned int)
AC_CHECK_TYPE(ulong, unsigned long)
AC_CHECK_TYPE(longlong, long long)
AC_CHECK_TYPE(ulonglong, unsigned long long)
AC_CHECK_TYPE(ssize_t, int)
AC_FUNC_VPRINTF
# Extra stuff for research purposes.
AC_ARG_ENABLE(special0,
[  --enable-special0    enable something],
[
case "${enableval}" in
yes)
	if test "$GCC" = yes; then
		CFLAGS="-g -O0"
	fi
	;;
no)
	;;
*)
	AC_MSG_ERROR(bad value ${enableval} for --enable-special0)
	;;
esac
], [])

AC_CONFIG_HEADERS([src/libjasper/include/jasper/jas_config.h])
	if (!(image = jas_image_decode(instream, fmtid, 0))) {
	if (!(fmtname = jas_image_fmttostr(fmtid))) {
		abort();
	}
	printf("%s %d %d %d %d %ld\n", fmtname, numcmpts, width, height, depth, (long) jas_image_rawsize(image));
	uchar *dp;
static int jas_iccgetuint(jas_stream_t *in, int n, ulonglong *val);
static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val);
static int jas_iccputsint(jas_stream_t *out, int n, longlong val);
static int jas_iccgetuint(jas_stream_t *in, int n, ulonglong *val)
	ulonglong v;
	ulonglong tmp;
	ulonglong tmp;
	*val = (tmp & 0x80000000) ? (-JAS_CAST(longlong, (((~tmp) &
	  0x7fffffff) + 1))) : JAS_CAST(longlong, tmp);
	ulonglong tmp;
	ulonglong tmp;
static int jas_iccputuint(jas_stream_t *out, int n, ulonglong val)
static int jas_iccputsint(jas_stream_t *out, int n, longlong val)
	ulonglong tmp;
jas_iccprof_t *jas_iccprof_createfrombuf(uchar *buf, int len)
uchar jas_iccprofdata_srgb[] =
uchar jas_iccprofdata_sgray[] = {
	uint_fast32_t rawsize;
		return 0;
	image->inmem_ = true;
		jas_image_destroy(image);
		return 0;
			jas_image_destroy(image);
			return 0;
	image->inmem_ = true;
	if (!jas_safe_size_mul(cmpt->width_, cmpt->height_, &size) ||
	  !jas_safe_size_mul(size, cmpt->cps_, &size)) {
static inline long decode_twos_comp(ulong c, int prec)
static inline ulong encode_twos_comp(long n, int prec)
	ulong result;
	ulong tmp;
jas_matrix_t *jas_seq2d_create(int xstart, int ystart, int xend, int yend)
jas_matrix_t *jas_matrix_create(int numrows, int numcols)
	int i;
	int i;
	int j;
	int i;
	int j;
void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, int xstart,
  int ystart, int xend, int yend)
void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, int r0,
  int c0, int r1, int c1)
	int i;
	int i;
	int j;
	int i;
	int j;
	int rowstep;
	int i;
	int j;
	int rowstep;
	int i;
	int j;
	int rowstep;
	int i;
	int j;
	int rowstep;
int jas_matrix_resize(jas_matrix_t *matrix, int numrows, int numcols)
	int size;
	int i;
	int i;
	int j;
	int rowstep;
	int i;
	int j;
	int numrows;
	int numcols;
	int xoff;
	int yoff;

	if (fscanf(in, "%d %d", &xoff, &yoff) != 2)
	if (fscanf(in, "%d %d", &numcols, &numrows) != 2)
	if (!(matrix = jas_seq2d_create(xoff, yoff, xoff + numcols, yoff + numrows)))
	int i;
	int j;
#if defined(HAVE_FCNTL_H)
#if defined(HAVE_UNISTD_H)
#if defined(WIN32) || defined(HAVE_IO_H)
			stream->bufbase_ = JAS_CAST(uchar *, buf);
#if defined(HAVE_GETTIMEOFDAY)
#elif defined(HAVE_GETRUSAGE)
	if (optstr) {
		jas_eprintf("warning: ignoring BMP decoder options\n");
		//return 0;
		//return 0;
		//bmp_info_destroy(info);
		//return 0;
		//return 0;
			//bmp_info_destroy(info);
			//return 0;
		//bmp_info_destroy(info);
		//return 0;
		//bmp_info_destroy(info);
		//jas_image_destroy(image);
		//return 0;
	uchar buf[2];
#define	uchar		unsigned char
#define	ushort		unsigned short
#define	uint		unsigned int
#define	ulong		unsigned long
#undef longlong
#define	longlong	long long
#undef ulonglong
#define	ulonglong	unsigned long long
/*#define	ssize_t		int*/

#define	HAVE_LIMITS_H		1
#define	HAVE_STDLIB_H		1
#define	HAVE_STDDEF_H		1
#include <jasper/jas_config.h>
#include <jasper/jas_config.h>
	uchar *ucdata; /* Unicode localizable description */
	uchar macdata[69]; /* Localizable Macintosh description */
extern uchar jas_iccprofdata_srgb[];
extern uchar jas_iccprofdata_sgray[];
jas_iccprof_t *jas_iccprof_createfrombuf(uchar *buf, int len);
	bool inmem_;
	int_fast32_t xstart_;
	int_fast32_t ystart_;
	int_fast32_t xend_;
	int_fast32_t yend_;
	int_fast32_t numrows_;
	int_fast32_t numcols_;
	(((matrix)->numrows_ > 1) ? jas_matrix_getref(matrix, i, 0) : jas_matrix_getref(matrix, 0, i))
jas_matrix_t *jas_matrix_create(int numrows, int numcols);
int jas_matrix_resize(jas_matrix_t *matrix, int numrows, int numcols);
void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, int r0,
  int c0, int r1, int c1);
jas_matrix_t *jas_seq2d_create(int xstart, int ystart, int xend, int yend);
void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, int xstart,
  int ystart, int xend, int yend);
#if defined(HAVE_FCNTL_H)
#if defined(HAVE_UNISTD_H)
	uchar *bufbase_;
	uchar *bufstart_;
	uchar *ptr_;
	uchar tinybuf_[JAS_STREAM_MAXPUTBACK + 1];
	uchar *buf_;
	  jas_stream_flushbuf((stream), (uchar)(c)) : \
#include<time.h>
#if defined(HAVE_SYS_TIME_H)
#if defined(HAVE_GETTIMEOFDAY)
#elif defined(HAVE_GETRUSAGE)
#if defined(WIN32) || defined(HAVE_WINDOWS_H)
#undef longlong
#define	longlong	INT64
#undef ulonglong
#define	ulonglong	UINT64
#if defined(HAVE_SYS_TYPES_H)
/* Hopefully, these macro definitions will fix more problems than they cause. */
#if !defined(uchar)
#define uchar unsigned char
#endif
#if !defined(ushort)
#define ushort unsigned short
#endif
#if !defined(uint)
#define uint unsigned int
#endif
#if !defined(ulong)
#define ulong unsigned long
#endif
#if !defined(longlong)
#define longlong long long
#endif
#if !defined(ulonglong)
#define ulonglong unsigned long long
#endif
	if (dec->ihdr->data.ihdr.numcmpts != JAS_CAST(uint,
	for (i = 1; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) {
		if (dec->bpcc->data.bpcc.numcmpts != JAS_CAST(uint, jas_image_numcmpts(
			for (i = 0; i < JAS_CAST(uint, jas_image_numcmpts(dec->image));
	  JAS_CAST(uint, jas_image_numcmpts(dec->image));
			if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(uint,
	for (i = 0; i < JAS_CAST(uint, jas_image_numcmpts(dec->image)); ++i) {
		if (JAS_CAST(ulong, jas_stream_tell(tmpstream)) != ms->len) {
		if (JAS_CAST(uint, jas_stream_read(in, ppm->data, ppm->len)) != ppm->len) {
	if (JAS_CAST(uint, jas_stream_write(out, (char *) ppm->data, ppm->len)) != ppm->len) {
	uchar *data;
	uchar *data;
	uchar *data;
	uchar *dataptr;
	uchar *data;
	if (!(com->data = JAS_CAST(uchar *, jas_strdup(buf)))) {
	uchar inbuffer;
*
typedef struct {
	size_t max_size;
} jpg_dec_importopts_t;

typedef enum {
	OPT_MAXSIZE,
} optid_t;

	{OPT_MAXSIZE, "max_size"},
	opts->max_size = 0;
			opts->max_size = atoi(jas_tvparser_getval(tvp));
	size_t size;
	if (opts.max_size) {
		if (!jas_safe_size_mul(cinfo.output_width, cinfo.output_height,
		  &size) ||
		  !jas_safe_size_mul(size, cinfo.output_components, &size)) {
			goto error;
		}
		if (size > opts.max_size) {
			jas_eprintf("image is too large\n");
			goto error;
		}
	}

	uchar buf[JPG_MAGICLEN];
	uchar buf[MIF_MAGICLEN];
	uchar magicbuf[MIF_MAGICLEN];
	uchar buf[PGX_MAGICLEN];
	uchar buf[2];
	uchar buf[2];
	uchar buf[RAS_MAGICLEN];
	2_crashes.bmp|jasper-doublefree-mem_close.jpg)
	ASAN_OPTIONS="${special_asan_options[*]}" "$imginfo" < "$in_file"
Fixed code: /src/libjasper/include/jasper/jas_pconf.h
/src/libjasper/include/jasper/jas_pconf.h.in
/src/libjasper/include/jasper/jas_pconf.h.in~
#include <jasper/jas_pconf2.h>
dnl AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h io.h unistd.h windows.h sys/time.h sys/types.h)

# Surely, there must be a better way to do this, but
# let's just get something working for now.

if test $ac_cv_header_fcntl_h = yes; then
	AC_SUBST([JAS_HAVE_FCNTL_H], ["#define JAS_HAVE_FCNTL_H 1"])
else
	AC_SUBST([JAS_HAVE_FCNTL_H], ["#undef JAS_HAVE_FCNTL_H"])
fi

if test $ac_cv_header_io_h = yes; then
	AC_SUBST([JAS_HAVE_IO_H], ["#define JAS_HAVE_IO_H 1"])
else
	AC_SUBST([JAS_HAVE_IO_H], ["#undef JAS_HAVE_IO_H"])
fi

if test $ac_cv_header_unistd_h = yes; then
	AC_SUBST([JAS_HAVE_UNISTD_H], ["#define JAS_HAVE_UNISTD_H 1"])
else
	AC_SUBST([JAS_HAVE_UNISTD_H], ["#undef JAS_HAVE_UNISTD_H"])
fi

if test $ac_cv_header_windows_h = yes; then
	AC_SUBST([JAS_HAVE_WINDOWS_H], ["#define JAS_HAVE_WINDOWS_H 1"])
else
	AC_SUBST([JAS_HAVE_WINDOWS_H], ["#undef JAS_HAVE_WINDOWS_H"])
fi

if test $ac_cv_header_sys_time_h = yes; then
	AC_SUBST([JAS_HAVE_SYS_TIME_H], ["#define JAS_HAVE_SYS_TIME_H 1"])
else
	AC_SUBST([JAS_HAVE_SYS_TIME_H], ["#undef JAS_HAVE_SYS_TIME_H"])
fi

if test $ac_cv_header_sys_types_h = yes; then
	AC_SUBST([JAS_HAVE_SYS_TYPES_H], ["#define JAS_HAVE_SYS_TYPES_H 1"])
else
	AC_SUBST([JAS_HAVE_SYS_TYPES_H], ["#undef JAS_HAVE_SYS_TYPES_H"])
fi
dnl AC_C_CONST
dnl AC_C_INLINE
dnl AC_TYPE_SIZE_T
dnl AC_CHECK_TYPE(uchar, unsigned char)
dnl AC_CHECK_TYPE(ushort, unsigned short)
dnl AC_CHECK_TYPE(uint, unsigned int)
dnl AC_CHECK_TYPE(ulong, unsigned long)
dnl AC_CHECK_TYPE(longlong, long long)
dnl AC_CHECK_TYPE(ulonglong, unsigned long long)
dnl AC_CHECK_TYPE(ssize_t, int)
if test $ac_cv_func_gettimeofday = yes; then
	AC_SUBST([JAS_HAVE_GETTIMEOFDAY], ["#define JAS_HAVE_GETTIMEOFDAY 1"])
else
	AC_SUBST([JAS_HAVE_GETTIMEOFDAY], ["#undef JAS_HAVE_GETTIMEOFDAY"])
fi

if test $ac_cv_func_getrusage = yes; then
	AC_SUBST([JAS_HAVE_GETRUSAGE], ["#define JAS_HAVE_GETRUSAGE 1"])
else
	AC_SUBST([JAS_HAVE_GETRUSAGE], ["#undef JAS_HAVE_GETRUSAGE"])
fi

dnl AC_FUNC_VPRINTF
# Extra stuff
# The private header file generated by AC_CONFIG_HEADERS is not
# currently used.  This just causes less verbose command lines
# when make is run.
AC_CONFIG_HEADERS([src/libjasper/include/jasper/jas_pconf.h])
src/libjasper/include/jasper/jas_config.h
	OPT_MAXSAMPLES,
	{OPT_MAXSAMPLES, "max-samples", JAS_OPT_HASARG},
	size_t max_samples;
	char optstr[32];
	max_samples = 64 * JAS_MEBI;
		case OPT_MAXSAMPLES:
			max_samples = strtoull(jas_optarg, 0, 10);
			break;
	snprintf(optstr, sizeof(optstr), "max_samples=%-zu", max_samples);

	if (!(image = jas_image_decode(instream, fmtid, optstr))) {
	if (!(fmtname = jas_image_fmttostr(fmtid))) {
		jas_eprintf("format name lookup failed\n");
		return EXIT_FAILURE;
	}

	printf("%s %d %d %d %d %ld\n", fmtname, numcmpts, width, height, depth,
	  JAS_CAST(long, jas_image_rawsize(image)));
	jas_uchar *dp;
static int jas_iccgetuint(jas_stream_t *in, int n, jas_ulonglong *val);
static int jas_iccputuint(jas_stream_t *out, int n, jas_ulonglong val);
static int jas_iccputsint(jas_stream_t *out, int n, jas_longlong val);
static int jas_iccgetuint(jas_stream_t *in, int n, jas_ulonglong *val)
	jas_ulonglong v;
	jas_ulonglong tmp;
	jas_ulonglong tmp;
	*val = (tmp & 0x80000000) ? (-JAS_CAST(jas_longlong, (((~tmp) &
	  0x7fffffff) + 1))) : JAS_CAST(jas_longlong, tmp);
	jas_ulonglong tmp;
	jas_ulonglong tmp;
static int jas_iccputuint(jas_stream_t *out, int n, jas_ulonglong val)
static int jas_iccputsint(jas_stream_t *out, int n, jas_longlong val)
	jas_ulonglong tmp;
jas_iccprof_t *jas_iccprof_createfrombuf(jas_uchar *buf, int len)
jas_uchar jas_iccprofdata_srgb[] =
jas_uchar jas_iccprofdata_sgray[] = {
	size_t rawsize;
	image = 0;

	JAS_DBGLOG(100, ("jas_image_create(%d, %p, %d)\n", numcmpts, cmptparms,
	  clrspc));

		goto error;
//	image->inmem_ = true;
		goto error;
#if 0
#endif
		if (!jas_safe_size_mul3(cmptparm->width, cmptparm->height,
		  (cmptparm->prec + 7), &rawsize)) {
			goto error;
		}
		rawsize /= 8;
		inmem = (rawsize < JAS_IMAGE_INMEMTHRESH);
			goto error;

error:
	if (image) {
		jas_image_destroy(image);
	}
	return 0;
//	image->inmem_ = true;
	JAS_DBGLOG(100, (
	  "jas_image_cmpt_create(%ld, %ld, %ld, %ld, %ld, %ld, %d, %d, %d)\n",
	  JAS_CAST(long, tlx),
	  JAS_CAST(long, tly),
	  JAS_CAST(long, hstep),
	  JAS_CAST(long, vstep),
	  JAS_CAST(long, width),
	  JAS_CAST(long, height),
	  JAS_CAST(int, depth),
	  sgnd,
	  inmem
	  ));

	if (!jas_safe_intfast32_mul3(width, height, depth, 0)) {
		goto error;
	}
	if (!jas_safe_size_mul3(cmpt->width_, cmpt->height_, cmpt->cps_, &size)) {
static inline long decode_twos_comp(jas_ulong c, int prec)
static inline jas_ulong encode_twos_comp(long n, int prec)
	jas_ulong result;
	jas_ulong tmp;
jas_matrix_t *jas_seq2d_create(jas_matind_t xstart, jas_matind_t ystart,
  jas_matind_t xend, jas_matind_t yend)
jas_matrix_t *jas_matrix_create(jas_matind_t numrows, jas_matind_t numcols)
	jas_matind_t i;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t i;
	jas_matind_t j;
void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, jas_matind_t xstart,
  jas_matind_t ystart, jas_matind_t xend, jas_matind_t yend)
void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1,
  jas_matind_t r0, jas_matind_t c0, jas_matind_t r1, jas_matind_t c1)
	jas_matind_t i;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t rowstep;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t rowstep;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t rowstep;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t rowstep;
int jas_matrix_resize(jas_matrix_t *matrix, jas_matind_t numrows,
  jas_matind_t numcols)
	jas_matind_t size;
	jas_matind_t i;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t rowstep;
	jas_matind_t i;
	jas_matind_t j;
	jas_matind_t numrows;
	jas_matind_t numcols;
	jas_matind_t xoff;
	jas_matind_t yoff;
	long tmp_xoff;
	long tmp_yoff;
	long tmp_numrows;
	long tmp_numcols;

	if (fscanf(in, "%ld %ld", &tmp_xoff, &tmp_yoff) != 2) {
	}
	xoff = tmp_xoff;
	yoff = tmp_yoff;
	if (fscanf(in, "%ld %ld", &tmp_numcols, &tmp_numrows) != 2) {
	}
	numrows = tmp_numrows;
	numcols = tmp_numcols;
	if (!(matrix = jas_seq2d_create(xoff, yoff, xoff + numcols,
	  yoff + numrows))) {
	}
	jas_matind_t i;
	jas_matind_t j;
/* The configuration header file should be included first. */
#include "jasper/jas_config.h"

#if defined(JAS_HAVE_FCNTL_H)
#if defined(JAS_HAVE_UNISTD_H)
#if defined(WIN32) || defined(JAS_HAVE_IO_H)
			stream->bufbase_ = JAS_CAST(jas_uchar *, buf);
/* The configuration header file should be included first. */
#include "jasper/jas_config.h"

#if defined(JAS_HAVE_GETTIMEOFDAY)
#elif defined(JAS_HAVE_GETRUSAGE)
#include "jasper/jas_tvp.h"
/******************************************************************************\
* Local types.
\******************************************************************************/

typedef struct {
	size_t max_samples;
} bmp_dec_importopts_t;

typedef enum {
	OPT_MAXSIZE,
} optid_t;

/******************************************************************************\
* Option parsing.
\******************************************************************************/

static jas_taginfo_t decopts[] = {
	{OPT_MAXSIZE, "max_samples"},
	{-1, 0}
};

static int bmp_dec_parseopts(char *optstr, bmp_dec_importopts_t *opts)
{
	jas_tvparser_t *tvp;

	opts->max_samples = 128 * JAS_MEBI;

	if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) {
		return -1;
	}

	while (!jas_tvparser_next(tvp)) {
		switch (jas_taginfo_nonull(jas_taginfos_lookup(decopts,
		  jas_tvparser_gettag(tvp)))->id) {
		case OPT_MAXSIZE:
			opts->max_samples = atoi(jas_tvparser_getval(tvp));
			break;
		default:
			jas_eprintf("warning: ignoring invalid option %s\n",
			  jas_tvparser_gettag(tvp));
			break;
		}
	}

	jas_tvparser_destroy(tvp);

	return 0;
}

	bmp_dec_importopts_t opts;
	size_t num_samples;
	if (bmp_dec_parseopts(optstr, &opts)) {
		goto error;
	if (!jas_safe_size_mul3(info->width, info->height, info->numplanes,
	  &num_samples)) {
		jas_eprintf("image size too large\n");
		goto error;
	}

	if (opts.max_samples > 0 && num_samples > opts.max_samples) {
		jas_eprintf("maximum number of pixels exceeded (%zu)\n",
		  opts.max_samples);
		goto error;
	}

	jas_uchar buf[2];
/* The configuration header file should be included first. */

#ifndef JAS_CONFIG_H
#define JAS_CONFIG_H

/* This preprocessor symbol identifies the version of JasPer. */
#define	JAS_VERSION "@JAS_VERSION@"

@JAS_HAVE_FCNTL_H@
@JAS_HAVE_IO_H@
@JAS_HAVE_UNISTD_H@
@JAS_HAVE_WINDOWS_H@
@JAS_HAVE_SYS_TIME_H@
@JAS_HAVE_SYS_TYPES_H@

@JAS_HAVE_GETTIMEOFDAY@
@JAS_HAVE_GETRUSAGE@

#if defined(__GNUC__) && !defined(__clang__)
#define JAS_ATTRIBUTE_DISABLE_USAN \
  __attribute__((no_sanitize_undefined))
#elif defined(__clang__)
#define JAS_ATTRIBUTE_DISABLE_USAN \
  __attribute__((no_sanitize("undefined")))
#else
#define JAS_ATTRIBUTE_DISABLE_USAN
#endif

#endif
/* The configuration header file should be included first. */
#include <jasper/jas_config.h>

/* The configuration header file should be included first. */
#include <jasper/jas_config.h>

/* The configuration header file should be included first. */
/* The configuration header file should be included first. */

	jas_uchar *ucdata; /* Unicode localizable description */
	jas_uchar macdata[69]; /* Localizable Macintosh description */
extern jas_uchar jas_iccprofdata_srgb[];
extern jas_uchar jas_iccprofdata_sgray[];
jas_iccprof_t *jas_iccprof_createfrombuf(jas_uchar *buf, int len);
/* The configuration header file should be included first. */

//	bool inmem_;
/* The configuration header file should be included first. */
/* The configuration header file should be included first. */
/* The configuration header file should be included first. */

#define JAS_KIBI	JAS_CAST(size_t, 1024)
#define JAS_MEBI	(JAS_KIBI * JAS_KIBI)

inline static bool jas_safe_size_mul3(size_t a, size_t b, size_t c,
  size_t *result)
{
	size_t tmp;
	if (!jas_safe_size_mul(a, b, &tmp) ||
	  !jas_safe_size_mul(tmp, c, &tmp)) {
		return false;
	}
	if (result) {
		*result = tmp;
	}
	return true;
}

/* Compute the sum of two size_t integer with overflow checking. */
inline static bool jas_safe_intfast32_mul(int_fast32_t x, int_fast32_t y,
  int_fast32_t *result)
{
	if (x > 0) {
		/* x is positive */
		if (y > 0) {
			/* x and y are positive */
			if (x > INT_FAST32_MAX / y) {
				return false;
			}
		} else {
			/* x positive, y nonpositive */
			if (y < INT_FAST32_MIN / x) {
				return false;
			}
		}
	} else {
		/* x is nonpositive */
		if (y > 0) {
			/* x is nonpositive, y is positive */
			if (x < INT_FAST32_MIN / y) {
				return false;
			}
		} else { /* x and y are nonpositive */
			if (x != 0 && y < INT_FAST32_MAX / x) {
				return false;
			}
		}
	}

	if (result) {
		*result = x * y;
	}
	return true;
}

inline static bool jas_safe_intfast32_mul3(int_fast32_t a, int_fast32_t b,
  int_fast32_t c, int_fast32_t *result)
{
	int_fast32_t tmp;
	if (!jas_safe_intfast32_mul(a, b, &tmp) ||
	  !jas_safe_intfast32_mul(tmp, c, &tmp)) {
		return false;
	}
	if (result) {
		*result = tmp;
	}
	return true;
}

/* The configuration header file should be included first. */
typedef int_fast32_t jas_matind_t;

	jas_matind_t xstart_;
	jas_matind_t ystart_;
	jas_matind_t xend_;
	jas_matind_t yend_;
	jas_matind_t numrows_;
	jas_matind_t numcols_;
	(((matrix)->numrows_ > 1) ? jas_matrix_getref(matrix, i, 0) : \
	  jas_matrix_getref(matrix, 0, i))
jas_matrix_t *jas_matrix_create(jas_matind_t numrows, jas_matind_t numcols);
int jas_matrix_resize(jas_matrix_t *matrix, jas_matind_t numrows, jas_matind_t numcols);
void jas_matrix_bindsub(jas_matrix_t *mat0, jas_matrix_t *mat1, jas_matind_t r0,
  jas_matind_t c0, jas_matind_t r1, jas_matind_t c1);
jas_matrix_t *jas_seq2d_create(jas_matind_t xstart, jas_matind_t ystart,
  jas_matind_t xend, jas_matind_t yend);
void jas_seq2d_bindsub(jas_matrix_t *s, jas_matrix_t *s1, jas_matind_t xstart,
  jas_matind_t ystart, jas_matind_t xend, jas_matind_t yend);
/* The configuration header file should be included first. */
#if defined(JAS_HAVE_FCNTL_H)
#if defined(JAS_HAVE_UNISTD_H)
	jas_uchar *bufbase_;
	jas_uchar *bufstart_;
	jas_uchar *ptr_;
	jas_uchar tinybuf_[JAS_STREAM_MAXPUTBACK + 1];
	jas_uchar *buf_;
	  jas_stream_flushbuf((stream), (jas_uchar)(c)) : \
/* The configuration header file should be included first. */

/* The configuration header file should be included first. */

#include<time.h>
#if defined(JAS_HAVE_SYS_TIME_H)
#if defined(JAS_HAVE_GETTIMEOFDAY)
#elif defined(JAS_HAVE_GETRUSAGE)
/* The configuration header file should be included first. */
/* The configuration header file should be included first. */
#if defined(WIN32) || defined(JAS_HAVE_WINDOWS_H)
// THIS SHOULD NO LONGER BE NEEDED SINCE MSVC SUPPORTS LONG LONG.
//#undef longlong
//#define	longlong	INT64
//#undef ulonglong
//#define	ulonglong	UINT64
#if defined(JAS_HAVE_SYS_TYPES_H)
#define jas_uchar unsigned char
#define jas_uint unsigned int
#define jas_ulong unsigned long
#define jas_longlong long long
#define jas_ulonglong unsigned long long
/* The configuration header file should be included first. */
/* The configuration header file should be included first. */

#include "jasper/jas_types.h"
	if (dec->ihdr->data.ihdr.numcmpts != JAS_CAST(jas_uint,
	for (i = 1; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); ++i) {
		if (dec->bpcc->data.bpcc.numcmpts != JAS_CAST(jas_uint, jas_image_numcmpts(
			for (i = 0; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image));
	  JAS_CAST(jas_uint, jas_image_numcmpts(dec->image));
			if (dec->cmap->data.cmap.ents[i].cmptno >= JAS_CAST(jas_uint,
	for (i = 0; i < JAS_CAST(jas_uint, jas_image_numcmpts(dec->image)); ++i) {
		if (JAS_CAST(jas_ulong, jas_stream_tell(tmpstream)) != ms->len) {
		if (JAS_CAST(jas_uint, jas_stream_read(in, ppm->data, ppm->len)) != ppm->len) {
	if (JAS_CAST(jas_uint, jas_stream_write(out, (char *) ppm->data, ppm->len)) != ppm->len) {
	jas_uchar *data;
	jas_uchar *data;
	jas_uchar *data;
	jas_uchar *dataptr;
	jas_uchar *data;
	if (!(com->data = JAS_CAST(jas_uchar *, jas_strdup(buf)))) {
	jas_uchar inbuffer;
typedef struct {
	size_t max_samples;
} jpg_dec_importopts_t;

typedef enum {
	OPT_MAXSIZE,
} optid_t;

* Option parsing.
	{OPT_MAXSIZE, "max_samples"},
	opts->max_samples = 64 * JAS_MEBI;
			opts->max_samples = atoi(jas_tvparser_getval(tvp));
	size_t num_samples;

	JAS_DBGLOG(100, ("jpg_decode(%p, \"%s\")\n", in, optstr));
	if (opts.max_samples > 0) {
		if (!jas_safe_size_mul3(cinfo.image_width, cinfo.image_height,
		  cinfo.num_components, &num_samples)) {
			goto error;
		}
		if (num_samples > opts.max_samples) {
			jas_eprintf("image is too large (%zu > %zu)\n", num_samples,
			  opts.max_samples);
			goto error;
		}
	}

	jas_uchar buf[JPG_MAGICLEN];
	jas_uchar buf[MIF_MAGICLEN];
	jas_uchar magicbuf[MIF_MAGICLEN];
	jas_uchar buf[PGX_MAGICLEN];
	jas_uchar buf[2];
	jas_uchar buf[2];
	jas_uchar buf[RAS_MAGICLEN];
	2_crashes.bmp)
		#jasper-doublefree-mem_close.jpg
		# Thie file 2_crashes.bmp must be skipped since it will try
		# to allocate a huge palette which can cause an ASAN failure.
	imginfo_opts=()
	imginfo_opts+=(--max-samples 100000000)
	ASAN_OPTIONS="${special_asan_options[*]}" \
	  "$imginfo" "${imginfo_opts[@]}" < "$in_file"