about summary refs log tree commit diff
path: root/converter/other/jpeg2000
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2020-09-26 23:52:08 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2020-09-26 23:52:08 +0000
commit4c361c0a7638b4f068e8b524e4ff43374a286018 (patch)
tree0aef192966a1ae996a9f2a0364f3ccbb15d512c7 /converter/other/jpeg2000
parentcd7f17a619a0421a1dfb2ceb09f4af60ead8ad5f (diff)
downloadnetpbm-mirror-4c361c0a7638b4f068e8b524e4ff43374a286018.tar.gz
netpbm-mirror-4c361c0a7638b4f068e8b524e4ff43374a286018.tar.xz
netpbm-mirror-4c361c0a7638b4f068e8b524e4ff43374a286018.zip
Promote Development to Advanced
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@3972 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other/jpeg2000')
-rw-r--r--converter/other/jpeg2000/Makefile6
-rw-r--r--converter/other/jpeg2000/jpeg2ktopam.c34
-rw-r--r--converter/other/jpeg2000/libjasper/base/jas_image.c41
-rw-r--r--converter/other/jpeg2000/libjasper/include/jasper/jas_image.h27
-rw-r--r--converter/other/jpeg2000/libjasper/jp2/jp2_dec.c93
-rw-r--r--converter/other/jpeg2000/libjasper/jpc/jpc_dec.c1085
-rw-r--r--converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.c1566
-rw-r--r--converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.h14
-rw-r--r--converter/other/jpeg2000/libjasper_compat.c26
-rw-r--r--converter/other/jpeg2000/libjasper_compat.h35
10 files changed, 1625 insertions, 1302 deletions
diff --git a/converter/other/jpeg2000/Makefile b/converter/other/jpeg2000/Makefile
index 6e5af8e7..9c8729ac 100644
--- a/converter/other/jpeg2000/Makefile
+++ b/converter/other/jpeg2000/Makefile
@@ -46,8 +46,8 @@ endif
 
 BINARIES = $(PORTBINARIES)
 
-OBJECTS = $(BINARIES:%=%.o)
-MERGE_OBJECTS = $(BINARIES:%=%.o2) 
+OBJECTS = $(BINARIES:%=%.o) libjasper_compat.o
+MERGE_OBJECTS = $(BINARIES:%=%.o2) libjasper_compat.o2
 ifeq ($(JASPERLIB),$(INTERNAL_JASPERLIB))
   # MERGE_OBJECTS contains relative paths, so $(INTERNAL_JASPERLIB) had better
   # be relative to the current directory.
@@ -63,7 +63,7 @@ include $(SRCDIR)/common.mk
 
 LIBOPTS = $(shell $(LIBOPT) $(JASPERLIB_USE))
 
-$(BINARIES): %: %.o $(JASPERLIB_DEP) $(LIBOPT)
+$(BINARIES): %: %.o libjasper_compat.o $(JASPERLIB_DEP) $(LIBOPT)
 $(BINARIES): LDFLAGS_TARGET = $(LIBOPTS) $(JASPERDEPLIBS)
 
 $(INTERNAL_JASPERLIB): $(BUILDDIR)/$(SUBDIR)/libjasper FORCE
diff --git a/converter/other/jpeg2000/jpeg2ktopam.c b/converter/other/jpeg2000/jpeg2ktopam.c
index b507f56e..bda0de2e 100644
--- a/converter/other/jpeg2000/jpeg2ktopam.c
+++ b/converter/other/jpeg2000/jpeg2ktopam.c
@@ -29,11 +29,9 @@
 
 #include "libjasper_compat.h"
 
-enum compmode {COMPMODE_INTEGER, COMPMODE_REAL};
 
-enum progression {PROG_LRCP, PROG_RLCP, PROG_RPCL, PROG_PCRL, PROG_CPRL};
 
-struct cmdlineInfo {
+struct CmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
     */
@@ -44,15 +42,15 @@ struct cmdlineInfo {
 
 
 static void
-parseCommandLine(int argc, char ** argv,
-                 struct cmdlineInfo * const cmdlineP) {
+parseCommandLine(int argc, const char ** argv,
+                 struct CmdlineInfo * const cmdlineP) {
 /*----------------------------------------------------------------------------
    Note that many of the strings that this function returns in the
    *cmdlineP structure are actually in the supplied argv array.  And
    sometimes, one of these strings is actually just a suffix of an entry
    in argv!
 -----------------------------------------------------------------------------*/
-    optEntry *option_def;
+    optEntry * option_def;
     optStruct3 opt;
 
     unsigned int debuglevelSpec;
@@ -71,7 +69,7 @@ parseCommandLine(int argc, char ** argv,
     opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = FALSE;  /* We have no parms that are negative numbers */
 
-    pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0);
+    pm_optParseOptions3(&argc, (char**)argv, opt, sizeof(opt), 0);
 
     if (!debuglevelSpec)
         cmdlineP->debuglevel = 0;
@@ -84,6 +82,7 @@ parseCommandLine(int argc, char ** argv,
         pm_error("Too many arguments.  The only argument accepted\n"
                  "is the input file specification");
 
+    free(option_def);
 }
 
 
@@ -114,9 +113,11 @@ static void
 readJ2k(const char *   const inputFilename,
         jas_image_t ** const jasperPP) {
 
+    const char * const options = "";
+
     jas_image_t * jasperP;
     jas_stream_t * instreamP;
-    const char * options;
+    const char * error;
 
     if (streq(inputFilename, "-")) {
         /* The input image is to be read from standard input. */
@@ -131,13 +132,10 @@ readJ2k(const char *   const inputFilename,
 
     validateJ2k(instreamP);
 
-    options = "";
-
-    jasperP = jas_image_decode(instreamP, jas_image_getfmt(instreamP),
-                               (char*)options);
-    if (jasperP == NULL)
-        pm_error("Unable to interpret JPEG-2000 input.  "
-                 "The Jasper library jas_image_decode() subroutine failed.");
+    pmjas_image_decode(instreamP, jas_image_getfmt(instreamP), options,
+                       &jasperP, &error);
+    if (error)
+        pm_error("Unable to interpret JPEG-2000 input.  %s", error);
 
     jas_stream_close(instreamP);
 
@@ -483,9 +481,9 @@ convertToPamPnm(struct pam *  const outpamP,
 
 
 int
-main(int argc, char **argv)
+main(int argc, const char **argv)
 {
-    struct cmdlineInfo cmdline;
+    struct CmdlineInfo cmdline;
     struct pam outpam;
     int * jasperCmpt;  /* malloc'ed */
        /* jaspercmpt[P] is the component number for use with the
@@ -493,7 +491,7 @@ main(int argc, char **argv)
        */
     jas_image_t * jasperP;
 
-    pnm_init(&argc, argv);
+    pm_proginit(&argc, argv);
 
     parseCommandLine(argc, argv, &cmdline);
 
diff --git a/converter/other/jpeg2000/libjasper/base/jas_image.c b/converter/other/jpeg2000/libjasper/base/jas_image.c
index 5c2822be..5ee13a0d 100644
--- a/converter/other/jpeg2000/libjasper/base/jas_image.c
+++ b/converter/other/jpeg2000/libjasper/base/jas_image.c
@@ -126,6 +126,8 @@
 #include <assert.h>
 #include <ctype.h>
 
+#include "netpbm/nstring.h"
+
 #include "jasper/jas_math.h"
 #include "jasper/jas_image.h"
 #include "jasper/jas_malloc.h"
@@ -379,22 +381,47 @@ static void jas_image_cmpt_destroy(jas_image_cmpt_t *cmpt)
 * Load and save operations.
 \*****************************************************************************/
 
-jas_image_t *jas_image_decode(jas_stream_t *in, int fmt, char *optstr)
-{
+void
+pmjas_image_decode(jas_stream_t * const in,
+				   int            const fmtArg,
+				   const char *   const optstr,
+				   jas_image_t ** const imagePP,
+				   const char **  const errorP) {
+/*----------------------------------------------------------------------------
+  Create an image from a stream in some specified format
+-----------------------------------------------------------------------------*/
 	jas_image_fmtinfo_t *fmtinfo;
+	int fmt;
 
 	/* If possible, try to determine the format of the input data. */
-	if (fmt < 0) {
+	if (fmtArg < 0) {
 		if ((fmt = jas_image_getfmt(in)) < 0) {
-			return 0;
+			pm_asprintf(errorP, "jas_image_getfmt failed");
+			return;
 		}
-	}
+	} else
+		fmt = fmtArg;
+
 	if (!(fmtinfo = jas_image_lookupfmtbyid(fmt))) {
-		return 0;
+		pm_asprintf(errorP, "jas_image_lookupfmtbyid of format %d failed",
+					fmt);
+		return;
+	}
+	{
+		const char * error;
+
+		(*fmtinfo->ops.decode)(in, optstr, imagePP, &error);
+		if (error) {
+			pm_asprintf(errorP, "decoder failed.  %s", error);
+			pm_strfree(error);
+		} else {
+			*errorP = NULL;
+		}
 	}
-	return (fmtinfo->ops.decode) ? (*fmtinfo->ops.decode)(in, optstr) : 0;
 }
 
+
+
 int jas_image_encode(jas_image_t *image, jas_stream_t *out, int fmt, char *optstr)
 {
 	jas_image_fmtinfo_t *fmtinfo;
diff --git a/converter/other/jpeg2000/libjasper/include/jasper/jas_image.h b/converter/other/jpeg2000/libjasper/include/jasper/jas_image.h
index 6e914efd..20170986 100644
--- a/converter/other/jpeg2000/libjasper/include/jasper/jas_image.h
+++ b/converter/other/jpeg2000/libjasper/include/jasper/jas_image.h
@@ -300,7 +300,10 @@ typedef struct {
 
 typedef struct {
 
-	jas_image_t *(*decode)(jas_stream_t *in, char *opts);
+	void (*decode)(jas_stream_t * const in,
+				   const char *   const opts,
+				   jas_image_t ** const imagePP,
+				   const char **  const errorP);
 	/* Decode image data from a stream. */
 
 	int (*encode)(jas_image_t *image, jas_stream_t *out, char *opts);
@@ -442,8 +445,14 @@ void jas_image_destroy(jas_image_t *image);
   any compression. */
 uint_fast32_t jas_image_rawsize(jas_image_t *image);
 
-/* Create an image from a stream in some specified format. */
-jas_image_t *jas_image_decode(jas_stream_t *in, int fmt, char *optstr);
+#define JAS_HAVE_PMJAS_IMAGE_DECODE
+
+void
+pmjas_image_decode(jas_stream_t * const in,
+				   int            const fmt,
+				   const char *   const optstr,
+				   jas_image_t ** const imagePP,
+				   const char **  const errorP);
 
 /* Write an image to a stream in a specified format. */
 int jas_image_encode(jas_image_t *image, jas_stream_t *out, int fmt,
@@ -567,14 +576,22 @@ int bmp_validate(jas_stream_t *in);
 
 #if !defined(EXCLUDE_JP2_CAPABILITY)
 /* Format-dependent operations for JP2 capability. */
-jas_image_t *jp2_decode(jas_stream_t *in, char *optstr);
+void
+jp2_decode(jas_stream_t * const in,
+		   const char *   const optstr,
+		   jas_image_t ** const imagePP,
+		   const char **  const errorP);
 int jp2_encode(jas_image_t *image, jas_stream_t *out, char *optstr);
 int jp2_validate(jas_stream_t *in);
 #endif
 
 #if !defined(EXCLUDE_JPC_CAPABILITY)
 /* Format-dependent operations for JPEG-2000 code stream capability. */
-jas_image_t *jpc_decode(jas_stream_t *in, char *optstr);
+void
+jpc_decode(jas_stream_t * const in,
+           const char *   const optstr,
+           jas_image_t ** const imagePP,
+           const char **  const errorP);
 int jpc_encode(jas_image_t *image, jas_stream_t *out, char *optstr);
 int jpc_validate(jas_stream_t *in);
 #endif
diff --git a/converter/other/jpeg2000/libjasper/jp2/jp2_dec.c b/converter/other/jpeg2000/libjasper/jp2/jp2_dec.c
index 4036f0f2..e8d71b0a 100644
--- a/converter/other/jpeg2000/libjasper/jp2/jp2_dec.c
+++ b/converter/other/jpeg2000/libjasper/jp2/jp2_dec.c
@@ -117,6 +117,8 @@
 #include "jasper/jas_malloc.h"
 #include "jasper/jas_version.h"
 
+#include "netpbm/nstring.h"
+
 #include "jp2_cod.h"
 #include "jp2_dec.h"
 
@@ -271,8 +273,11 @@ fromiccpcs(int cs) {
 
 
 
-jas_image_t *
-jp2_decode(jas_stream_t *in, char *optstr) {
+void
+jp2_decode(jas_stream_t * const in,
+           const char *   const optstr,
+           jas_image_t ** const imagePP,
+           const char **  const errorP) {
 
     jp2_box_t *box;
     int found;
@@ -295,32 +300,34 @@ jp2_decode(jas_stream_t *in, char *optstr) {
     image = 0;
 
     if (!(dec = jp2_dec_create())) {
-        goto error;
+        pm_asprintf(errorP, "jp2_dec_create failed");
+        goto cleanup;
     }
 
     /* Get the first box.  This should be a JP box. */
     if (!(box = jp2_box_get(in))) {
-        jas_eprintf("error: cannot get box\n");
-        goto error;
+        pm_asprintf(errorP, "cannot get box");
+        goto cleanup;
     }
     if (box->type != JP2_BOX_JP) {
-        jas_eprintf("error: expecting signature box\n");
-        goto error;
+        pm_asprintf(errorP, "expecting signature box");
+        goto cleanup;
     }
     if (box->data.jp.magic != JP2_JP_MAGIC) {
-        jas_eprintf("incorrect magic number\n");
-        goto error;
+        pm_asprintf(errorP, "incorrect magic number");
+        goto cleanup;
     }
     jp2_box_destroy(box);
     box = 0;
 
     /* Get the second box.  This should be a FTYP box. */
     if (!(box = jp2_box_get(in))) {
-        goto error;
+        pm_asprintf(errorP, "cannot get second box");
+        goto cleanup;
     }
     if (box->type != JP2_BOX_FTYP) {
-        jas_eprintf("expecting file type box\n");
-        goto error;
+        pm_asprintf(errorP, "expecting file type box");
+        goto cleanup;
     }
     jp2_box_destroy(box);
     box = 0;
@@ -329,7 +336,7 @@ jp2_decode(jas_stream_t *in, char *optstr) {
     found = 0;
     while ((box = jp2_box_get(in))) {
         if (jas_getdbglevel() >= 1) {
-            fprintf(stderr, "box type %s\n", box->info->name);
+            jas_eprintf("box type '%s'\n", box->info->name);
         }
         switch (box->type) {
         case JP2_BOX_JP2C:
@@ -382,19 +389,24 @@ jp2_decode(jas_stream_t *in, char *optstr) {
     }
 
     if (!found) {
-        jas_eprintf("error: no code stream found\n");
-        goto error;
+        pm_asprintf(errorP, "no code stream found");
+        goto cleanup;
     }
 
-    if (!(dec->image = jpc_decode(in, optstr))) {
-        jas_eprintf("error: cannot decode code stream\n");
-        goto error;
+    {
+        const char * decodeError;
+        jpc_decode(in, optstr, &dec->image, &decodeError);
+        if (decodeError) {
+            pm_asprintf(errorP, "cannot decode code stream.  %s", decodeError);
+            pm_strfree(decodeError);
+            goto cleanup;
+        }
     }
 
     /* An IHDR box must be present. */
     if (!dec->ihdr) {
-        jas_eprintf("error: missing IHDR box\n");
-        goto error;
+        pm_asprintf(errorP, "missing IHDR box");
+        goto cleanup;
     }
 
     /* Does the number of components indicated in the IHDR box match
@@ -405,8 +417,8 @@ jp2_decode(jas_stream_t *in, char *optstr) {
 
     /* At least one component must be present. */
     if (!jas_image_numcmpts(dec->image)) {
-        jas_eprintf("error: no components\n");
-        goto error;
+        pm_asprintf(errorP, "no components");
+        goto cleanup;
     }
 
     /* Determine if all components have the same data type. */
@@ -428,15 +440,15 @@ jp2_decode(jas_stream_t *in, char *optstr) {
 
     /* Can we handle the compression type? */
     if (dec->ihdr->data.ihdr.comptype != JP2_IHDR_COMPTYPE) {
-        jas_eprintf("error: not capable of this compression type\n");
-        goto error;
+        pm_asprintf(errorP, "not capable of this compression type");
+        goto cleanup;
     }
 
     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_image_numcmpts(
-          dec->image)) {
+                dec->image)) {
             jas_eprintf("warning: number of components mismatch\n");
         }
         /* Is the component data type information indicated in the BPCC
@@ -455,8 +467,8 @@ jp2_decode(jas_stream_t *in, char *optstr) {
 
     /* A COLR box must be present. */
     if (!dec->colr) {
-        jas_eprintf("error: no COLR box\n");
-        goto error;
+        pm_asprintf(errorP, "no COLR box");
+        goto cleanup;
     }
 
     switch (dec->colr->data.colr.method) {
@@ -502,14 +514,14 @@ jp2_decode(jas_stream_t *in, char *optstr) {
             /* Is the component number reasonable? */
             if (dec->cmap->data.cmap.ents[i].cmptno >=
                 jas_image_numcmpts(dec->image)) {
-                jas_eprintf("error: invalid component number in CMAP box\n");
-                goto error;
+                pm_asprintf(errorP, "invalid component number in CMAP box");
+                goto cleanup;
             }
             /* Is the LUT index reasonable? */
             if (dec->cmap->data.cmap.ents[i].pcol >=
                 dec->pclr->data.pclr.numchans) {
-                jas_eprintf("error: invalid CMAP LUT index\n");
-                goto error;
+                pm_asprintf(errorP, "invalid CMAP LUT index");
+                goto cleanup;
             }
         }
     }
@@ -517,8 +529,8 @@ jp2_decode(jas_stream_t *in, char *optstr) {
     /* Allocate space for the channel-number to component-number LUT. */
     dec->chantocmptlut = jas_malloc(dec->numchans * sizeof(uint_fast16_t));
     if (!dec->chantocmptlut) {
-        jas_eprintf("error: no memory\n");
-        goto error;
+        pm_asprintf(errorP, "no memory");
+        goto cleanup;
     }
 
     if (!dec->cmap) {
@@ -564,8 +576,8 @@ jp2_decode(jas_stream_t *in, char *optstr) {
                 }
 #endif
             } else {
-                jas_eprintf("error: invalid MTYP in CMAP box\n");
-                goto error;
+                pm_asprintf(errorP, "invalid MTYP in CMAP box");
+                goto cleanup;
             }
         }
     }
@@ -604,8 +616,8 @@ jp2_decode(jas_stream_t *in, char *optstr) {
 
     /* Ensure that some components survived. */
     if (!jas_image_numcmpts(dec->image)) {
-        jas_eprintf("error: no components\n");
-        goto error;
+        pm_asprintf(errorP, "no components");
+        goto cleanup;
     }
 
     /* Prevent the image from being destroyed later. */
@@ -614,16 +626,17 @@ jp2_decode(jas_stream_t *in, char *optstr) {
 
     jp2_dec_destroy(dec);
 
-    return image;
+    *imagePP = image;
+    *errorP = NULL;
+    return;
 
-error:
+cleanup:
     if (box) {
         jp2_box_destroy(box);
     }
     if (dec) {
         jp2_dec_destroy(dec);
     }
-    return 0;
 }
 
 
diff --git a/converter/other/jpeg2000/libjasper/jpc/jpc_dec.c b/converter/other/jpeg2000/libjasper/jpc/jpc_dec.c
index 4d4dfc50..140169ec 100644
--- a/converter/other/jpeg2000/libjasper/jpc/jpc_dec.c
+++ b/converter/other/jpeg2000/libjasper/jpc/jpc_dec.c
@@ -114,15 +114,13 @@
  * $Id$
  */
 
-/*****************************************************************************\
-* Includes.
-\*****************************************************************************/
-
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdbool.h>
 #include <assert.h>
 
 #include "pm.h"
+#include "netpbm/nstring.h"
 
 #include "jasper/jas_types.h"
 #include "jasper/jas_math.h"
@@ -164,7 +162,10 @@ typedef struct {
     /* The states in which this type of marker segment can be
       validly encountered. */
 
-    int (*action)(jpc_dec_t *dec, jpc_ms_t *ms);
+    void (*action)(jpc_dec_t *   const dec,
+                   jpc_ms_t *    const ms,
+                   bool *        const doneP,
+                   const char ** const errorP);
     /* The action to take upon encountering this type of marker segment. */
 
 } jpc_dec_mstabent_t;
@@ -223,119 +224,263 @@ static void jpc_dec_cp_destroy(jpc_dec_cp_t *cp);
 static int jpc_dec_cp_setfrompoc(jpc_dec_cp_t *cp, jpc_poc_t *poc, int reset);
 static int jpc_pi_addpchgfrompoc(jpc_pi_t *pi, jpc_poc_t *poc);
 
-static int jpc_dec_decode(jpc_dec_t *dec);
 static jpc_dec_t *jpc_dec_create(jpc_dec_importopts_t *impopts, jas_stream_t *in);
 static void jpc_dec_destroy(jpc_dec_t *dec);
 static void jpc_dequantize(jas_matrix_t *x, jpc_fix_t absstepsize);
 static void jpc_undo_roi(jas_matrix_t *x, int roishift, int bgshift, int numbps);
 static jpc_fix_t jpc_calcabsstepsize(int stepsize, int numbits);
-static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile);
 static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile);
 static int jpc_dec_tilefini(jpc_dec_t *dec, jpc_dec_tile_t *tile);
-static int jpc_dec_process_soc(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_sod(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_eoc(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_cod(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_coc(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_rgn(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_qcd(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_qcc(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_poc(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_ppm(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_ppt(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_com(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_unk(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_process_crg(jpc_dec_t *dec, jpc_ms_t *ms);
-static int jpc_dec_parseopts(char *optstr, jpc_dec_importopts_t *opts);
 
-/******************************************************************************\
-* Global data.
-\******************************************************************************/
 
-jpc_dec_mstabent_t jpc_dec_mstab[] = {
-    {JPC_MS_SOC, JPC_MHSOC, jpc_dec_process_soc},
-    {JPC_MS_SOT, JPC_MH | JPC_TPHSOT, jpc_dec_process_sot},
-    {JPC_MS_SOD, JPC_TPH, jpc_dec_process_sod},
-    {JPC_MS_EOC, JPC_TPHSOT, jpc_dec_process_eoc},
-    {JPC_MS_SIZ, JPC_MHSIZ, jpc_dec_process_siz},
-    {JPC_MS_COD, JPC_MH | JPC_TPH, jpc_dec_process_cod},
-    {JPC_MS_COC, JPC_MH | JPC_TPH, jpc_dec_process_coc},
-    {JPC_MS_RGN, JPC_MH | JPC_TPH, jpc_dec_process_rgn},
-    {JPC_MS_QCD, JPC_MH | JPC_TPH, jpc_dec_process_qcd},
-    {JPC_MS_QCC, JPC_MH | JPC_TPH, jpc_dec_process_qcc},
-    {JPC_MS_POC, JPC_MH | JPC_TPH, jpc_dec_process_poc},
-    {JPC_MS_TLM, JPC_MH, 0},
-    {JPC_MS_PLM, JPC_MH, 0},
-    {JPC_MS_PLT, JPC_TPH, 0},
-    {JPC_MS_PPM, JPC_MH, jpc_dec_process_ppm},
-    {JPC_MS_PPT, JPC_TPH, jpc_dec_process_ppt},
-    {JPC_MS_SOP, 0, 0},
-    {JPC_MS_CRG, JPC_MH, jpc_dec_process_crg},
-    {JPC_MS_COM, JPC_MH | JPC_TPH, jpc_dec_process_com},
-    {0, JPC_MH | JPC_TPH, jpc_dec_process_unk}
-};
 
-/*****************************************************************************\
-* The main entry point for the JPEG-2000 decoder.
-\*****************************************************************************/
+static void
+jpc_dec_tiledecode(jpc_dec_t *      const dec,
+                   jpc_dec_tile_t * const tile,
+                   const char **    const errorP) {
 
-jas_image_t *jpc_decode(jas_stream_t *in, char *optstr)
-{
-    jpc_dec_importopts_t opts;
-    jpc_dec_t *dec;
-    jas_image_t *image;
+    int i;
+    int j;
+    jpc_dec_tcomp_t *tcomp;
+    jpc_dec_rlvl_t *rlvl;
+    jpc_dec_band_t *band;
+    int compno;
+    int rlvlno;
+    int bandno;
+    int adjust;
+    int v;
+    jpc_dec_ccp_t *ccp;
+    jpc_dec_cmpt_t *cmpt;
+    const char * error;
 
-    dec = 0;
+    jpc_dec_decodecblks(dec, tile, &error);
 
-    if (jpc_dec_parseopts(optstr, &opts)) {
-        goto error;
+    if (error) {
+        pm_asprintf(errorP, "jpc_dec_decodecblks failed.  %s", error);
+        return;
     }
 
-    jpc_initluts();
+    /* Perform dequantization. */
+    for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
+         ++compno, ++tcomp) {
+        ccp = &tile->cp->ccps[compno];
+        for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;
+             ++rlvlno, ++rlvl) {
+            if (!rlvl->bands) {
+                continue;
+            }
+            for (bandno = 0, band = rlvl->bands;
+                 bandno < rlvl->numbands; ++bandno, ++band) {
+                if (!band->data) {
+                    continue;
+                }
+                jpc_undo_roi(band->data, band->roishift, ccp->roishift -
+                             band->roishift, band->numbps);
+                if (tile->realmode) {
+                    jas_matrix_asl(band->data, JPC_FIX_FRACBITS);
+                    jpc_dequantize(band->data, band->absstepsize);
+                }
 
-    if (!(dec = jpc_dec_create(&opts, in))) {
-        goto error;
+            }
+        }
     }
 
-    /* Do most of the work. */
-    if (jpc_dec_decode(dec)) {
-        goto error;
+    /* Apply an inverse wavelet transform if necessary. */
+    for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
+         ++compno, ++tcomp) {
+        ccp = &tile->cp->ccps[compno];
+        jpc_tsfb_synthesize(tcomp->tsfb,
+                            ((ccp->qmfbid ==
+                              JPC_COX_RFT) ? JPC_TSFB_RITIMODE : 0),
+                            tcomp->data);
     }
 
-    if (jas_image_numcmpts(dec->image) >= 3) {
-        jas_image_setcolorspace(dec->image, JAS_IMAGE_CS_RGB);
-        jas_image_setcmpttype(dec->image, 0,
-          JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_R));
-        jas_image_setcmpttype(dec->image, 1,
-          JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_G));
-        jas_image_setcmpttype(dec->image, 2,
-          JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_B));
-    } else {
-        jas_image_setcolorspace(dec->image, JAS_IMAGE_CS_GRAY);
-        jas_image_setcmpttype(dec->image, 0,
-          JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y));
+
+    /* Apply an inverse intercomponent transform if necessary. */
+    switch (tile->cp->mctid) {
+    case JPC_MCT_RCT:
+        assert(dec->numcomps == 3);
+        jpc_irct(tile->tcomps[0].data, tile->tcomps[1].data,
+                 tile->tcomps[2].data);
+        break;
+    case JPC_MCT_ICT:
+        assert(dec->numcomps == 3);
+        jpc_iict(tile->tcomps[0].data, tile->tcomps[1].data,
+                 tile->tcomps[2].data);
+        break;
     }
 
-    /* Save the return value. */
-    image = dec->image;
+    /* Perform rounding and convert to integer values. */
+    if (tile->realmode) {
+        for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
+             ++compno, ++tcomp) {
+            for (i = 0; i < jas_matrix_numrows(tcomp->data); ++i) {
+                for (j = 0; j < jas_matrix_numcols(tcomp->data); ++j) {
+                    v = jas_matrix_get(tcomp->data, i, j);
+                    v = jpc_fix_round(v);
+                    jas_matrix_set(tcomp->data, i, j, jpc_fixtoint(v));
+                }
+            }
+        }
+    }
 
-    /* Stop the image from being discarded. */
-    dec->image = 0;
+    /* Perform level shift. */
+    for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
+             dec->numcomps; ++compno, ++tcomp, ++cmpt) {
+        adjust = cmpt->sgnd ? 0 : (1 << (cmpt->prec - 1));
+        for (i = 0; i < jas_matrix_numrows(tcomp->data); ++i) {
+            for (j = 0; j < jas_matrix_numcols(tcomp->data); ++j) {
+                *jas_matrix_getref(tcomp->data, i, j) += adjust;
+            }
+        }
+    }
 
-    /* Destroy decoder. */
-    jpc_dec_destroy(dec);
+    /* Perform clipping. */
+    for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
+             dec->numcomps; ++compno, ++tcomp, ++cmpt) {
+        jpc_fix_t mn;
+        jpc_fix_t mx;
+        mn = cmpt->sgnd ? (-(1 << (cmpt->prec - 1))) : (0);
+        mx = cmpt->sgnd ? ((1 << (cmpt->prec - 1)) - 1) : ((1 <<
+                                                            cmpt->prec) - 1);
+        jas_matrix_clip(tcomp->data, mn, mx);
+    }
 
-    return image;
+    /* XXX need to free tsfb struct */
 
-error:
-    if (dec) {
-        jpc_dec_destroy(dec);
+    /* Write the data for each component of the image. */
+    for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
+             dec->numcomps; ++compno, ++tcomp, ++cmpt) {
+        if (jas_image_writecmpt(dec->image, compno, tcomp->xstart -
+                                JPC_CEILDIV(dec->xstart, cmpt->hstep),
+                                tcomp->ystart -
+                                JPC_CEILDIV(dec->ystart, cmpt->vstep),
+                                jas_matrix_numcols(
+                                    tcomp->data),
+                                jas_matrix_numrows(tcomp->data),
+                                tcomp->data)) {
+            pm_asprintf(errorP, "write component failed");
+            return;
+        }
     }
-    return 0;
+    *errorP = NULL;
 }
 
+
+
+static void
+jpc_dec_process_sod(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
+    jpc_dec_tile_t *tile;
+    int pos;
+
+    if (!(tile = dec->curtile)) {
+        pm_asprintf(errorP, "No current tile");
+        return;
+    }
+
+    if (!tile->partno) {
+        if (!jpc_dec_cp_isvalid(tile->cp)) {
+            pm_asprintf(errorP, "CP is not valid");
+            return;
+        }
+        if (jpc_dec_cp_prepare(tile->cp)) {
+            pm_asprintf(errorP, "fpc_dec_cp_prepare failed");
+            return;
+        }
+        if (jpc_dec_tileinit(dec, tile)) {
+            pm_asprintf(errorP, "jpc_dec_tileinit failed");
+            return;
+        }
+    }
+
+    /* Are packet headers stored in the main header or tile-part header? */
+    if (dec->pkthdrstreams) {
+        /* Get the stream containing the packet header data for this
+          tile-part. */
+        if (!(tile->pkthdrstream = jpc_streamlist_remove(dec->pkthdrstreams, 0))) {
+            pm_asprintf(errorP, "jpc_streamlist_remove failed");
+            return;
+        }
+    }
+
+    if (tile->pptstab) {
+        if (!tile->pkthdrstream) {
+            if (!(tile->pkthdrstream = jas_stream_memopen(0, 0))) {
+                pm_asprintf(errorP, "jas_stream_memopen failed");
+                return;
+            }
+        }
+        pos = jas_stream_tell(tile->pkthdrstream);
+        jas_stream_seek(tile->pkthdrstream, 0, SEEK_END);
+        if (jpc_pptstabwrite(tile->pkthdrstream, tile->pptstab)) {
+            pm_asprintf(errorP, "jpc_pptstabwrite failed");
+            return;
+        }
+        jas_stream_seek(tile->pkthdrstream, pos, SEEK_SET);
+        jpc_ppxstab_destroy(tile->pptstab);
+        tile->pptstab = 0;
+    }
+
+    if (jas_getdbglevel() >= 10) {
+        jpc_dec_dump(dec, stderr);
+    }
+
+    if (jpc_dec_decodepkts(dec, (tile->pkthdrstream) ? tile->pkthdrstream :
+      dec->in, dec->in)) {
+        pm_asprintf(errorP, "jpc_dec_decodepkts failed");
+        return;
+    }
+
+    /* Gobble any unconsumed tile data. */
+    if (dec->curtileendoff > 0) {
+        uint_fast32_t curoff;
+        uint_fast32_t n;
+        curoff = jas_stream_getrwcount(dec->in);
+        if (curoff < dec->curtileendoff) {
+            n = dec->curtileendoff - curoff;
+            pm_message("warning: ignoring trailing garbage (%lu bytes)",
+                       (unsigned long) n);
+
+            while (n-- > 0) {
+                if (jas_stream_getc(dec->in) == EOF) {
+                    pm_asprintf(errorP, "read error");
+                    return;
+                }
+            }
+        } else if (curoff > dec->curtileendoff) {
+            pm_message("warning: not enough tile data (%lu bytes)",
+                       (unsigned long) curoff - dec->curtileendoff);
+        }
+    }
+
+    if (tile->numparts > 0 && tile->partno == tile->numparts - 1) {
+        const char * error;
+        jpc_dec_tiledecode(dec, tile, &error);
+        if (error) {
+            pm_asprintf(errorP, "jpc_dec_tiledecode failed.  %s", error);
+            pm_strfree(error);
+            return;
+        }
+        jpc_dec_tilefini(dec, tile);
+    }
+
+    dec->curtile = 0;
+
+    /* Increment the expected tile-part number. */
+    ++tile->partno;
+
+    /* We should expect to encounter a SOT marker segment next. */
+    dec->state = JPC_TPHSOT;
+
+    *errorP = NULL;
+}
+
+
+
 typedef enum {
     OPT_MAXLYRS,
     OPT_MAXPKTS,
@@ -349,7 +494,8 @@ jas_taginfo_t decopts[] = {
     {-1, 0}
 };
 
-static int jpc_dec_parseopts(char *optstr, jpc_dec_importopts_t *opts)
+static int
+jpc_dec_parseopts(const char *optstr, jpc_dec_importopts_t *opts)
 {
     jas_tvparser_t *tvp;
 
@@ -374,8 +520,8 @@ static int jpc_dec_parseopts(char *optstr, jpc_dec_importopts_t *opts)
             opts->maxpkts = atoi(jas_tvparser_getval(tvp));
             break;
         default:
-            fprintf(stderr, "warning: ignoring invalid option %s\n",
-              jas_tvparser_gettag(tvp));
+            pm_message("warning: ignoring invalid option %s",
+                       jas_tvparser_gettag(tvp));
             break;
         }
     }
@@ -385,79 +531,14 @@ static int jpc_dec_parseopts(char *optstr, jpc_dec_importopts_t *opts)
     return 0;
 }
 
-/******************************************************************************\
-* Code for table-driven code stream decoder.
-\******************************************************************************/
-
-static jpc_dec_mstabent_t *jpc_dec_mstab_lookup(uint_fast16_t id)
-{
-    jpc_dec_mstabent_t *mstabent;
-    for (mstabent = jpc_dec_mstab; mstabent->id != 0; ++mstabent) {
-        if (mstabent->id == id) {
-            break;
-        }
-    }
-    return mstabent;
-}
-
-static int jpc_dec_decode(jpc_dec_t *dec)
-{
-    jpc_ms_t *ms;
-    jpc_dec_mstabent_t *mstabent;
-    int ret;
-    jpc_cstate_t *cstate;
-
-    if (!(cstate = jpc_cstate_create())) {
-        return -1;
-    }
-    dec->cstate = cstate;
-
-    /* Initially, we should expect to encounter a SOC marker segment. */
-    dec->state = JPC_MHSOC;
-
-    for (;;) {
-
-        /* Get the next marker segment in the code stream. */
-        if (!(ms = jpc_getms(dec->in, cstate))) {
-            fprintf(stderr, "cannot get marker segment\n");
-            return -1;
-        }
-
-        mstabent = jpc_dec_mstab_lookup(ms->id);
-        assert(mstabent);
-
-        /* Ensure that this type of marker segment is permitted
-          at this point in the code stream. */
-        if (!(dec->state & mstabent->validstates)) {
-            fprintf(stderr, "unexpected marker segment type\n");
-            jpc_ms_destroy(ms);
-            return -1;
-        }
-
-        /* Process the marker segment. */
-        if (mstabent->action) {
-            ret = (*mstabent->action)(dec, ms);
-        } else {
-            /* No explicit action is required. */
-            ret = 0;
-        }
-
-        /* Destroy the marker segment. */
-        jpc_ms_destroy(ms);
-
-        if (ret < 0) {
-            return -1;
-        } else if (ret > 0) {
-            break;
-        }
 
-    }
 
-    return 0;
-}
+static void
+jpc_dec_process_crg(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
 
-static int jpc_dec_process_crg(jpc_dec_t *dec, jpc_ms_t *ms)
-{
     /* Ignore the information in the CRG marker segment for now.
        This information serves no useful purpose for decoding anyhow.
        Some other parts of the code need to be changed if these lines
@@ -475,19 +556,33 @@ static int jpc_dec_process_crg(jpc_dec_t *dec, jpc_ms_t *ms)
         cmpt->vsubstep = crg->comps[cmptno].voff;
     }
 #endif
-    return 0;
+    *doneP = false;
+    *errorP = NULL;
 }
 
-static int jpc_dec_process_soc(jpc_dec_t *dec, jpc_ms_t *ms)
-{
+
+
+static void
+jpc_dec_process_soc(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
     /* We should expect to encounter a SIZ marker segment next. */
     dec->state = JPC_MHSIZ;
 
-    return 0;
+    *doneP = false;
+    *errorP = NULL;
 }
 
-static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms)
-{
+
+
+static void
+jpc_dec_process_sot(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
     jpc_dec_tile_t *tile;
     jpc_sot_t *sot = &ms->parms.sot;
     jas_image_cmptparm_t *compinfos;
@@ -512,8 +607,9 @@ static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms)
         }
 
         if (!(dec->image = jas_image_create(dec->numcomps, compinfos,
-          JAS_IMAGE_CS_UNKNOWN))) {
-            return -1;
+                                            JAS_IMAGE_CS_UNKNOWN))) {
+            pm_asprintf(errorP, "jas_image_create failed");
+            return;
         }
         jas_free(compinfos);
 
@@ -538,18 +634,20 @@ static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms)
     }
 
     if (sot->tileno > dec->numtiles) {
-        fprintf(stderr, "invalid tile number in SOT marker segment\n");
-        return -1;
+        pm_asprintf(errorP, "invalid tile number in SOT marker segment");
+        return;
     }
     /* Set the current tile. */
     dec->curtile = &dec->tiles[sot->tileno];
     tile = dec->curtile;
     /* Ensure that this is the expected part number. */
     if (sot->partno != tile->partno) {
-        return -1;
+        pm_asprintf(errorP, "Unexpected part number");
+        return;
     }
     if (tile->numparts > 0 && sot->partno >= tile->numparts) {
-        return -1;
+        pm_asprintf(errorP, "part number greater than number of parts");
+        return;
     }
     if (!tile->numparts && sot->numparts > 0) {
         tile->numparts = sot->numparts;
@@ -563,7 +661,8 @@ static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms)
         tile->state = JPC_TILE_ACTIVE;
         assert(!tile->cp);
         if (!(tile->cp = jpc_dec_cp_copy(dec->cp))) {
-            return -1;
+            pm_asprintf(errorP, "jpc_dec_cp_copy failed");
+            return;
         }
         jpc_dec_cp_resetflags(dec->cp);
         break;
@@ -581,107 +680,11 @@ static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms)
       segments next. */
     dec->state = JPC_TPH;
 
-    return 0;
+    *doneP = false;
+    *errorP = NULL;
 }
 
-static int jpc_dec_process_sod(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-    jpc_dec_tile_t *tile;
-    int pos;
-
-    if (!(tile = dec->curtile)) {
-        return -1;
-    }
-
-    if (!tile->partno) {
-        if (!jpc_dec_cp_isvalid(tile->cp)) {
-            return -1;
-        }
-        if (jpc_dec_cp_prepare(tile->cp)) {
-            return -1;
-        }
-        if (jpc_dec_tileinit(dec, tile)) {
-            return -1;
-        }
-    }
-
-    /* Are packet headers stored in the main header or tile-part header? */
-    if (dec->pkthdrstreams) {
-        /* Get the stream containing the packet header data for this
-          tile-part. */
-        if (!(tile->pkthdrstream = jpc_streamlist_remove(dec->pkthdrstreams, 0))) {
-            return -1;
-        }
-    }
-
-    if (tile->pptstab) {
-        if (!tile->pkthdrstream) {
-            if (!(tile->pkthdrstream = jas_stream_memopen(0, 0))) {
-                return -1;
-            }
-        }
-        pos = jas_stream_tell(tile->pkthdrstream);
-        jas_stream_seek(tile->pkthdrstream, 0, SEEK_END);
-        if (jpc_pptstabwrite(tile->pkthdrstream, tile->pptstab)) {
-            return -1;
-        }
-        jas_stream_seek(tile->pkthdrstream, pos, SEEK_SET);
-        jpc_ppxstab_destroy(tile->pptstab);
-        tile->pptstab = 0;
-    }
-
-    if (jas_getdbglevel() >= 10) {
-        jpc_dec_dump(dec, stderr);
-    }
-
-    if (jpc_dec_decodepkts(dec, (tile->pkthdrstream) ? tile->pkthdrstream :
-      dec->in, dec->in)) {
-        fprintf(stderr, "jpc_dec_decodepkts failed\n");
-        return -1;
-    }
-
-    /* Gobble any unconsumed tile data. */
-    if (dec->curtileendoff > 0) {
-        uint_fast32_t curoff;
-        uint_fast32_t n;
-        curoff = jas_stream_getrwcount(dec->in);
-        if (curoff < dec->curtileendoff) {
-            n = dec->curtileendoff - curoff;
-            fprintf(stderr,
-              "warning: ignoring trailing garbage (%lu bytes)\n",
-              (unsigned long) n);
-
-            while (n-- > 0) {
-                if (jas_stream_getc(dec->in) == EOF) {
-                    fprintf(stderr, "read error\n");
-                    return -1;
-                }
-            }
-        } else if (curoff > dec->curtileendoff) {
-            fprintf(stderr,
-              "warning: not enough tile data (%lu bytes)\n",
-              (unsigned long) curoff - dec->curtileendoff);
-        }
-
-    }
-
-    if (tile->numparts > 0 && tile->partno == tile->numparts - 1) {
-        if (jpc_dec_tiledecode(dec, tile)) {
-            return -1;
-        }
-        jpc_dec_tilefini(dec, tile);
-    }
-
-    dec->curtile = 0;
-
-    /* Increment the expected tile-part number. */
-    ++tile->partno;
-
-    /* We should expect to encounter a SOT marker segment next. */
-    dec->state = JPC_TPHSOT;
 
-    return 0;
-}
 
 static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile)
 {
@@ -1059,136 +1062,25 @@ if (!prc->cblks) {
     return 0;
 }
 
-static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile)
-{
-    int i;
-    int j;
-    jpc_dec_tcomp_t *tcomp;
-    jpc_dec_rlvl_t *rlvl;
-    jpc_dec_band_t *band;
-    int compno;
-    int rlvlno;
-    int bandno;
-    int adjust;
-    int v;
-    jpc_dec_ccp_t *ccp;
-    jpc_dec_cmpt_t *cmpt;
 
-    if (jpc_dec_decodecblks(dec, tile)) {
-        fprintf(stderr, "jpc_dec_decodecblks failed\n");
-        return -1;
-    }
 
-    /* Perform dequantization. */
-    for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
-      ++compno, ++tcomp) {
-        ccp = &tile->cp->ccps[compno];
-        for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;
-          ++rlvlno, ++rlvl) {
-            if (!rlvl->bands) {
-                continue;
-            }
-            for (bandno = 0, band = rlvl->bands;
-              bandno < rlvl->numbands; ++bandno, ++band) {
-                if (!band->data) {
-                    continue;
-                }
-                jpc_undo_roi(band->data, band->roishift, ccp->roishift -
-                  band->roishift, band->numbps);
-                if (tile->realmode) {
-                    jas_matrix_asl(band->data, JPC_FIX_FRACBITS);
-                    jpc_dequantize(band->data, band->absstepsize);
-                }
+static void
+jpc_dec_process_eoc(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
 
-            }
-        }
-    }
-
-    /* Apply an inverse wavelet transform if necessary. */
-    for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
-      ++compno, ++tcomp) {
-        ccp = &tile->cp->ccps[compno];
-        jpc_tsfb_synthesize(tcomp->tsfb, ((ccp->qmfbid ==
-          JPC_COX_RFT) ? JPC_TSFB_RITIMODE : 0), tcomp->data);
-    }
-
-
-    /* Apply an inverse intercomponent transform if necessary. */
-    switch (tile->cp->mctid) {
-    case JPC_MCT_RCT:
-        assert(dec->numcomps == 3);
-        jpc_irct(tile->tcomps[0].data, tile->tcomps[1].data,
-          tile->tcomps[2].data);
-        break;
-    case JPC_MCT_ICT:
-        assert(dec->numcomps == 3);
-        jpc_iict(tile->tcomps[0].data, tile->tcomps[1].data,
-          tile->tcomps[2].data);
-        break;
-    }
-
-    /* Perform rounding and convert to integer values. */
-    if (tile->realmode) {
-        for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
-          ++compno, ++tcomp) {
-            for (i = 0; i < jas_matrix_numrows(tcomp->data); ++i) {
-                for (j = 0; j < jas_matrix_numcols(tcomp->data); ++j) {
-                    v = jas_matrix_get(tcomp->data, i, j);
-                    v = jpc_fix_round(v);
-                    jas_matrix_set(tcomp->data, i, j, jpc_fixtoint(v));
-                }
-            }
-        }
-    }
-
-    /* Perform level shift. */
-    for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
-      dec->numcomps; ++compno, ++tcomp, ++cmpt) {
-        adjust = cmpt->sgnd ? 0 : (1 << (cmpt->prec - 1));
-        for (i = 0; i < jas_matrix_numrows(tcomp->data); ++i) {
-            for (j = 0; j < jas_matrix_numcols(tcomp->data); ++j) {
-                *jas_matrix_getref(tcomp->data, i, j) += adjust;
-            }
-        }
-    }
-
-    /* Perform clipping. */
-    for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
-      dec->numcomps; ++compno, ++tcomp, ++cmpt) {
-        jpc_fix_t mn;
-        jpc_fix_t mx;
-        mn = cmpt->sgnd ? (-(1 << (cmpt->prec - 1))) : (0);
-        mx = cmpt->sgnd ? ((1 << (cmpt->prec - 1)) - 1) : ((1 <<
-          cmpt->prec) - 1);
-        jas_matrix_clip(tcomp->data, mn, mx);
-    }
-
-    /* XXX need to free tsfb struct */
-
-    /* Write the data for each component of the image. */
-    for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
-      dec->numcomps; ++compno, ++tcomp, ++cmpt) {
-        if (jas_image_writecmpt(dec->image, compno, tcomp->xstart -
-          JPC_CEILDIV(dec->xstart, cmpt->hstep), tcomp->ystart -
-          JPC_CEILDIV(dec->ystart, cmpt->vstep), jas_matrix_numcols(
-          tcomp->data), jas_matrix_numrows(tcomp->data), tcomp->data)) {
-            fprintf(stderr, "write component failed\n");
-            return -4;
-        }
-    }
-
-    return 0;
-}
-
-static int jpc_dec_process_eoc(jpc_dec_t *dec, jpc_ms_t *ms)
-{
     int tileno;
     jpc_dec_tile_t *tile;
     for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; ++tileno,
       ++tile) {
         if (tile->state == JPC_TILE_ACTIVE) {
-            if (jpc_dec_tiledecode(dec, tile)) {
-                return -1;
+            const char * error;
+            jpc_dec_tiledecode(dec, tile, &error);
+            if (error) {
+                pm_asprintf(errorP, "jpc_dec_tiledecode failed.  %s", error);
+                pm_strfree(error);
+                return;
             }
         }
         jpc_dec_tilefini(dec, tile);
@@ -1197,11 +1089,17 @@ static int jpc_dec_process_eoc(jpc_dec_t *dec, jpc_ms_t *ms)
     /* We are done processing the code stream. */
     dec->state = JPC_MT;
 
-    return 1;
+    *doneP = true;
 }
 
-static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms)
-{
+
+
+static void
+jpc_dec_process_siz(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
     jpc_siz_t *siz = &ms->parms.siz;
     uint_fast16_t compno;
     uint_fast32_t tileno;
@@ -1221,11 +1119,13 @@ static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms)
     dec->tileyoff = siz->tileyoff;
     dec->numcomps = siz->numcomps;
     if (!(dec->cp = jpc_dec_cp_create(dec->numcomps))) {
-        return -1;
+        pm_asprintf(errorP, "jpc_dec_cp_create failed");
+        return;
     }
 
     if (!(dec->cmpts = jas_malloc(dec->numcomps * sizeof(jpc_dec_cmpt_t)))) {
-        return -1;
+        pm_asprintf(errorP, "jas_malloc failed");
+        return;
     }
 
     for (compno = 0, cmpt = dec->cmpts; compno < dec->numcomps; ++compno,
@@ -1248,7 +1148,8 @@ static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms)
     dec->numvtiles = JPC_CEILDIV(dec->yend - dec->tileyoff, dec->tileheight);
     dec->numtiles = dec->numhtiles * dec->numvtiles;
     if (!(dec->tiles = jas_malloc(dec->numtiles * sizeof(jpc_dec_tile_t)))) {
-        return -1;
+        pm_asprintf(errorP, "jas_malloc failed");
+        return;
     }
 
     for (tileno = 0, tile = dec->tiles;
@@ -1280,9 +1181,10 @@ static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms)
         tile->pkthdrstreampos = 0;
         tile->pptstab = 0;
         tile->cp = 0;
-        if (!(tile->tcomps = jas_malloc(dec->numcomps *
-          sizeof(jpc_dec_tcomp_t)))) {
-            return -1;
+        tile->tcomps = jas_malloc(dec->numcomps * sizeof(jpc_dec_tcomp_t));
+        if (!tile->tcomps) {
+            pm_asprintf(errorP, "jas_malloc failed");
+            return;
         }
         for (compno = 0, cmpt = dec->cmpts, tcomp = tile->tcomps;
           compno < dec->numcomps; ++compno, ++cmpt, ++tcomp) {
@@ -1302,11 +1204,18 @@ static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms)
       or an SOT marker segment next. */
     dec->state = JPC_MH;
 
-    return 0;
+    *doneP = false;
+    *errorP = NULL;
 }
 
-static int jpc_dec_process_cod(jpc_dec_t *dec, jpc_ms_t *ms)
-{
+
+
+static void
+jpc_dec_process_cod(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
     jpc_cod_t *cod = &ms->parms.cod;
     jpc_dec_tile_t *tile;
 
@@ -1316,26 +1225,34 @@ static int jpc_dec_process_cod(jpc_dec_t *dec, jpc_ms_t *ms)
         break;
     case JPC_TPH:
         if (!(tile = dec->curtile)) {
-            return -1;
+            pm_asprintf(errorP, "No current tile");
+            return;
         }
         if (tile->partno != 0) {
-            return -1;
+            pm_asprintf(errorP, "part number is not zero");
+            return;
         }
         jpc_dec_cp_setfromcod(tile->cp, cod);
         break;
     }
-    return 0;
+    *doneP = false;
+    *errorP = NULL;
 }
 
-static int jpc_dec_process_coc(jpc_dec_t *dec, jpc_ms_t *ms)
-{
+
+
+static void
+jpc_dec_process_coc(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
     jpc_coc_t *coc = &ms->parms.coc;
     jpc_dec_tile_t *tile;
 
     if (coc->compno > dec->numcomps) {
-        fprintf(stderr,
-          "invalid component number in COC marker segment\n");
-        return -1;
+        pm_asprintf(errorP, "invalid component number in COC marker segment");
+        return;
     }
     switch (dec->state) {
     case JPC_MH:
@@ -1343,26 +1260,34 @@ static int jpc_dec_process_coc(jpc_dec_t *dec, jpc_ms_t *ms)
         break;
     case JPC_TPH:
         if (!(tile = dec->curtile)) {
-            return -1;
+            pm_asprintf(errorP, "No current tile");
+            return;
         }
         if (tile->partno > 0) {
-            return -1;
+            pm_asprintf(errorP, "Part number is not zero");
+            return;
         }
         jpc_dec_cp_setfromcoc(tile->cp, coc);
         break;
     }
-    return 0;
+    *doneP = false;
+    *errorP = NULL;
 }
 
-static int jpc_dec_process_rgn(jpc_dec_t *dec, jpc_ms_t *ms)
-{
+
+
+static void
+jpc_dec_process_rgn(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
     jpc_rgn_t *rgn = &ms->parms.rgn;
     jpc_dec_tile_t *tile;
 
     if (rgn->compno > dec->numcomps) {
-        fprintf(stderr,
-          "invalid component number in RGN marker segment\n");
-        return -1;
+        pm_asprintf(errorP, "invalid component number in RGN marker segment");
+        return;
     }
     switch (dec->state) {
     case JPC_MH:
@@ -1370,20 +1295,29 @@ static int jpc_dec_process_rgn(jpc_dec_t *dec, jpc_ms_t *ms)
         break;
     case JPC_TPH:
         if (!(tile = dec->curtile)) {
-            return -1;
+            pm_asprintf(errorP, "No current tile");
+            return;
         }
         if (tile->partno > 0) {
-            return -1;
+            pm_asprintf(errorP, "Part number is not zero");
+            return;
         }
         jpc_dec_cp_setfromrgn(tile->cp, rgn);
         break;
     }
 
-    return 0;
+    *doneP = false;
+    *errorP = NULL;
 }
 
-static int jpc_dec_process_qcd(jpc_dec_t *dec, jpc_ms_t *ms)
-{
+
+
+static void
+jpc_dec_process_qcd(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
     jpc_qcd_t *qcd = &ms->parms.qcd;
     jpc_dec_tile_t *tile;
 
@@ -1393,26 +1327,34 @@ static int jpc_dec_process_qcd(jpc_dec_t *dec, jpc_ms_t *ms)
         break;
     case JPC_TPH:
         if (!(tile = dec->curtile)) {
-            return -1;
+            pm_asprintf(errorP, "No current tile");
+            return;
         }
         if (tile->partno > 0) {
-            return -1;
+            pm_asprintf(errorP, "Part number is not zero");
+            return;
         }
         jpc_dec_cp_setfromqcd(tile->cp, qcd);
         break;
     }
-    return 0;
+    *doneP = false;
+    *errorP = NULL;
 }
 
-static int jpc_dec_process_qcc(jpc_dec_t *dec, jpc_ms_t *ms)
-{
+
+
+static void
+jpc_dec_process_qcc(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
     jpc_qcc_t *qcc = &ms->parms.qcc;
     jpc_dec_tile_t *tile;
 
     if (qcc->compno > dec->numcomps) {
-        fprintf(stderr,
-          "invalid component number in QCC marker segment\n");
-        return -1;
+        pm_asprintf(errorP, "invalid component number in QCC marker segment");
+        return;
     }
     switch (dec->state) {
     case JPC_MH:
@@ -1420,69 +1362,98 @@ static int jpc_dec_process_qcc(jpc_dec_t *dec, jpc_ms_t *ms)
         break;
     case JPC_TPH:
         if (!(tile = dec->curtile)) {
-            return -1;
+            pm_asprintf(errorP, "No current tile");
+            return;
         }
         if (tile->partno > 0) {
-            return -1;
+            pm_asprintf(errorP, "Part number is not zero");
+            return;
         }
         jpc_dec_cp_setfromqcc(tile->cp, qcc);
         break;
     }
-    return 0;
+    *doneP = false;
+    *errorP = NULL;
 }
 
-static int jpc_dec_process_poc(jpc_dec_t *dec, jpc_ms_t *ms)
-{
+
+
+static void
+jpc_dec_process_poc(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
     jpc_poc_t *poc = &ms->parms.poc;
     jpc_dec_tile_t *tile;
     switch (dec->state) {
     case JPC_MH:
         if (jpc_dec_cp_setfrompoc(dec->cp, poc, 1)) {
-            return -1;
+            pm_asprintf(errorP, "jpc_dec_cp_setfrompoc failed");
+            return;
         }
         break;
     case JPC_TPH:
         if (!(tile = dec->curtile)) {
-            return -1;
+            pm_asprintf(errorP, "No current tile");
+            return;
         }
         if (!tile->partno) {
             if (jpc_dec_cp_setfrompoc(tile->cp, poc, (!tile->partno))) {
-                return -1;
+                pm_asprintf(errorP, "jpc_dec_cp_setfrompoc failed");
+                return;
             }
         } else {
             jpc_pi_addpchgfrompoc(tile->pi, poc);
         }
         break;
     }
-    return 0;
+    *doneP = false;
+    *errorP = NULL;
 }
 
-static int jpc_dec_process_ppm(jpc_dec_t *dec, jpc_ms_t *ms)
-{
+
+
+static void
+jpc_dec_process_ppm(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
     jpc_ppm_t *ppm = &ms->parms.ppm;
     jpc_ppxstabent_t *ppmstabent;
 
     if (!dec->ppmstab) {
         if (!(dec->ppmstab = jpc_ppxstab_create())) {
-            return -1;
+            pm_asprintf(errorP, "jpc_ppxstab_create failed");
+            return;
         }
     }
 
     if (!(ppmstabent = jpc_ppxstabent_create())) {
-        return -1;
+        pm_asprintf(errorP, "jpc_ppxstabent_create failed");
+        return;
     }
     ppmstabent->ind = ppm->ind;
     ppmstabent->data = ppm->data;
     ppm->data = 0;
     ppmstabent->len = ppm->len;
     if (jpc_ppxstab_insert(dec->ppmstab, ppmstabent)) {
-        return -1;
+        pm_asprintf(errorP, "jpc_ppxstab_insert failed");
+        return;
     }
-    return 0;
+    *doneP = false;
+    *errorP = NULL;
 }
 
-static int jpc_dec_process_ppt(jpc_dec_t *dec, jpc_ms_t *ms)
-{
+
+
+static void
+jpc_dec_process_ppt(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
     jpc_ppt_t *ppt = &ms->parms.ppt;
     jpc_dec_tile_t *tile;
     jpc_ppxstabent_t *pptstabent;
@@ -1490,34 +1461,55 @@ static int jpc_dec_process_ppt(jpc_dec_t *dec, jpc_ms_t *ms)
     tile = dec->curtile;
     if (!tile->pptstab) {
         if (!(tile->pptstab = jpc_ppxstab_create())) {
-            return -1;
+            pm_asprintf(errorP, "jpc_ppxstab_create failed");
+            return;
         }
     }
     if (!(pptstabent = jpc_ppxstabent_create())) {
-        return -1;
+        pm_asprintf(errorP, "jpc_ppxstabent_create failed");
+        return;
     }
     pptstabent->ind = ppt->ind;
     pptstabent->data = ppt->data;
     ppt->data = 0;
     pptstabent->len = ppt->len;
     if (jpc_ppxstab_insert(tile->pptstab, pptstabent)) {
-        return -1;
+        pm_asprintf(errorP, "jpc_ppxstab_insert failed.");
+        return;
     }
-    return 0;
+    *doneP = false;
+    *errorP = NULL;
 }
 
-static int jpc_dec_process_com(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-    return 0;
+
+
+static void
+jpc_dec_process_com(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
+    *doneP = false;
+    *errorP = NULL;
 }
 
-static int jpc_dec_process_unk(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-    fprintf(stderr, "warning: ignoring unknown marker segment\n");
+
+
+static void
+jpc_dec_process_unk(jpc_dec_t *   const dec,
+                    jpc_ms_t *    const ms,
+                    bool *        const doneP,
+                    const char ** const errorP) {
+
+    pm_message("warning: ignoring unknown marker segment");
     jpc_ms_dump(ms, stderr);
-    return 0;
+
+    *doneP = false;
+    *errorP = NULL;
 }
 
+
+
 /******************************************************************************\
 *
 \******************************************************************************/
@@ -2370,3 +2362,168 @@ void jpc_ppxstabent_destroy(jpc_ppxstabent_t *ent)
     }
     jas_free(ent);
 }
+
+
+
+jpc_dec_mstabent_t jpc_dec_mstab[] = {
+    {JPC_MS_SOC, JPC_MHSOC, jpc_dec_process_soc},
+    {JPC_MS_SOT, JPC_MH | JPC_TPHSOT, jpc_dec_process_sot},
+    {JPC_MS_SOD, JPC_TPH, jpc_dec_process_sod},
+    {JPC_MS_EOC, JPC_TPHSOT, jpc_dec_process_eoc},
+    {JPC_MS_SIZ, JPC_MHSIZ, jpc_dec_process_siz},
+    {JPC_MS_COD, JPC_MH | JPC_TPH, jpc_dec_process_cod},
+    {JPC_MS_COC, JPC_MH | JPC_TPH, jpc_dec_process_coc},
+    {JPC_MS_RGN, JPC_MH | JPC_TPH, jpc_dec_process_rgn},
+    {JPC_MS_QCD, JPC_MH | JPC_TPH, jpc_dec_process_qcd},
+    {JPC_MS_QCC, JPC_MH | JPC_TPH, jpc_dec_process_qcc},
+    {JPC_MS_POC, JPC_MH | JPC_TPH, jpc_dec_process_poc},
+    {JPC_MS_TLM, JPC_MH, 0},
+    {JPC_MS_PLM, JPC_MH, 0},
+    {JPC_MS_PLT, JPC_TPH, 0},
+    {JPC_MS_PPM, JPC_MH, jpc_dec_process_ppm},
+    {JPC_MS_PPT, JPC_TPH, jpc_dec_process_ppt},
+    {JPC_MS_SOP, 0, 0},
+    {JPC_MS_CRG, JPC_MH, jpc_dec_process_crg},
+    {JPC_MS_COM, JPC_MH | JPC_TPH, jpc_dec_process_com},
+    {0, JPC_MH | JPC_TPH, jpc_dec_process_unk}
+};
+
+
+
+static jpc_dec_mstabent_t *jpc_dec_mstab_lookup(uint_fast16_t id)
+{
+    jpc_dec_mstabent_t *mstabent;
+    for (mstabent = jpc_dec_mstab; mstabent->id != 0; ++mstabent) {
+        if (mstabent->id == id) {
+            break;
+        }
+    }
+    return mstabent;
+}
+
+
+
+static void
+jpc_dec_decode(jpc_dec_t *   const dec,
+               const char ** const errorP) {
+
+    jpc_ms_t *ms;
+    jpc_dec_mstabent_t *mstabent;
+    bool done;
+    jpc_cstate_t *cstate;
+
+    if (!(cstate = jpc_cstate_create())) {
+        pm_asprintf(errorP, "jpc_cstate_create failed");
+        return;
+    }
+    dec->cstate = cstate;
+
+    /* Initially, we should expect to encounter a SOC marker segment. */
+    dec->state = JPC_MHSOC;
+
+    *errorP = NULL;   /* initial value */
+
+    for (;;) {
+
+        /* Get the next marker segment in the code stream. */
+        if (!(ms = jpc_getms(dec->in, cstate))) {
+            pm_asprintf(errorP, "cannot get marker segment");
+            return;
+        }
+
+        mstabent = jpc_dec_mstab_lookup(ms->id);
+        assert(mstabent);
+
+        /* Ensure that this type of marker segment is permitted
+          at this point in the code stream. */
+        if (!(dec->state & mstabent->validstates)) {
+            pm_asprintf(errorP, "unexpected marker segment type");
+            jpc_ms_destroy(ms);
+            return;
+        }
+
+        /* Process the marker segment. */
+        if (mstabent->action) {
+            (*mstabent->action)(dec, ms, &done, errorP);
+        } else {
+            /* No explicit action is required. */
+            *errorP = NULL;
+            done = false;
+        }
+
+        /* Destroy the marker segment. */
+        jpc_ms_destroy(ms);
+
+        if (*errorP) {
+            return;
+        } else if (done) {
+            break;
+        }
+    }
+}
+
+
+
+/*****************************************************************************\
+* The main entry point for the JPEG-2000 decoder.
+\*****************************************************************************/
+
+void
+jpc_decode(jas_stream_t * const in,
+           const char *   const optstr,
+           jas_image_t ** const imagePP,
+           const char **  const errorP) {
+
+    jpc_dec_importopts_t opts;
+    jpc_dec_t *dec;
+    jas_image_t *image;
+    const char * error;
+
+    if (jpc_dec_parseopts(optstr, &opts)) {
+        pm_asprintf(errorP, "jpc_dec_parseopts failed");
+        return;
+    }
+
+    jpc_initluts();
+
+    dec = jpc_dec_create(&opts, in);
+
+    if (!dec) {
+        pm_asprintf(errorP, "jpc_dec_create failed");
+    } else {
+        /* Do most of the work. */
+        jpc_dec_decode(dec, &error);
+        if (error) {
+            pm_asprintf(errorP, "jpc_dec_decode failed.  %s", error);
+            pm_strfree(error);
+        } else {
+            if (jas_image_numcmpts(dec->image) >= 3) {
+                jas_image_setcolorspace(dec->image, JAS_IMAGE_CS_RGB);
+                jas_image_setcmpttype(dec->image, 0,
+                                      JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_R));
+                jas_image_setcmpttype(dec->image, 1,
+                                      JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_G));
+                jas_image_setcmpttype(dec->image, 2,
+                                      JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_RGB_B));
+            } else {
+                jas_image_setcolorspace(dec->image, JAS_IMAGE_CS_GRAY);
+                jas_image_setcmpttype(dec->image, 0,
+                                      JAS_IMAGE_CT_COLOR(JAS_IMAGE_CT_GRAY_Y));
+            }
+
+            /* Save the return value. */
+            image = dec->image;
+
+            /* Stop the image from being discarded. */
+            dec->image = 0;
+
+            *imagePP = image;
+
+            *errorP = NULL;
+        }
+        jpc_dec_destroy(dec);
+    }
+}
+
+
+
diff --git a/converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.c b/converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.c
index 01a54ea8..b6c5e14f 100644
--- a/converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.c
+++ b/converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.c
@@ -124,6 +124,8 @@
 #include <stdlib.h>
 #include <assert.h>
 
+#include "netpbm/nstring.h"
+
 #include "jasper/jas_fix.h"
 #include "jasper/jas_stream.h"
 #include "jasper/jas_math.h"
@@ -138,817 +140,871 @@
 *
 \******************************************************************************/
 
-static int jpc_dec_decodecblk(jpc_dec_t *dec, jpc_dec_tile_t *tile, jpc_dec_tcomp_t *tcomp, jpc_dec_band_t *band,
-  jpc_dec_cblk_t *cblk, int dopartial, int maxlyrs);
-static int dec_sigpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int orient,
-  int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
-static int dec_rawsigpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos,
-  int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
-static int dec_refpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int vcausalflag,
-  jas_matrix_t *flags, jas_matrix_t *data);
-static int dec_rawrefpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos,
-  int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
-static int dec_clnpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int orient,
-  int vcausalflag, int segsymflag, jas_matrix_t *flags, jas_matrix_t *data);
-
 #if defined(DEBUG)
 static long t1dec_cnt = 0;
 #endif
 
 #if !defined(DEBUG)
-#define	JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename) \
-	((v) = jpc_mqdec_getbit(mqdec))
+#define JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename) \
+    ((v) = jpc_mqdec_getbit(mqdec))
 #else
-#define	JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename) \
+#define JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename) \
 { \
-	(v) = jpc_mqdec_getbit(mqdec); \
-	if (jas_getdbglevel() >= 100) { \
-		fprintf(stderr, "index = %ld; passtype = %s; symtype = %s; sym = %d\n", t1dec_cnt, passtypename, symtypename, v); \
-		++t1dec_cnt; \
-	} \
+    (v) = jpc_mqdec_getbit(mqdec); \
+    if (jas_getdbglevel() >= 100) { \
+        fprintf(stderr, "index = %ld; passtype = %s; symtype = %s; sym = %d\n", t1dec_cnt, passtypename, symtypename, v); \
+        ++t1dec_cnt; \
+    } \
 }
 #endif
-#define	JPC_T1D_GETBITNOSKEW(mqdec, v, passtypename, symtypename) \
-	JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename)
+#define JPC_T1D_GETBITNOSKEW(mqdec, v, passtypename, symtypename) \
+    JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename)
 
 #if !defined(DEBUG)
-#define	JPC_T1D_RAWGETBIT(bitstream, v, passtypename, symtypename) \
-	((v) = jpc_bitstream_getbit(bitstream))
+#define JPC_T1D_RAWGETBIT(bitstream, v, passtypename, symtypename) \
+    ((v) = jpc_bitstream_getbit(bitstream))
 #else
-#define	JPC_T1D_RAWGETBIT(bitstream, v, passtypename, symtypename) \
+#define JPC_T1D_RAWGETBIT(bitstream, v, passtypename, symtypename) \
 { \
-	(v) = jpc_bitstream_getbit(bitstream); \
-	if (jas_getdbglevel() >= 100) { \
-		fprintf(stderr, "index = %ld; passtype = %s; symtype = %s; sym = %d\n", t1dec_cnt, passtypename, symtypename, v); \
-		++t1dec_cnt; \
-	} \
+    (v) = jpc_bitstream_getbit(bitstream); \
+    if (jas_getdbglevel() >= 100) { \
+        fprintf(stderr, "index = %ld; passtype = %s; symtype = %s; sym = %d\n", t1dec_cnt, passtypename, symtypename, v); \
+        ++t1dec_cnt; \
+    } \
 }
 #endif
 
-/******************************************************************************\
-* Code.
-\******************************************************************************/
 
-int jpc_dec_decodecblks(jpc_dec_t *dec, jpc_dec_tile_t *tile)
-{
-	jpc_dec_tcomp_t *tcomp;
-	int compcnt;
-	jpc_dec_rlvl_t *rlvl;
-	int rlvlcnt;
-	jpc_dec_band_t *band;
-	int bandcnt;
-	jpc_dec_prc_t *prc;
-	int prccnt;
-	jpc_dec_cblk_t *cblk;
-	int cblkcnt;
-
-	for (compcnt = dec->numcomps, tcomp = tile->tcomps; compcnt > 0;
-	  --compcnt, ++tcomp) {
-		for (rlvlcnt = tcomp->numrlvls, rlvl = tcomp->rlvls;
-		  rlvlcnt > 0; --rlvlcnt, ++rlvl) {
-			if (!rlvl->bands) {
-				continue;
-			}
-			for (bandcnt = rlvl->numbands, band = rlvl->bands;
-			  bandcnt > 0; --bandcnt, ++band) {
-				if (!band->data) {
-					continue;
-				}
-				for (prccnt = rlvl->numprcs, prc = band->prcs;
-				  prccnt > 0; --prccnt, ++prc) {
-					if (!prc->cblks) {
-						continue;
-					}
-					for (cblkcnt = prc->numcblks,
-					  cblk = prc->cblks; cblkcnt > 0;
-					  --cblkcnt, ++cblk) {
-						if (jpc_dec_decodecblk(dec, tile, tcomp,
-						  band, cblk, 1, JPC_MAXLYRS)) {
-							return -1;
-						}
-					}
-				}
-
-			}
-		}
-	}
-
-	return 0;
-}
-
-static int jpc_dec_decodecblk(jpc_dec_t *dec, jpc_dec_tile_t *tile, jpc_dec_tcomp_t *tcomp, jpc_dec_band_t *band,
-  jpc_dec_cblk_t *cblk, int dopartial, int maxlyrs)
-{
-	jpc_dec_seg_t *seg;
-	int i;
-	int bpno;
-	int passtype;
-	int ret;
-	int compno;
-	int filldata;
-	int fillmask;
-	jpc_dec_ccp_t *ccp;
-
-	compno = tcomp - tile->tcomps;
-
-	if (!cblk->flags) {
-		/* Note: matrix is assumed to be zeroed */
-		if (!(cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) +
-		  2, jas_matrix_numcols(cblk->data) + 2))) {
-			return -1;
-		}
-	}
-
-	seg = cblk->segs.head;
-	while (seg && (seg != cblk->curseg || dopartial) && (maxlyrs < 0 ||
-	  seg->lyrno < maxlyrs)) {
-		assert(seg->numpasses >= seg->maxpasses || dopartial);
-		assert(seg->stream);
-		jas_stream_rewind(seg->stream);
-		jas_stream_setrwcount(seg->stream, 0);
-		if (seg->type == JPC_SEG_MQ) {
-			if (!cblk->mqdec) {
-				if (!(cblk->mqdec = jpc_mqdec_create(JPC_NUMCTXS, 0))) {
-					return -1;
-				}
-				jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
-			}
-			jpc_mqdec_setinput(cblk->mqdec, seg->stream);
-			jpc_mqdec_init(cblk->mqdec);
-		} else {
-			assert(seg->type == JPC_SEG_RAW);
-			if (!cblk->nulldec) {
-				if (!(cblk->nulldec = jpc_bitstream_sopen(seg->stream, "r"))) {
-					assert(0);
-				}
-			}
-		}
-
-
-		for (i = 0; i < seg->numpasses; ++i) {
-			if (cblk->numimsbs > band->numbps) {
-				ccp = &tile->cp->ccps[compno];
-				if (ccp->roishift <= 0) {
-					fprintf(stderr, "warning: corrupt code stream\n");
-				} else {
-					if (cblk->numimsbs < ccp->roishift - band->numbps) {
-						fprintf(stderr, "warning: corrupt code stream\n");
-					}
-				}
-			}
-			bpno = band->roishift + band->numbps - 1 - (cblk->numimsbs +
-			  (seg->passno + i - cblk->firstpassno + 2) / 3);
-if (bpno < 0) {
-	goto premature_exit;
-}
-#if 1
-			passtype = (seg->passno + i + 2) % 3;
-#else
-			passtype = JPC_PASSTYPE(seg->passno + i + 2);
-#endif
-			assert(bpno >= 0 && bpno < 31);
-			switch (passtype) {
-			case JPC_SIGPASS:
-				ret = (seg->type == JPC_SEG_MQ) ? dec_sigpass(dec,
-				  cblk->mqdec, bpno, band->orient,
-				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
-				  cblk->flags, cblk->data) :
-				  dec_rawsigpass(dec, cblk->nulldec, bpno,
-				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
-				  cblk->flags, cblk->data);
-				break;
-			case JPC_REFPASS:
-				ret = (seg->type == JPC_SEG_MQ) ?
-				  dec_refpass(dec, cblk->mqdec, bpno,
-				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
-				  cblk->flags, cblk->data) :
-				  dec_rawrefpass(dec, cblk->nulldec, bpno,
-				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
-				  cblk->flags, cblk->data);
-				break;
-			case JPC_CLNPASS:
-				assert(seg->type == JPC_SEG_MQ);
-				ret = dec_clnpass(dec, cblk->mqdec, bpno,
-				  band->orient, (tile->cp->ccps[compno].cblkctx &
-				  JPC_COX_VSC) != 0, (tile->cp->ccps[compno].cblkctx &
-				  JPC_COX_SEGSYM) != 0, cblk->flags,
-				  cblk->data);
-				break;
-			default:
-				ret = -1;
-				break;
-			}
-			/* Do we need to reset after each coding pass? */
-			if (tile->cp->ccps[compno].cblkctx & JPC_COX_RESET) {
-				jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
-			}
-
-			if (ret) {
-				fprintf(stderr, "coding pass failed passtype=%d segtype=%d\n", passtype, seg->type);
-				return -1;
-			}
-
-		}
-
-		if (seg->type == JPC_SEG_MQ) {
-/* Note: dont destroy mq decoder because context info will be lost */
-		} else {
-			assert(seg->type == JPC_SEG_RAW);
-			if (tile->cp->ccps[compno].cblkctx & JPC_COX_PTERM) {
-				fillmask = 0x7f;
-				filldata = 0x2a;
-			} else {
-				fillmask = 0;
-				filldata = 0;
-			}
-			if ((ret = jpc_bitstream_inalign(cblk->nulldec, fillmask,
-			  filldata)) < 0) {
-				return -1;
-			} else if (ret > 0) {
-				fprintf(stderr, "warning: bad termination pattern detected\n");
-			}
-			jpc_bitstream_close(cblk->nulldec);
-			cblk->nulldec = 0;
-		}
-
-		cblk->curseg = seg->next;
-		jpc_seglist_remove(&cblk->segs, seg);
-		jpc_seg_destroy(seg);
-		seg = cblk->curseg;
-	}
-
-	assert(dopartial ? (!cblk->curseg) : 1);
-
-premature_exit:
-	return 0;
-}
 
 /******************************************************************************\
 * Code for significance pass.
 \******************************************************************************/
 
-#define	jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf, orient, mqdec, vcausalflag) \
+#define jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf, orient, mqdec, vcausalflag) \
 { \
-	int f; \
-	int v; \
-	f = *(fp); \
-	if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
-		jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO(f, (orient))); \
-		JPC_T1D_GETBIT((mqdec), v, "SIG", "ZC"); \
-		if (v) { \
-			jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \
-			JPC_T1D_GETBIT((mqdec), v, "SIG", "SC"); \
-			v ^= JPC_GETSPB(f); \
-			JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
-			*(fp) |= JPC_SIG; \
-			*(dp) = (v) ? (-(oneplushalf)) : (oneplushalf); \
-		} \
-		*(fp) |= JPC_VISIT; \
-	} \
+    int f; \
+    int v; \
+    f = *(fp); \
+    if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
+        jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO(f, (orient))); \
+        JPC_T1D_GETBIT((mqdec), v, "SIG", "ZC"); \
+        if (v) { \
+            jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \
+            JPC_T1D_GETBIT((mqdec), v, "SIG", "SC"); \
+            v ^= JPC_GETSPB(f); \
+            JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
+            *(fp) |= JPC_SIG; \
+            *(dp) = (v) ? (-(oneplushalf)) : (oneplushalf); \
+        } \
+        *(fp) |= JPC_VISIT; \
+    } \
 }
 
-static int dec_sigpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos, int orient,
-  int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data)
-{
-	int i;
-	int j;
-	int one;
-	int half;
-	int oneplushalf;
-	int vscanlen;
-	int width;
-	int height;
-	jpc_fix_t *fp;
-	int frowstep;
-	int fstripestep;
-	jpc_fix_t *fstripestart;
-	jpc_fix_t *fvscanstart;
-	jpc_fix_t *dp;
-	int drowstep;
-	int dstripestep;
-	jpc_fix_t *dstripestart;
-	jpc_fix_t *dvscanstart;
-	int k;
-
-	width = jas_matrix_numcols(data);
-	height = jas_matrix_numrows(data);
-	frowstep = jas_matrix_rowstep(flags);
-	drowstep = jas_matrix_rowstep(data);
-	fstripestep = frowstep << 2;
-	dstripestep = drowstep << 2;
-
-	one = 1 << bitpos;
-	half = one >> 1;
-	oneplushalf = one | half;
-
-	fstripestart = jas_matrix_getref(flags, 1, 1);
-	dstripestart = jas_matrix_getref(data, 0, 0);
-	for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
-	  dstripestart += dstripestep) {
-		fvscanstart = fstripestart;
-		dvscanstart = dstripestart;
-		vscanlen = JAS_MIN(i, 4);
-		for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
-			fp = fvscanstart;
-			dp = dvscanstart;
-			k = vscanlen;
-
-			/* Process first sample in vertical scan. */
-			jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
-			  orient, mqdec, vcausalflag);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process second sample in vertical scan. */
-			jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
-			  orient, mqdec, 0);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process third sample in vertical scan. */
-			jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
-			  orient, mqdec, 0);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process fourth sample in vertical scan. */
-			jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
-			  orient, mqdec, 0);
-		}
-	}
-	return 0;
+#define jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, in, vcausalflag) \
+{ \
+    jpc_fix_t f = *(fp); \
+    jpc_fix_t v; \
+    if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
+        JPC_T1D_RAWGETBIT(in, v, "SIG", "ZC"); \
+        if (v < 0) { \
+            return -1; \
+        } \
+        if (v) { \
+            JPC_T1D_RAWGETBIT(in, v, "SIG", "SC"); \
+            if (v < 0) { \
+                return -1; \
+            } \
+            JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
+            *(fp) |= JPC_SIG; \
+            *(dp) = v ? (-oneplushalf) : (oneplushalf); \
+        } \
+        *(fp) |= JPC_VISIT; \
+    } \
 }
 
-#define	jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, in, vcausalflag) \
-{ \
-	jpc_fix_t f = *(fp); \
-	jpc_fix_t v; \
-	if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
-		JPC_T1D_RAWGETBIT(in, v, "SIG", "ZC"); \
-		if (v < 0) { \
-			return -1; \
-		} \
-		if (v) { \
-			JPC_T1D_RAWGETBIT(in, v, "SIG", "SC"); \
-			if (v < 0) { \
-				return -1; \
-			} \
-			JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
-			*(fp) |= JPC_SIG; \
-			*(dp) = v ? (-oneplushalf) : (oneplushalf); \
-		} \
-		*(fp) |= JPC_VISIT; \
-	} \
+
+
+static int
+dec_sigpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos,
+            int orient,
+            int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data)
+{
+    int i;
+    int j;
+    int one;
+    int half;
+    int oneplushalf;
+    int vscanlen;
+    int width;
+    int height;
+    jpc_fix_t *fp;
+    int frowstep;
+    int fstripestep;
+    jpc_fix_t *fstripestart;
+    jpc_fix_t *fvscanstart;
+    jpc_fix_t *dp;
+    int drowstep;
+    int dstripestep;
+    jpc_fix_t *dstripestart;
+    jpc_fix_t *dvscanstart;
+    int k;
+
+    width = jas_matrix_numcols(data);
+    height = jas_matrix_numrows(data);
+    frowstep = jas_matrix_rowstep(flags);
+    drowstep = jas_matrix_rowstep(data);
+    fstripestep = frowstep << 2;
+    dstripestep = drowstep << 2;
+
+    one = 1 << bitpos;
+    half = one >> 1;
+    oneplushalf = one | half;
+
+    fstripestart = jas_matrix_getref(flags, 1, 1);
+    dstripestart = jas_matrix_getref(data, 0, 0);
+    for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
+      dstripestart += dstripestep) {
+        fvscanstart = fstripestart;
+        dvscanstart = dstripestart;
+        vscanlen = JAS_MIN(i, 4);
+        for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
+            fp = fvscanstart;
+            dp = dvscanstart;
+            k = vscanlen;
+
+            /* Process first sample in vertical scan. */
+            jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
+              orient, mqdec, vcausalflag);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process second sample in vertical scan. */
+            jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
+              orient, mqdec, 0);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process third sample in vertical scan. */
+            jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
+              orient, mqdec, 0);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process fourth sample in vertical scan. */
+            jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
+              orient, mqdec, 0);
+        }
+    }
+    return 0;
 }
 
-static int dec_rawsigpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, int vcausalflag,
-  jas_matrix_t *flags, jas_matrix_t *data)
+
+
+static int
+dec_rawsigpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos,
+               int vcausalflag,
+               jas_matrix_t *flags, jas_matrix_t *data)
 {
-	int i;
-	int j;
-	int k;
-	int one;
-	int half;
-	int oneplushalf;
-	int vscanlen;
-	int width;
-	int height;
-	jpc_fix_t *fp;
-	int frowstep;
-	int fstripestep;
-	jpc_fix_t *fstripestart;
-	jpc_fix_t *fvscanstart;
-	jpc_fix_t *dp;
-	int drowstep;
-	int dstripestep;
-	jpc_fix_t *dstripestart;
-	jpc_fix_t *dvscanstart;
-
-	width = jas_matrix_numcols(data);
-	height = jas_matrix_numrows(data);
-	frowstep = jas_matrix_rowstep(flags);
-	drowstep = jas_matrix_rowstep(data);
-	fstripestep = frowstep << 2;
-	dstripestep = drowstep << 2;
-
-	one = 1 << bitpos;
-	half = one >> 1;
-	oneplushalf = one | half;
-
-	fstripestart = jas_matrix_getref(flags, 1, 1);
-	dstripestart = jas_matrix_getref(data, 0, 0);
-	for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
-	  dstripestart += dstripestep) {
-		fvscanstart = fstripestart;
-		dvscanstart = dstripestart;
-		vscanlen = JAS_MIN(i, 4);
-		for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
-			fp = fvscanstart;
-			dp = dvscanstart;
-			k = vscanlen;
-
-			/* Process first sample in vertical scan. */
-			jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
-			  in, vcausalflag);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process second sample in vertical scan. */
-			jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
-			  in, 0);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process third sample in vertical scan. */
-			jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
-			  in, 0);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process fourth sample in vertical scan. */
-			jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
-			  in, 0);
-
-		}
-	}
-	return 0;
+    int i;
+    int j;
+    int k;
+    int one;
+    int half;
+    int oneplushalf;
+    int vscanlen;
+    int width;
+    int height;
+    jpc_fix_t *fp;
+    int frowstep;
+    int fstripestep;
+    jpc_fix_t *fstripestart;
+    jpc_fix_t *fvscanstart;
+    jpc_fix_t *dp;
+    int drowstep;
+    int dstripestep;
+    jpc_fix_t *dstripestart;
+    jpc_fix_t *dvscanstart;
+
+    width = jas_matrix_numcols(data);
+    height = jas_matrix_numrows(data);
+    frowstep = jas_matrix_rowstep(flags);
+    drowstep = jas_matrix_rowstep(data);
+    fstripestep = frowstep << 2;
+    dstripestep = drowstep << 2;
+
+    one = 1 << bitpos;
+    half = one >> 1;
+    oneplushalf = one | half;
+
+    fstripestart = jas_matrix_getref(flags, 1, 1);
+    dstripestart = jas_matrix_getref(data, 0, 0);
+    for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
+      dstripestart += dstripestep) {
+        fvscanstart = fstripestart;
+        dvscanstart = dstripestart;
+        vscanlen = JAS_MIN(i, 4);
+        for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
+            fp = fvscanstart;
+            dp = dvscanstart;
+            k = vscanlen;
+
+            /* Process first sample in vertical scan. */
+            jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
+              in, vcausalflag);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process second sample in vertical scan. */
+            jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
+              in, 0);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process third sample in vertical scan. */
+            jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
+              in, 0);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process fourth sample in vertical scan. */
+            jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
+              in, 0);
+
+        }
+    }
+    return 0;
 }
 
+
+
 /******************************************************************************\
 * Code for refinement pass.
 \******************************************************************************/
 
-#define	jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, vcausalflag) \
+#define jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, vcausalflag) \
 { \
-	int v; \
-	int t; \
-	if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
-		jpc_mqdec_setcurctx((mqdec), JPC_GETMAGCTXNO(*(fp))); \
-		JPC_T1D_GETBITNOSKEW((mqdec), v, "REF", "MR"); \
-		t = (v ? (poshalf) : (neghalf)); \
-		*(dp) += (*(dp) < 0) ? (-t) : t; \
-		*(fp) |= JPC_REFINE; \
-	} \
+    int v; \
+    int t; \
+    if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
+        jpc_mqdec_setcurctx((mqdec), JPC_GETMAGCTXNO(*(fp))); \
+        JPC_T1D_GETBITNOSKEW((mqdec), v, "REF", "MR"); \
+        t = (v ? (poshalf) : (neghalf)); \
+        *(dp) += (*(dp) < 0) ? (-t) : t; \
+        *(fp) |= JPC_REFINE; \
+    } \
 }
 
-static int dec_refpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos,
-  int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data)
+
+
+static int
+dec_refpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos,
+            int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data)
 {
-	int i;
-	int j;
-	int vscanlen;
-	int width;
-	int height;
-	int one;
-	int poshalf;
-	int neghalf;
-	jpc_fix_t *fp;
-	int frowstep;
-	int fstripestep;
-	jpc_fix_t *fstripestart;
-	jpc_fix_t *fvscanstart;
-	jpc_fix_t *dp;
-	int drowstep;
-	int dstripestep;
-	jpc_fix_t *dstripestart;
-	jpc_fix_t *dvscanstart;
-	int k;
-
-	width = jas_matrix_numcols(data);
-	height = jas_matrix_numrows(data);
-	frowstep = jas_matrix_rowstep(flags);
-	drowstep = jas_matrix_rowstep(data);
-	fstripestep = frowstep << 2;
-	dstripestep = drowstep << 2;
-
-	one = 1 << bitpos;
-	poshalf = one >> 1;
-	neghalf = (bitpos > 0) ? (-poshalf) : (-1);
-
-	fstripestart = jas_matrix_getref(flags, 1, 1);
-	dstripestart = jas_matrix_getref(data, 0, 0);
-	for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
-	  dstripestart += dstripestep) {
-		fvscanstart = fstripestart;
-		dvscanstart = dstripestart;
-		vscanlen = JAS_MIN(i, 4);
-		for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
-			fp = fvscanstart;
-			dp = dvscanstart;
-			k = vscanlen;
-
-			/* Process first sample in vertical scan. */
-			jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec,
-			  vcausalflag);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process second sample in vertical scan. */
-			jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process third sample in vertical scan. */
-			jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process fourth sample in vertical scan. */
-			jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
-		}
-	}
-
-	return 0;
+    int i;
+    int j;
+    int vscanlen;
+    int width;
+    int height;
+    int one;
+    int poshalf;
+    int neghalf;
+    jpc_fix_t *fp;
+    int frowstep;
+    int fstripestep;
+    jpc_fix_t *fstripestart;
+    jpc_fix_t *fvscanstart;
+    jpc_fix_t *dp;
+    int drowstep;
+    int dstripestep;
+    jpc_fix_t *dstripestart;
+    jpc_fix_t *dvscanstart;
+    int k;
+
+    width = jas_matrix_numcols(data);
+    height = jas_matrix_numrows(data);
+    frowstep = jas_matrix_rowstep(flags);
+    drowstep = jas_matrix_rowstep(data);
+    fstripestep = frowstep << 2;
+    dstripestep = drowstep << 2;
+
+    one = 1 << bitpos;
+    poshalf = one >> 1;
+    neghalf = (bitpos > 0) ? (-poshalf) : (-1);
+
+    fstripestart = jas_matrix_getref(flags, 1, 1);
+    dstripestart = jas_matrix_getref(data, 0, 0);
+    for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
+      dstripestart += dstripestep) {
+        fvscanstart = fstripestart;
+        dvscanstart = dstripestart;
+        vscanlen = JAS_MIN(i, 4);
+        for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
+            fp = fvscanstart;
+            dp = dvscanstart;
+            k = vscanlen;
+
+            /* Process first sample in vertical scan. */
+            jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec,
+              vcausalflag);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process second sample in vertical scan. */
+            jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process third sample in vertical scan. */
+            jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process fourth sample in vertical scan. */
+            jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
+        }
+    }
+
+    return 0;
 }
 
-#define	jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, vcausalflag) \
+#define jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, vcausalflag) \
 { \
-	jpc_fix_t v; \
-	jpc_fix_t t; \
-	if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
-		JPC_T1D_RAWGETBIT(in, v, "REF", "MAGREF"); \
-		if (v < 0) { \
-			return -1; \
-		} \
-		t = (v ? poshalf : neghalf); \
-		*(dp) += (*(dp) < 0) ? (-t) : t; \
-		*(fp) |= JPC_REFINE; \
-	} \
+    jpc_fix_t v; \
+    jpc_fix_t t; \
+    if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
+        JPC_T1D_RAWGETBIT(in, v, "REF", "MAGREF"); \
+        if (v < 0) { \
+            return -1; \
+        } \
+        t = (v ? poshalf : neghalf); \
+        *(dp) += (*(dp) < 0) ? (-t) : t; \
+        *(fp) |= JPC_REFINE; \
+    } \
 }
 
-static int dec_rawrefpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, int vcausalflag,
-  jas_matrix_t *flags, jas_matrix_t *data)
+
+
+static int
+dec_rawrefpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos,
+               int vcausalflag,
+               jas_matrix_t *flags, jas_matrix_t *data)
 {
-	int i;
-	int j;
-	int k;
-	int vscanlen;
-	int width;
-	int height;
-	int one;
-	int poshalf;
-	int neghalf;
-	jpc_fix_t *fp;
-	int frowstep;
-	int fstripestep;
-	jpc_fix_t *fstripestart;
-	jpc_fix_t *fvscanstart;
-	jpc_fix_t *dp;
-	int drowstep;
-	int dstripestep;
-	jpc_fix_t *dstripestart;
-	jpc_fix_t *dvscanstart;
-
-	width = jas_matrix_numcols(data);
-	height = jas_matrix_numrows(data);
-	frowstep = jas_matrix_rowstep(flags);
-	drowstep = jas_matrix_rowstep(data);
-	fstripestep = frowstep << 2;
-	dstripestep = drowstep << 2;
-
-	one = 1 << bitpos;
-	poshalf = one >> 1;
-	neghalf = (bitpos > 0) ? (-poshalf) : (-1);
-
-	fstripestart = jas_matrix_getref(flags, 1, 1);
-	dstripestart = jas_matrix_getref(data, 0, 0);
-	for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
-	  dstripestart += dstripestep) {
-		fvscanstart = fstripestart;
-		dvscanstart = dstripestart;
-		vscanlen = JAS_MIN(i, 4);
-		for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
-			fp = fvscanstart;
-			dp = dvscanstart;
-			k = vscanlen;
-
-			/* Process first sample in vertical scan. */
-			jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in,
-			  vcausalflag);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process second sample in vertical scan. */
-			jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process third sample in vertical scan. */
-			jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process fourth sample in vertical scan. */
-			jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
-		}
-	}
-	return 0;
+    int i;
+    int j;
+    int k;
+    int vscanlen;
+    int width;
+    int height;
+    int one;
+    int poshalf;
+    int neghalf;
+    jpc_fix_t *fp;
+    int frowstep;
+    int fstripestep;
+    jpc_fix_t *fstripestart;
+    jpc_fix_t *fvscanstart;
+    jpc_fix_t *dp;
+    int drowstep;
+    int dstripestep;
+    jpc_fix_t *dstripestart;
+    jpc_fix_t *dvscanstart;
+
+    width = jas_matrix_numcols(data);
+    height = jas_matrix_numrows(data);
+    frowstep = jas_matrix_rowstep(flags);
+    drowstep = jas_matrix_rowstep(data);
+    fstripestep = frowstep << 2;
+    dstripestep = drowstep << 2;
+
+    one = 1 << bitpos;
+    poshalf = one >> 1;
+    neghalf = (bitpos > 0) ? (-poshalf) : (-1);
+
+    fstripestart = jas_matrix_getref(flags, 1, 1);
+    dstripestart = jas_matrix_getref(data, 0, 0);
+    for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
+      dstripestart += dstripestep) {
+        fvscanstart = fstripestart;
+        dvscanstart = dstripestart;
+        vscanlen = JAS_MIN(i, 4);
+        for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
+            fp = fvscanstart;
+            dp = dvscanstart;
+            k = vscanlen;
+
+            /* Process first sample in vertical scan. */
+            jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in,
+              vcausalflag);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process second sample in vertical scan. */
+            jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process third sample in vertical scan. */
+            jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process fourth sample in vertical scan. */
+            jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
+        }
+    }
+    return 0;
 }
 
+
+
 /******************************************************************************\
 * Code for cleanup pass.
 \******************************************************************************/
 
-#define	jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient, mqdec, flabel, plabel, vcausalflag) \
+#define jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient, mqdec, flabel, plabel, vcausalflag) \
 { \
-	int v; \
+    int v; \
 flabel \
-	if (!((f) & (JPC_SIG | JPC_VISIT))) { \
-		jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO((f), (orient))); \
-		JPC_T1D_GETBIT((mqdec), v, "CLN", "ZC"); \
-		if (v) { \
+    if (!((f) & (JPC_SIG | JPC_VISIT))) { \
+        jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO((f), (orient))); \
+        JPC_T1D_GETBIT((mqdec), v, "CLN", "ZC"); \
+        if (v) { \
 plabel \
-			/* Coefficient is significant. */ \
-			jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \
-			JPC_T1D_GETBIT((mqdec), v, "CLN", "SC"); \
-			v ^= JPC_GETSPB(f); \
-			*(dp) = (v) ? (-(oneplushalf)) : (oneplushalf); \
-			JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
-			*(fp) |= JPC_SIG; \
-		} \
-	} \
-	/* XXX - Is this correct?  Can aggregation cause some VISIT bits not to be reset?  Check. */ \
-	*(fp) &= ~JPC_VISIT; \
+            /* Coefficient is significant. */ \
+            jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \
+            JPC_T1D_GETBIT((mqdec), v, "CLN", "SC"); \
+            v ^= JPC_GETSPB(f); \
+            *(dp) = (v) ? (-(oneplushalf)) : (oneplushalf); \
+            JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
+            *(fp) |= JPC_SIG; \
+        } \
+    } \
+    /* XXX - Is this correct?  Can aggregation cause some VISIT bits not to be reset?  Check. */ \
+    *(fp) &= ~JPC_VISIT; \
 }
 
-static int dec_clnpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos, int orient,
-  int vcausalflag, int segsymflag, jas_matrix_t *flags, jas_matrix_t *data)
+static int
+dec_clnpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos,
+            int orient, int vcausalflag, int segsymflag, jas_matrix_t *flags,
+            jas_matrix_t *data)
 {
-	int i;
-	int j;
-	int k;
-	int vscanlen;
-	int v;
-	int half;
-	int runlen;
-	int f;
-	int width;
-	int height;
-	int one;
-	int oneplushalf;
-
-	jpc_fix_t *fp;
-	int frowstep;
-	int fstripestep;
-	jpc_fix_t *fstripestart;
-	jpc_fix_t *fvscanstart;
-
-	jpc_fix_t *dp;
-	int drowstep;
-	int dstripestep;
-	jpc_fix_t *dstripestart;
-	jpc_fix_t *dvscanstart;
-
-	one = 1 << bitpos;
-	half = one >> 1;
-	oneplushalf = one | half;
-
-	width = jas_matrix_numcols(data);
-	height = jas_matrix_numrows(data);
-
-	frowstep = jas_matrix_rowstep(flags);
-	drowstep = jas_matrix_rowstep(data);
-	fstripestep = frowstep << 2;
-	dstripestep = drowstep << 2;
-
-	fstripestart = jas_matrix_getref(flags, 1, 1);
-	dstripestart = jas_matrix_getref(data, 0, 0);
-	for (i = 0; i < height; i += 4, fstripestart += fstripestep,
-	  dstripestart += dstripestep) {
-		fvscanstart = fstripestart;
-		dvscanstart = dstripestart;
-		vscanlen = JAS_MIN(4, height - i);
-		for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
-			fp = fvscanstart;
-			if (vscanlen >= 4 && (!((*fp) & (JPC_SIG | JPC_VISIT |
-			  JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) & (JPC_SIG |
-			  JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) &
-			  (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep,
-			  !((*fp) & (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK)))) {
-
-				jpc_mqdec_setcurctx(mqdec, JPC_AGGCTXNO);
-				JPC_T1D_GETBIT(mqdec, v, "CLN", "AGG");
-				if (!v) {
-					continue;
-				}
-				jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
-				JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL");
-				runlen = v;
-				JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL");
-				runlen = (runlen << 1) | v;
-				f = *(fp = fvscanstart + frowstep * runlen);
-				dp = dvscanstart + drowstep * runlen;
-				k = vscanlen - runlen;
-				switch (runlen) {
-				case 0:
-					goto clnpass_partial0;
-					break;
-				case 1:
-					goto clnpass_partial1;
-					break;
-				case 2:
-					goto clnpass_partial2;
-					break;
-				case 3:
-					goto clnpass_partial3;
-					break;
-				}
-			} else {
-				f = *(fp = fvscanstart);
-				dp = dvscanstart;
-				k = vscanlen;
-				goto clnpass_full0;
-			}
-
-			/* Process first sample in vertical scan. */
-			jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
-			  mqdec, clnpass_full0:, clnpass_partial0:,
-			  vcausalflag);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process second sample in vertical scan. */
-			f = *fp;
-			jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
-				mqdec, ;, clnpass_partial1:, 0);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process third sample in vertical scan. */
-			f = *fp;
-			jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
-				mqdec, ;, clnpass_partial2:, 0);
-			if (--k <= 0) {
-				continue;
-			}
-			fp += frowstep;
-			dp += drowstep;
-
-			/* Process fourth sample in vertical scan. */
-			f = *fp;
-			jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
-				mqdec, ;, clnpass_partial3:, 0);
-		}
-	}
-
-	if (segsymflag) {
-		int segsymval;
-		segsymval = 0;
-		jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
-		JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
-		segsymval = (segsymval << 1) | (v & 1);
-		JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
-		segsymval = (segsymval << 1) | (v & 1);
-		JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
-		segsymval = (segsymval << 1) | (v & 1);
-		JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
-		segsymval = (segsymval << 1) | (v & 1);
-		if (segsymval != 0xa) {
-			fprintf(stderr, "warning: bad segmentation symbol\n");
-		}
-	}
-
-	return 0;
+    int i;
+    int j;
+    int k;
+    int vscanlen;
+    int v;
+    int half;
+    int runlen;
+    int f;
+    int width;
+    int height;
+    int one;
+    int oneplushalf;
+
+    jpc_fix_t *fp;
+    int frowstep;
+    int fstripestep;
+    jpc_fix_t *fstripestart;
+    jpc_fix_t *fvscanstart;
+
+    jpc_fix_t *dp;
+    int drowstep;
+    int dstripestep;
+    jpc_fix_t *dstripestart;
+    jpc_fix_t *dvscanstart;
+
+    one = 1 << bitpos;
+    half = one >> 1;
+    oneplushalf = one | half;
+
+    width = jas_matrix_numcols(data);
+    height = jas_matrix_numrows(data);
+
+    frowstep = jas_matrix_rowstep(flags);
+    drowstep = jas_matrix_rowstep(data);
+    fstripestep = frowstep << 2;
+    dstripestep = drowstep << 2;
+
+    fstripestart = jas_matrix_getref(flags, 1, 1);
+    dstripestart = jas_matrix_getref(data, 0, 0);
+    for (i = 0; i < height; i += 4, fstripestart += fstripestep,
+      dstripestart += dstripestep) {
+        fvscanstart = fstripestart;
+        dvscanstart = dstripestart;
+        vscanlen = JAS_MIN(4, height - i);
+        for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
+            fp = fvscanstart;
+            if (vscanlen >= 4 && (!((*fp) & (JPC_SIG | JPC_VISIT |
+              JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) & (JPC_SIG |
+              JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) &
+              (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep,
+              !((*fp) & (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK)))) {
+
+                jpc_mqdec_setcurctx(mqdec, JPC_AGGCTXNO);
+                JPC_T1D_GETBIT(mqdec, v, "CLN", "AGG");
+                if (!v) {
+                    continue;
+                }
+                jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
+                JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL");
+                runlen = v;
+                JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL");
+                runlen = (runlen << 1) | v;
+                f = *(fp = fvscanstart + frowstep * runlen);
+                dp = dvscanstart + drowstep * runlen;
+                k = vscanlen - runlen;
+                switch (runlen) {
+                case 0:
+                    goto clnpass_partial0;
+                    break;
+                case 1:
+                    goto clnpass_partial1;
+                    break;
+                case 2:
+                    goto clnpass_partial2;
+                    break;
+                case 3:
+                    goto clnpass_partial3;
+                    break;
+                }
+            } else {
+                f = *(fp = fvscanstart);
+                dp = dvscanstart;
+                k = vscanlen;
+                goto clnpass_full0;
+            }
+
+            /* Process first sample in vertical scan. */
+            jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
+              mqdec, clnpass_full0:, clnpass_partial0:,
+              vcausalflag);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process second sample in vertical scan. */
+            f = *fp;
+            jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
+                mqdec, ;, clnpass_partial1:, 0);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process third sample in vertical scan. */
+            f = *fp;
+            jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
+                mqdec, ;, clnpass_partial2:, 0);
+            if (--k <= 0) {
+                continue;
+            }
+            fp += frowstep;
+            dp += drowstep;
+
+            /* Process fourth sample in vertical scan. */
+            f = *fp;
+            jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
+                mqdec, ;, clnpass_partial3:, 0);
+        }
+    }
+
+    if (segsymflag) {
+        int segsymval;
+        segsymval = 0;
+        jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
+        JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
+        segsymval = (segsymval << 1) | (v & 1);
+        JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
+        segsymval = (segsymval << 1) | (v & 1);
+        JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
+        segsymval = (segsymval << 1) | (v & 1);
+        JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
+        segsymval = (segsymval << 1) | (v & 1);
+        if (segsymval != 0xa) {
+            fprintf(stderr, "warning: bad segmentation symbol\n");
+        }
+    }
+
+    return 0;
+}
+
+
+
+static void
+jpc_dec_decodecblk(jpc_dec_t *       const dec,
+                   jpc_dec_tile_t *  const tile,
+                   jpc_dec_tcomp_t * const tcomp,
+                   jpc_dec_band_t *  const band,
+                   jpc_dec_cblk_t *  const cblk,
+                   int               const dopartial,
+                   int               const maxlyrs,
+                   const char **     const errorP) {
+
+    jpc_dec_seg_t *seg;
+    int i;
+    int bpno;
+    int passtype;
+    int ret;
+    int compno;
+    int filldata;
+    int fillmask;
+    jpc_dec_ccp_t *ccp;
+
+    compno = tcomp - tile->tcomps;
+
+    if (!cblk->flags) {
+        /* Note: matrix is assumed to be zeroed */
+        unsigned int const nrow = jas_matrix_numrows(cblk->data) + 2;
+        unsigned int const ncol = jas_matrix_numcols(cblk->data) + 2;
+        cblk->flags = jas_matrix_create(nrow, ncol);
+        if (!cblk->flags) {
+            pm_asprintf(errorP, "Out of memory allocating a flags matrix of "
+                        "%u rows by %u columns", nrow, ncol);
+            return;
+        }
+    }
+
+    seg = cblk->segs.head;
+    while (seg && (seg != cblk->curseg || dopartial) && (maxlyrs < 0 ||
+      seg->lyrno < maxlyrs)) {
+        assert(seg->numpasses >= seg->maxpasses || dopartial);
+        assert(seg->stream);
+        jas_stream_rewind(seg->stream);
+        jas_stream_setrwcount(seg->stream, 0);
+        if (seg->type == JPC_SEG_MQ) {
+            if (!cblk->mqdec) {
+                if (!(cblk->mqdec = jpc_mqdec_create(JPC_NUMCTXS, 0))) {
+                    pm_asprintf(errorP, "jpc_mqdec_create failed");
+                    return;
+                }
+                jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
+            }
+            jpc_mqdec_setinput(cblk->mqdec, seg->stream);
+            jpc_mqdec_init(cblk->mqdec);
+        } else {
+            assert(seg->type == JPC_SEG_RAW);
+            if (!cblk->nulldec) {
+                if (!(cblk->nulldec = jpc_bitstream_sopen(seg->stream, "r"))) {
+                    assert(0);
+                }
+            }
+        }
+
+
+        for (i = 0; i < seg->numpasses; ++i) {
+            if (cblk->numimsbs > band->numbps) {
+                ccp = &tile->cp->ccps[compno];
+                if (ccp->roishift <= 0) {
+                    fprintf(stderr, "warning: corrupt code stream\n");
+                } else {
+                    if (cblk->numimsbs < ccp->roishift - band->numbps) {
+                        fprintf(stderr, "warning: corrupt code stream\n");
+                    }
+                }
+            }
+            bpno = band->roishift + band->numbps - 1 - (cblk->numimsbs +
+              (seg->passno + i - cblk->firstpassno + 2) / 3);
+            if (bpno < 0) {
+                goto exit;
+            }
+#if 1
+            passtype = (seg->passno + i + 2) % 3;
+#else
+            passtype = JPC_PASSTYPE(seg->passno + i + 2);
+#endif
+            assert(bpno >= 0 && bpno < 31);
+            switch (passtype) {
+            case JPC_SIGPASS:
+                ret = (seg->type == JPC_SEG_MQ) ? dec_sigpass(dec,
+                  cblk->mqdec, bpno, band->orient,
+                  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
+                  cblk->flags, cblk->data) :
+                  dec_rawsigpass(dec, cblk->nulldec, bpno,
+                  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
+                  cblk->flags, cblk->data);
+                break;
+            case JPC_REFPASS:
+                ret = (seg->type == JPC_SEG_MQ) ?
+                  dec_refpass(dec, cblk->mqdec, bpno,
+                  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
+                  cblk->flags, cblk->data) :
+                  dec_rawrefpass(dec, cblk->nulldec, bpno,
+                  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
+                  cblk->flags, cblk->data);
+                break;
+            case JPC_CLNPASS:
+                assert(seg->type == JPC_SEG_MQ);
+                ret = dec_clnpass(dec, cblk->mqdec, bpno,
+                  band->orient, (tile->cp->ccps[compno].cblkctx &
+                  JPC_COX_VSC) != 0, (tile->cp->ccps[compno].cblkctx &
+                  JPC_COX_SEGSYM) != 0, cblk->flags,
+                  cblk->data);
+                break;
+            default:
+                ret = -1;
+                break;
+            }
+            /* Do we need to reset after each coding pass? */
+            if (tile->cp->ccps[compno].cblkctx & JPC_COX_RESET) {
+                jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
+            }
+
+            if (ret) {
+                pm_asprintf(errorP,
+                            "coding pass failed passtype=%d segtype=%d",
+                            passtype, seg->type);
+                return;
+            }
+
+        }
+
+        if (seg->type == JPC_SEG_MQ) {
+            /* Note: dont destroy mq decoder because context info will be
+               lost
+            */
+        } else {
+            assert(seg->type == JPC_SEG_RAW);
+            if (tile->cp->ccps[compno].cblkctx & JPC_COX_PTERM) {
+                fillmask = 0x7f;
+                filldata = 0x2a;
+            } else {
+                fillmask = 0;
+                filldata = 0;
+            }
+            if ((ret = jpc_bitstream_inalign(cblk->nulldec, fillmask,
+              filldata)) < 0) {
+                pm_asprintf(errorP, "jpc_bitstream_inalign failed");
+                return;
+            } else if (ret > 0) {
+                pm_message("warning: bad termination pattern detected");
+            }
+            jpc_bitstream_close(cblk->nulldec);
+            cblk->nulldec = 0;
+        }
+
+        cblk->curseg = seg->next;
+        jpc_seglist_remove(&cblk->segs, seg);
+        jpc_seg_destroy(seg);
+        seg = cblk->curseg;
+    }
+
+    assert(dopartial ? (!cblk->curseg) : 1);
+
+exit:
+    *errorP = NULL;
 }
+
+
+
+void
+jpc_dec_decodecblks(jpc_dec_t *      const decP,
+                    jpc_dec_tile_t * const tileP,
+                    const char **    const errorP) {
+/*----------------------------------------------------------------------------
+  Decode all of the code blocks for a particular tile
+-----------------------------------------------------------------------------*/
+    unsigned int compcnt;
+    jpc_dec_tcomp_t * tcompP;
+
+    for (compcnt = 0, tcompP = tileP->tcomps;
+         compcnt < decP->numcomps;
+         ++compcnt, ++tcompP) {
+
+        unsigned int rlvlcnt;
+        jpc_dec_rlvl_t * rlvlP;
+
+        for (rlvlcnt = 0, rlvlP = tcompP->rlvls;
+             rlvlcnt < tcompP->numrlvls;
+             ++rlvlcnt, ++rlvlP) {
+
+            if (rlvlP->bands) {
+                unsigned int bandcnt;
+                jpc_dec_band_t * bandP;
+
+                for (bandcnt = 0, bandP = rlvlP->bands;
+                     bandcnt < rlvlP->numbands;
+                     ++bandcnt, ++bandP) {
+
+                    if (bandP->data) {
+                        unsigned int prccnt;
+                        jpc_dec_prc_t * prcP;
+
+                        for (prccnt = 0, prcP = bandP->prcs;
+                             prccnt < rlvlP->numprcs;
+                             ++prccnt, ++prcP) {
+
+                            if (prcP->cblks) {
+                                unsigned int cblkcnt;
+                                jpc_dec_cblk_t * cblkP;
+
+                                for (cblkcnt = 0, cblkP = prcP->cblks;
+                                     cblkcnt < prcP->numcblks;
+                                     ++cblkcnt, ++cblkP) {
+
+                                    const char * error;
+
+                                    jpc_dec_decodecblk(decP, tileP, tcompP,
+                                                       bandP, cblkP, 1,
+                                                       JPC_MAXLYRS, &error);
+                                    if (error) {
+                                        pm_asprintf(errorP,
+                                                    "jpc_dec_decodecblk "
+                                                    "failed on component %u, "
+                                                    "resolution level %u, "
+                                                    "band %u, prc %u, "
+                                                    "code block %u.  %s",
+                                                    compcnt, rlvlcnt, bandcnt,
+                                                    prccnt, cblkcnt, error);
+                                        pm_strfree(error);
+                                        return;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    *errorP = NULL;
+}
+
diff --git a/converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.h b/converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.h
index e28a1f57..f8b3b342 100644
--- a/converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.h
+++ b/converter/other/jpeg2000/libjasper/jpc/jpc_t1dec.h
@@ -119,19 +119,13 @@
 #ifndef JPC_T1DEC_H
 #define JPC_T1DEC_H
 
-/******************************************************************************\
-* Includes.
-\******************************************************************************/
-
 #include "jpc_dec.h"
 #include "jpc_mqdec.h"
 #include "jpc_t1cod.h"
 
-/******************************************************************************\
-* Functions.
-\******************************************************************************/
-
-/* Decode all of the code blocks for a particular tile. */
-int jpc_dec_decodecblks(jpc_dec_t *dec, jpc_dec_tile_t *tile);
+void
+jpc_dec_decodecblks(jpc_dec_t *      const decP,
+                    jpc_dec_tile_t * const tileP,
+                    const char **    const errorP);
 
 #endif
diff --git a/converter/other/jpeg2000/libjasper_compat.c b/converter/other/jpeg2000/libjasper_compat.c
new file mode 100644
index 00000000..101820a3
--- /dev/null
+++ b/converter/other/jpeg2000/libjasper_compat.c
@@ -0,0 +1,26 @@
+#include "netpbm/nstring.h"
+
+#include "jasper/jasper.h"
+#include "jasper/jas_image.h"
+
+#ifndef JAS_HAVE_PMJAS_IMAGE_DECODE
+
+void
+pmjas_image_decode(jas_stream_t * const in,
+                   int            const fmtArg,
+                   const char *   const optstr,
+                   jas_image_t ** const imagePP,
+                   const char **  const errorP) {
+
+    jas_image_t * const jasperP = jas_image_decode(in, fmtArg, optstr);
+
+    if (jasperP) {
+        *imagePP = jasperP;
+        *errorP  = errorP;
+    } else {
+        pm_asprintf(errorP, "Failed.  Details may have been written to "
+                    "Standard Error");
+    }
+}
+
+#endif
diff --git a/converter/other/jpeg2000/libjasper_compat.h b/converter/other/jpeg2000/libjasper_compat.h
index 401144a3..45dd904b 100644
--- a/converter/other/jpeg2000/libjasper_compat.h
+++ b/converter/other/jpeg2000/libjasper_compat.h
@@ -1,12 +1,18 @@
 /* Here's some stuff to create backward compatibility with older Jasper
    libraries.  Unfortunately, new versions of the Jasper library are not
    backward compatible with old applications.
+
+   This also makes the programs compatible with both distributed Jasper
+   libraries and the Netpbm fork of Jasper distributed with Netpbm.
 */
 /* The color space thing got more complex between Version 1.600 and
    1.701.  For example, it now allows for multiple kinds of RGB, whereas
    in 1.600 RGB meant SRGB.  As part of that change, names changed
    from "colorspace" to "clrspc".
 */
+#include "jasper/jasper.h"
+#include "jasper/jas_image.h"
+
 #if defined(jas_image_setcolorspace)
 /* Old style color space */
 #define jas_image_setclrspc jas_image_setcolorspace
@@ -22,3 +28,32 @@
 #define JAS_CLRSPC_FAM_UNKNOWN JAS_IMAGE_CS_UNKNOWN
 
 #endif
+
+
+#ifndef JAS_HAVE_PMJAS_IMAGE_DECODE
+
+/* The Netpbm version of jas_image_decode (pmjas_image_decode) returns a
+   description of the problem when it fails and does not molest Standard
+   Error.  Real libjasper just indicates that it failed, after writing some
+   explanation (but not as much as the Netpbm version returns) to Standard
+   Error.
+*/
+void
+pmjas_image_decode(jas_stream_t * const in,
+                   int            const fmtArg,
+                   const char *   const optstr,
+                   jas_image_t ** const imagePP,
+                   const char **  const errorP) {
+
+    jas_image_t * const jasperP = jas_image_decode(in, fmtArg, optstr);
+
+    if (jasperP) {
+        *imagePP = jasperP;
+        *errorP  = errorP;
+    } else {
+        pm_asprintf(errorP, "Failed.  Details may have been written to "
+                    "Standard Error");
+    }
+}
+
+#endif