vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

jpc_dec.c (60135B)


      1 /*
      2  * Copyright (c) 1999-2000 Image Power, Inc. and the University of
      3  *   British Columbia.
      4  * Copyright (c) 2001-2003 Michael David Adams.
      5  * All rights reserved.
      6  */
      7 
      8 /* __START_OF_JASPER_LICENSE__
      9  * 
     10  * JasPer License Version 2.0
     11  * 
     12  * Copyright (c) 1999-2000 Image Power, Inc.
     13  * Copyright (c) 1999-2000 The University of British Columbia
     14  * Copyright (c) 2001-2003 Michael David Adams
     15  * 
     16  * All rights reserved.
     17  * 
     18  * Permission is hereby granted, free of charge, to any person (the
     19  * "User") obtaining a copy of this software and associated documentation
     20  * files (the "Software"), to deal in the Software without restriction,
     21  * including without limitation the rights to use, copy, modify, merge,
     22  * publish, distribute, and/or sell copies of the Software, and to permit
     23  * persons to whom the Software is furnished to do so, subject to the
     24  * following conditions:
     25  * 
     26  * 1.  The above copyright notices and this permission notice (which
     27  * includes the disclaimer below) shall be included in all copies or
     28  * substantial portions of the Software.
     29  * 
     30  * 2.  The name of a copyright holder shall not be used to endorse or
     31  * promote products derived from the Software without specific prior
     32  * written permission.
     33  * 
     34  * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
     35  * LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
     36  * THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
     37  * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
     38  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
     39  * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO
     40  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
     41  * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
     42  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
     43  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
     44  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE
     45  * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
     46  * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
     47  * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
     48  * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
     49  * PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS
     50  * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
     51  * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE
     52  * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
     53  * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
     54  * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
     55  * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
     56  * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
     57  * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
     58  * RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
     59  * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
     60  * 
     61  * __END_OF_JASPER_LICENSE__
     62  */
     63 
     64 /*
     65  * $Id: jpc_dec.c 1918 2005-07-24 14:12:08Z baford $
     66  */
     67 
     68 /******************************************************************************\
     69 * Includes.
     70 \******************************************************************************/
     71 
     72 #include <stdio.h>
     73 #include <stdlib.h>
     74 #include <assert.h>
     75 
     76 #include "jasper/jas_types.h"
     77 #include "jasper/jas_math.h"
     78 #include "jasper/jas_tvp.h"
     79 #include "jasper/jas_malloc.h"
     80 #include "jasper/jas_debug.h"
     81 
     82 #include "jpc_fix.h"
     83 #include "jpc_dec.h"
     84 #include "jpc_cs.h"
     85 #include "jpc_mct.h"
     86 #include "jpc_t2dec.h"
     87 #include "jpc_t1dec.h"
     88 #include "jpc_math.h"
     89 
     90 /******************************************************************************\
     91 *
     92 \******************************************************************************/
     93 
     94 #define	JPC_MHSOC	0x0001
     95   /* In the main header, expecting a SOC marker segment. */
     96 #define	JPC_MHSIZ	0x0002
     97   /* In the main header, expecting a SIZ marker segment. */
     98 #define	JPC_MH		0x0004
     99   /* In the main header, expecting "other" marker segments. */
    100 #define	JPC_TPHSOT	0x0008
    101   /* In a tile-part header, expecting a SOT marker segment. */
    102 #define	JPC_TPH		0x0010
    103   /* In a tile-part header, expecting "other" marker segments. */
    104 #define	JPC_MT		0x0020
    105   /* In the main trailer. */
    106 
    107 typedef struct {
    108 
    109 	uint_fast16_t id;
    110 	/* The marker segment type. */
    111 
    112 	int validstates;
    113 	/* The states in which this type of marker segment can be
    114 	  validly encountered. */
    115 
    116 	int (*action)(jpc_dec_t *dec, jpc_ms_t *ms);
    117 	/* The action to take upon encountering this type of marker segment. */
    118 
    119 } jpc_dec_mstabent_t;
    120 
    121 /******************************************************************************\
    122 *
    123 \******************************************************************************/
    124 
    125 /* COD/COC parameters have been specified. */
    126 #define	JPC_CSET	0x0001
    127 /* QCD/QCC parameters have been specified. */
    128 #define	JPC_QSET	0x0002
    129 /* COD/COC parameters set from a COC marker segment. */
    130 #define	JPC_COC	0x0004
    131 /* QCD/QCC parameters set from a QCC marker segment. */
    132 #define	JPC_QCC	0x0008
    133 
    134 /******************************************************************************\
    135 * Local function prototypes.
    136 \******************************************************************************/
    137 
    138 static int jpc_dec_dump(jpc_dec_t *dec, FILE *out);
    139 
    140 jpc_ppxstab_t *jpc_ppxstab_create(void);
    141 void jpc_ppxstab_destroy(jpc_ppxstab_t *tab);
    142 int jpc_ppxstab_grow(jpc_ppxstab_t *tab, int maxents);
    143 int jpc_ppxstab_insert(jpc_ppxstab_t *tab, jpc_ppxstabent_t *ent);
    144 jpc_streamlist_t *jpc_ppmstabtostreams(jpc_ppxstab_t *tab);
    145 int jpc_pptstabwrite(jas_stream_t *out, jpc_ppxstab_t *tab);
    146 jpc_ppxstabent_t *jpc_ppxstabent_create(void);
    147 void jpc_ppxstabent_destroy(jpc_ppxstabent_t *ent);
    148 
    149 int jpc_streamlist_numstreams(jpc_streamlist_t *streamlist);
    150 jpc_streamlist_t *jpc_streamlist_create(void);
    151 int jpc_streamlist_insert(jpc_streamlist_t *streamlist, int streamno,
    152   jas_stream_t *stream);
    153 jas_stream_t *jpc_streamlist_remove(jpc_streamlist_t *streamlist, int streamno);
    154 void jpc_streamlist_destroy(jpc_streamlist_t *streamlist);
    155 jas_stream_t *jpc_streamlist_get(jpc_streamlist_t *streamlist, int streamno);
    156 
    157 static void jpc_dec_cp_resetflags(jpc_dec_cp_t *cp);
    158 static jpc_dec_cp_t *jpc_dec_cp_create(uint_fast16_t numcomps);
    159 static int jpc_dec_cp_isvalid(jpc_dec_cp_t *cp);
    160 static jpc_dec_cp_t *jpc_dec_cp_copy(jpc_dec_cp_t *cp);
    161 static int jpc_dec_cp_setfromcod(jpc_dec_cp_t *cp, jpc_cod_t *cod);
    162 static int jpc_dec_cp_setfromcoc(jpc_dec_cp_t *cp, jpc_coc_t *coc);
    163 static int jpc_dec_cp_setfromcox(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp,
    164   jpc_coxcp_t *compparms, int flags);
    165 static int jpc_dec_cp_setfromqcd(jpc_dec_cp_t *cp, jpc_qcd_t *qcd);
    166 static int jpc_dec_cp_setfromqcc(jpc_dec_cp_t *cp, jpc_qcc_t *qcc);
    167 static int jpc_dec_cp_setfromqcx(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp,
    168   jpc_qcxcp_t *compparms, int flags);
    169 static int jpc_dec_cp_setfromrgn(jpc_dec_cp_t *cp, jpc_rgn_t *rgn);
    170 static int jpc_dec_cp_prepare(jpc_dec_cp_t *cp);
    171 static void jpc_dec_cp_destroy(jpc_dec_cp_t *cp);
    172 static int jpc_dec_cp_setfrompoc(jpc_dec_cp_t *cp, jpc_poc_t *poc, int reset);
    173 static int jpc_pi_addpchgfrompoc(jpc_pi_t *pi, jpc_poc_t *poc);
    174 
    175 static int jpc_dec_decode(jpc_dec_t *dec);
    176 static jpc_dec_t *jpc_dec_create(jpc_dec_importopts_t *impopts, jas_stream_t *in);
    177 static void jpc_dec_destroy(jpc_dec_t *dec);
    178 static void jpc_dequantize(jas_matrix_t *x, jpc_fix_t absstepsize);
    179 static void jpc_undo_roi(jas_matrix_t *x, int roishift, int bgshift, int numbps);
    180 static jpc_fix_t jpc_calcabsstepsize(int stepsize, int numbits);
    181 static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile);
    182 static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile);
    183 static int jpc_dec_tilefini(jpc_dec_t *dec, jpc_dec_tile_t *tile);
    184 static int jpc_dec_process_soc(jpc_dec_t *dec, jpc_ms_t *ms);
    185 static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms);
    186 static int jpc_dec_process_sod(jpc_dec_t *dec, jpc_ms_t *ms);
    187 static int jpc_dec_process_eoc(jpc_dec_t *dec, jpc_ms_t *ms);
    188 static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms);
    189 static int jpc_dec_process_cod(jpc_dec_t *dec, jpc_ms_t *ms);
    190 static int jpc_dec_process_coc(jpc_dec_t *dec, jpc_ms_t *ms);
    191 static int jpc_dec_process_rgn(jpc_dec_t *dec, jpc_ms_t *ms);
    192 static int jpc_dec_process_qcd(jpc_dec_t *dec, jpc_ms_t *ms);
    193 static int jpc_dec_process_qcc(jpc_dec_t *dec, jpc_ms_t *ms);
    194 static int jpc_dec_process_poc(jpc_dec_t *dec, jpc_ms_t *ms);
    195 static int jpc_dec_process_ppm(jpc_dec_t *dec, jpc_ms_t *ms);
    196 static int jpc_dec_process_ppt(jpc_dec_t *dec, jpc_ms_t *ms);
    197 static int jpc_dec_process_com(jpc_dec_t *dec, jpc_ms_t *ms);
    198 static int jpc_dec_process_unk(jpc_dec_t *dec, jpc_ms_t *ms);
    199 static int jpc_dec_process_crg(jpc_dec_t *dec, jpc_ms_t *ms);
    200 static int jpc_dec_parseopts(char *optstr, jpc_dec_importopts_t *opts);
    201 
    202 static jpc_dec_mstabent_t *jpc_dec_mstab_lookup(uint_fast16_t id);
    203 
    204 /******************************************************************************\
    205 * Global data.
    206 \******************************************************************************/
    207 
    208 jpc_dec_mstabent_t jpc_dec_mstab[] = {
    209 	{JPC_MS_SOC, JPC_MHSOC, jpc_dec_process_soc},
    210 	{JPC_MS_SOT, JPC_MH | JPC_TPHSOT, jpc_dec_process_sot},
    211 	{JPC_MS_SOD, JPC_TPH, jpc_dec_process_sod},
    212 	{JPC_MS_EOC, JPC_TPHSOT, jpc_dec_process_eoc},
    213 	{JPC_MS_SIZ, JPC_MHSIZ, jpc_dec_process_siz},
    214 	{JPC_MS_COD, JPC_MH | JPC_TPH, jpc_dec_process_cod},
    215 	{JPC_MS_COC, JPC_MH | JPC_TPH, jpc_dec_process_coc},
    216 	{JPC_MS_RGN, JPC_MH | JPC_TPH, jpc_dec_process_rgn},
    217 	{JPC_MS_QCD, JPC_MH | JPC_TPH, jpc_dec_process_qcd},
    218 	{JPC_MS_QCC, JPC_MH | JPC_TPH, jpc_dec_process_qcc},
    219 	{JPC_MS_POC, JPC_MH | JPC_TPH, jpc_dec_process_poc},
    220 	{JPC_MS_TLM, JPC_MH, 0},
    221 	{JPC_MS_PLM, JPC_MH, 0},
    222 	{JPC_MS_PLT, JPC_TPH, 0},
    223 	{JPC_MS_PPM, JPC_MH, jpc_dec_process_ppm},
    224 	{JPC_MS_PPT, JPC_TPH, jpc_dec_process_ppt},
    225 	{JPC_MS_SOP, 0, 0},
    226 	{JPC_MS_CRG, JPC_MH, jpc_dec_process_crg},
    227 	{JPC_MS_COM, JPC_MH | JPC_TPH, jpc_dec_process_com},
    228 	{0, JPC_MH | JPC_TPH, jpc_dec_process_unk}
    229 };
    230 
    231 /******************************************************************************\
    232 * The main entry point for the JPEG-2000 decoder.
    233 \******************************************************************************/
    234 
    235 jas_image_t *jpc_decode(jas_stream_t *in, char *optstr)
    236 {
    237 	jpc_dec_importopts_t opts;
    238 	jpc_dec_t *dec;
    239 	jas_image_t *image;
    240 
    241 	dec = 0;
    242 
    243 	if (jpc_dec_parseopts(optstr, &opts)) {
    244 		goto error;
    245 	}
    246 
    247 	jpc_initluts();
    248 
    249 	if (!(dec = jpc_dec_create(&opts, in))) {
    250 		goto error;
    251 	}
    252 
    253 	/* Do most of the work. */
    254 	if (jpc_dec_decode(dec)) {
    255 		goto error;
    256 	}
    257 
    258 	if (jas_image_numcmpts(dec->image) >= 3) {
    259 		jas_image_setclrspc(dec->image, JAS_CLRSPC_SRGB);
    260 		jas_image_setcmpttype(dec->image, 0,
    261 		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
    262 		jas_image_setcmpttype(dec->image, 1,
    263 		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
    264 		jas_image_setcmpttype(dec->image, 2,
    265 		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
    266 	} else {
    267 		jas_image_setclrspc(dec->image, JAS_CLRSPC_SGRAY);
    268 		jas_image_setcmpttype(dec->image, 0,
    269 		  JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
    270 	}
    271 
    272 	/* Save the return value. */
    273 	image = dec->image;
    274 
    275 	/* Stop the image from being discarded. */
    276 	dec->image = 0;
    277 
    278 	/* Destroy decoder. */
    279 	jpc_dec_destroy(dec);
    280 
    281 	return image;
    282 
    283 error:
    284 	if (dec) {
    285 		jpc_dec_destroy(dec);
    286 	}
    287 	return 0;
    288 }
    289 
    290 typedef enum {
    291 	OPT_MAXLYRS,
    292 	OPT_MAXPKTS,
    293 	OPT_DEBUG
    294 } optid_t;
    295 
    296 jas_taginfo_t decopts[] = {
    297 	{OPT_MAXLYRS, "maxlyrs"},
    298 	{OPT_MAXPKTS, "maxpkts"},
    299 	{OPT_DEBUG, "debug"},
    300 	{-1, 0}
    301 };
    302 
    303 static int jpc_dec_parseopts(char *optstr, jpc_dec_importopts_t *opts)
    304 {
    305 	jas_tvparser_t *tvp;
    306 
    307 	opts->debug = 0;
    308 	opts->maxlyrs = JPC_MAXLYRS;
    309 	opts->maxpkts = -1;
    310 
    311 	if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) {
    312 		return -1;
    313 	}
    314 
    315 	while (!jas_tvparser_next(tvp)) {
    316 		switch (jas_taginfo_nonull(jas_taginfos_lookup(decopts,
    317 		  jas_tvparser_gettag(tvp)))->id) {
    318 		case OPT_MAXLYRS:
    319 			opts->maxlyrs = atoi(jas_tvparser_getval(tvp));
    320 			break;
    321 		case OPT_DEBUG:
    322 			opts->debug = atoi(jas_tvparser_getval(tvp));
    323 			break;
    324 		case OPT_MAXPKTS:
    325 			opts->maxpkts = atoi(jas_tvparser_getval(tvp));
    326 			break;
    327 		default:
    328 			fprintf(stderr, "warning: ignoring invalid option %s\n",
    329 			  jas_tvparser_gettag(tvp));
    330 			break;
    331 		}
    332 	}
    333 
    334 	jas_tvparser_destroy(tvp);
    335 
    336 	return 0;
    337 }
    338 
    339 /******************************************************************************\
    340 * Code for table-driven code stream decoder.
    341 \******************************************************************************/
    342 
    343 static jpc_dec_mstabent_t *jpc_dec_mstab_lookup(uint_fast16_t id)
    344 {
    345 	jpc_dec_mstabent_t *mstabent;
    346 	for (mstabent = jpc_dec_mstab; mstabent->id != 0; ++mstabent) {
    347 		if (mstabent->id == id) {
    348 			break;
    349 		}
    350 	}
    351 	return mstabent;
    352 }
    353 
    354 static int jpc_dec_decode(jpc_dec_t *dec)
    355 {
    356 	jpc_ms_t *ms;
    357 	jpc_dec_mstabent_t *mstabent;
    358 	int ret;
    359 	jpc_cstate_t *cstate;
    360 
    361 	if (!(cstate = jpc_cstate_create())) {
    362 		return -1;
    363 	}
    364 	dec->cstate = cstate;
    365 
    366 	/* Initially, we should expect to encounter a SOC marker segment. */
    367 	dec->state = JPC_MHSOC;
    368 
    369 	for (;;) {
    370 
    371 		/* Get the next marker segment in the code stream. */
    372 		if (!(ms = jpc_getms(dec->in, cstate))) {
    373 			fprintf(stderr, "cannot get marker segment\n");
    374 			return -1;
    375 		}
    376 
    377 		mstabent = jpc_dec_mstab_lookup(ms->id);
    378 		assert(mstabent);
    379 
    380 		/* Ensure that this type of marker segment is permitted
    381 		  at this point in the code stream. */
    382 		if (!(dec->state & mstabent->validstates)) {
    383 			fprintf(stderr, "unexpected marker segment type\n");
    384 			jpc_ms_destroy(ms);
    385 			return -1;
    386 		}
    387 
    388 		/* Process the marker segment. */
    389 		if (mstabent->action) {
    390 			ret = (*mstabent->action)(dec, ms);
    391 		} else {
    392 			/* No explicit action is required. */
    393 			ret = 0;
    394 		}
    395 
    396 		/* Destroy the marker segment. */
    397 		jpc_ms_destroy(ms);
    398 
    399 		if (ret < 0) {
    400 			return -1;
    401 		} else if (ret > 0) {
    402 			break;
    403 		}
    404 
    405 	}
    406 
    407 	return 0;
    408 }
    409 
    410 static int jpc_dec_process_crg(jpc_dec_t *dec, jpc_ms_t *ms)
    411 {
    412 	int cmptno;
    413 	jpc_dec_cmpt_t *cmpt;
    414 	jpc_crg_t *crg;
    415 
    416 	crg = &ms->parms.crg;
    417 	for (cmptno = 0, cmpt = dec->cmpts; cmptno < dec->numcomps; ++cmptno,
    418 	  ++cmpt) {
    419 		/* Ignore the information in the CRG marker segment for now.
    420 		  This information serves no useful purpose for decoding anyhow.
    421 		  Some other parts of the code need to be changed if these lines
    422 		  are uncommented.
    423 		cmpt->hsubstep = crg->comps[cmptno].hoff;
    424 		cmpt->vsubstep = crg->comps[cmptno].voff;
    425 		*/
    426 	}
    427 	return 0;
    428 }
    429 
    430 static int jpc_dec_process_soc(jpc_dec_t *dec, jpc_ms_t *ms)
    431 {
    432 	/* Eliminate warnings about unused variables. */
    433 	ms = 0;
    434 
    435 	/* We should expect to encounter a SIZ marker segment next. */
    436 	dec->state = JPC_MHSIZ;
    437 
    438 	return 0;
    439 }
    440 
    441 static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms)
    442 {
    443 	jpc_dec_tile_t *tile;
    444 	jpc_sot_t *sot = &ms->parms.sot;
    445 	jas_image_cmptparm_t *compinfos;
    446 	jas_image_cmptparm_t *compinfo;
    447 	jpc_dec_cmpt_t *cmpt;
    448 	int cmptno;
    449 
    450 	if (dec->state == JPC_MH) {
    451 
    452 		compinfos = jas_malloc(dec->numcomps * sizeof(jas_image_cmptparm_t));
    453 		assert(compinfos);
    454 		for (cmptno = 0, cmpt = dec->cmpts, compinfo = compinfos;
    455 		  cmptno < dec->numcomps; ++cmptno, ++cmpt, ++compinfo) {
    456 			compinfo->tlx = 0;
    457 			compinfo->tly = 0;
    458 			compinfo->prec = cmpt->prec;
    459 			compinfo->sgnd = cmpt->sgnd;
    460 			compinfo->width = cmpt->width;
    461 			compinfo->height = cmpt->height;
    462 			compinfo->hstep = cmpt->hstep;
    463 			compinfo->vstep = cmpt->vstep;
    464 		}
    465 
    466 		if (!(dec->image = jas_image_create(dec->numcomps, compinfos,
    467 		  JAS_CLRSPC_UNKNOWN))) {
    468 			return -1;
    469 		}
    470 		jas_free(compinfos);
    471 
    472 		/* Is the packet header information stored in PPM marker segments in
    473 		  the main header? */
    474 		if (dec->ppmstab) {
    475 			/* Convert the PPM marker segment data into a collection of streams
    476 			  (one stream per tile-part). */
    477 			if (!(dec->pkthdrstreams = jpc_ppmstabtostreams(dec->ppmstab))) {
    478 				abort();
    479 			}
    480 			jpc_ppxstab_destroy(dec->ppmstab);
    481 			dec->ppmstab = 0;
    482 		}
    483 	}
    484 
    485 	if (sot->len > 0) {
    486 		dec->curtileendoff = jas_stream_getrwcount(dec->in) - ms->len -
    487 		  4 + sot->len;
    488 	} else {
    489 		dec->curtileendoff = 0;
    490 	}
    491 
    492 	if (JAS_CAST(int, sot->tileno) > dec->numtiles) {
    493 		fprintf(stderr, "invalid tile number in SOT marker segment\n");
    494 		return -1;
    495 	}
    496 	/* Set the current tile. */
    497 	dec->curtile = &dec->tiles[sot->tileno];
    498 	tile = dec->curtile;
    499 	/* Ensure that this is the expected part number. */
    500 	if (sot->partno != tile->partno) {
    501 		return -1;
    502 	}
    503 	if (tile->numparts > 0 && sot->partno >= tile->numparts) {
    504 		return -1;
    505 	}
    506 	if (!tile->numparts && sot->numparts > 0) {
    507 		tile->numparts = sot->numparts;
    508 	}
    509 
    510 	tile->pptstab = 0;
    511 
    512 	switch (tile->state) {
    513 	case JPC_TILE_INIT:
    514 		/* This is the first tile-part for this tile. */
    515 		tile->state = JPC_TILE_ACTIVE;
    516 		assert(!tile->cp);
    517 		if (!(tile->cp = jpc_dec_cp_copy(dec->cp))) {
    518 			return -1;
    519 		}
    520 		jpc_dec_cp_resetflags(dec->cp);
    521 		break;
    522 	default:
    523 		if (sot->numparts == sot->partno - 1) {
    524 			tile->state = JPC_TILE_ACTIVELAST;
    525 		}
    526 		break;
    527 	}
    528 
    529 	/* Note: We do not increment the expected tile-part number until
    530 	  all processing for this tile-part is complete. */
    531 
    532 	/* We should expect to encounter other tile-part header marker
    533 	  segments next. */
    534 	dec->state = JPC_TPH;
    535 
    536 	return 0;
    537 }
    538 
    539 static int jpc_dec_process_sod(jpc_dec_t *dec, jpc_ms_t *ms)
    540 {
    541 	jpc_dec_tile_t *tile;
    542 	int pos;
    543 
    544 	/* Eliminate compiler warnings about unused variables. */
    545 	ms = 0;
    546 
    547 	if (!(tile = dec->curtile)) {
    548 		return -1;
    549 	}
    550 
    551 	if (!tile->partno) {
    552 		if (!jpc_dec_cp_isvalid(tile->cp)) {
    553 			return -1;
    554 		}
    555 		jpc_dec_cp_prepare(tile->cp);
    556 		if (jpc_dec_tileinit(dec, tile)) {
    557 			return -1;
    558 		}
    559 	}
    560 
    561 	/* Are packet headers stored in the main header or tile-part header? */
    562 	if (dec->pkthdrstreams) {
    563 		/* Get the stream containing the packet header data for this
    564 		  tile-part. */
    565 		if (!(tile->pkthdrstream = jpc_streamlist_remove(dec->pkthdrstreams, 0))) {
    566 			return -1;
    567 		}
    568 	}
    569 
    570 	if (tile->pptstab) {
    571 		if (!tile->pkthdrstream) {
    572 			if (!(tile->pkthdrstream = jas_stream_memopen(0, 0))) {
    573 				return -1;
    574 			}
    575 		}
    576 		pos = jas_stream_tell(tile->pkthdrstream);
    577 		jas_stream_seek(tile->pkthdrstream, 0, SEEK_END);
    578 		if (jpc_pptstabwrite(tile->pkthdrstream, tile->pptstab)) {
    579 			return -1;
    580 		}
    581 		jas_stream_seek(tile->pkthdrstream, pos, SEEK_SET);
    582 		jpc_ppxstab_destroy(tile->pptstab);
    583 		tile->pptstab = 0;
    584 	}
    585 
    586 	if (jas_getdbglevel() >= 10) {
    587 		jpc_dec_dump(dec, stderr);
    588 	}
    589 
    590 	if (jpc_dec_decodepkts(dec, (tile->pkthdrstream) ? tile->pkthdrstream :
    591 	  dec->in, dec->in)) {
    592 		fprintf(stderr, "jpc_dec_decodepkts failed\n");
    593 		return -1;
    594 	}
    595 
    596 	/* Gobble any unconsumed tile data. */
    597 	if (dec->curtileendoff > 0) {
    598 		long curoff;
    599 		uint_fast32_t n;
    600 		curoff = jas_stream_getrwcount(dec->in);
    601 		if (curoff < dec->curtileendoff) {
    602 			n = dec->curtileendoff - curoff;
    603 			fprintf(stderr,
    604 			  "warning: ignoring trailing garbage (%lu bytes)\n",
    605 			  (unsigned long) n);
    606 
    607 			while (n-- > 0) {
    608 				if (jas_stream_getc(dec->in) == EOF) {
    609 					fprintf(stderr, "read error\n");
    610 					return -1;
    611 				}
    612 			}
    613 		} else if (curoff > dec->curtileendoff) {
    614 			fprintf(stderr,
    615 			  "warning: not enough tile data (%lu bytes)\n",
    616 			  (unsigned long) curoff - dec->curtileendoff);
    617 		}
    618 
    619 	}
    620 
    621 	if (tile->numparts > 0 && tile->partno == tile->numparts - 1) {
    622 		if (jpc_dec_tiledecode(dec, tile)) {
    623 			return -1;
    624 		}
    625 		jpc_dec_tilefini(dec, tile);
    626 	}
    627 
    628 	dec->curtile = 0;
    629 
    630 	/* Increment the expected tile-part number. */
    631 	++tile->partno;
    632 
    633 	/* We should expect to encounter a SOT marker segment next. */
    634 	dec->state = JPC_TPHSOT;
    635 
    636 	return 0;
    637 }
    638 
    639 static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile)
    640 {
    641 	jpc_dec_tcomp_t *tcomp;
    642 	int compno;
    643 	int rlvlno;
    644 	jpc_dec_rlvl_t *rlvl;
    645 	jpc_dec_band_t *band;
    646 	jpc_dec_prc_t *prc;
    647 	int bndno;
    648 	jpc_tsfb_band_t *bnd;
    649 	int bandno;
    650 	jpc_dec_ccp_t *ccp;
    651 	int prccnt;
    652 	jpc_dec_cblk_t *cblk;
    653 	int cblkcnt;
    654 	uint_fast32_t tlprcxstart;
    655 	uint_fast32_t tlprcystart;
    656 	uint_fast32_t brprcxend;
    657 	uint_fast32_t brprcyend;
    658 	uint_fast32_t tlcbgxstart;
    659 	uint_fast32_t tlcbgystart;
    660 	uint_fast32_t brcbgxend;
    661 	uint_fast32_t brcbgyend;
    662 	uint_fast32_t cbgxstart;
    663 	uint_fast32_t cbgystart;
    664 	uint_fast32_t cbgxend;
    665 	uint_fast32_t cbgyend;
    666 	uint_fast32_t tlcblkxstart;
    667 	uint_fast32_t tlcblkystart;
    668 	uint_fast32_t brcblkxend;
    669 	uint_fast32_t brcblkyend;
    670 	uint_fast32_t cblkxstart;
    671 	uint_fast32_t cblkystart;
    672 	uint_fast32_t cblkxend;
    673 	uint_fast32_t cblkyend;
    674 	uint_fast32_t tmpxstart;
    675 	uint_fast32_t tmpystart;
    676 	uint_fast32_t tmpxend;
    677 	uint_fast32_t tmpyend;
    678 	jpc_dec_cp_t *cp;
    679 	jpc_tsfb_band_t bnds[64];
    680 	jpc_pchg_t *pchg;
    681 	int pchgno;
    682 	jpc_dec_cmpt_t *cmpt;
    683 
    684 	cp = tile->cp;
    685 	tile->realmode = 0;
    686 	if (cp->mctid == JPC_MCT_ICT) {
    687 		tile->realmode = 1;
    688 	}
    689 
    690 	for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
    691 	  dec->numcomps; ++compno, ++tcomp, ++cmpt) {
    692 		ccp = &tile->cp->ccps[compno];
    693 		if (ccp->qmfbid == JPC_COX_INS) {
    694 			tile->realmode = 1;
    695 		}
    696 		tcomp->numrlvls = ccp->numrlvls;
    697 		if (!(tcomp->rlvls = jas_malloc(tcomp->numrlvls *
    698 		  sizeof(jpc_dec_rlvl_t)))) {
    699 			return -1;
    700 		}
    701 		if (!(tcomp->data = jas_seq2d_create(JPC_CEILDIV(tile->xstart,
    702 		  cmpt->hstep), JPC_CEILDIV(tile->ystart, cmpt->vstep),
    703 		  JPC_CEILDIV(tile->xend, cmpt->hstep), JPC_CEILDIV(tile->yend,
    704 		  cmpt->vstep)))) {
    705 			return -1;
    706 		}
    707 		if (!(tcomp->tsfb = jpc_cod_gettsfb(ccp->qmfbid,
    708 		  tcomp->numrlvls - 1))) {
    709 			return -1;
    710 		}
    711 {
    712 	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);
    713 }
    714 		for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;
    715 		  ++rlvlno, ++rlvl) {
    716 rlvl->bands = 0;
    717 			rlvl->xstart = JPC_CEILDIVPOW2(tcomp->xstart,
    718 			  tcomp->numrlvls - 1 - rlvlno);
    719 			rlvl->ystart = JPC_CEILDIVPOW2(tcomp->ystart,
    720 			  tcomp->numrlvls - 1 - rlvlno);
    721 			rlvl->xend = JPC_CEILDIVPOW2(tcomp->xend,
    722 			  tcomp->numrlvls - 1 - rlvlno);
    723 			rlvl->yend = JPC_CEILDIVPOW2(tcomp->yend,
    724 			  tcomp->numrlvls - 1 - rlvlno);
    725 			rlvl->prcwidthexpn = ccp->prcwidthexpns[rlvlno];
    726 			rlvl->prcheightexpn = ccp->prcheightexpns[rlvlno];
    727 			tlprcxstart = JPC_FLOORDIVPOW2(rlvl->xstart,
    728 			  rlvl->prcwidthexpn) << rlvl->prcwidthexpn;
    729 			tlprcystart = JPC_FLOORDIVPOW2(rlvl->ystart,
    730 			  rlvl->prcheightexpn) << rlvl->prcheightexpn;
    731 			brprcxend = JPC_CEILDIVPOW2(rlvl->xend,
    732 			  rlvl->prcwidthexpn) << rlvl->prcwidthexpn;
    733 			brprcyend = JPC_CEILDIVPOW2(rlvl->yend,
    734 			  rlvl->prcheightexpn) << rlvl->prcheightexpn;
    735 			rlvl->numhprcs = (brprcxend - tlprcxstart) >>
    736 			  rlvl->prcwidthexpn;
    737 			rlvl->numvprcs = (brprcyend - tlprcystart) >>
    738 			  rlvl->prcheightexpn;
    739 			rlvl->numprcs = rlvl->numhprcs * rlvl->numvprcs;
    740 
    741 			if (rlvl->xstart >= rlvl->xend || rlvl->ystart >= rlvl->yend) {
    742 				rlvl->bands = 0;
    743 				rlvl->numprcs = 0;
    744 				rlvl->numhprcs = 0;
    745 				rlvl->numvprcs = 0;
    746 				continue;
    747 			}	
    748 			if (!rlvlno) {
    749 				tlcbgxstart = tlprcxstart;
    750 				tlcbgystart = tlprcystart;
    751 				brcbgxend = brprcxend;
    752 				brcbgyend = brprcyend;
    753 				rlvl->cbgwidthexpn = rlvl->prcwidthexpn;
    754 				rlvl->cbgheightexpn = rlvl->prcheightexpn;
    755 			} else {
    756 				tlcbgxstart = JPC_CEILDIVPOW2(tlprcxstart, 1);
    757 				tlcbgystart = JPC_CEILDIVPOW2(tlprcystart, 1);
    758 				brcbgxend = JPC_CEILDIVPOW2(brprcxend, 1);
    759 				brcbgyend = JPC_CEILDIVPOW2(brprcyend, 1);
    760 				rlvl->cbgwidthexpn = rlvl->prcwidthexpn - 1;
    761 				rlvl->cbgheightexpn = rlvl->prcheightexpn - 1;
    762 			}
    763 			rlvl->cblkwidthexpn = JAS_MIN(ccp->cblkwidthexpn,
    764 			  rlvl->cbgwidthexpn);
    765 			rlvl->cblkheightexpn = JAS_MIN(ccp->cblkheightexpn,
    766 			  rlvl->cbgheightexpn);
    767 
    768 			rlvl->numbands = (!rlvlno) ? 1 : 3;
    769 			if (!(rlvl->bands = jas_malloc(rlvl->numbands *
    770 			  sizeof(jpc_dec_band_t)))) {
    771 				return -1;
    772 			}
    773 			for (bandno = 0, band = rlvl->bands;
    774 			  bandno < rlvl->numbands; ++bandno, ++band) {
    775 				bndno = (!rlvlno) ? 0 : (3 * (rlvlno - 1) +
    776 				  bandno + 1);
    777 				bnd = &bnds[bndno];
    778 
    779 				band->orient = bnd->orient;
    780 				band->stepsize = ccp->stepsizes[bndno];
    781 				band->analgain = JPC_NOMINALGAIN(ccp->qmfbid,
    782 				  tcomp->numrlvls - 1, rlvlno, band->orient);
    783 				band->absstepsize = jpc_calcabsstepsize(band->stepsize,
    784 				  cmpt->prec + band->analgain);
    785 				band->numbps = ccp->numguardbits +
    786 				  JPC_QCX_GETEXPN(band->stepsize) - 1;
    787 				band->roishift = (ccp->roishift + band->numbps >= JPC_PREC) ?
    788 				  (JPC_PREC - 1 - band->numbps) : ccp->roishift;
    789 				band->data = 0;
    790 				band->prcs = 0;
    791 				if (bnd->xstart == bnd->xend || bnd->ystart == bnd->yend) {
    792 					continue;
    793 				}
    794 				if (!(band->data = jas_seq2d_create(0, 0, 0, 0))) {
    795 					return -1;
    796 				}
    797 				jas_seq2d_bindsub(band->data, tcomp->data, bnd->locxstart, bnd->locystart, bnd->locxend, bnd->locyend);
    798 				jas_seq2d_setshift(band->data, bnd->xstart, bnd->ystart);
    799 
    800 				assert(rlvl->numprcs);
    801 
    802 				if (!(band->prcs = jas_malloc(rlvl->numprcs * sizeof(jpc_dec_prc_t)))) {
    803 					return -1;
    804 				}
    805 
    806 /************************************************/
    807 	cbgxstart = tlcbgxstart;
    808 	cbgystart = tlcbgystart;
    809 	for (prccnt = rlvl->numprcs, prc = band->prcs;
    810 	  prccnt > 0; --prccnt, ++prc) {
    811 		cbgxend = cbgxstart + (1 << rlvl->cbgwidthexpn);
    812 		cbgyend = cbgystart + (1 << rlvl->cbgheightexpn);
    813 		prc->xstart = JAS_MAX(cbgxstart, JAS_CAST(uint_fast32_t, jas_seq2d_xstart(band->data)));
    814 		prc->ystart = JAS_MAX(cbgystart, JAS_CAST(uint_fast32_t, jas_seq2d_ystart(band->data)));
    815 		prc->xend = JAS_MIN(cbgxend, JAS_CAST(uint_fast32_t, jas_seq2d_xend(band->data)));
    816 		prc->yend = JAS_MIN(cbgyend, JAS_CAST(uint_fast32_t, jas_seq2d_yend(band->data)));
    817 		if (prc->xend > prc->xstart && prc->yend > prc->ystart) {
    818 			tlcblkxstart = JPC_FLOORDIVPOW2(prc->xstart,
    819 			  rlvl->cblkwidthexpn) << rlvl->cblkwidthexpn;
    820 			tlcblkystart = JPC_FLOORDIVPOW2(prc->ystart,
    821 			  rlvl->cblkheightexpn) << rlvl->cblkheightexpn;
    822 			brcblkxend = JPC_CEILDIVPOW2(prc->xend,
    823 			  rlvl->cblkwidthexpn) << rlvl->cblkwidthexpn;
    824 			brcblkyend = JPC_CEILDIVPOW2(prc->yend,
    825 			  rlvl->cblkheightexpn) << rlvl->cblkheightexpn;
    826 			prc->numhcblks = (brcblkxend - tlcblkxstart) >>
    827 			  rlvl->cblkwidthexpn;
    828 			prc->numvcblks = (brcblkyend - tlcblkystart) >>
    829 			  rlvl->cblkheightexpn;
    830 			prc->numcblks = prc->numhcblks * prc->numvcblks;
    831 			assert(prc->numcblks > 0);
    832 
    833 			if (!(prc->incltagtree = jpc_tagtree_create(prc->numhcblks, prc->numvcblks))) {
    834 				return -1;
    835 			}
    836 			if (!(prc->numimsbstagtree = jpc_tagtree_create(prc->numhcblks, prc->numvcblks))) {
    837 				return -1;
    838 			}
    839 			if (!(prc->cblks = jas_malloc(prc->numcblks * sizeof(jpc_dec_cblk_t)))) {
    840 				return -1;
    841 			}
    842 
    843 			cblkxstart = cbgxstart;
    844 			cblkystart = cbgystart;
    845 			for (cblkcnt = prc->numcblks, cblk = prc->cblks; cblkcnt > 0;) {
    846 				cblkxend = cblkxstart + (1 << rlvl->cblkwidthexpn);
    847 				cblkyend = cblkystart + (1 << rlvl->cblkheightexpn);
    848 				tmpxstart = JAS_MAX(cblkxstart, prc->xstart);
    849 				tmpystart = JAS_MAX(cblkystart, prc->ystart);
    850 				tmpxend = JAS_MIN(cblkxend, prc->xend);
    851 				tmpyend = JAS_MIN(cblkyend, prc->yend);
    852 				if (tmpxend > tmpxstart && tmpyend > tmpystart) {
    853 					cblk->firstpassno = -1;
    854 					cblk->mqdec = 0;
    855 					cblk->nulldec = 0;
    856 					cblk->flags = 0;
    857 					cblk->numpasses = 0;
    858 					cblk->segs.head = 0;
    859 					cblk->segs.tail = 0;
    860 					cblk->curseg = 0;
    861 					cblk->numimsbs = 0;
    862 					cblk->numlenbits = 3;
    863 					cblk->flags = 0;
    864 					if (!(cblk->data = jas_seq2d_create(0, 0, 0, 0))) {
    865 						return -1;
    866 					}
    867 					jas_seq2d_bindsub(cblk->data, band->data, tmpxstart, tmpystart, tmpxend, tmpyend);
    868 					++cblk;
    869 					--cblkcnt;
    870 				}
    871 				cblkxstart += 1 << rlvl->cblkwidthexpn;
    872 				if (cblkxstart >= cbgxend) {
    873 					cblkxstart = cbgxstart;
    874 					cblkystart += 1 << rlvl->cblkheightexpn;
    875 				}
    876 			}
    877 
    878 		} else {
    879 			prc->cblks = 0;
    880 			prc->incltagtree = 0;
    881 			prc->numimsbstagtree = 0;
    882 		}
    883 		cbgxstart += 1 << rlvl->cbgwidthexpn;
    884 		if (cbgxstart >= brcbgxend) {
    885 			cbgxstart = tlcbgxstart;
    886 			cbgystart += 1 << rlvl->cbgheightexpn;
    887 		}
    888 
    889 	}
    890 /********************************************/
    891 			}
    892 		}
    893 	}
    894 
    895 if (!(tile->pi = jpc_dec_pi_create(dec, tile)))
    896 {
    897 	return -1;
    898 }
    899 
    900 	for (pchgno = 0; pchgno < jpc_pchglist_numpchgs(tile->cp->pchglist);
    901 	  ++pchgno) {
    902 		pchg = jpc_pchg_copy(jpc_pchglist_get(tile->cp->pchglist, pchgno));
    903 		assert(pchg);
    904 		jpc_pi_addpchg(tile->pi, pchg);
    905 	}
    906 	jpc_pi_init(tile->pi);
    907 
    908 	return 0;
    909 }
    910 
    911 static int jpc_dec_tilefini(jpc_dec_t *dec, jpc_dec_tile_t *tile)
    912 {
    913 	jpc_dec_tcomp_t *tcomp;
    914 	int compno;
    915 	int bandno;
    916 	int rlvlno;
    917 	jpc_dec_band_t *band;
    918 	jpc_dec_rlvl_t *rlvl;
    919 	int prcno;
    920 	jpc_dec_prc_t *prc;
    921 	jpc_dec_seg_t *seg;
    922 	jpc_dec_cblk_t *cblk;
    923 	int cblkno;
    924 
    925 if (tile->tcomps) {
    926 
    927 	for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
    928 	  ++compno, ++tcomp) {
    929 		for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;
    930 		  ++rlvlno, ++rlvl) {
    931 if (!rlvl->bands) {
    932 	continue;
    933 }
    934 			for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands; ++bandno, ++band) {
    935 if (band->prcs) {
    936 				for (prcno = 0, prc = band->prcs; prcno <
    937 				  rlvl->numprcs; ++prcno, ++prc) {
    938 if (!prc->cblks) {
    939 	continue;
    940 }
    941 					for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks; ++cblkno, ++cblk) {
    942 
    943 	while (cblk->segs.head) {
    944 		seg = cblk->segs.head;
    945 		jpc_seglist_remove(&cblk->segs, seg);
    946 		jpc_seg_destroy(seg);
    947 	}
    948 	jas_matrix_destroy(cblk->data);
    949 	if (cblk->mqdec) {
    950 		jpc_mqdec_destroy(cblk->mqdec);
    951 	}
    952 	if (cblk->nulldec) {
    953 		jpc_bitstream_close(cblk->nulldec);
    954 	}
    955 	if (cblk->flags) {
    956 		jas_matrix_destroy(cblk->flags);
    957 	}
    958 					}
    959 					if (prc->incltagtree) {
    960 						jpc_tagtree_destroy(prc->incltagtree);
    961 					}
    962 					if (prc->numimsbstagtree) {
    963 						jpc_tagtree_destroy(prc->numimsbstagtree);
    964 					}
    965 					if (prc->cblks) {
    966 						jas_free(prc->cblks);
    967 					}
    968 				}
    969 }
    970 				if (band->data) {
    971 					jas_matrix_destroy(band->data);
    972 				}
    973 				if (band->prcs) {
    974 					jas_free(band->prcs);
    975 				}
    976 			}
    977 			if (rlvl->bands) {
    978 				jas_free(rlvl->bands);
    979 			}
    980 		}
    981 		if (tcomp->rlvls) {
    982 			jas_free(tcomp->rlvls);
    983 		}
    984 		if (tcomp->data) {
    985 			jas_matrix_destroy(tcomp->data);
    986 		}
    987 		if (tcomp->tsfb) {
    988 			jpc_tsfb_destroy(tcomp->tsfb);
    989 		}
    990 	}
    991 }
    992 	if (tile->cp) {
    993 		jpc_dec_cp_destroy(tile->cp);
    994 		tile->cp = 0;
    995 	}
    996 	if (tile->tcomps) {
    997 		jas_free(tile->tcomps);
    998 		tile->tcomps = 0;
    999 	}
   1000 	if (tile->pi) {
   1001 		jpc_pi_destroy(tile->pi);
   1002 		tile->pi = 0;
   1003 	}
   1004 	if (tile->pkthdrstream) {
   1005 		jas_stream_close(tile->pkthdrstream);
   1006 		tile->pkthdrstream = 0;
   1007 	}
   1008 	if (tile->pptstab) {
   1009 		jpc_ppxstab_destroy(tile->pptstab);
   1010 		tile->pptstab = 0;
   1011 	}
   1012 
   1013 	tile->state = JPC_TILE_DONE;
   1014 
   1015 	return 0;
   1016 }
   1017 
   1018 static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile)
   1019 {
   1020 	int i;
   1021 	int j;
   1022 	jpc_dec_tcomp_t *tcomp;
   1023 	jpc_dec_rlvl_t *rlvl;
   1024 	jpc_dec_band_t *band;
   1025 	int compno;
   1026 	int rlvlno;
   1027 	int bandno;
   1028 	int adjust;
   1029 	int v;
   1030 	jpc_dec_ccp_t *ccp;
   1031 	jpc_dec_cmpt_t *cmpt;
   1032 
   1033 	if (jpc_dec_decodecblks(dec, tile)) {
   1034 		fprintf(stderr, "jpc_dec_decodecblks failed\n");
   1035 		return -1;
   1036 	}
   1037 
   1038 	/* Perform dequantization. */
   1039 	for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
   1040 	  ++compno, ++tcomp) {
   1041 		ccp = &tile->cp->ccps[compno];
   1042 		for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;
   1043 		  ++rlvlno, ++rlvl) {
   1044 			if (!rlvl->bands) {
   1045 				continue;
   1046 			}
   1047 			for (bandno = 0, band = rlvl->bands;
   1048 			  bandno < rlvl->numbands; ++bandno, ++band) {
   1049 				if (!band->data) {
   1050 					continue;
   1051 				}
   1052 				jpc_undo_roi(band->data, band->roishift, ccp->roishift -
   1053 				  band->roishift, band->numbps);
   1054 				if (tile->realmode) {
   1055 					jas_matrix_asl(band->data, JPC_FIX_FRACBITS);
   1056 					jpc_dequantize(band->data, band->absstepsize);
   1057 				}
   1058 
   1059 			}
   1060 		}
   1061 	}
   1062 
   1063 	/* Apply an inverse wavelet transform if necessary. */
   1064 	for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
   1065 	  ++compno, ++tcomp) {
   1066 		ccp = &tile->cp->ccps[compno];
   1067 		jpc_tsfb_synthesize(tcomp->tsfb, ((ccp->qmfbid ==
   1068 		  JPC_COX_RFT) ? JPC_TSFB_RITIMODE : 0), tcomp->data);
   1069 	}
   1070 
   1071 
   1072 	/* Apply an inverse intercomponent transform if necessary. */
   1073 	switch (tile->cp->mctid) {
   1074 	case JPC_MCT_RCT:
   1075 		assert(dec->numcomps == 3);
   1076 		jpc_irct(tile->tcomps[0].data, tile->tcomps[1].data,
   1077 		  tile->tcomps[2].data);
   1078 		break;
   1079 	case JPC_MCT_ICT:
   1080 		assert(dec->numcomps == 3);
   1081 		jpc_iict(tile->tcomps[0].data, tile->tcomps[1].data,
   1082 		  tile->tcomps[2].data);
   1083 		break;
   1084 	}
   1085 
   1086 	/* Perform rounding and convert to integer values. */
   1087 	if (tile->realmode) {
   1088 		for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
   1089 		  ++compno, ++tcomp) {
   1090 			for (i = 0; i < jas_matrix_numrows(tcomp->data); ++i) {
   1091 				for (j = 0; j < jas_matrix_numcols(tcomp->data); ++j) {
   1092 					v = jas_matrix_get(tcomp->data, i, j);
   1093 					v = jpc_fix_round(v);
   1094 					jas_matrix_set(tcomp->data, i, j, jpc_fixtoint(v));
   1095 				}
   1096 			}
   1097 		}
   1098 	}
   1099 
   1100 	/* Perform level shift. */
   1101 	for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
   1102 	  dec->numcomps; ++compno, ++tcomp, ++cmpt) {
   1103 		adjust = cmpt->sgnd ? 0 : (1 << (cmpt->prec - 1));
   1104 		for (i = 0; i < jas_matrix_numrows(tcomp->data); ++i) {
   1105 			for (j = 0; j < jas_matrix_numcols(tcomp->data); ++j) {
   1106 				*jas_matrix_getref(tcomp->data, i, j) += adjust;
   1107 			}
   1108 		}
   1109 	}
   1110 
   1111 	/* Perform clipping. */
   1112 	for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
   1113 	  dec->numcomps; ++compno, ++tcomp, ++cmpt) {
   1114 		jpc_fix_t mn;
   1115 		jpc_fix_t mx;
   1116 		mn = cmpt->sgnd ? (-(1 << (cmpt->prec - 1))) : (0);
   1117 		mx = cmpt->sgnd ? ((1 << (cmpt->prec - 1)) - 1) : ((1 <<
   1118 		  cmpt->prec) - 1);
   1119 		jas_matrix_clip(tcomp->data, mn, mx);
   1120 	}
   1121 
   1122 	/* XXX need to free tsfb struct */
   1123 
   1124 	/* Write the data for each component of the image. */
   1125 	for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
   1126 	  dec->numcomps; ++compno, ++tcomp, ++cmpt) {
   1127 		if (jas_image_writecmpt(dec->image, compno, tcomp->xstart -
   1128 		  JPC_CEILDIV(dec->xstart, cmpt->hstep), tcomp->ystart -
   1129 		  JPC_CEILDIV(dec->ystart, cmpt->vstep), jas_matrix_numcols(
   1130 		  tcomp->data), jas_matrix_numrows(tcomp->data), tcomp->data)) {
   1131 			fprintf(stderr, "write component failed\n");
   1132 			return -4;
   1133 		}
   1134 	}
   1135 
   1136 	return 0;
   1137 }
   1138 
   1139 static int jpc_dec_process_eoc(jpc_dec_t *dec, jpc_ms_t *ms)
   1140 {
   1141 	int tileno;
   1142 	jpc_dec_tile_t *tile;
   1143 
   1144 	/* Eliminate compiler warnings about unused variables. */
   1145 	ms = 0;
   1146 
   1147 	for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; ++tileno,
   1148 	  ++tile) {
   1149 		if (tile->state == JPC_TILE_ACTIVE) {
   1150 			if (jpc_dec_tiledecode(dec, tile)) {
   1151 				return -1;
   1152 			}
   1153 		}
   1154 		jpc_dec_tilefini(dec, tile);
   1155 	}
   1156 
   1157 	/* We are done processing the code stream. */
   1158 	dec->state = JPC_MT;
   1159 
   1160 	return 1;
   1161 }
   1162 
   1163 static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms)
   1164 {
   1165 	jpc_siz_t *siz = &ms->parms.siz;
   1166 	int compno;
   1167 	int tileno;
   1168 	jpc_dec_tile_t *tile;
   1169 	jpc_dec_tcomp_t *tcomp;
   1170 	int htileno;
   1171 	int vtileno;
   1172 	jpc_dec_cmpt_t *cmpt;
   1173 
   1174 	dec->xstart = siz->xoff;
   1175 	dec->ystart = siz->yoff;
   1176 	dec->xend = siz->width;
   1177 	dec->yend = siz->height;
   1178 	dec->tilewidth = siz->tilewidth;
   1179 	dec->tileheight = siz->tileheight;
   1180 	dec->tilexoff = siz->tilexoff;
   1181 	dec->tileyoff = siz->tileyoff;
   1182 	dec->numcomps = siz->numcomps;
   1183 	if (!(dec->cp = jpc_dec_cp_create(dec->numcomps))) {
   1184 		return -1;
   1185 	}
   1186 
   1187 	if (!(dec->cmpts = jas_malloc(dec->numcomps * sizeof(jpc_dec_cmpt_t)))) {
   1188 		return -1;
   1189 	}
   1190 
   1191 	for (compno = 0, cmpt = dec->cmpts; compno < dec->numcomps; ++compno,
   1192 	  ++cmpt) {
   1193 		cmpt->prec = siz->comps[compno].prec;
   1194 		cmpt->sgnd = siz->comps[compno].sgnd;
   1195 		cmpt->hstep = siz->comps[compno].hsamp;
   1196 		cmpt->vstep = siz->comps[compno].vsamp;
   1197 		cmpt->width = JPC_CEILDIV(dec->xend, cmpt->hstep) -
   1198 		  JPC_CEILDIV(dec->xstart, cmpt->hstep);
   1199 		cmpt->height = JPC_CEILDIV(dec->yend, cmpt->vstep) -
   1200 		  JPC_CEILDIV(dec->ystart, cmpt->vstep);
   1201 		cmpt->hsubstep = 0;
   1202 		cmpt->vsubstep = 0;
   1203 	}
   1204 
   1205 	dec->image = 0;
   1206 
   1207 	dec->numhtiles = JPC_CEILDIV(dec->xend - dec->tilexoff, dec->tilewidth);
   1208 	dec->numvtiles = JPC_CEILDIV(dec->yend - dec->tileyoff, dec->tileheight);
   1209 	dec->numtiles = dec->numhtiles * dec->numvtiles;
   1210 	if (!(dec->tiles = jas_malloc(dec->numtiles * sizeof(jpc_dec_tile_t)))) {
   1211 		return -1;
   1212 	}
   1213 
   1214 	for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; ++tileno,
   1215 	  ++tile) {
   1216 		htileno = tileno % dec->numhtiles;
   1217 		vtileno = tileno / dec->numhtiles;
   1218 		tile->realmode = 0;
   1219 		tile->state = JPC_TILE_INIT;
   1220 		tile->xstart = JAS_MAX(dec->tilexoff + htileno * dec->tilewidth,
   1221 		  dec->xstart);
   1222 		tile->ystart = JAS_MAX(dec->tileyoff + vtileno * dec->tileheight,
   1223 		  dec->ystart);
   1224 		tile->xend = JAS_MIN(dec->tilexoff + (htileno + 1) *
   1225 		  dec->tilewidth, dec->xend);
   1226 		tile->yend = JAS_MIN(dec->tileyoff + (vtileno + 1) *
   1227 		  dec->tileheight, dec->yend);
   1228 		tile->numparts = 0;
   1229 		tile->partno = 0;
   1230 		tile->pkthdrstream = 0;
   1231 		tile->pkthdrstreampos = 0;
   1232 		tile->pptstab = 0;
   1233 		tile->cp = 0;
   1234 		if (!(tile->tcomps = jas_malloc(dec->numcomps *
   1235 		  sizeof(jpc_dec_tcomp_t)))) {
   1236 			return -1;
   1237 		}
   1238 		for (compno = 0, cmpt = dec->cmpts, tcomp = tile->tcomps;
   1239 		  compno < dec->numcomps; ++compno, ++cmpt, ++tcomp) {
   1240 			tcomp->rlvls = 0;
   1241 			tcomp->data = 0;
   1242 			tcomp->xstart = JPC_CEILDIV(tile->xstart, cmpt->hstep);
   1243 			tcomp->ystart = JPC_CEILDIV(tile->ystart, cmpt->vstep);
   1244 			tcomp->xend = JPC_CEILDIV(tile->xend, cmpt->hstep);
   1245 			tcomp->yend = JPC_CEILDIV(tile->yend, cmpt->vstep);
   1246 			tcomp->tsfb = 0;
   1247 		}
   1248 	}
   1249 
   1250 	dec->pkthdrstreams = 0;
   1251 
   1252 	/* We should expect to encounter other main header marker segments
   1253 	  or an SOT marker segment next. */
   1254 	dec->state = JPC_MH;
   1255 
   1256 	return 0;
   1257 }
   1258 
   1259 static int jpc_dec_process_cod(jpc_dec_t *dec, jpc_ms_t *ms)
   1260 {
   1261 	jpc_cod_t *cod = &ms->parms.cod;
   1262 	jpc_dec_tile_t *tile;
   1263 
   1264 	switch (dec->state) {
   1265 	case JPC_MH:
   1266 		jpc_dec_cp_setfromcod(dec->cp, cod);
   1267 		break;
   1268 	case JPC_TPH:
   1269 		if (!(tile = dec->curtile)) {
   1270 			return -1;
   1271 		}
   1272 		if (tile->partno != 0) {
   1273 			return -1;
   1274 		}
   1275 		jpc_dec_cp_setfromcod(tile->cp, cod);
   1276 		break;
   1277 	}
   1278 	return 0;
   1279 }
   1280 
   1281 static int jpc_dec_process_coc(jpc_dec_t *dec, jpc_ms_t *ms)
   1282 {
   1283 	jpc_coc_t *coc = &ms->parms.coc;
   1284 	jpc_dec_tile_t *tile;
   1285 
   1286 	if (JAS_CAST(int, coc->compno) > dec->numcomps) {
   1287 		fprintf(stderr,
   1288 		  "invalid component number in COC marker segment\n");
   1289 		return -1;
   1290 	}
   1291 	switch (dec->state) {
   1292 	case JPC_MH:
   1293 		jpc_dec_cp_setfromcoc(dec->cp, coc);
   1294 		break;
   1295 	case JPC_TPH:
   1296 		if (!(tile = dec->curtile)) {
   1297 			return -1;
   1298 		}
   1299 		if (tile->partno > 0) {
   1300 			return -1;
   1301 		}
   1302 		jpc_dec_cp_setfromcoc(tile->cp, coc);
   1303 		break;
   1304 	}
   1305 	return 0;
   1306 }
   1307 
   1308 static int jpc_dec_process_rgn(jpc_dec_t *dec, jpc_ms_t *ms)
   1309 {
   1310 	jpc_rgn_t *rgn = &ms->parms.rgn;
   1311 	jpc_dec_tile_t *tile;
   1312 
   1313 	if (JAS_CAST(int, rgn->compno) > dec->numcomps) {
   1314 		fprintf(stderr,
   1315 		  "invalid component number in RGN marker segment\n");
   1316 		return -1;
   1317 	}
   1318 	switch (dec->state) {
   1319 	case JPC_MH:
   1320 		jpc_dec_cp_setfromrgn(dec->cp, rgn);
   1321 		break;
   1322 	case JPC_TPH:
   1323 		if (!(tile = dec->curtile)) {
   1324 			return -1;
   1325 		}
   1326 		if (tile->partno > 0) {
   1327 			return -1;
   1328 		}
   1329 		jpc_dec_cp_setfromrgn(tile->cp, rgn);
   1330 		break;
   1331 	}
   1332 
   1333 	return 0;
   1334 }
   1335 
   1336 static int jpc_dec_process_qcd(jpc_dec_t *dec, jpc_ms_t *ms)
   1337 {
   1338 	jpc_qcd_t *qcd = &ms->parms.qcd;
   1339 	jpc_dec_tile_t *tile;
   1340 
   1341 	switch (dec->state) {
   1342 	case JPC_MH:
   1343 		jpc_dec_cp_setfromqcd(dec->cp, qcd);
   1344 		break;
   1345 	case JPC_TPH:
   1346 		if (!(tile = dec->curtile)) {
   1347 			return -1;
   1348 		}
   1349 		if (tile->partno > 0) {
   1350 			return -1;
   1351 		}
   1352 		jpc_dec_cp_setfromqcd(tile->cp, qcd);
   1353 		break;
   1354 	}
   1355 	return 0;
   1356 }
   1357 
   1358 static int jpc_dec_process_qcc(jpc_dec_t *dec, jpc_ms_t *ms)
   1359 {
   1360 	jpc_qcc_t *qcc = &ms->parms.qcc;
   1361 	jpc_dec_tile_t *tile;
   1362 
   1363 	if (JAS_CAST(int, qcc->compno) > dec->numcomps) {
   1364 		fprintf(stderr,
   1365 		  "invalid component number in QCC marker segment\n");
   1366 		return -1;
   1367 	}
   1368 	switch (dec->state) {
   1369 	case JPC_MH:
   1370 		jpc_dec_cp_setfromqcc(dec->cp, qcc);
   1371 		break;
   1372 	case JPC_TPH:
   1373 		if (!(tile = dec->curtile)) {
   1374 			return -1;
   1375 		}
   1376 		if (tile->partno > 0) {
   1377 			return -1;
   1378 		}
   1379 		jpc_dec_cp_setfromqcc(tile->cp, qcc);
   1380 		break;
   1381 	}
   1382 	return 0;
   1383 }
   1384 
   1385 static int jpc_dec_process_poc(jpc_dec_t *dec, jpc_ms_t *ms)
   1386 {
   1387 	jpc_poc_t *poc = &ms->parms.poc;
   1388 	jpc_dec_tile_t *tile;
   1389 	switch (dec->state) {
   1390 	case JPC_MH:
   1391 		if (jpc_dec_cp_setfrompoc(dec->cp, poc, 1)) {
   1392 			return -1;
   1393 		}
   1394 		break;
   1395 	case JPC_TPH:
   1396 		if (!(tile = dec->curtile)) {
   1397 			return -1;
   1398 		}
   1399 		if (!tile->partno) {
   1400 			if (jpc_dec_cp_setfrompoc(tile->cp, poc, (!tile->partno))) {
   1401 				return -1;
   1402 			}
   1403 		} else {
   1404 			jpc_pi_addpchgfrompoc(tile->pi, poc);
   1405 		}
   1406 		break;
   1407 	}
   1408 	return 0;
   1409 }
   1410 
   1411 static int jpc_dec_process_ppm(jpc_dec_t *dec, jpc_ms_t *ms)
   1412 {
   1413 	jpc_ppm_t *ppm = &ms->parms.ppm;
   1414 	jpc_ppxstabent_t *ppmstabent;
   1415 
   1416 	if (!dec->ppmstab) {
   1417 		if (!(dec->ppmstab = jpc_ppxstab_create())) {
   1418 			return -1;
   1419 		}
   1420 	}
   1421 
   1422 	if (!(ppmstabent = jpc_ppxstabent_create())) {
   1423 		return -1;
   1424 	}
   1425 	ppmstabent->ind = ppm->ind;
   1426 	ppmstabent->data = ppm->data;
   1427 	ppm->data = 0;
   1428 	ppmstabent->len = ppm->len;
   1429 	if (jpc_ppxstab_insert(dec->ppmstab, ppmstabent)) {
   1430 		return -1;
   1431 	}
   1432 	return 0;
   1433 }
   1434 
   1435 static int jpc_dec_process_ppt(jpc_dec_t *dec, jpc_ms_t *ms)
   1436 {
   1437 	jpc_ppt_t *ppt = &ms->parms.ppt;
   1438 	jpc_dec_tile_t *tile;
   1439 	jpc_ppxstabent_t *pptstabent;
   1440 
   1441 	tile = dec->curtile;
   1442 	if (!tile->pptstab) {
   1443 		if (!(tile->pptstab = jpc_ppxstab_create())) {
   1444 			return -1;
   1445 		}
   1446 	}
   1447 	if (!(pptstabent = jpc_ppxstabent_create())) {
   1448 		return -1;
   1449 	}
   1450 	pptstabent->ind = ppt->ind;
   1451 	pptstabent->data = ppt->data;
   1452 	ppt->data = 0;
   1453 	pptstabent->len = ppt->len;
   1454 	if (jpc_ppxstab_insert(tile->pptstab, pptstabent)) {
   1455 		return -1;
   1456 	}
   1457 	return 0;
   1458 }
   1459 
   1460 static int jpc_dec_process_com(jpc_dec_t *dec, jpc_ms_t *ms)
   1461 {
   1462 	/* Eliminate compiler warnings about unused variables. */
   1463 	dec = 0;
   1464 	ms = 0;
   1465 
   1466 	return 0;
   1467 }
   1468 
   1469 static int jpc_dec_process_unk(jpc_dec_t *dec, jpc_ms_t *ms)
   1470 {
   1471 	/* Eliminate compiler warnings about unused variables. */
   1472 	dec = 0;
   1473 
   1474 	fprintf(stderr, "warning: ignoring unknown marker segment\n");
   1475 	jpc_ms_dump(ms, stderr);
   1476 	return 0;
   1477 }
   1478 
   1479 /******************************************************************************\
   1480 *
   1481 \******************************************************************************/
   1482 
   1483 static jpc_dec_cp_t *jpc_dec_cp_create(uint_fast16_t numcomps)
   1484 {
   1485 	jpc_dec_cp_t *cp;
   1486 	jpc_dec_ccp_t *ccp;
   1487 	int compno;
   1488 
   1489 	if (!(cp = jas_malloc(sizeof(jpc_dec_cp_t)))) {
   1490 		return 0;
   1491 	}
   1492 	cp->flags = 0;
   1493 	cp->numcomps = numcomps;
   1494 	cp->prgord = 0;
   1495 	cp->numlyrs = 0;
   1496 	cp->mctid = 0;
   1497 	cp->csty = 0;
   1498 	if (!(cp->ccps = jas_malloc(cp->numcomps * sizeof(jpc_dec_ccp_t)))) {
   1499 		return 0;
   1500 	}
   1501 	if (!(cp->pchglist = jpc_pchglist_create())) {
   1502 		jas_free(cp->ccps);
   1503 		return 0;
   1504 	}
   1505 	for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
   1506 	  ++compno, ++ccp) {
   1507 		ccp->flags = 0;
   1508 		ccp->numrlvls = 0;
   1509 		ccp->cblkwidthexpn = 0;
   1510 		ccp->cblkheightexpn = 0;
   1511 		ccp->qmfbid = 0;
   1512 		ccp->numstepsizes = 0;
   1513 		ccp->numguardbits = 0;
   1514 		ccp->roishift = 0;
   1515 		ccp->cblkctx = 0;
   1516 	}
   1517 	return cp;
   1518 }
   1519 
   1520 static jpc_dec_cp_t *jpc_dec_cp_copy(jpc_dec_cp_t *cp)
   1521 {
   1522 	jpc_dec_cp_t *newcp;
   1523 	jpc_dec_ccp_t *newccp;
   1524 	jpc_dec_ccp_t *ccp;
   1525 	int compno;
   1526 
   1527 	if (!(newcp = jpc_dec_cp_create(cp->numcomps))) {
   1528 		return 0;
   1529 	}
   1530 	newcp->flags = cp->flags;
   1531 	newcp->prgord = cp->prgord;
   1532 	newcp->numlyrs = cp->numlyrs;
   1533 	newcp->mctid = cp->mctid;
   1534 	newcp->csty = cp->csty;
   1535 	jpc_pchglist_destroy(newcp->pchglist);
   1536 	newcp->pchglist = 0;
   1537 	if (!(newcp->pchglist = jpc_pchglist_copy(cp->pchglist))) {
   1538 		jas_free(newcp);
   1539 		return 0;
   1540 	}
   1541 	for (compno = 0, newccp = newcp->ccps, ccp = cp->ccps;
   1542 	  compno < cp->numcomps;
   1543 	  ++compno, ++newccp, ++ccp) {
   1544 		*newccp = *ccp;
   1545 	}
   1546 	return newcp;
   1547 }
   1548 
   1549 static void jpc_dec_cp_resetflags(jpc_dec_cp_t *cp)
   1550 {
   1551 	int compno;
   1552 	jpc_dec_ccp_t *ccp;
   1553 	cp->flags &= (JPC_CSET | JPC_QSET);
   1554 	for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
   1555 	  ++compno, ++ccp) {
   1556 		ccp->flags = 0;
   1557 	}
   1558 }
   1559 
   1560 static void jpc_dec_cp_destroy(jpc_dec_cp_t *cp)
   1561 {
   1562 	if (cp->ccps) {
   1563 		jas_free(cp->ccps);
   1564 	}
   1565 	if (cp->pchglist) {
   1566 		jpc_pchglist_destroy(cp->pchglist);
   1567 	}
   1568 	jas_free(cp);
   1569 }
   1570 
   1571 static int jpc_dec_cp_isvalid(jpc_dec_cp_t *cp)
   1572 {
   1573 	uint_fast16_t compcnt;
   1574 	jpc_dec_ccp_t *ccp;
   1575 
   1576 	if (!(cp->flags & JPC_CSET) || !(cp->flags & JPC_QSET)) {
   1577 		return 0;
   1578 	}
   1579 	for (compcnt = cp->numcomps, ccp = cp->ccps; compcnt > 0; --compcnt,
   1580 	  ++ccp) {
   1581 		/* Is there enough step sizes for the number of bands? */
   1582 		if ((ccp->qsty != JPC_QCX_SIQNT && JAS_CAST(int, ccp->numstepsizes) < 3 *
   1583 		  ccp->numrlvls - 2) || (ccp->qsty == JPC_QCX_SIQNT &&
   1584 		  ccp->numstepsizes != 1)) {
   1585 			return 0;
   1586 		}
   1587 	}
   1588 	return 1;
   1589 }
   1590 
   1591 static void calcstepsizes(uint_fast16_t refstepsize, int numrlvls,
   1592   uint_fast16_t *stepsizes)
   1593 {
   1594 	int bandno;
   1595 	int numbands;
   1596 	uint_fast16_t expn;
   1597 	uint_fast16_t mant;
   1598 	expn = JPC_QCX_GETEXPN(refstepsize);
   1599 	mant = JPC_QCX_GETMANT(refstepsize);
   1600 	numbands = 3 * numrlvls - 2;
   1601 	for (bandno = 0; bandno < numbands; ++bandno) {
   1602 		stepsizes[bandno] = JPC_QCX_MANT(mant) | JPC_QCX_EXPN(expn +
   1603 		  (numrlvls - 1) - (numrlvls - 1 - ((bandno > 0) ? ((bandno + 2) / 3) : (0))));
   1604 	}
   1605 }
   1606 
   1607 static int jpc_dec_cp_prepare(jpc_dec_cp_t *cp)
   1608 {
   1609 	jpc_dec_ccp_t *ccp;
   1610 	int compno;
   1611 	int i;
   1612 	for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
   1613 	  ++compno, ++ccp) {
   1614 		if (!(ccp->csty & JPC_COX_PRT)) {
   1615 			for (i = 0; i < JPC_MAXRLVLS; ++i) {
   1616 				ccp->prcwidthexpns[i] = 15;
   1617 				ccp->prcheightexpns[i] = 15;
   1618 			}
   1619 		}
   1620 		if (ccp->qsty == JPC_QCX_SIQNT) {
   1621 			calcstepsizes(ccp->stepsizes[0], ccp->numrlvls, ccp->stepsizes);
   1622 		}
   1623 	}
   1624 	return 0;
   1625 }
   1626 
   1627 static int jpc_dec_cp_setfromcod(jpc_dec_cp_t *cp, jpc_cod_t *cod)
   1628 {
   1629 	jpc_dec_ccp_t *ccp;
   1630 	int compno;
   1631 	cp->flags |= JPC_CSET;
   1632 	cp->prgord = cod->prg;
   1633 	if (cod->mctrans) {
   1634 		cp->mctid = (cod->compparms.qmfbid == JPC_COX_INS) ? (JPC_MCT_ICT) : (JPC_MCT_RCT);
   1635 	} else {
   1636 		cp->mctid = JPC_MCT_NONE;
   1637 	}
   1638 	cp->numlyrs = cod->numlyrs;
   1639 	cp->csty = cod->csty & (JPC_COD_SOP | JPC_COD_EPH);
   1640 	for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
   1641 	  ++compno, ++ccp) {
   1642 		jpc_dec_cp_setfromcox(cp, ccp, &cod->compparms, 0);
   1643 	}
   1644 	cp->flags |= JPC_CSET;
   1645 	return 0;
   1646 }
   1647 
   1648 static int jpc_dec_cp_setfromcoc(jpc_dec_cp_t *cp, jpc_coc_t *coc)
   1649 {
   1650 	jpc_dec_cp_setfromcox(cp, &cp->ccps[coc->compno], &coc->compparms, JPC_COC);
   1651 	return 0;
   1652 }
   1653 
   1654 static int jpc_dec_cp_setfromcox(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp,
   1655   jpc_coxcp_t *compparms, int flags)
   1656 {
   1657 	int rlvlno;
   1658 
   1659 	/* Eliminate compiler warnings about unused variables. */
   1660 	cp = 0;
   1661 
   1662 	if ((flags & JPC_COC) || !(ccp->flags & JPC_COC)) {
   1663 		ccp->numrlvls = compparms->numdlvls + 1;
   1664 		ccp->cblkwidthexpn = JPC_COX_GETCBLKSIZEEXPN(
   1665 		  compparms->cblkwidthval);
   1666 		ccp->cblkheightexpn = JPC_COX_GETCBLKSIZEEXPN(
   1667 		  compparms->cblkheightval);
   1668 		ccp->qmfbid = compparms->qmfbid;
   1669 		ccp->cblkctx = compparms->cblksty;
   1670 		ccp->csty = compparms->csty & JPC_COX_PRT;
   1671 		for (rlvlno = 0; rlvlno < compparms->numrlvls; ++rlvlno) {
   1672 			ccp->prcwidthexpns[rlvlno] =
   1673 			  compparms->rlvls[rlvlno].parwidthval;
   1674 			ccp->prcheightexpns[rlvlno] =
   1675 			  compparms->rlvls[rlvlno].parheightval;
   1676 		}
   1677 		ccp->flags |= flags | JPC_CSET;
   1678 	}
   1679 	return 0;
   1680 }
   1681 
   1682 static int jpc_dec_cp_setfromqcd(jpc_dec_cp_t *cp, jpc_qcd_t *qcd)
   1683 {
   1684 	int compno;
   1685 	jpc_dec_ccp_t *ccp;
   1686 	for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
   1687 	  ++compno, ++ccp) {
   1688 		jpc_dec_cp_setfromqcx(cp, ccp, &qcd->compparms, 0);
   1689 	}
   1690 	cp->flags |= JPC_QSET;
   1691 	return 0;
   1692 }
   1693 
   1694 static int jpc_dec_cp_setfromqcc(jpc_dec_cp_t *cp, jpc_qcc_t *qcc)
   1695 {
   1696 	return jpc_dec_cp_setfromqcx(cp, &cp->ccps[qcc->compno], &qcc->compparms, JPC_QCC);
   1697 }
   1698 
   1699 static int jpc_dec_cp_setfromqcx(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp,
   1700   jpc_qcxcp_t *compparms, int flags)
   1701 {
   1702 	int bandno;
   1703 
   1704 	/* Eliminate compiler warnings about unused variables. */
   1705 	cp = 0;
   1706 
   1707 	if ((flags & JPC_QCC) || !(ccp->flags & JPC_QCC)) {
   1708 		ccp->flags |= flags | JPC_QSET;
   1709 		for (bandno = 0; bandno < compparms->numstepsizes; ++bandno) {
   1710 			ccp->stepsizes[bandno] = compparms->stepsizes[bandno];
   1711 		}
   1712 		ccp->numstepsizes = compparms->numstepsizes;
   1713 		ccp->numguardbits = compparms->numguard;
   1714 		ccp->qsty = compparms->qntsty;
   1715 	}
   1716 	return 0;
   1717 }
   1718 
   1719 static int jpc_dec_cp_setfromrgn(jpc_dec_cp_t *cp, jpc_rgn_t *rgn)
   1720 {
   1721 	jpc_dec_ccp_t *ccp;
   1722 	ccp = &cp->ccps[rgn->compno];
   1723 	ccp->roishift = rgn->roishift;
   1724 	return 0;
   1725 }
   1726 
   1727 static int jpc_pi_addpchgfrompoc(jpc_pi_t *pi, jpc_poc_t *poc)
   1728 {
   1729 	int pchgno;
   1730 	jpc_pchg_t *pchg;
   1731 	for (pchgno = 0; pchgno < poc->numpchgs; ++pchgno) {
   1732 		if (!(pchg = jpc_pchg_copy(&poc->pchgs[pchgno]))) {
   1733 			return -1;
   1734 		}
   1735 		if (jpc_pchglist_insert(pi->pchglist, -1, pchg)) {
   1736 			return -1;
   1737 		}
   1738 	}
   1739 	return 0;
   1740 }
   1741 
   1742 static int jpc_dec_cp_setfrompoc(jpc_dec_cp_t *cp, jpc_poc_t *poc, int reset)
   1743 {
   1744 	int pchgno;
   1745 	jpc_pchg_t *pchg;
   1746 	if (reset) {
   1747 		while (jpc_pchglist_numpchgs(cp->pchglist) > 0) {
   1748 			pchg = jpc_pchglist_remove(cp->pchglist, 0);
   1749 			jpc_pchg_destroy(pchg);
   1750 		}
   1751 	}
   1752 	for (pchgno = 0; pchgno < poc->numpchgs; ++pchgno) {
   1753 		if (!(pchg = jpc_pchg_copy(&poc->pchgs[pchgno]))) {
   1754 			return -1;
   1755 		}
   1756 		if (jpc_pchglist_insert(cp->pchglist, -1, pchg)) {
   1757 			return -1;
   1758 		}
   1759 	}
   1760 	return 0;
   1761 }
   1762 
   1763 static jpc_fix_t jpc_calcabsstepsize(int stepsize, int numbits)
   1764 {
   1765 	jpc_fix_t absstepsize;
   1766 	int n;
   1767 
   1768 	absstepsize = jpc_inttofix(1);
   1769 	n = JPC_FIX_FRACBITS - 11;
   1770 	absstepsize |= (n >= 0) ? (JPC_QCX_GETMANT(stepsize) << n) :
   1771 	  (JPC_QCX_GETMANT(stepsize) >> (-n));
   1772 	n = numbits - JPC_QCX_GETEXPN(stepsize);
   1773 	absstepsize = (n >= 0) ? (absstepsize << n) : (absstepsize >> (-n));
   1774 	return absstepsize;
   1775 }
   1776 
   1777 static void jpc_dequantize(jas_matrix_t *x, jpc_fix_t absstepsize)
   1778 {
   1779 	int i;
   1780 	int j;
   1781 	int t;
   1782 
   1783 	assert(absstepsize >= 0);
   1784 	if (absstepsize == jpc_inttofix(1)) {
   1785 		return;
   1786 	}
   1787 
   1788 	for (i = 0; i < jas_matrix_numrows(x); ++i) {
   1789 		for (j = 0; j < jas_matrix_numcols(x); ++j) {
   1790 			t = jas_matrix_get(x, i, j);
   1791 			if (t) {
   1792 				t = jpc_fix_mul(t, absstepsize);
   1793 			} else {
   1794 				t = 0;
   1795 			}
   1796 			jas_matrix_set(x, i, j, t);
   1797 		}
   1798 	}
   1799 
   1800 }
   1801 
   1802 static void jpc_undo_roi(jas_matrix_t *x, int roishift, int bgshift, int numbps)
   1803 {
   1804 	int i;
   1805 	int j;
   1806 	int thresh;
   1807 	jpc_fix_t val;
   1808 	jpc_fix_t mag;
   1809 	bool warn;
   1810 	uint_fast32_t mask;
   1811 
   1812 	if (roishift == 0 && bgshift == 0) {
   1813 		return;
   1814 	}
   1815 	thresh = 1 << roishift;
   1816 
   1817 	warn = false;
   1818 	for (i = 0; i < jas_matrix_numrows(x); ++i) {
   1819 		for (j = 0; j < jas_matrix_numcols(x); ++j) {
   1820 			val = jas_matrix_get(x, i, j);
   1821 			mag = JAS_ABS(val);
   1822 			if (mag >= thresh) {
   1823 				/* We are dealing with ROI data. */
   1824 				mag >>= roishift;
   1825 				val = (val < 0) ? (-mag) : mag;
   1826 				jas_matrix_set(x, i, j, val);
   1827 			} else {
   1828 				/* We are dealing with non-ROI (i.e., background) data. */
   1829 				mag <<= bgshift;
   1830 				mask = (1 << numbps) - 1;
   1831 				/* Perform a basic sanity check on the sample value. */
   1832 				/* Some implementations write garbage in the unused
   1833 				  most-significant bit planes introduced by ROI shifting.
   1834 				  Here we ensure that any such bits are masked off. */
   1835 				if (mag & (~mask)) {
   1836 					if (!warn) {
   1837 						fprintf(stderr,
   1838 						  "warning: possibly corrupt code stream\n");
   1839 						warn = true;
   1840 					}
   1841 					mag &= mask;
   1842 				}
   1843 				val = (val < 0) ? (-mag) : mag;
   1844 				jas_matrix_set(x, i, j, val);
   1845 			}
   1846 		}
   1847 	}
   1848 }
   1849 
   1850 static jpc_dec_t *jpc_dec_create(jpc_dec_importopts_t *impopts, jas_stream_t *in)
   1851 {
   1852 	jpc_dec_t *dec;
   1853 
   1854 	if (!(dec = jas_malloc(sizeof(jpc_dec_t)))) {
   1855 		return 0;
   1856 	}
   1857 
   1858 	dec->image = 0;
   1859 	dec->xstart = 0;
   1860 	dec->ystart = 0;
   1861 	dec->xend = 0;
   1862 	dec->yend = 0;
   1863 	dec->tilewidth = 0;
   1864 	dec->tileheight = 0;
   1865 	dec->tilexoff = 0;
   1866 	dec->tileyoff = 0;
   1867 	dec->numhtiles = 0;
   1868 	dec->numvtiles = 0;
   1869 	dec->numtiles = 0;
   1870 	dec->tiles = 0;
   1871 	dec->curtile = 0;
   1872 	dec->numcomps = 0;
   1873 	dec->in = in;
   1874 	dec->cp = 0;
   1875 	dec->maxlyrs = impopts->maxlyrs;
   1876 	dec->maxpkts = impopts->maxpkts;
   1877 dec->numpkts = 0;
   1878 	dec->ppmseqno = 0;
   1879 	dec->state = 0;
   1880 	dec->cmpts = 0;
   1881 	dec->pkthdrstreams = 0;
   1882 	dec->ppmstab = 0;
   1883 	dec->curtileendoff = 0;
   1884 
   1885 	return dec;
   1886 }
   1887 
   1888 static void jpc_dec_destroy(jpc_dec_t *dec)
   1889 {
   1890 	if (dec->cstate) {
   1891 		jpc_cstate_destroy(dec->cstate);
   1892 	}
   1893 	if (dec->pkthdrstreams) {
   1894 		jpc_streamlist_destroy(dec->pkthdrstreams);
   1895 	}
   1896 	if (dec->image) {
   1897 		jas_image_destroy(dec->image);
   1898 	}
   1899 
   1900 	if (dec->cp) {
   1901 		jpc_dec_cp_destroy(dec->cp);
   1902 	}
   1903 
   1904 	if (dec->cmpts) {
   1905 		jas_free(dec->cmpts);
   1906 	}
   1907 
   1908 	if (dec->tiles) {
   1909 		jas_free(dec->tiles);
   1910 	}
   1911 
   1912 	jas_free(dec);
   1913 }
   1914 
   1915 /******************************************************************************\
   1916 *
   1917 \******************************************************************************/
   1918 
   1919 void jpc_seglist_insert(jpc_dec_seglist_t *list, jpc_dec_seg_t *ins, jpc_dec_seg_t *node)
   1920 {
   1921 	jpc_dec_seg_t *prev;
   1922 	jpc_dec_seg_t *next;
   1923 
   1924 	prev = ins;
   1925 	node->prev = prev;
   1926 	next = prev ? (prev->next) : 0;
   1927 	node->prev = prev;
   1928 	node->next = next;
   1929 	if (prev) {
   1930 		prev->next = node;
   1931 	} else {
   1932 		list->head = node;
   1933 	}
   1934 	if (next) {
   1935 		next->prev = node;
   1936 	} else {
   1937 		list->tail = node;
   1938 	}
   1939 }
   1940 
   1941 void jpc_seglist_remove(jpc_dec_seglist_t *list, jpc_dec_seg_t *seg)
   1942 {
   1943 	jpc_dec_seg_t *prev;
   1944 	jpc_dec_seg_t *next;
   1945 
   1946 	prev = seg->prev;
   1947 	next = seg->next;
   1948 	if (prev) {
   1949 		prev->next = next;
   1950 	} else {
   1951 		list->head = next;
   1952 	}
   1953 	if (next) {
   1954 		next->prev = prev;
   1955 	} else {
   1956 		list->tail = prev;
   1957 	}
   1958 	seg->prev = 0;
   1959 	seg->next = 0;
   1960 }
   1961 
   1962 jpc_dec_seg_t *jpc_seg_alloc()
   1963 {
   1964 	jpc_dec_seg_t *seg;
   1965 
   1966 	if (!(seg = jas_malloc(sizeof(jpc_dec_seg_t)))) {
   1967 		return 0;
   1968 	}
   1969 	seg->prev = 0;
   1970 	seg->next = 0;
   1971 	seg->passno = -1;
   1972 	seg->numpasses = 0;
   1973 	seg->maxpasses = 0;
   1974 	seg->type = JPC_SEG_INVALID;
   1975 	seg->stream = 0;
   1976 	seg->cnt = 0;
   1977 	seg->complete = 0;
   1978 	seg->lyrno = -1;
   1979 	return seg;
   1980 }
   1981 
   1982 void jpc_seg_destroy(jpc_dec_seg_t *seg)
   1983 {
   1984 	if (seg->stream) {
   1985 		jas_stream_close(seg->stream);
   1986 	}
   1987 	jas_free(seg);
   1988 }
   1989 
   1990 static int jpc_dec_dump(jpc_dec_t *dec, FILE *out)
   1991 {
   1992 	jpc_dec_tile_t *tile;
   1993 	int tileno;
   1994 	jpc_dec_tcomp_t *tcomp;
   1995 	int compno;
   1996 	jpc_dec_rlvl_t *rlvl;
   1997 	int rlvlno;
   1998 	jpc_dec_band_t *band;
   1999 	int bandno;
   2000 	jpc_dec_prc_t *prc;
   2001 	int prcno;
   2002 	jpc_dec_cblk_t *cblk;
   2003 	int cblkno;
   2004 
   2005 	for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles;
   2006 	  ++tileno, ++tile) {
   2007 		for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
   2008 		  ++compno, ++tcomp) {
   2009 			for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno <
   2010 			  tcomp->numrlvls; ++rlvlno, ++rlvl) {
   2011 fprintf(out, "RESOLUTION LEVEL %d\n", rlvlno);
   2012 fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n",
   2013   (int)rlvl->xstart, (int)rlvl->ystart,(int) rlvl->xend, (int)rlvl->yend, (int)rlvl->xend -
   2014   (int)rlvl->xstart, (int)rlvl->yend - (int)rlvl->ystart);
   2015 				for (bandno = 0, band = rlvl->bands;
   2016 				  bandno < rlvl->numbands; ++bandno, ++band) {
   2017 fprintf(out, "BAND %d\n", bandno);
   2018 fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n",
   2019   jas_seq2d_xstart(band->data), jas_seq2d_ystart(band->data), jas_seq2d_xend(band->data),
   2020   jas_seq2d_yend(band->data), jas_seq2d_xend(band->data) - jas_seq2d_xstart(band->data),
   2021   jas_seq2d_yend(band->data) - jas_seq2d_ystart(band->data));
   2022 					for (prcno = 0, prc = band->prcs;
   2023 					  prcno < rlvl->numprcs; ++prcno,
   2024 					  ++prc) {
   2025 fprintf(out, "CODE BLOCK GROUP %d\n", prcno);
   2026 fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n",
   2027   (int)prc->xstart, (int)prc->ystart, (int)prc->xend, (int)prc->yend, (int)prc->xend -
   2028   (int)prc->xstart, (int)prc->yend - (int)prc->ystart);
   2029 						for (cblkno = 0, cblk =
   2030 						  prc->cblks; cblkno <
   2031 						  prc->numcblks; ++cblkno,
   2032 						  ++cblk) {
   2033 fprintf(out, "CODE BLOCK %d\n", cblkno);
   2034 fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n",
   2035   jas_seq2d_xstart(cblk->data), jas_seq2d_ystart(cblk->data), jas_seq2d_xend(cblk->data),
   2036   jas_seq2d_yend(cblk->data), jas_seq2d_xend(cblk->data) - jas_seq2d_xstart(cblk->data),
   2037   jas_seq2d_yend(cblk->data) - jas_seq2d_ystart(cblk->data));
   2038 						}
   2039 					}
   2040 				}
   2041 			}
   2042 		}
   2043 	}
   2044 
   2045 	return 0;
   2046 }
   2047 
   2048 jpc_streamlist_t *jpc_streamlist_create()
   2049 {
   2050 	jpc_streamlist_t *streamlist;
   2051 	int i;
   2052 
   2053 	if (!(streamlist = jas_malloc(sizeof(jpc_streamlist_t)))) {
   2054 		return 0;
   2055 	}
   2056 	streamlist->numstreams = 0;
   2057 	streamlist->maxstreams = 100;
   2058 	if (!(streamlist->streams = jas_malloc(streamlist->maxstreams *
   2059 	  sizeof(jas_stream_t *)))) {
   2060 		jas_free(streamlist);
   2061 		return 0;
   2062 	}
   2063 	for (i = 0; i < streamlist->maxstreams; ++i) {
   2064 		streamlist->streams[i] = 0;
   2065 	}
   2066 	return streamlist;
   2067 }
   2068 
   2069 int jpc_streamlist_insert(jpc_streamlist_t *streamlist, int streamno,
   2070   jas_stream_t *stream)
   2071 {
   2072 	jas_stream_t **newstreams;
   2073 	int newmaxstreams;
   2074 	int i;
   2075 	/* Grow the array of streams if necessary. */
   2076 	if (streamlist->numstreams >= streamlist->maxstreams) {
   2077 		newmaxstreams = streamlist->maxstreams + 1024;
   2078 		if (!(newstreams = jas_realloc(streamlist->streams,
   2079 		  (newmaxstreams + 1024) * sizeof(jas_stream_t *)))) {
   2080 			return -1;
   2081 		}
   2082 		for (i = streamlist->numstreams; i < streamlist->maxstreams; ++i) {
   2083 			streamlist->streams[i] = 0;
   2084 		}
   2085 		streamlist->maxstreams = newmaxstreams;
   2086 		streamlist->streams = newstreams;
   2087 	}
   2088 	if (streamno != streamlist->numstreams) {
   2089 		/* Can only handle insertion at start of list. */
   2090 		return -1;
   2091 	}
   2092 	streamlist->streams[streamno] = stream;
   2093 	++streamlist->numstreams;
   2094 	return 0;
   2095 }
   2096 
   2097 jas_stream_t *jpc_streamlist_remove(jpc_streamlist_t *streamlist, int streamno)
   2098 {
   2099 	jas_stream_t *stream;
   2100 	int i;
   2101 	if (streamno >= streamlist->numstreams) {
   2102 		abort();
   2103 	}
   2104 	stream = streamlist->streams[streamno];
   2105 	for (i = streamno + 1; i < streamlist->numstreams; ++i) {
   2106 		streamlist->streams[i - 1] = streamlist->streams[i];
   2107 	}
   2108 	--streamlist->numstreams;
   2109 	return stream;
   2110 }
   2111 
   2112 void jpc_streamlist_destroy(jpc_streamlist_t *streamlist)
   2113 {
   2114 	int streamno;
   2115 	if (streamlist->streams) {
   2116 		for (streamno = 0; streamno < streamlist->numstreams;
   2117 		  ++streamno) {
   2118 			jas_stream_close(streamlist->streams[streamno]);
   2119 		}
   2120 		jas_free(streamlist->streams);
   2121 	}
   2122 	jas_free(streamlist);
   2123 }
   2124 
   2125 jas_stream_t *jpc_streamlist_get(jpc_streamlist_t *streamlist, int streamno)
   2126 {
   2127 	assert(streamno < streamlist->numstreams);
   2128 	return streamlist->streams[streamno];
   2129 }
   2130 
   2131 int jpc_streamlist_numstreams(jpc_streamlist_t *streamlist)
   2132 {
   2133 	return streamlist->numstreams;
   2134 }
   2135 
   2136 jpc_ppxstab_t *jpc_ppxstab_create()
   2137 {
   2138 	jpc_ppxstab_t *tab;
   2139 
   2140 	if (!(tab = jas_malloc(sizeof(jpc_ppxstab_t)))) {
   2141 		return 0;
   2142 	}
   2143 	tab->numents = 0;
   2144 	tab->maxents = 0;
   2145 	tab->ents = 0;
   2146 	return tab;
   2147 }
   2148 
   2149 void jpc_ppxstab_destroy(jpc_ppxstab_t *tab)
   2150 {
   2151 	int i;
   2152 	for (i = 0; i < tab->numents; ++i) {
   2153 		jpc_ppxstabent_destroy(tab->ents[i]);
   2154 	}
   2155 	if (tab->ents) {
   2156 		jas_free(tab->ents);
   2157 	}
   2158 	jas_free(tab);
   2159 }
   2160 
   2161 int jpc_ppxstab_grow(jpc_ppxstab_t *tab, int maxents)
   2162 {
   2163 	jpc_ppxstabent_t **newents;
   2164 	if (tab->maxents < maxents) {
   2165 		newents = (tab->ents) ? jas_realloc(tab->ents, maxents *
   2166 		  sizeof(jpc_ppxstabent_t *)) : jas_malloc(maxents * sizeof(jpc_ppxstabent_t *));
   2167 		if (!newents) {
   2168 			return -1;
   2169 		}
   2170 		tab->ents = newents;
   2171 		tab->maxents = maxents;
   2172 	}
   2173 	return 0;
   2174 }
   2175 
   2176 int jpc_ppxstab_insert(jpc_ppxstab_t *tab, jpc_ppxstabent_t *ent)
   2177 {
   2178 	int inspt;
   2179 	int i;
   2180 
   2181 	for (i = 0; i < tab->numents; ++i) {
   2182 		if (tab->ents[i]->ind > ent->ind) {
   2183 			break;
   2184 		}
   2185 	}
   2186 	inspt = i;
   2187 
   2188 	if (tab->numents >= tab->maxents) {
   2189 		if (jpc_ppxstab_grow(tab, tab->maxents + 128)) {
   2190 			return -1;
   2191 		}
   2192 	}
   2193 
   2194 	for (i = tab->numents; i > inspt; --i) {
   2195 		tab->ents[i] = tab->ents[i - 1];
   2196 	}
   2197 	tab->ents[i] = ent;
   2198 	++tab->numents;
   2199 
   2200 	return 0;
   2201 }
   2202 
   2203 jpc_streamlist_t *jpc_ppmstabtostreams(jpc_ppxstab_t *tab)
   2204 {
   2205 	jpc_streamlist_t *streams;
   2206 	uchar *dataptr;
   2207 	uint_fast32_t datacnt;
   2208 	uint_fast32_t tpcnt;
   2209 	jpc_ppxstabent_t *ent;
   2210 	int entno;
   2211 	jas_stream_t *stream;
   2212 	int n;
   2213 
   2214 	if (!(streams = jpc_streamlist_create())) {
   2215 		goto error;
   2216 	}
   2217 
   2218 	if (!tab->numents) {
   2219 		return streams;
   2220 	}
   2221 
   2222 	entno = 0;
   2223 	ent = tab->ents[entno];
   2224 	dataptr = ent->data;
   2225 	datacnt = ent->len;
   2226 	for (;;) {
   2227 
   2228 		/* Get the length of the packet header data for the current
   2229 		  tile-part. */
   2230 		if (datacnt < 4) {
   2231 			goto error;
   2232 		}
   2233 		if (!(stream = jas_stream_memopen(0, 0))) {
   2234 			goto error;
   2235 		}
   2236 		if (jpc_streamlist_insert(streams, jpc_streamlist_numstreams(streams),
   2237 		  stream)) {
   2238 			goto error;
   2239 		}
   2240 		tpcnt = (dataptr[0] << 24) | (dataptr[1] << 16) | (dataptr[2] << 8)
   2241 		  | dataptr[3];
   2242 		datacnt -= 4;
   2243 		dataptr += 4;
   2244 
   2245 		/* Get the packet header data for the current tile-part. */
   2246 		while (tpcnt) {
   2247 			if (!datacnt) {
   2248 				if (++entno >= tab->numents) {
   2249 					goto error;
   2250 				}
   2251 				ent = tab->ents[entno];
   2252 				dataptr = ent->data;
   2253 				datacnt = ent->len;
   2254 			}
   2255 			n = JAS_MIN(tpcnt, datacnt);
   2256 			if (jas_stream_write(stream, dataptr, n) != n) {
   2257 				goto error;
   2258 			}
   2259 			tpcnt -= n;
   2260 			dataptr += n;
   2261 			datacnt -= n;
   2262 		}
   2263 		jas_stream_rewind(stream);
   2264 		if (!datacnt) {
   2265 			if (++entno >= tab->numents) {
   2266 				break;
   2267 			}
   2268 			ent = tab->ents[entno];
   2269 			dataptr = ent->data;
   2270 			datacnt = ent->len;
   2271 		}
   2272 	}
   2273 
   2274 	return streams;
   2275 
   2276 error:
   2277 	jpc_streamlist_destroy(streams);
   2278 	return 0;
   2279 }
   2280 
   2281 int jpc_pptstabwrite(jas_stream_t *out, jpc_ppxstab_t *tab)
   2282 {
   2283 	int i;
   2284 	jpc_ppxstabent_t *ent;
   2285 	for (i = 0; i < tab->numents; ++i) {
   2286 		ent = tab->ents[i];
   2287 		if (jas_stream_write(out, ent->data, ent->len) != JAS_CAST(int, ent->len)) {
   2288 			return -1;
   2289 		}
   2290 	}
   2291 	return 0;
   2292 }
   2293 
   2294 jpc_ppxstabent_t *jpc_ppxstabent_create()
   2295 {
   2296 	jpc_ppxstabent_t *ent;
   2297 	if (!(ent = jas_malloc(sizeof(jpc_ppxstabent_t)))) {
   2298 		return 0;
   2299 	}
   2300 	ent->data = 0;
   2301 	ent->len = 0;
   2302 	ent->ind = 0;
   2303 	return ent;
   2304 }
   2305 
   2306 void jpc_ppxstabent_destroy(jpc_ppxstabent_t *ent)
   2307 {
   2308 	if (ent->data) {
   2309 		jas_free(ent->data);
   2310 	}
   2311 	jas_free(ent);
   2312 }