Update to 2.0.0 tree from current Fremantle build
[opencv] / otherlibs / _graphics / src / libjasper / jpc_dec.c
diff --git a/otherlibs/_graphics/src/libjasper/jpc_dec.c b/otherlibs/_graphics/src/libjasper/jpc_dec.c
deleted file mode 100644 (file)
index a3ae344..0000000
+++ /dev/null
@@ -1,2305 +0,0 @@
-/*
- * Copyright (c) 1999-2000 Image Power, Inc. and the University of
- *   British Columbia.
- * Copyright (c) 2001-2003 Michael David Adams.
- * All rights reserved.
- */
-
-/* __START_OF_JASPER_LICENSE__
- * 
- * JasPer License Version 2.0
- * 
- * Copyright (c) 2001-2006 Michael David Adams
- * Copyright (c) 1999-2000 Image Power, Inc.
- * Copyright (c) 1999-2000 The University of British Columbia
- * 
- * All rights reserved.
- * 
- * Permission is hereby granted, free of charge, to any person (the
- * "User") obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, and/or sell copies of the Software, and to permit
- * persons to whom the Software is furnished to do so, subject to the
- * following conditions:
- * 
- * 1.  The above copyright notices and this permission notice (which
- * includes the disclaimer below) shall be included in all copies or
- * substantial portions of the Software.
- * 
- * 2.  The name of a copyright holder shall not be used to endorse or
- * promote products derived from the Software without specific prior
- * written permission.
- * 
- * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
- * LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
- * THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
- * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
- * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
- * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE
- * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
- * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
- * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
- * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
- * PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS
- * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
- * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE
- * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
- * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
- * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
- * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
- * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
- * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
- * RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
- * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
- * 
- * __END_OF_JASPER_LICENSE__
- */
-
-/*
- * $Id: jpc_dec.c,v 1.2 2008/05/26 09:40:52 vp153 Exp $
- */
-
-/******************************************************************************\
-* Includes.
-\******************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#include "jasper/jas_types.h"
-#include "jasper/jas_math.h"
-#include "jasper/jas_tvp.h"
-#include "jasper/jas_malloc.h"
-#include "jasper/jas_debug.h"
-
-#include "jpc_fix.h"
-#include "jpc_dec.h"
-#include "jpc_cs.h"
-#include "jpc_mct.h"
-#include "jpc_t2dec.h"
-#include "jpc_t1dec.h"
-#include "jpc_math.h"
-
-/******************************************************************************\
-*
-\******************************************************************************/
-
-#define        JPC_MHSOC       0x0001
-  /* In the main header, expecting a SOC marker segment. */
-#define        JPC_MHSIZ       0x0002
-  /* In the main header, expecting a SIZ marker segment. */
-#define        JPC_MH          0x0004
-  /* In the main header, expecting "other" marker segments. */
-#define        JPC_TPHSOT      0x0008
-  /* In a tile-part header, expecting a SOT marker segment. */
-#define        JPC_TPH         0x0010
-  /* In a tile-part header, expecting "other" marker segments. */
-#define        JPC_MT          0x0020
-  /* In the main trailer. */
-
-typedef struct {
-
-       uint_fast16_t id;
-       /* The marker segment type. */
-
-       int validstates;
-       /* The states in which this type of marker segment can be
-         validly encountered. */
-
-       int (*action)(jpc_dec_t *dec, jpc_ms_t *ms);
-       /* The action to take upon encountering this type of marker segment. */
-
-} jpc_dec_mstabent_t;
-
-/******************************************************************************\
-*
-\******************************************************************************/
-
-/* COD/COC parameters have been specified. */
-#define        JPC_CSET        0x0001
-/* QCD/QCC parameters have been specified. */
-#define        JPC_QSET        0x0002
-/* COD/COC parameters set from a COC marker segment. */
-#define        JPC_COC 0x0004
-/* QCD/QCC parameters set from a QCC marker segment. */
-#define        JPC_QCC 0x0008
-
-/******************************************************************************\
-* Local function prototypes.
-\******************************************************************************/
-
-static int jpc_dec_dump(jpc_dec_t *dec, FILE *out);
-
-jpc_ppxstab_t *jpc_ppxstab_create(void);
-void jpc_ppxstab_destroy(jpc_ppxstab_t *tab);
-int jpc_ppxstab_grow(jpc_ppxstab_t *tab, int maxents);
-int jpc_ppxstab_insert(jpc_ppxstab_t *tab, jpc_ppxstabent_t *ent);
-jpc_streamlist_t *jpc_ppmstabtostreams(jpc_ppxstab_t *tab);
-int jpc_pptstabwrite(jas_stream_t *out, jpc_ppxstab_t *tab);
-jpc_ppxstabent_t *jpc_ppxstabent_create(void);
-void jpc_ppxstabent_destroy(jpc_ppxstabent_t *ent);
-
-int jpc_streamlist_numstreams(jpc_streamlist_t *streamlist);
-jpc_streamlist_t *jpc_streamlist_create(void);
-int jpc_streamlist_insert(jpc_streamlist_t *streamlist, int streamno,
-  jas_stream_t *stream);
-jas_stream_t *jpc_streamlist_remove(jpc_streamlist_t *streamlist, int streamno);
-void jpc_streamlist_destroy(jpc_streamlist_t *streamlist);
-jas_stream_t *jpc_streamlist_get(jpc_streamlist_t *streamlist, int streamno);
-
-static void jpc_dec_cp_resetflags(jpc_dec_cp_t *cp);
-static jpc_dec_cp_t *jpc_dec_cp_create(uint_fast16_t numcomps);
-static int jpc_dec_cp_isvalid(jpc_dec_cp_t *cp);
-static jpc_dec_cp_t *jpc_dec_cp_copy(jpc_dec_cp_t *cp);
-static int jpc_dec_cp_setfromcod(jpc_dec_cp_t *cp, jpc_cod_t *cod);
-static int jpc_dec_cp_setfromcoc(jpc_dec_cp_t *cp, jpc_coc_t *coc);
-static int jpc_dec_cp_setfromcox(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp,
-  jpc_coxcp_t *compparms, int flags);
-static int jpc_dec_cp_setfromqcd(jpc_dec_cp_t *cp, jpc_qcd_t *qcd);
-static int jpc_dec_cp_setfromqcc(jpc_dec_cp_t *cp, jpc_qcc_t *qcc);
-static int jpc_dec_cp_setfromqcx(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp,
-  jpc_qcxcp_t *compparms, int flags);
-static int jpc_dec_cp_setfromrgn(jpc_dec_cp_t *cp, jpc_rgn_t *rgn);
-static int jpc_dec_cp_prepare(jpc_dec_cp_t *cp);
-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);
-
-static jpc_dec_mstabent_t *jpc_dec_mstab_lookup(uint_fast16_t id);
-
-/******************************************************************************\
-* 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.
-\******************************************************************************/
-
-jas_image_t *jpc_decode(jas_stream_t *in, char *optstr)
-{
-       jpc_dec_importopts_t opts;
-       jpc_dec_t *dec;
-       jas_image_t *image;
-
-       dec = 0;
-
-       if (jpc_dec_parseopts(optstr, &opts)) {
-               goto error;
-       }
-
-       jpc_initluts();
-
-       if (!(dec = jpc_dec_create(&opts, in))) {
-               goto error;
-       }
-
-       /* Do most of the work. */
-       if (jpc_dec_decode(dec)) {
-               goto error;
-       }
-
-       if (jas_image_numcmpts(dec->image) >= 3) {
-               jas_image_setclrspc(dec->image, JAS_CLRSPC_SRGB);
-               jas_image_setcmpttype(dec->image, 0,
-                 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
-               jas_image_setcmpttype(dec->image, 1,
-                 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
-               jas_image_setcmpttype(dec->image, 2,
-                 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
-       } else {
-               jas_image_setclrspc(dec->image, JAS_CLRSPC_SGRAY);
-               jas_image_setcmpttype(dec->image, 0,
-                 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
-       }
-
-       /* Save the return value. */
-       image = dec->image;
-
-       /* Stop the image from being discarded. */
-       dec->image = 0;
-
-       /* Destroy decoder. */
-       jpc_dec_destroy(dec);
-
-       return image;
-
-error:
-       if (dec) {
-               jpc_dec_destroy(dec);
-       }
-       return 0;
-}
-
-typedef enum {
-       OPT_MAXLYRS,
-       OPT_MAXPKTS,
-       OPT_DEBUG
-} optid_t;
-
-jas_taginfo_t decopts[] = {
-       {OPT_MAXLYRS, "maxlyrs"},
-       {OPT_MAXPKTS, "maxpkts"},
-       {OPT_DEBUG, "debug"},
-       {-1, 0}
-};
-
-static int jpc_dec_parseopts(char *optstr, jpc_dec_importopts_t *opts)
-{
-       jas_tvparser_t *tvp;
-
-       opts->debug = 0;
-       opts->maxlyrs = JPC_MAXLYRS;
-       opts->maxpkts = -1;
-
-       if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) {
-               return -1;
-       }
-
-       while (!jas_tvparser_next(tvp)) {
-               switch (jas_taginfo_nonull(jas_taginfos_lookup(decopts,
-                 jas_tvparser_gettag(tvp)))->id) {
-               case OPT_MAXLYRS:
-                       opts->maxlyrs = atoi(jas_tvparser_getval(tvp));
-                       break;
-               case OPT_DEBUG:
-                       opts->debug = atoi(jas_tvparser_getval(tvp));
-                       break;
-               case OPT_MAXPKTS:
-                       opts->maxpkts = atoi(jas_tvparser_getval(tvp));
-                       break;
-               default:
-                       jas_eprintf("warning: ignoring invalid option %s\n",
-                         jas_tvparser_gettag(tvp));
-                       break;
-               }
-       }
-
-       jas_tvparser_destroy(tvp);
-
-       return 0;
-}
-
-/******************************************************************************\
-* 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))) {
-                       jas_eprintf("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)) {
-                       jas_eprintf("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 int jpc_dec_process_crg(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       int cmptno;
-       jpc_dec_cmpt_t *cmpt;
-       jpc_crg_t *crg;
-
-       crg = &ms->parms.crg;
-       for (cmptno = 0, cmpt = dec->cmpts; cmptno < dec->numcomps; ++cmptno,
-         ++cmpt) {
-               /* 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
-                 are uncommented.
-               cmpt->hsubstep = crg->comps[cmptno].hoff;
-               cmpt->vsubstep = crg->comps[cmptno].voff;
-               */
-       }
-       return 0;
-}
-
-static int jpc_dec_process_soc(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       /* Eliminate warnings about unused variables. */
-       ms = 0;
-
-       /* We should expect to encounter a SIZ marker segment next. */
-       dec->state = JPC_MHSIZ;
-
-       return 0;
-}
-
-static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       jpc_dec_tile_t *tile;
-       jpc_sot_t *sot = &ms->parms.sot;
-       jas_image_cmptparm_t *compinfos;
-       jas_image_cmptparm_t *compinfo;
-       jpc_dec_cmpt_t *cmpt;
-       int cmptno;
-
-       if (dec->state == JPC_MH) {
-
-               compinfos = jas_malloc(dec->numcomps * sizeof(jas_image_cmptparm_t));
-               assert(compinfos);
-               for (cmptno = 0, cmpt = dec->cmpts, compinfo = compinfos;
-                 cmptno < dec->numcomps; ++cmptno, ++cmpt, ++compinfo) {
-                       compinfo->tlx = 0;
-                       compinfo->tly = 0;
-                       compinfo->prec = cmpt->prec;
-                       compinfo->sgnd = cmpt->sgnd;
-                       compinfo->width = cmpt->width;
-                       compinfo->height = cmpt->height;
-                       compinfo->hstep = cmpt->hstep;
-                       compinfo->vstep = cmpt->vstep;
-               }
-
-               if (!(dec->image = jas_image_create(dec->numcomps, compinfos,
-                 JAS_CLRSPC_UNKNOWN))) {
-                       return -1;
-               }
-               jas_free(compinfos);
-
-               /* Is the packet header information stored in PPM marker segments in
-                 the main header? */
-               if (dec->ppmstab) {
-                       /* Convert the PPM marker segment data into a collection of streams
-                         (one stream per tile-part). */
-                       if (!(dec->pkthdrstreams = jpc_ppmstabtostreams(dec->ppmstab))) {
-                               abort();
-                       }
-                       jpc_ppxstab_destroy(dec->ppmstab);
-                       dec->ppmstab = 0;
-               }
-       }
-
-       if (sot->len > 0) {
-               dec->curtileendoff = jas_stream_getrwcount(dec->in) - ms->len -
-                 4 + sot->len;
-       } else {
-               dec->curtileendoff = 0;
-       }
-
-       if (JAS_CAST(int, sot->tileno) > dec->numtiles) {
-               jas_eprintf("invalid tile number in SOT marker segment\n");
-               return -1;
-       }
-       /* 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;
-       }
-       if (tile->numparts > 0 && sot->partno >= tile->numparts) {
-               return -1;
-       }
-       if (!tile->numparts && sot->numparts > 0) {
-               tile->numparts = sot->numparts;
-       }
-
-       tile->pptstab = 0;
-
-       switch (tile->state) {
-       case JPC_TILE_INIT:
-               /* This is the first tile-part for this tile. */
-               tile->state = JPC_TILE_ACTIVE;
-               assert(!tile->cp);
-               if (!(tile->cp = jpc_dec_cp_copy(dec->cp))) {
-                       return -1;
-               }
-               jpc_dec_cp_resetflags(dec->cp);
-               break;
-       default:
-               if (sot->numparts == sot->partno - 1) {
-                       tile->state = JPC_TILE_ACTIVELAST;
-               }
-               break;
-       }
-
-       /* Note: We do not increment the expected tile-part number until
-         all processing for this tile-part is complete. */
-
-       /* We should expect to encounter other tile-part header marker
-         segments next. */
-       dec->state = JPC_TPH;
-
-       return 0;
-}
-
-static int jpc_dec_process_sod(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       jpc_dec_tile_t *tile;
-       int pos;
-
-       /* Eliminate compiler warnings about unused variables. */
-       ms = 0;
-
-       if (!(tile = dec->curtile)) {
-               return -1;
-       }
-
-       if (!tile->partno) {
-               if (!jpc_dec_cp_isvalid(tile->cp)) {
-                       return -1;
-               }
-               jpc_dec_cp_prepare(tile->cp);
-               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)) {
-               jas_eprintf("jpc_dec_decodepkts failed\n");
-               return -1;
-       }
-
-       /* Gobble any unconsumed tile data. */
-       if (dec->curtileendoff > 0) {
-               long curoff;
-               uint_fast32_t n;
-               curoff = jas_stream_getrwcount(dec->in);
-               if (curoff < dec->curtileendoff) {
-                       n = dec->curtileendoff - curoff;
-                       jas_eprintf("warning: ignoring trailing garbage (%lu bytes)\n",
-                         (unsigned long) n);
-
-                       while (n-- > 0) {
-                               if (jas_stream_getc(dec->in) == EOF) {
-                                       jas_eprintf("read error\n");
-                                       return -1;
-                               }
-                       }
-               } else if (curoff > dec->curtileendoff) {
-                       jas_eprintf("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)
-{
-       jpc_dec_tcomp_t *tcomp;
-       int compno;
-       int rlvlno;
-       jpc_dec_rlvl_t *rlvl;
-       jpc_dec_band_t *band;
-       jpc_dec_prc_t *prc;
-       int bndno;
-       jpc_tsfb_band_t *bnd;
-       int bandno;
-       jpc_dec_ccp_t *ccp;
-       int prccnt;
-       jpc_dec_cblk_t *cblk;
-       int cblkcnt;
-       uint_fast32_t tlprcxstart;
-       uint_fast32_t tlprcystart;
-       uint_fast32_t brprcxend;
-       uint_fast32_t brprcyend;
-       uint_fast32_t tlcbgxstart;
-       uint_fast32_t tlcbgystart;
-       uint_fast32_t brcbgxend;
-       uint_fast32_t brcbgyend;
-       uint_fast32_t cbgxstart;
-       uint_fast32_t cbgystart;
-       uint_fast32_t cbgxend;
-       uint_fast32_t cbgyend;
-       uint_fast32_t tlcblkxstart;
-       uint_fast32_t tlcblkystart;
-       uint_fast32_t brcblkxend;
-       uint_fast32_t brcblkyend;
-       uint_fast32_t cblkxstart;
-       uint_fast32_t cblkystart;
-       uint_fast32_t cblkxend;
-       uint_fast32_t cblkyend;
-       uint_fast32_t tmpxstart;
-       uint_fast32_t tmpystart;
-       uint_fast32_t tmpxend;
-       uint_fast32_t tmpyend;
-       jpc_dec_cp_t *cp;
-       jpc_tsfb_band_t bnds[64];
-       jpc_pchg_t *pchg;
-       int pchgno;
-       jpc_dec_cmpt_t *cmpt;
-
-       cp = tile->cp;
-       tile->realmode = 0;
-       if (cp->mctid == JPC_MCT_ICT) {
-               tile->realmode = 1;
-       }
-
-       for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
-         dec->numcomps; ++compno, ++tcomp, ++cmpt) {
-               ccp = &tile->cp->ccps[compno];
-               if (ccp->qmfbid == JPC_COX_INS) {
-                       tile->realmode = 1;
-               }
-               tcomp->numrlvls = ccp->numrlvls;
-               if (!(tcomp->rlvls = jas_malloc(tcomp->numrlvls *
-                 sizeof(jpc_dec_rlvl_t)))) {
-                       return -1;
-               }
-               if (!(tcomp->data = jas_seq2d_create(JPC_CEILDIV(tile->xstart,
-                 cmpt->hstep), JPC_CEILDIV(tile->ystart, cmpt->vstep),
-                 JPC_CEILDIV(tile->xend, cmpt->hstep), JPC_CEILDIV(tile->yend,
-                 cmpt->vstep)))) {
-                       return -1;
-               }
-               if (!(tcomp->tsfb = jpc_cod_gettsfb(ccp->qmfbid,
-                 tcomp->numrlvls - 1))) {
-                       return -1;
-               }
-{
-       jpc_tsfb_getbands(tcomp->tsfb, jas_seq2d_xstart(tcomp->data), jas_seq2d_ystart(tcomp->data), jas_seq2d_xend(tcomp->data), jas_seq2d_yend(tcomp->data), bnds);
-}
-               for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;
-                 ++rlvlno, ++rlvl) {
-rlvl->bands = 0;
-                       rlvl->xstart = JPC_CEILDIVPOW2(tcomp->xstart,
-                         tcomp->numrlvls - 1 - rlvlno);
-                       rlvl->ystart = JPC_CEILDIVPOW2(tcomp->ystart,
-                         tcomp->numrlvls - 1 - rlvlno);
-                       rlvl->xend = JPC_CEILDIVPOW2(tcomp->xend,
-                         tcomp->numrlvls - 1 - rlvlno);
-                       rlvl->yend = JPC_CEILDIVPOW2(tcomp->yend,
-                         tcomp->numrlvls - 1 - rlvlno);
-                       rlvl->prcwidthexpn = ccp->prcwidthexpns[rlvlno];
-                       rlvl->prcheightexpn = ccp->prcheightexpns[rlvlno];
-                       tlprcxstart = JPC_FLOORDIVPOW2(rlvl->xstart,
-                         rlvl->prcwidthexpn) << rlvl->prcwidthexpn;
-                       tlprcystart = JPC_FLOORDIVPOW2(rlvl->ystart,
-                         rlvl->prcheightexpn) << rlvl->prcheightexpn;
-                       brprcxend = JPC_CEILDIVPOW2(rlvl->xend,
-                         rlvl->prcwidthexpn) << rlvl->prcwidthexpn;
-                       brprcyend = JPC_CEILDIVPOW2(rlvl->yend,
-                         rlvl->prcheightexpn) << rlvl->prcheightexpn;
-                       rlvl->numhprcs = (brprcxend - tlprcxstart) >>
-                         rlvl->prcwidthexpn;
-                       rlvl->numvprcs = (brprcyend - tlprcystart) >>
-                         rlvl->prcheightexpn;
-                       rlvl->numprcs = rlvl->numhprcs * rlvl->numvprcs;
-
-                       if (rlvl->xstart >= rlvl->xend || rlvl->ystart >= rlvl->yend) {
-                               rlvl->bands = 0;
-                               rlvl->numprcs = 0;
-                               rlvl->numhprcs = 0;
-                               rlvl->numvprcs = 0;
-                               continue;
-                       }       
-                       if (!rlvlno) {
-                               tlcbgxstart = tlprcxstart;
-                               tlcbgystart = tlprcystart;
-                               brcbgxend = brprcxend;
-                               brcbgyend = brprcyend;
-                               rlvl->cbgwidthexpn = rlvl->prcwidthexpn;
-                               rlvl->cbgheightexpn = rlvl->prcheightexpn;
-                       } else {
-                               tlcbgxstart = JPC_CEILDIVPOW2(tlprcxstart, 1);
-                               tlcbgystart = JPC_CEILDIVPOW2(tlprcystart, 1);
-                               brcbgxend = JPC_CEILDIVPOW2(brprcxend, 1);
-                               brcbgyend = JPC_CEILDIVPOW2(brprcyend, 1);
-                               rlvl->cbgwidthexpn = rlvl->prcwidthexpn - 1;
-                               rlvl->cbgheightexpn = rlvl->prcheightexpn - 1;
-                       }
-                       rlvl->cblkwidthexpn = JAS_MIN(ccp->cblkwidthexpn,
-                         rlvl->cbgwidthexpn);
-                       rlvl->cblkheightexpn = JAS_MIN(ccp->cblkheightexpn,
-                         rlvl->cbgheightexpn);
-
-                       rlvl->numbands = (!rlvlno) ? 1 : 3;
-                       if (!(rlvl->bands = jas_malloc(rlvl->numbands *
-                         sizeof(jpc_dec_band_t)))) {
-                               return -1;
-                       }
-                       for (bandno = 0, band = rlvl->bands;
-                         bandno < rlvl->numbands; ++bandno, ++band) {
-                               bndno = (!rlvlno) ? 0 : (3 * (rlvlno - 1) +
-                                 bandno + 1);
-                               bnd = &bnds[bndno];
-
-                               band->orient = bnd->orient;
-                               band->stepsize = ccp->stepsizes[bndno];
-                               band->analgain = JPC_NOMINALGAIN(ccp->qmfbid,
-                                 tcomp->numrlvls - 1, rlvlno, band->orient);
-                               band->absstepsize = jpc_calcabsstepsize(band->stepsize,
-                                 cmpt->prec + band->analgain);
-                               band->numbps = ccp->numguardbits +
-                                 JPC_QCX_GETEXPN(band->stepsize) - 1;
-                               band->roishift = (ccp->roishift + band->numbps >= JPC_PREC) ?
-                                 (JPC_PREC - 1 - band->numbps) : ccp->roishift;
-                               band->data = 0;
-                               band->prcs = 0;
-                               if (bnd->xstart == bnd->xend || bnd->ystart == bnd->yend) {
-                                       continue;
-                               }
-                               if (!(band->data = jas_seq2d_create(0, 0, 0, 0))) {
-                                       return -1;
-                               }
-                               jas_seq2d_bindsub(band->data, tcomp->data, bnd->locxstart, bnd->locystart, bnd->locxend, bnd->locyend);
-                               jas_seq2d_setshift(band->data, bnd->xstart, bnd->ystart);
-
-                               assert(rlvl->numprcs);
-
-                               if (!(band->prcs = jas_malloc(rlvl->numprcs * sizeof(jpc_dec_prc_t)))) {
-                                       return -1;
-                               }
-
-/************************************************/
-       cbgxstart = tlcbgxstart;
-       cbgystart = tlcbgystart;
-       for (prccnt = rlvl->numprcs, prc = band->prcs;
-         prccnt > 0; --prccnt, ++prc) {
-               cbgxend = cbgxstart + (1 << rlvl->cbgwidthexpn);
-               cbgyend = cbgystart + (1 << rlvl->cbgheightexpn);
-               prc->xstart = JAS_MAX(cbgxstart, JAS_CAST(uint_fast32_t, jas_seq2d_xstart(band->data)));
-               prc->ystart = JAS_MAX(cbgystart, JAS_CAST(uint_fast32_t, jas_seq2d_ystart(band->data)));
-               prc->xend = JAS_MIN(cbgxend, JAS_CAST(uint_fast32_t, jas_seq2d_xend(band->data)));
-               prc->yend = JAS_MIN(cbgyend, JAS_CAST(uint_fast32_t, jas_seq2d_yend(band->data)));
-               if (prc->xend > prc->xstart && prc->yend > prc->ystart) {
-                       tlcblkxstart = JPC_FLOORDIVPOW2(prc->xstart,
-                         rlvl->cblkwidthexpn) << rlvl->cblkwidthexpn;
-                       tlcblkystart = JPC_FLOORDIVPOW2(prc->ystart,
-                         rlvl->cblkheightexpn) << rlvl->cblkheightexpn;
-                       brcblkxend = JPC_CEILDIVPOW2(prc->xend,
-                         rlvl->cblkwidthexpn) << rlvl->cblkwidthexpn;
-                       brcblkyend = JPC_CEILDIVPOW2(prc->yend,
-                         rlvl->cblkheightexpn) << rlvl->cblkheightexpn;
-                       prc->numhcblks = (brcblkxend - tlcblkxstart) >>
-                         rlvl->cblkwidthexpn;
-                       prc->numvcblks = (brcblkyend - tlcblkystart) >>
-                         rlvl->cblkheightexpn;
-                       prc->numcblks = prc->numhcblks * prc->numvcblks;
-                       assert(prc->numcblks > 0);
-
-                       if (!(prc->incltagtree = jpc_tagtree_create(prc->numhcblks, prc->numvcblks))) {
-                               return -1;
-                       }
-                       if (!(prc->numimsbstagtree = jpc_tagtree_create(prc->numhcblks, prc->numvcblks))) {
-                               return -1;
-                       }
-                       if (!(prc->cblks = jas_malloc(prc->numcblks * sizeof(jpc_dec_cblk_t)))) {
-                               return -1;
-                       }
-
-                       cblkxstart = cbgxstart;
-                       cblkystart = cbgystart;
-                       for (cblkcnt = prc->numcblks, cblk = prc->cblks; cblkcnt > 0;) {
-                               cblkxend = cblkxstart + (1 << rlvl->cblkwidthexpn);
-                               cblkyend = cblkystart + (1 << rlvl->cblkheightexpn);
-                               tmpxstart = JAS_MAX(cblkxstart, prc->xstart);
-                               tmpystart = JAS_MAX(cblkystart, prc->ystart);
-                               tmpxend = JAS_MIN(cblkxend, prc->xend);
-                               tmpyend = JAS_MIN(cblkyend, prc->yend);
-                               if (tmpxend > tmpxstart && tmpyend > tmpystart) {
-                                       cblk->firstpassno = -1;
-                                       cblk->mqdec = 0;
-                                       cblk->nulldec = 0;
-                                       cblk->flags = 0;
-                                       cblk->numpasses = 0;
-                                       cblk->segs.head = 0;
-                                       cblk->segs.tail = 0;
-                                       cblk->curseg = 0;
-                                       cblk->numimsbs = 0;
-                                       cblk->numlenbits = 3;
-                                       cblk->flags = 0;
-                                       if (!(cblk->data = jas_seq2d_create(0, 0, 0, 0))) {
-                                               return -1;
-                                       }
-                                       jas_seq2d_bindsub(cblk->data, band->data, tmpxstart, tmpystart, tmpxend, tmpyend);
-                                       ++cblk;
-                                       --cblkcnt;
-                               }
-                               cblkxstart += 1 << rlvl->cblkwidthexpn;
-                               if (cblkxstart >= cbgxend) {
-                                       cblkxstart = cbgxstart;
-                                       cblkystart += 1 << rlvl->cblkheightexpn;
-                               }
-                       }
-
-               } else {
-                       prc->cblks = 0;
-                       prc->incltagtree = 0;
-                       prc->numimsbstagtree = 0;
-               }
-               cbgxstart += 1 << rlvl->cbgwidthexpn;
-               if (cbgxstart >= brcbgxend) {
-                       cbgxstart = tlcbgxstart;
-                       cbgystart += 1 << rlvl->cbgheightexpn;
-               }
-
-       }
-/********************************************/
-                       }
-               }
-       }
-
-if (!(tile->pi = jpc_dec_pi_create(dec, tile)))
-{
-       return -1;
-}
-
-       for (pchgno = 0; pchgno < jpc_pchglist_numpchgs(tile->cp->pchglist);
-         ++pchgno) {
-               pchg = jpc_pchg_copy(jpc_pchglist_get(tile->cp->pchglist, pchgno));
-               assert(pchg);
-               jpc_pi_addpchg(tile->pi, pchg);
-       }
-       jpc_pi_init(tile->pi);
-
-       return 0;
-}
-
-static int jpc_dec_tilefini(jpc_dec_t *dec, jpc_dec_tile_t *tile)
-{
-       jpc_dec_tcomp_t *tcomp;
-       int compno;
-       int bandno;
-       int rlvlno;
-       jpc_dec_band_t *band;
-       jpc_dec_rlvl_t *rlvl;
-       int prcno;
-       jpc_dec_prc_t *prc;
-       jpc_dec_seg_t *seg;
-       jpc_dec_cblk_t *cblk;
-       int cblkno;
-
-if (tile->tcomps) {
-
-       for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
-         ++compno, ++tcomp) {
-               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->prcs) {
-                               for (prcno = 0, prc = band->prcs; prcno <
-                                 rlvl->numprcs; ++prcno, ++prc) {
-if (!prc->cblks) {
-       continue;
-}
-                                       for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks; ++cblkno, ++cblk) {
-
-       while (cblk->segs.head) {
-               seg = cblk->segs.head;
-               jpc_seglist_remove(&cblk->segs, seg);
-               jpc_seg_destroy(seg);
-       }
-       jas_matrix_destroy(cblk->data);
-       if (cblk->mqdec) {
-               jpc_mqdec_destroy(cblk->mqdec);
-       }
-       if (cblk->nulldec) {
-               jpc_bitstream_close(cblk->nulldec);
-       }
-       if (cblk->flags) {
-               jas_matrix_destroy(cblk->flags);
-       }
-                                       }
-                                       if (prc->incltagtree) {
-                                               jpc_tagtree_destroy(prc->incltagtree);
-                                       }
-                                       if (prc->numimsbstagtree) {
-                                               jpc_tagtree_destroy(prc->numimsbstagtree);
-                                       }
-                                       if (prc->cblks) {
-                                               jas_free(prc->cblks);
-                                       }
-                               }
-}
-                               if (band->data) {
-                                       jas_matrix_destroy(band->data);
-                               }
-                               if (band->prcs) {
-                                       jas_free(band->prcs);
-                               }
-                       }
-                       if (rlvl->bands) {
-                               jas_free(rlvl->bands);
-                       }
-               }
-               if (tcomp->rlvls) {
-                       jas_free(tcomp->rlvls);
-               }
-               if (tcomp->data) {
-                       jas_matrix_destroy(tcomp->data);
-               }
-               if (tcomp->tsfb) {
-                       jpc_tsfb_destroy(tcomp->tsfb);
-               }
-       }
-}
-       if (tile->cp) {
-               jpc_dec_cp_destroy(tile->cp);
-               tile->cp = 0;
-       }
-       if (tile->tcomps) {
-               jas_free(tile->tcomps);
-               tile->tcomps = 0;
-       }
-       if (tile->pi) {
-               jpc_pi_destroy(tile->pi);
-               tile->pi = 0;
-       }
-       if (tile->pkthdrstream) {
-               jas_stream_close(tile->pkthdrstream);
-               tile->pkthdrstream = 0;
-       }
-       if (tile->pptstab) {
-               jpc_ppxstab_destroy(tile->pptstab);
-               tile->pptstab = 0;
-       }
-
-       tile->state = JPC_TILE_DONE;
-
-       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)) {
-               jas_eprintf("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);
-                               }
-
-                       }
-               }
-       }
-
-       /* 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, 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)) {
-                       jas_eprintf("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;
-
-       /* Eliminate compiler warnings about unused variables. */
-       ms = 0;
-
-       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;
-                       }
-               }
-               jpc_dec_tilefini(dec, tile);
-       }
-
-       /* We are done processing the code stream. */
-       dec->state = JPC_MT;
-
-       return 1;
-}
-
-static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       jpc_siz_t *siz = &ms->parms.siz;
-       int compno;
-       int tileno;
-       jpc_dec_tile_t *tile;
-       jpc_dec_tcomp_t *tcomp;
-       int htileno;
-       int vtileno;
-       jpc_dec_cmpt_t *cmpt;
-
-       dec->xstart = siz->xoff;
-       dec->ystart = siz->yoff;
-       dec->xend = siz->width;
-       dec->yend = siz->height;
-       dec->tilewidth = siz->tilewidth;
-       dec->tileheight = siz->tileheight;
-       dec->tilexoff = siz->tilexoff;
-       dec->tileyoff = siz->tileyoff;
-       dec->numcomps = siz->numcomps;
-       if (!(dec->cp = jpc_dec_cp_create(dec->numcomps))) {
-               return -1;
-       }
-
-       if (!(dec->cmpts = jas_malloc(dec->numcomps * sizeof(jpc_dec_cmpt_t)))) {
-               return -1;
-       }
-
-       for (compno = 0, cmpt = dec->cmpts; compno < dec->numcomps; ++compno,
-         ++cmpt) {
-               cmpt->prec = siz->comps[compno].prec;
-               cmpt->sgnd = siz->comps[compno].sgnd;
-               cmpt->hstep = siz->comps[compno].hsamp;
-               cmpt->vstep = siz->comps[compno].vsamp;
-               cmpt->width = JPC_CEILDIV(dec->xend, cmpt->hstep) -
-                 JPC_CEILDIV(dec->xstart, cmpt->hstep);
-               cmpt->height = JPC_CEILDIV(dec->yend, cmpt->vstep) -
-                 JPC_CEILDIV(dec->ystart, cmpt->vstep);
-               cmpt->hsubstep = 0;
-               cmpt->vsubstep = 0;
-       }
-
-       dec->image = 0;
-
-       dec->numhtiles = JPC_CEILDIV(dec->xend - dec->tilexoff, dec->tilewidth);
-       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;
-       }
-
-       for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; ++tileno,
-         ++tile) {
-               htileno = tileno % dec->numhtiles;
-               vtileno = tileno / dec->numhtiles;
-               tile->realmode = 0;
-               tile->state = JPC_TILE_INIT;
-               tile->xstart = JAS_MAX(dec->tilexoff + htileno * dec->tilewidth,
-                 dec->xstart);
-               tile->ystart = JAS_MAX(dec->tileyoff + vtileno * dec->tileheight,
-                 dec->ystart);
-               tile->xend = JAS_MIN(dec->tilexoff + (htileno + 1) *
-                 dec->tilewidth, dec->xend);
-               tile->yend = JAS_MIN(dec->tileyoff + (vtileno + 1) *
-                 dec->tileheight, dec->yend);
-               tile->numparts = 0;
-               tile->partno = 0;
-               tile->pkthdrstream = 0;
-               tile->pkthdrstreampos = 0;
-               tile->pptstab = 0;
-               tile->cp = 0;
-               if (!(tile->tcomps = jas_malloc(dec->numcomps *
-                 sizeof(jpc_dec_tcomp_t)))) {
-                       return -1;
-               }
-               for (compno = 0, cmpt = dec->cmpts, tcomp = tile->tcomps;
-                 compno < dec->numcomps; ++compno, ++cmpt, ++tcomp) {
-                       tcomp->rlvls = 0;
-                       tcomp->data = 0;
-                       tcomp->xstart = JPC_CEILDIV(tile->xstart, cmpt->hstep);
-                       tcomp->ystart = JPC_CEILDIV(tile->ystart, cmpt->vstep);
-                       tcomp->xend = JPC_CEILDIV(tile->xend, cmpt->hstep);
-                       tcomp->yend = JPC_CEILDIV(tile->yend, cmpt->vstep);
-                       tcomp->tsfb = 0;
-               }
-       }
-
-       dec->pkthdrstreams = 0;
-
-       /* We should expect to encounter other main header marker segments
-         or an SOT marker segment next. */
-       dec->state = JPC_MH;
-
-       return 0;
-}
-
-static int jpc_dec_process_cod(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       jpc_cod_t *cod = &ms->parms.cod;
-       jpc_dec_tile_t *tile;
-
-       switch (dec->state) {
-       case JPC_MH:
-               jpc_dec_cp_setfromcod(dec->cp, cod);
-               break;
-       case JPC_TPH:
-               if (!(tile = dec->curtile)) {
-                       return -1;
-               }
-               if (tile->partno != 0) {
-                       return -1;
-               }
-               jpc_dec_cp_setfromcod(tile->cp, cod);
-               break;
-       }
-       return 0;
-}
-
-static int jpc_dec_process_coc(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       jpc_coc_t *coc = &ms->parms.coc;
-       jpc_dec_tile_t *tile;
-
-       if (JAS_CAST(int, coc->compno) > dec->numcomps) {
-               jas_eprintf("invalid component number in COC marker segment\n");
-               return -1;
-       }
-       switch (dec->state) {
-       case JPC_MH:
-               jpc_dec_cp_setfromcoc(dec->cp, coc);
-               break;
-       case JPC_TPH:
-               if (!(tile = dec->curtile)) {
-                       return -1;
-               }
-               if (tile->partno > 0) {
-                       return -1;
-               }
-               jpc_dec_cp_setfromcoc(tile->cp, coc);
-               break;
-       }
-       return 0;
-}
-
-static int jpc_dec_process_rgn(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       jpc_rgn_t *rgn = &ms->parms.rgn;
-       jpc_dec_tile_t *tile;
-
-       if (JAS_CAST(int, rgn->compno) > dec->numcomps) {
-               jas_eprintf("invalid component number in RGN marker segment\n");
-               return -1;
-       }
-       switch (dec->state) {
-       case JPC_MH:
-               jpc_dec_cp_setfromrgn(dec->cp, rgn);
-               break;
-       case JPC_TPH:
-               if (!(tile = dec->curtile)) {
-                       return -1;
-               }
-               if (tile->partno > 0) {
-                       return -1;
-               }
-               jpc_dec_cp_setfromrgn(tile->cp, rgn);
-               break;
-       }
-
-       return 0;
-}
-
-static int jpc_dec_process_qcd(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       jpc_qcd_t *qcd = &ms->parms.qcd;
-       jpc_dec_tile_t *tile;
-
-       switch (dec->state) {
-       case JPC_MH:
-               jpc_dec_cp_setfromqcd(dec->cp, qcd);
-               break;
-       case JPC_TPH:
-               if (!(tile = dec->curtile)) {
-                       return -1;
-               }
-               if (tile->partno > 0) {
-                       return -1;
-               }
-               jpc_dec_cp_setfromqcd(tile->cp, qcd);
-               break;
-       }
-       return 0;
-}
-
-static int jpc_dec_process_qcc(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       jpc_qcc_t *qcc = &ms->parms.qcc;
-       jpc_dec_tile_t *tile;
-
-       if (JAS_CAST(int, qcc->compno) > dec->numcomps) {
-               jas_eprintf("invalid component number in QCC marker segment\n");
-               return -1;
-       }
-       switch (dec->state) {
-       case JPC_MH:
-               jpc_dec_cp_setfromqcc(dec->cp, qcc);
-               break;
-       case JPC_TPH:
-               if (!(tile = dec->curtile)) {
-                       return -1;
-               }
-               if (tile->partno > 0) {
-                       return -1;
-               }
-               jpc_dec_cp_setfromqcc(tile->cp, qcc);
-               break;
-       }
-       return 0;
-}
-
-static int jpc_dec_process_poc(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       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;
-               }
-               break;
-       case JPC_TPH:
-               if (!(tile = dec->curtile)) {
-                       return -1;
-               }
-               if (!tile->partno) {
-                       if (jpc_dec_cp_setfrompoc(tile->cp, poc, (!tile->partno))) {
-                               return -1;
-                       }
-               } else {
-                       jpc_pi_addpchgfrompoc(tile->pi, poc);
-               }
-               break;
-       }
-       return 0;
-}
-
-static int jpc_dec_process_ppm(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       jpc_ppm_t *ppm = &ms->parms.ppm;
-       jpc_ppxstabent_t *ppmstabent;
-
-       if (!dec->ppmstab) {
-               if (!(dec->ppmstab = jpc_ppxstab_create())) {
-                       return -1;
-               }
-       }
-
-       if (!(ppmstabent = jpc_ppxstabent_create())) {
-               return -1;
-       }
-       ppmstabent->ind = ppm->ind;
-       ppmstabent->data = ppm->data;
-       ppm->data = 0;
-       ppmstabent->len = ppm->len;
-       if (jpc_ppxstab_insert(dec->ppmstab, ppmstabent)) {
-               return -1;
-       }
-       return 0;
-}
-
-static int jpc_dec_process_ppt(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       jpc_ppt_t *ppt = &ms->parms.ppt;
-       jpc_dec_tile_t *tile;
-       jpc_ppxstabent_t *pptstabent;
-
-       tile = dec->curtile;
-       if (!tile->pptstab) {
-               if (!(tile->pptstab = jpc_ppxstab_create())) {
-                       return -1;
-               }
-       }
-       if (!(pptstabent = jpc_ppxstabent_create())) {
-               return -1;
-       }
-       pptstabent->ind = ppt->ind;
-       pptstabent->data = ppt->data;
-       ppt->data = 0;
-       pptstabent->len = ppt->len;
-       if (jpc_ppxstab_insert(tile->pptstab, pptstabent)) {
-               return -1;
-       }
-       return 0;
-}
-
-static int jpc_dec_process_com(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       /* Eliminate compiler warnings about unused variables. */
-       dec = 0;
-       ms = 0;
-
-       return 0;
-}
-
-static int jpc_dec_process_unk(jpc_dec_t *dec, jpc_ms_t *ms)
-{
-       /* Eliminate compiler warnings about unused variables. */
-       dec = 0;
-
-       jas_eprintf("warning: ignoring unknown marker segment\n");
-       jpc_ms_dump(ms, stderr);
-       return 0;
-}
-
-/******************************************************************************\
-*
-\******************************************************************************/
-
-static jpc_dec_cp_t *jpc_dec_cp_create(uint_fast16_t numcomps)
-{
-       jpc_dec_cp_t *cp;
-       jpc_dec_ccp_t *ccp;
-       int compno;
-
-       if (!(cp = jas_malloc(sizeof(jpc_dec_cp_t)))) {
-               return 0;
-       }
-       cp->flags = 0;
-       cp->numcomps = numcomps;
-       cp->prgord = 0;
-       cp->numlyrs = 0;
-       cp->mctid = 0;
-       cp->csty = 0;
-       if (!(cp->ccps = jas_malloc(cp->numcomps * sizeof(jpc_dec_ccp_t)))) {
-               return 0;
-       }
-       if (!(cp->pchglist = jpc_pchglist_create())) {
-               jas_free(cp->ccps);
-               return 0;
-       }
-       for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
-         ++compno, ++ccp) {
-               ccp->flags = 0;
-               ccp->numrlvls = 0;
-               ccp->cblkwidthexpn = 0;
-               ccp->cblkheightexpn = 0;
-               ccp->qmfbid = 0;
-               ccp->numstepsizes = 0;
-               ccp->numguardbits = 0;
-               ccp->roishift = 0;
-               ccp->cblkctx = 0;
-       }
-       return cp;
-}
-
-static jpc_dec_cp_t *jpc_dec_cp_copy(jpc_dec_cp_t *cp)
-{
-       jpc_dec_cp_t *newcp;
-       jpc_dec_ccp_t *newccp;
-       jpc_dec_ccp_t *ccp;
-       int compno;
-
-       if (!(newcp = jpc_dec_cp_create(cp->numcomps))) {
-               return 0;
-       }
-       newcp->flags = cp->flags;
-       newcp->prgord = cp->prgord;
-       newcp->numlyrs = cp->numlyrs;
-       newcp->mctid = cp->mctid;
-       newcp->csty = cp->csty;
-       jpc_pchglist_destroy(newcp->pchglist);
-       newcp->pchglist = 0;
-       if (!(newcp->pchglist = jpc_pchglist_copy(cp->pchglist))) {
-               jas_free(newcp);
-               return 0;
-       }
-       for (compno = 0, newccp = newcp->ccps, ccp = cp->ccps;
-         compno < cp->numcomps;
-         ++compno, ++newccp, ++ccp) {
-               *newccp = *ccp;
-       }
-       return newcp;
-}
-
-static void jpc_dec_cp_resetflags(jpc_dec_cp_t *cp)
-{
-       int compno;
-       jpc_dec_ccp_t *ccp;
-       cp->flags &= (JPC_CSET | JPC_QSET);
-       for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
-         ++compno, ++ccp) {
-               ccp->flags = 0;
-       }
-}
-
-static void jpc_dec_cp_destroy(jpc_dec_cp_t *cp)
-{
-       if (cp->ccps) {
-               jas_free(cp->ccps);
-       }
-       if (cp->pchglist) {
-               jpc_pchglist_destroy(cp->pchglist);
-       }
-       jas_free(cp);
-}
-
-static int jpc_dec_cp_isvalid(jpc_dec_cp_t *cp)
-{
-       uint_fast16_t compcnt;
-       jpc_dec_ccp_t *ccp;
-
-       if (!(cp->flags & JPC_CSET) || !(cp->flags & JPC_QSET)) {
-               return 0;
-       }
-       for (compcnt = cp->numcomps, ccp = cp->ccps; compcnt > 0; --compcnt,
-         ++ccp) {
-               /* Is there enough step sizes for the number of bands? */
-               if ((ccp->qsty != JPC_QCX_SIQNT && JAS_CAST(int, ccp->numstepsizes) < 3 *
-                 ccp->numrlvls - 2) || (ccp->qsty == JPC_QCX_SIQNT &&
-                 ccp->numstepsizes != 1)) {
-                       return 0;
-               }
-       }
-       return 1;
-}
-
-static void calcstepsizes(uint_fast16_t refstepsize, int numrlvls,
-  uint_fast16_t *stepsizes)
-{
-       int bandno;
-       int numbands;
-       uint_fast16_t expn;
-       uint_fast16_t mant;
-       expn = JPC_QCX_GETEXPN(refstepsize);
-       mant = JPC_QCX_GETMANT(refstepsize);
-       numbands = 3 * numrlvls - 2;
-       for (bandno = 0; bandno < numbands; ++bandno) {
-               stepsizes[bandno] = JPC_QCX_MANT(mant) | JPC_QCX_EXPN(expn +
-                 (numrlvls - 1) - (numrlvls - 1 - ((bandno > 0) ? ((bandno + 2) / 3) : (0))));
-       }
-}
-
-static int jpc_dec_cp_prepare(jpc_dec_cp_t *cp)
-{
-       jpc_dec_ccp_t *ccp;
-       int compno;
-       int i;
-       for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
-         ++compno, ++ccp) {
-               if (!(ccp->csty & JPC_COX_PRT)) {
-                       for (i = 0; i < JPC_MAXRLVLS; ++i) {
-                               ccp->prcwidthexpns[i] = 15;
-                               ccp->prcheightexpns[i] = 15;
-                       }
-               }
-               if (ccp->qsty == JPC_QCX_SIQNT) {
-                       calcstepsizes(ccp->stepsizes[0], ccp->numrlvls, ccp->stepsizes);
-               }
-       }
-       return 0;
-}
-
-static int jpc_dec_cp_setfromcod(jpc_dec_cp_t *cp, jpc_cod_t *cod)
-{
-       jpc_dec_ccp_t *ccp;
-       int compno;
-       cp->flags |= JPC_CSET;
-       cp->prgord = cod->prg;
-       if (cod->mctrans) {
-               cp->mctid = (cod->compparms.qmfbid == JPC_COX_INS) ? (JPC_MCT_ICT) : (JPC_MCT_RCT);
-       } else {
-               cp->mctid = JPC_MCT_NONE;
-       }
-       cp->numlyrs = cod->numlyrs;
-       cp->csty = cod->csty & (JPC_COD_SOP | JPC_COD_EPH);
-       for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
-         ++compno, ++ccp) {
-               jpc_dec_cp_setfromcox(cp, ccp, &cod->compparms, 0);
-       }
-       cp->flags |= JPC_CSET;
-       return 0;
-}
-
-static int jpc_dec_cp_setfromcoc(jpc_dec_cp_t *cp, jpc_coc_t *coc)
-{
-       jpc_dec_cp_setfromcox(cp, &cp->ccps[coc->compno], &coc->compparms, JPC_COC);
-       return 0;
-}
-
-static int jpc_dec_cp_setfromcox(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp,
-  jpc_coxcp_t *compparms, int flags)
-{
-       int rlvlno;
-
-       /* Eliminate compiler warnings about unused variables. */
-       cp = 0;
-
-       if ((flags & JPC_COC) || !(ccp->flags & JPC_COC)) {
-               ccp->numrlvls = compparms->numdlvls + 1;
-               ccp->cblkwidthexpn = JPC_COX_GETCBLKSIZEEXPN(
-                 compparms->cblkwidthval);
-               ccp->cblkheightexpn = JPC_COX_GETCBLKSIZEEXPN(
-                 compparms->cblkheightval);
-               ccp->qmfbid = compparms->qmfbid;
-               ccp->cblkctx = compparms->cblksty;
-               ccp->csty = compparms->csty & JPC_COX_PRT;
-               for (rlvlno = 0; rlvlno < compparms->numrlvls; ++rlvlno) {
-                       ccp->prcwidthexpns[rlvlno] =
-                         compparms->rlvls[rlvlno].parwidthval;
-                       ccp->prcheightexpns[rlvlno] =
-                         compparms->rlvls[rlvlno].parheightval;
-               }
-               ccp->flags |= flags | JPC_CSET;
-       }
-       return 0;
-}
-
-static int jpc_dec_cp_setfromqcd(jpc_dec_cp_t *cp, jpc_qcd_t *qcd)
-{
-       int compno;
-       jpc_dec_ccp_t *ccp;
-       for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
-         ++compno, ++ccp) {
-               jpc_dec_cp_setfromqcx(cp, ccp, &qcd->compparms, 0);
-       }
-       cp->flags |= JPC_QSET;
-       return 0;
-}
-
-static int jpc_dec_cp_setfromqcc(jpc_dec_cp_t *cp, jpc_qcc_t *qcc)
-{
-       return jpc_dec_cp_setfromqcx(cp, &cp->ccps[qcc->compno], &qcc->compparms, JPC_QCC);
-}
-
-static int jpc_dec_cp_setfromqcx(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp,
-  jpc_qcxcp_t *compparms, int flags)
-{
-       int bandno;
-
-       /* Eliminate compiler warnings about unused variables. */
-       cp = 0;
-
-       if ((flags & JPC_QCC) || !(ccp->flags & JPC_QCC)) {
-               ccp->flags |= flags | JPC_QSET;
-               for (bandno = 0; bandno < compparms->numstepsizes; ++bandno) {
-                       ccp->stepsizes[bandno] = compparms->stepsizes[bandno];
-               }
-               ccp->numstepsizes = compparms->numstepsizes;
-               ccp->numguardbits = compparms->numguard;
-               ccp->qsty = compparms->qntsty;
-       }
-       return 0;
-}
-
-static int jpc_dec_cp_setfromrgn(jpc_dec_cp_t *cp, jpc_rgn_t *rgn)
-{
-       jpc_dec_ccp_t *ccp;
-       ccp = &cp->ccps[rgn->compno];
-       ccp->roishift = rgn->roishift;
-       return 0;
-}
-
-static int jpc_pi_addpchgfrompoc(jpc_pi_t *pi, jpc_poc_t *poc)
-{
-       int pchgno;
-       jpc_pchg_t *pchg;
-       for (pchgno = 0; pchgno < poc->numpchgs; ++pchgno) {
-               if (!(pchg = jpc_pchg_copy(&poc->pchgs[pchgno]))) {
-                       return -1;
-               }
-               if (jpc_pchglist_insert(pi->pchglist, -1, pchg)) {
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-static int jpc_dec_cp_setfrompoc(jpc_dec_cp_t *cp, jpc_poc_t *poc, int reset)
-{
-       int pchgno;
-       jpc_pchg_t *pchg;
-       if (reset) {
-               while (jpc_pchglist_numpchgs(cp->pchglist) > 0) {
-                       pchg = jpc_pchglist_remove(cp->pchglist, 0);
-                       jpc_pchg_destroy(pchg);
-               }
-       }
-       for (pchgno = 0; pchgno < poc->numpchgs; ++pchgno) {
-               if (!(pchg = jpc_pchg_copy(&poc->pchgs[pchgno]))) {
-                       return -1;
-               }
-               if (jpc_pchglist_insert(cp->pchglist, -1, pchg)) {
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-static jpc_fix_t jpc_calcabsstepsize(int stepsize, int numbits)
-{
-       jpc_fix_t absstepsize;
-       int n;
-
-       absstepsize = jpc_inttofix(1);
-       n = JPC_FIX_FRACBITS - 11;
-       absstepsize |= (n >= 0) ? (JPC_QCX_GETMANT(stepsize) << n) :
-         (JPC_QCX_GETMANT(stepsize) >> (-n));
-       n = numbits - JPC_QCX_GETEXPN(stepsize);
-       absstepsize = (n >= 0) ? (absstepsize << n) : (absstepsize >> (-n));
-       return absstepsize;
-}
-
-static void jpc_dequantize(jas_matrix_t *x, jpc_fix_t absstepsize)
-{
-       int i;
-       int j;
-       int t;
-
-       assert(absstepsize >= 0);
-       if (absstepsize == jpc_inttofix(1)) {
-               return;
-       }
-
-       for (i = 0; i < jas_matrix_numrows(x); ++i) {
-               for (j = 0; j < jas_matrix_numcols(x); ++j) {
-                       t = jas_matrix_get(x, i, j);
-                       if (t) {
-                               t = jpc_fix_mul(t, absstepsize);
-                       } else {
-                               t = 0;
-                       }
-                       jas_matrix_set(x, i, j, t);
-               }
-       }
-
-}
-
-static void jpc_undo_roi(jas_matrix_t *x, int roishift, int bgshift, int numbps)
-{
-       int i;
-       int j;
-       int thresh;
-       jpc_fix_t val;
-       jpc_fix_t mag;
-       bool warn;
-       uint_fast32_t mask;
-
-       if (roishift == 0 && bgshift == 0) {
-               return;
-       }
-       thresh = 1 << roishift;
-
-       warn = false;
-       for (i = 0; i < jas_matrix_numrows(x); ++i) {
-               for (j = 0; j < jas_matrix_numcols(x); ++j) {
-                       val = jas_matrix_get(x, i, j);
-                       mag = JAS_ABS(val);
-                       if (mag >= thresh) {
-                               /* We are dealing with ROI data. */
-                               mag >>= roishift;
-                               val = (val < 0) ? (-mag) : mag;
-                               jas_matrix_set(x, i, j, val);
-                       } else {
-                               /* We are dealing with non-ROI (i.e., background) data. */
-                               mag <<= bgshift;
-                               mask = (1 << numbps) - 1;
-                               /* Perform a basic sanity check on the sample value. */
-                               /* Some implementations write garbage in the unused
-                                 most-significant bit planes introduced by ROI shifting.
-                                 Here we ensure that any such bits are masked off. */
-                               if (mag & (~mask)) {
-                                       if (!warn) {
-                                               jas_eprintf("warning: possibly corrupt code stream\n");
-                                               warn = true;
-                                       }
-                                       mag &= mask;
-                               }
-                               val = (val < 0) ? (-mag) : mag;
-                               jas_matrix_set(x, i, j, val);
-                       }
-               }
-       }
-}
-
-static jpc_dec_t *jpc_dec_create(jpc_dec_importopts_t *impopts, jas_stream_t *in)
-{
-       jpc_dec_t *dec;
-
-       if (!(dec = jas_malloc(sizeof(jpc_dec_t)))) {
-               return 0;
-       }
-
-       dec->image = 0;
-       dec->xstart = 0;
-       dec->ystart = 0;
-       dec->xend = 0;
-       dec->yend = 0;
-       dec->tilewidth = 0;
-       dec->tileheight = 0;
-       dec->tilexoff = 0;
-       dec->tileyoff = 0;
-       dec->numhtiles = 0;
-       dec->numvtiles = 0;
-       dec->numtiles = 0;
-       dec->tiles = 0;
-       dec->curtile = 0;
-       dec->numcomps = 0;
-       dec->in = in;
-       dec->cp = 0;
-       dec->maxlyrs = impopts->maxlyrs;
-       dec->maxpkts = impopts->maxpkts;
-dec->numpkts = 0;
-       dec->ppmseqno = 0;
-       dec->state = 0;
-       dec->cmpts = 0;
-       dec->pkthdrstreams = 0;
-       dec->ppmstab = 0;
-       dec->curtileendoff = 0;
-
-       return dec;
-}
-
-static void jpc_dec_destroy(jpc_dec_t *dec)
-{
-       if (dec->cstate) {
-               jpc_cstate_destroy(dec->cstate);
-       }
-       if (dec->pkthdrstreams) {
-               jpc_streamlist_destroy(dec->pkthdrstreams);
-       }
-       if (dec->image) {
-               jas_image_destroy(dec->image);
-       }
-
-       if (dec->cp) {
-               jpc_dec_cp_destroy(dec->cp);
-       }
-
-       if (dec->cmpts) {
-               jas_free(dec->cmpts);
-       }
-
-       if (dec->tiles) {
-               jas_free(dec->tiles);
-       }
-
-       jas_free(dec);
-}
-
-/******************************************************************************\
-*
-\******************************************************************************/
-
-void jpc_seglist_insert(jpc_dec_seglist_t *list, jpc_dec_seg_t *ins, jpc_dec_seg_t *node)
-{
-       jpc_dec_seg_t *prev;
-       jpc_dec_seg_t *next;
-
-       prev = ins;
-       node->prev = prev;
-       next = prev ? (prev->next) : 0;
-       node->prev = prev;
-       node->next = next;
-       if (prev) {
-               prev->next = node;
-       } else {
-               list->head = node;
-       }
-       if (next) {
-               next->prev = node;
-       } else {
-               list->tail = node;
-       }
-}
-
-void jpc_seglist_remove(jpc_dec_seglist_t *list, jpc_dec_seg_t *seg)
-{
-       jpc_dec_seg_t *prev;
-       jpc_dec_seg_t *next;
-
-       prev = seg->prev;
-       next = seg->next;
-       if (prev) {
-               prev->next = next;
-       } else {
-               list->head = next;
-       }
-       if (next) {
-               next->prev = prev;
-       } else {
-               list->tail = prev;
-       }
-       seg->prev = 0;
-       seg->next = 0;
-}
-
-jpc_dec_seg_t *jpc_seg_alloc()
-{
-       jpc_dec_seg_t *seg;
-
-       if (!(seg = jas_malloc(sizeof(jpc_dec_seg_t)))) {
-               return 0;
-       }
-       seg->prev = 0;
-       seg->next = 0;
-       seg->passno = -1;
-       seg->numpasses = 0;
-       seg->maxpasses = 0;
-       seg->type = JPC_SEG_INVALID;
-       seg->stream = 0;
-       seg->cnt = 0;
-       seg->complete = 0;
-       seg->lyrno = -1;
-       return seg;
-}
-
-void jpc_seg_destroy(jpc_dec_seg_t *seg)
-{
-       if (seg->stream) {
-               jas_stream_close(seg->stream);
-       }
-       jas_free(seg);
-}
-
-static int jpc_dec_dump(jpc_dec_t *dec, FILE *out)
-{
-       jpc_dec_tile_t *tile;
-       int tileno;
-       jpc_dec_tcomp_t *tcomp;
-       int compno;
-       jpc_dec_rlvl_t *rlvl;
-       int rlvlno;
-       jpc_dec_band_t *band;
-       int bandno;
-       jpc_dec_prc_t *prc;
-       int prcno;
-       jpc_dec_cblk_t *cblk;
-       int cblkno;
-
-       for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles;
-         ++tileno, ++tile) {
-               for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
-                 ++compno, ++tcomp) {
-                       for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno <
-                         tcomp->numrlvls; ++rlvlno, ++rlvl) {
-fprintf(out, "RESOLUTION LEVEL %d\n", rlvlno);
-fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n",
-  rlvl->xstart, rlvl->ystart, rlvl->xend, rlvl->yend, rlvl->xend -
-  rlvl->xstart, rlvl->yend - rlvl->ystart);
-                               for (bandno = 0, band = rlvl->bands;
-                                 bandno < rlvl->numbands; ++bandno, ++band) {
-fprintf(out, "BAND %d\n", bandno);
-fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n",
-  jas_seq2d_xstart(band->data), jas_seq2d_ystart(band->data), jas_seq2d_xend(band->data),
-  jas_seq2d_yend(band->data), jas_seq2d_xend(band->data) - jas_seq2d_xstart(band->data),
-  jas_seq2d_yend(band->data) - jas_seq2d_ystart(band->data));
-                                       for (prcno = 0, prc = band->prcs;
-                                         prcno < rlvl->numprcs; ++prcno,
-                                         ++prc) {
-fprintf(out, "CODE BLOCK GROUP %d\n", prcno);
-fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n",
-  prc->xstart, prc->ystart, prc->xend, prc->yend, prc->xend -
-  prc->xstart, prc->yend - prc->ystart);
-                                               for (cblkno = 0, cblk =
-                                                 prc->cblks; cblkno <
-                                                 prc->numcblks; ++cblkno,
-                                                 ++cblk) {
-fprintf(out, "CODE BLOCK %d\n", cblkno);
-fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n",
-  jas_seq2d_xstart(cblk->data), jas_seq2d_ystart(cblk->data), jas_seq2d_xend(cblk->data),
-  jas_seq2d_yend(cblk->data), jas_seq2d_xend(cblk->data) - jas_seq2d_xstart(cblk->data),
-  jas_seq2d_yend(cblk->data) - jas_seq2d_ystart(cblk->data));
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-
-       return 0;
-}
-
-jpc_streamlist_t *jpc_streamlist_create()
-{
-       jpc_streamlist_t *streamlist;
-       int i;
-
-       if (!(streamlist = jas_malloc(sizeof(jpc_streamlist_t)))) {
-               return 0;
-       }
-       streamlist->numstreams = 0;
-       streamlist->maxstreams = 100;
-       if (!(streamlist->streams = jas_malloc(streamlist->maxstreams *
-         sizeof(jas_stream_t *)))) {
-               jas_free(streamlist);
-               return 0;
-       }
-       for (i = 0; i < streamlist->maxstreams; ++i) {
-               streamlist->streams[i] = 0;
-       }
-       return streamlist;
-}
-
-int jpc_streamlist_insert(jpc_streamlist_t *streamlist, int streamno,
-  jas_stream_t *stream)
-{
-       jas_stream_t **newstreams;
-       int newmaxstreams;
-       int i;
-       /* Grow the array of streams if necessary. */
-       if (streamlist->numstreams >= streamlist->maxstreams) {
-               newmaxstreams = streamlist->maxstreams + 1024;
-               if (!(newstreams = jas_realloc(streamlist->streams,
-                 (newmaxstreams + 1024) * sizeof(jas_stream_t *)))) {
-                       return -1;
-               }
-               for (i = streamlist->numstreams; i < streamlist->maxstreams; ++i) {
-                       streamlist->streams[i] = 0;
-               }
-               streamlist->maxstreams = newmaxstreams;
-               streamlist->streams = newstreams;
-       }
-       if (streamno != streamlist->numstreams) {
-               /* Can only handle insertion at start of list. */
-               return -1;
-       }
-       streamlist->streams[streamno] = stream;
-       ++streamlist->numstreams;
-       return 0;
-}
-
-jas_stream_t *jpc_streamlist_remove(jpc_streamlist_t *streamlist, int streamno)
-{
-       jas_stream_t *stream;
-       int i;
-       if (streamno >= streamlist->numstreams) {
-               abort();
-       }
-       stream = streamlist->streams[streamno];
-       for (i = streamno + 1; i < streamlist->numstreams; ++i) {
-               streamlist->streams[i - 1] = streamlist->streams[i];
-       }
-       --streamlist->numstreams;
-       return stream;
-}
-
-void jpc_streamlist_destroy(jpc_streamlist_t *streamlist)
-{
-       int streamno;
-       if (streamlist->streams) {
-               for (streamno = 0; streamno < streamlist->numstreams;
-                 ++streamno) {
-                       jas_stream_close(streamlist->streams[streamno]);
-               }
-               jas_free(streamlist->streams);
-       }
-       jas_free(streamlist);
-}
-
-jas_stream_t *jpc_streamlist_get(jpc_streamlist_t *streamlist, int streamno)
-{
-       assert(streamno < streamlist->numstreams);
-       return streamlist->streams[streamno];
-}
-
-int jpc_streamlist_numstreams(jpc_streamlist_t *streamlist)
-{
-       return streamlist->numstreams;
-}
-
-jpc_ppxstab_t *jpc_ppxstab_create()
-{
-       jpc_ppxstab_t *tab;
-
-       if (!(tab = jas_malloc(sizeof(jpc_ppxstab_t)))) {
-               return 0;
-       }
-       tab->numents = 0;
-       tab->maxents = 0;
-       tab->ents = 0;
-       return tab;
-}
-
-void jpc_ppxstab_destroy(jpc_ppxstab_t *tab)
-{
-       int i;
-       for (i = 0; i < tab->numents; ++i) {
-               jpc_ppxstabent_destroy(tab->ents[i]);
-       }
-       if (tab->ents) {
-               jas_free(tab->ents);
-       }
-       jas_free(tab);
-}
-
-int jpc_ppxstab_grow(jpc_ppxstab_t *tab, int maxents)
-{
-       jpc_ppxstabent_t **newents;
-       if (tab->maxents < maxents) {
-               newents = (tab->ents) ? jas_realloc(tab->ents, maxents *
-                 sizeof(jpc_ppxstabent_t *)) : jas_malloc(maxents * sizeof(jpc_ppxstabent_t *));
-               if (!newents) {
-                       return -1;
-               }
-               tab->ents = newents;
-               tab->maxents = maxents;
-       }
-       return 0;
-}
-
-int jpc_ppxstab_insert(jpc_ppxstab_t *tab, jpc_ppxstabent_t *ent)
-{
-       int inspt;
-       int i;
-
-       for (i = 0; i < tab->numents; ++i) {
-               if (tab->ents[i]->ind > ent->ind) {
-                       break;
-               }
-       }
-       inspt = i;
-
-       if (tab->numents >= tab->maxents) {
-               if (jpc_ppxstab_grow(tab, tab->maxents + 128)) {
-                       return -1;
-               }
-       }
-
-       for (i = tab->numents; i > inspt; --i) {
-               tab->ents[i] = tab->ents[i - 1];
-       }
-       tab->ents[i] = ent;
-       ++tab->numents;
-
-       return 0;
-}
-
-jpc_streamlist_t *jpc_ppmstabtostreams(jpc_ppxstab_t *tab)
-{
-       jpc_streamlist_t *streams;
-       uchar *dataptr;
-       uint_fast32_t datacnt;
-       uint_fast32_t tpcnt;
-       jpc_ppxstabent_t *ent;
-       int entno;
-       jas_stream_t *stream;
-       int n;
-
-       if (!(streams = jpc_streamlist_create())) {
-               goto error;
-       }
-
-       if (!tab->numents) {
-               return streams;
-       }
-
-       entno = 0;
-       ent = tab->ents[entno];
-       dataptr = ent->data;
-       datacnt = ent->len;
-       for (;;) {
-
-               /* Get the length of the packet header data for the current
-                 tile-part. */
-               if (datacnt < 4) {
-                       goto error;
-               }
-               if (!(stream = jas_stream_memopen(0, 0))) {
-                       goto error;
-               }
-               if (jpc_streamlist_insert(streams, jpc_streamlist_numstreams(streams),
-                 stream)) {
-                       goto error;
-               }
-               tpcnt = (dataptr[0] << 24) | (dataptr[1] << 16) | (dataptr[2] << 8)
-                 | dataptr[3];
-               datacnt -= 4;
-               dataptr += 4;
-
-               /* Get the packet header data for the current tile-part. */
-               while (tpcnt) {
-                       if (!datacnt) {
-                               if (++entno >= tab->numents) {
-                                       goto error;
-                               }
-                               ent = tab->ents[entno];
-                               dataptr = ent->data;
-                               datacnt = ent->len;
-                       }
-                       n = JAS_MIN(tpcnt, datacnt);
-                       if (jas_stream_write(stream, dataptr, n) != n) {
-                               goto error;
-                       }
-                       tpcnt -= n;
-                       dataptr += n;
-                       datacnt -= n;
-               }
-               jas_stream_rewind(stream);
-               if (!datacnt) {
-                       if (++entno >= tab->numents) {
-                               break;
-                       }
-                       ent = tab->ents[entno];
-                       dataptr = ent->data;
-                       datacnt = ent->len;
-               }
-       }
-
-       return streams;
-
-error:
-       jpc_streamlist_destroy(streams);
-       return 0;
-}
-
-int jpc_pptstabwrite(jas_stream_t *out, jpc_ppxstab_t *tab)
-{
-       int i;
-       jpc_ppxstabent_t *ent;
-       for (i = 0; i < tab->numents; ++i) {
-               ent = tab->ents[i];
-               if (jas_stream_write(out, ent->data, ent->len) != JAS_CAST(int, ent->len)) {
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-jpc_ppxstabent_t *jpc_ppxstabent_create()
-{
-       jpc_ppxstabent_t *ent;
-       if (!(ent = jas_malloc(sizeof(jpc_ppxstabent_t)))) {
-               return 0;
-       }
-       ent->data = 0;
-       ent->len = 0;
-       ent->ind = 0;
-       return ent;
-}
-
-void jpc_ppxstabent_destroy(jpc_ppxstabent_t *ent)
-{
-       if (ent->data) {
-               jas_free(ent->data);
-       }
-       jas_free(ent);
-}