vx32

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

jpc_t1dec.c (25593B)


      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  * Tier 1 Decoder
     66  *
     67  * $Id: jpc_t1dec.c 1918 2005-07-24 14:12:08Z baford $
     68  */
     69 
     70 /******************************************************************************\
     71 * Includes.
     72 \******************************************************************************/
     73 
     74 #include <stdio.h>
     75 #include <stdlib.h>
     76 #include <assert.h>
     77 
     78 #include "jasper/jas_fix.h"
     79 #include "jasper/jas_stream.h"
     80 #include "jasper/jas_math.h"
     81 
     82 #include "jpc_bs.h"
     83 #include "jpc_mqdec.h"
     84 #include "jpc_t1dec.h"
     85 #include "jpc_t1cod.h"
     86 #include "jpc_dec.h"
     87 
     88 /******************************************************************************\
     89 *
     90 \******************************************************************************/
     91 
     92 static int jpc_dec_decodecblk(jpc_dec_t *dec, jpc_dec_tile_t *tile, jpc_dec_tcomp_t *tcomp, jpc_dec_band_t *band,
     93   jpc_dec_cblk_t *cblk, int dopartial, int maxlyrs);
     94 static int dec_sigpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int orient,
     95   int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
     96 static int dec_rawsigpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos,
     97   int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
     98 static int dec_refpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int vcausalflag,
     99   jas_matrix_t *flags, jas_matrix_t *data);
    100 static int dec_rawrefpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos,
    101   int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
    102 static int dec_clnpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int orient,
    103   int vcausalflag, int segsymflag, jas_matrix_t *flags, jas_matrix_t *data);
    104 
    105 #if defined(DEBUG)
    106 static long t1dec_cnt = 0;
    107 #endif
    108 
    109 #if !defined(DEBUG)
    110 #define	JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename) \
    111 	((v) = jpc_mqdec_getbit(mqdec))
    112 #else
    113 #define	JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename) \
    114 { \
    115 	(v) = jpc_mqdec_getbit(mqdec); \
    116 	if (jas_getdbglevel() >= 100) { \
    117 		fprintf(stderr, "index = %ld; passtype = %s; symtype = %s; sym = %d\n", t1dec_cnt, passtypename, symtypename, v); \
    118 		++t1dec_cnt; \
    119 	} \
    120 }
    121 #endif
    122 #define	JPC_T1D_GETBITNOSKEW(mqdec, v, passtypename, symtypename) \
    123 	JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename)
    124 
    125 #if !defined(DEBUG)
    126 #define	JPC_T1D_RAWGETBIT(bitstream, v, passtypename, symtypename) \
    127 	((v) = jpc_bitstream_getbit(bitstream))
    128 #else
    129 #define	JPC_T1D_RAWGETBIT(bitstream, v, passtypename, symtypename) \
    130 { \
    131 	(v) = jpc_bitstream_getbit(bitstream); \
    132 	if (jas_getdbglevel() >= 100) { \
    133 		fprintf(stderr, "index = %ld; passtype = %s; symtype = %s; sym = %d\n", t1dec_cnt, passtypename, symtypename, v); \
    134 		++t1dec_cnt; \
    135 	} \
    136 }
    137 #endif
    138 
    139 /******************************************************************************\
    140 * Code.
    141 \******************************************************************************/
    142 
    143 int jpc_dec_decodecblks(jpc_dec_t *dec, jpc_dec_tile_t *tile)
    144 {
    145 	jpc_dec_tcomp_t *tcomp;
    146 	int compcnt;
    147 	jpc_dec_rlvl_t *rlvl;
    148 	int rlvlcnt;
    149 	jpc_dec_band_t *band;
    150 	int bandcnt;
    151 	jpc_dec_prc_t *prc;
    152 	int prccnt;
    153 	jpc_dec_cblk_t *cblk;
    154 	int cblkcnt;
    155 
    156 	for (compcnt = dec->numcomps, tcomp = tile->tcomps; compcnt > 0;
    157 	  --compcnt, ++tcomp) {
    158 		for (rlvlcnt = tcomp->numrlvls, rlvl = tcomp->rlvls;
    159 		  rlvlcnt > 0; --rlvlcnt, ++rlvl) {
    160 			if (!rlvl->bands) {
    161 				continue;
    162 			}
    163 			for (bandcnt = rlvl->numbands, band = rlvl->bands;
    164 			  bandcnt > 0; --bandcnt, ++band) {
    165 				if (!band->data) {
    166 					continue;
    167 				}
    168 				for (prccnt = rlvl->numprcs, prc = band->prcs;
    169 				  prccnt > 0; --prccnt, ++prc) {
    170 					if (!prc->cblks) {
    171 						continue;
    172 					}
    173 					for (cblkcnt = prc->numcblks,
    174 					  cblk = prc->cblks; cblkcnt > 0;
    175 					  --cblkcnt, ++cblk) {
    176 						if (jpc_dec_decodecblk(dec, tile, tcomp,
    177 						  band, cblk, 1, JPC_MAXLYRS)) {
    178 							return -1;
    179 						}
    180 					}
    181 				}
    182 
    183 			}
    184 		}
    185 	}
    186 
    187 	return 0;
    188 }
    189 
    190 static int jpc_dec_decodecblk(jpc_dec_t *dec, jpc_dec_tile_t *tile, jpc_dec_tcomp_t *tcomp, jpc_dec_band_t *band,
    191   jpc_dec_cblk_t *cblk, int dopartial, int maxlyrs)
    192 {
    193 	jpc_dec_seg_t *seg;
    194 	int i;
    195 	int bpno;
    196 	int passtype;
    197 	int ret;
    198 	int compno;
    199 	int filldata;
    200 	int fillmask;
    201 	jpc_dec_ccp_t *ccp;
    202 
    203 	compno = tcomp - tile->tcomps;
    204 
    205 	if (!cblk->flags) {
    206 		/* Note: matrix is assumed to be zeroed */
    207 		if (!(cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) +
    208 		  2, jas_matrix_numcols(cblk->data) + 2))) {
    209 			return -1;
    210 		}
    211 	}
    212 
    213 	seg = cblk->segs.head;
    214 	while (seg && (seg != cblk->curseg || dopartial) && (maxlyrs < 0 ||
    215 	  seg->lyrno < maxlyrs)) {
    216 		assert(seg->numpasses >= seg->maxpasses || dopartial);
    217 		assert(seg->stream);
    218 		jas_stream_rewind(seg->stream);
    219 		jas_stream_setrwcount(seg->stream, 0);
    220 		if (seg->type == JPC_SEG_MQ) {
    221 			if (!cblk->mqdec) {
    222 				if (!(cblk->mqdec = jpc_mqdec_create(JPC_NUMCTXS, 0))) {
    223 					return -1;
    224 				}
    225 				jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
    226 			}
    227 			jpc_mqdec_setinput(cblk->mqdec, seg->stream);
    228 			jpc_mqdec_init(cblk->mqdec);
    229 		} else {
    230 			assert(seg->type == JPC_SEG_RAW);
    231 			if (!cblk->nulldec) {
    232 				if (!(cblk->nulldec = jpc_bitstream_sopen(seg->stream, "r"))) {
    233 					assert(0);
    234 				}
    235 			}
    236 		}
    237 
    238 
    239 		for (i = 0; i < seg->numpasses; ++i) {
    240 			if (cblk->numimsbs > band->numbps) {
    241 				ccp = &tile->cp->ccps[compno];
    242 				if (ccp->roishift <= 0) {
    243 					fprintf(stderr, "warning: corrupt code stream\n");
    244 				} else {
    245 					if (cblk->numimsbs < ccp->roishift - band->numbps) {
    246 						fprintf(stderr, "warning: corrupt code stream\n");
    247 					}
    248 				}
    249 			}
    250 			bpno = band->roishift + band->numbps - 1 - (cblk->numimsbs +
    251 			  (seg->passno + i - cblk->firstpassno + 2) / 3);
    252 if (bpno < 0) {
    253 	goto premature_exit;
    254 }
    255 #if 1
    256 			passtype = (seg->passno + i + 2) % 3;
    257 #else
    258 			passtype = JPC_PASSTYPE(seg->passno + i + 2);
    259 #endif
    260 			assert(bpno >= 0 && bpno < 31);
    261 			switch (passtype) {
    262 			case JPC_SIGPASS:
    263 				ret = (seg->type == JPC_SEG_MQ) ? dec_sigpass(dec,
    264 				  cblk->mqdec, bpno, band->orient,
    265 				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
    266 				  cblk->flags, cblk->data) :
    267 				  dec_rawsigpass(dec, cblk->nulldec, bpno,
    268 				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
    269 				  cblk->flags, cblk->data);
    270 				break;
    271 			case JPC_REFPASS:
    272 				ret = (seg->type == JPC_SEG_MQ) ?
    273 				  dec_refpass(dec, cblk->mqdec, bpno,
    274 				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
    275 				  cblk->flags, cblk->data) :
    276 				  dec_rawrefpass(dec, cblk->nulldec, bpno,
    277 				  (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
    278 				  cblk->flags, cblk->data);
    279 				break;
    280 			case JPC_CLNPASS:
    281 				assert(seg->type == JPC_SEG_MQ);
    282 				ret = dec_clnpass(dec, cblk->mqdec, bpno,
    283 				  band->orient, (tile->cp->ccps[compno].cblkctx &
    284 				  JPC_COX_VSC) != 0, (tile->cp->ccps[compno].cblkctx &
    285 				  JPC_COX_SEGSYM) != 0, cblk->flags,
    286 				  cblk->data);
    287 				break;
    288 			default:
    289 				ret = -1;
    290 				break;
    291 			}
    292 			/* Do we need to reset after each coding pass? */
    293 			if (tile->cp->ccps[compno].cblkctx & JPC_COX_RESET) {
    294 				jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
    295 			}
    296 
    297 			if (ret) {
    298 				fprintf(stderr, "coding pass failed passtype=%d segtype=%d\n", passtype, seg->type);
    299 				return -1;
    300 			}
    301 
    302 		}
    303 
    304 		if (seg->type == JPC_SEG_MQ) {
    305 /* Note: dont destroy mq decoder because context info will be lost */
    306 		} else {
    307 			assert(seg->type == JPC_SEG_RAW);
    308 			if (tile->cp->ccps[compno].cblkctx & JPC_COX_PTERM) {
    309 				fillmask = 0x7f;
    310 				filldata = 0x2a;
    311 			} else {
    312 				fillmask = 0;
    313 				filldata = 0;
    314 			}
    315 			if ((ret = jpc_bitstream_inalign(cblk->nulldec, fillmask,
    316 			  filldata)) < 0) {
    317 				return -1;
    318 			} else if (ret > 0) {
    319 				fprintf(stderr, "warning: bad termination pattern detected\n");
    320 			}
    321 			jpc_bitstream_close(cblk->nulldec);
    322 			cblk->nulldec = 0;
    323 		}
    324 
    325 		cblk->curseg = seg->next;
    326 		jpc_seglist_remove(&cblk->segs, seg);
    327 		jpc_seg_destroy(seg);
    328 		seg = cblk->curseg;
    329 	}
    330 
    331 	assert(dopartial ? (!cblk->curseg) : 1);
    332 
    333 premature_exit:
    334 	return 0;
    335 }
    336 
    337 /******************************************************************************\
    338 * Code for significance pass.
    339 \******************************************************************************/
    340 
    341 #define	jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf, orient, mqdec, vcausalflag) \
    342 { \
    343 	int f; \
    344 	int v; \
    345 	f = *(fp); \
    346 	if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
    347 		jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO(f, (orient))); \
    348 		JPC_T1D_GETBIT((mqdec), v, "SIG", "ZC"); \
    349 		if (v) { \
    350 			jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \
    351 			JPC_T1D_GETBIT((mqdec), v, "SIG", "SC"); \
    352 			v ^= JPC_GETSPB(f); \
    353 			JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
    354 			*(fp) |= JPC_SIG; \
    355 			*(dp) = (v) ? (-(oneplushalf)) : (oneplushalf); \
    356 		} \
    357 		*(fp) |= JPC_VISIT; \
    358 	} \
    359 }
    360 
    361 static int dec_sigpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos, int orient,
    362   int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data)
    363 {
    364 	int i;
    365 	int j;
    366 	int one;
    367 	int half;
    368 	int oneplushalf;
    369 	int vscanlen;
    370 	int width;
    371 	int height;
    372 	jpc_fix_t *fp;
    373 	int frowstep;
    374 	int fstripestep;
    375 	jpc_fix_t *fstripestart;
    376 	jpc_fix_t *fvscanstart;
    377 	jpc_fix_t *dp;
    378 	int drowstep;
    379 	int dstripestep;
    380 	jpc_fix_t *dstripestart;
    381 	jpc_fix_t *dvscanstart;
    382 	int k;
    383 
    384 	/* Avoid compiler warning about unused parameters. */
    385 	dec = 0;
    386 
    387 	width = jas_matrix_numcols(data);
    388 	height = jas_matrix_numrows(data);
    389 	frowstep = jas_matrix_rowstep(flags);
    390 	drowstep = jas_matrix_rowstep(data);
    391 	fstripestep = frowstep << 2;
    392 	dstripestep = drowstep << 2;
    393 
    394 	one = 1 << bitpos;
    395 	half = one >> 1;
    396 	oneplushalf = one | half;
    397 
    398 	fstripestart = jas_matrix_getref(flags, 1, 1);
    399 	dstripestart = jas_matrix_getref(data, 0, 0);
    400 	for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
    401 	  dstripestart += dstripestep) {
    402 		fvscanstart = fstripestart;
    403 		dvscanstart = dstripestart;
    404 		vscanlen = JAS_MIN(i, 4);
    405 		for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
    406 			fp = fvscanstart;
    407 			dp = dvscanstart;
    408 			k = vscanlen;
    409 
    410 			/* Process first sample in vertical scan. */
    411 			jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
    412 			  orient, mqdec, vcausalflag);
    413 			if (--k <= 0) {
    414 				continue;
    415 			}
    416 			fp += frowstep;
    417 			dp += drowstep;
    418 
    419 			/* Process second sample in vertical scan. */
    420 			jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
    421 			  orient, mqdec, 0);
    422 			if (--k <= 0) {
    423 				continue;
    424 			}
    425 			fp += frowstep;
    426 			dp += drowstep;
    427 
    428 			/* Process third sample in vertical scan. */
    429 			jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
    430 			  orient, mqdec, 0);
    431 			if (--k <= 0) {
    432 				continue;
    433 			}
    434 			fp += frowstep;
    435 			dp += drowstep;
    436 
    437 			/* Process fourth sample in vertical scan. */
    438 			jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
    439 			  orient, mqdec, 0);
    440 		}
    441 	}
    442 	return 0;
    443 }
    444 
    445 #define	jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, in, vcausalflag) \
    446 { \
    447 	jpc_fix_t f = *(fp); \
    448 	jpc_fix_t v; \
    449 	if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
    450 		JPC_T1D_RAWGETBIT(in, v, "SIG", "ZC"); \
    451 		if (v < 0) { \
    452 			return -1; \
    453 		} \
    454 		if (v) { \
    455 			JPC_T1D_RAWGETBIT(in, v, "SIG", "SC"); \
    456 			if (v < 0) { \
    457 				return -1; \
    458 			} \
    459 			JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
    460 			*(fp) |= JPC_SIG; \
    461 			*(dp) = v ? (-oneplushalf) : (oneplushalf); \
    462 		} \
    463 		*(fp) |= JPC_VISIT; \
    464 	} \
    465 }
    466 
    467 static int dec_rawsigpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, int vcausalflag,
    468   jas_matrix_t *flags, jas_matrix_t *data)
    469 {
    470 	int i;
    471 	int j;
    472 	int k;
    473 	int one;
    474 	int half;
    475 	int oneplushalf;
    476 	int vscanlen;
    477 	int width;
    478 	int height;
    479 	jpc_fix_t *fp;
    480 	int frowstep;
    481 	int fstripestep;
    482 	jpc_fix_t *fstripestart;
    483 	jpc_fix_t *fvscanstart;
    484 	jpc_fix_t *dp;
    485 	int drowstep;
    486 	int dstripestep;
    487 	jpc_fix_t *dstripestart;
    488 	jpc_fix_t *dvscanstart;
    489 
    490 	/* Avoid compiler warning about unused parameters. */
    491 	dec = 0;
    492 
    493 	width = jas_matrix_numcols(data);
    494 	height = jas_matrix_numrows(data);
    495 	frowstep = jas_matrix_rowstep(flags);
    496 	drowstep = jas_matrix_rowstep(data);
    497 	fstripestep = frowstep << 2;
    498 	dstripestep = drowstep << 2;
    499 
    500 	one = 1 << bitpos;
    501 	half = one >> 1;
    502 	oneplushalf = one | half;
    503 
    504 	fstripestart = jas_matrix_getref(flags, 1, 1);
    505 	dstripestart = jas_matrix_getref(data, 0, 0);
    506 	for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
    507 	  dstripestart += dstripestep) {
    508 		fvscanstart = fstripestart;
    509 		dvscanstart = dstripestart;
    510 		vscanlen = JAS_MIN(i, 4);
    511 		for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
    512 			fp = fvscanstart;
    513 			dp = dvscanstart;
    514 			k = vscanlen;
    515 
    516 			/* Process first sample in vertical scan. */
    517 			jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
    518 			  in, vcausalflag);
    519 			if (--k <= 0) {
    520 				continue;
    521 			}
    522 			fp += frowstep;
    523 			dp += drowstep;
    524 
    525 			/* Process second sample in vertical scan. */
    526 			jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
    527 			  in, 0);
    528 			if (--k <= 0) {
    529 				continue;
    530 			}
    531 			fp += frowstep;
    532 			dp += drowstep;
    533 
    534 			/* Process third sample in vertical scan. */
    535 			jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
    536 			  in, 0);
    537 			if (--k <= 0) {
    538 				continue;
    539 			}
    540 			fp += frowstep;
    541 			dp += drowstep;
    542 
    543 			/* Process fourth sample in vertical scan. */
    544 			jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
    545 			  in, 0);
    546 
    547 		}
    548 	}
    549 	return 0;
    550 }
    551 
    552 /******************************************************************************\
    553 * Code for refinement pass.
    554 \******************************************************************************/
    555 
    556 #define	jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, vcausalflag) \
    557 { \
    558 	int v; \
    559 	int t; \
    560 	if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
    561 		jpc_mqdec_setcurctx((mqdec), JPC_GETMAGCTXNO(*(fp))); \
    562 		JPC_T1D_GETBITNOSKEW((mqdec), v, "REF", "MR"); \
    563 		t = (v ? (poshalf) : (neghalf)); \
    564 		*(dp) += (*(dp) < 0) ? (-t) : t; \
    565 		*(fp) |= JPC_REFINE; \
    566 	} \
    567 }
    568 
    569 static int dec_refpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos,
    570   int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data)
    571 {
    572 	int i;
    573 	int j;
    574 	int vscanlen;
    575 	int width;
    576 	int height;
    577 	int one;
    578 	int poshalf;
    579 	int neghalf;
    580 	jpc_fix_t *fp;
    581 	int frowstep;
    582 	int fstripestep;
    583 	jpc_fix_t *fstripestart;
    584 	jpc_fix_t *fvscanstart;
    585 	jpc_fix_t *dp;
    586 	int drowstep;
    587 	int dstripestep;
    588 	jpc_fix_t *dstripestart;
    589 	jpc_fix_t *dvscanstart;
    590 	int k;
    591 
    592 	/* Avoid compiler warning about unused parameters. */
    593 	dec = 0;
    594 	vcausalflag = 0;
    595 
    596 	width = jas_matrix_numcols(data);
    597 	height = jas_matrix_numrows(data);
    598 	frowstep = jas_matrix_rowstep(flags);
    599 	drowstep = jas_matrix_rowstep(data);
    600 	fstripestep = frowstep << 2;
    601 	dstripestep = drowstep << 2;
    602 
    603 	one = 1 << bitpos;
    604 	poshalf = one >> 1;
    605 	neghalf = (bitpos > 0) ? (-poshalf) : (-1);
    606 
    607 	fstripestart = jas_matrix_getref(flags, 1, 1);
    608 	dstripestart = jas_matrix_getref(data, 0, 0);
    609 	for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
    610 	  dstripestart += dstripestep) {
    611 		fvscanstart = fstripestart;
    612 		dvscanstart = dstripestart;
    613 		vscanlen = JAS_MIN(i, 4);
    614 		for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
    615 			fp = fvscanstart;
    616 			dp = dvscanstart;
    617 			k = vscanlen;
    618 
    619 			/* Process first sample in vertical scan. */
    620 			jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec,
    621 			  vcausalflag);
    622 			if (--k <= 0) {
    623 				continue;
    624 			}
    625 			fp += frowstep;
    626 			dp += drowstep;
    627 
    628 			/* Process second sample in vertical scan. */
    629 			jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
    630 			if (--k <= 0) {
    631 				continue;
    632 			}
    633 			fp += frowstep;
    634 			dp += drowstep;
    635 
    636 			/* Process third sample in vertical scan. */
    637 			jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
    638 			if (--k <= 0) {
    639 				continue;
    640 			}
    641 			fp += frowstep;
    642 			dp += drowstep;
    643 
    644 			/* Process fourth sample in vertical scan. */
    645 			jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
    646 		}
    647 	}
    648 
    649 	return 0;
    650 }
    651 
    652 #define	jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, vcausalflag) \
    653 { \
    654 	jpc_fix_t v; \
    655 	jpc_fix_t t; \
    656 	if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
    657 		JPC_T1D_RAWGETBIT(in, v, "REF", "MAGREF"); \
    658 		if (v < 0) { \
    659 			return -1; \
    660 		} \
    661 		t = (v ? poshalf : neghalf); \
    662 		*(dp) += (*(dp) < 0) ? (-t) : t; \
    663 		*(fp) |= JPC_REFINE; \
    664 	} \
    665 }
    666 
    667 static int dec_rawrefpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, int vcausalflag,
    668   jas_matrix_t *flags, jas_matrix_t *data)
    669 {
    670 	int i;
    671 	int j;
    672 	int k;
    673 	int vscanlen;
    674 	int width;
    675 	int height;
    676 	int one;
    677 	int poshalf;
    678 	int neghalf;
    679 	jpc_fix_t *fp;
    680 	int frowstep;
    681 	int fstripestep;
    682 	jpc_fix_t *fstripestart;
    683 	jpc_fix_t *fvscanstart;
    684 	jpc_fix_t *dp;
    685 	int drowstep;
    686 	int dstripestep;
    687 	jpc_fix_t *dstripestart;
    688 	jpc_fix_t *dvscanstart;
    689 
    690 	/* Avoid compiler warning about unused parameters. */
    691 	dec = 0;
    692 	vcausalflag = 0;
    693 
    694 	width = jas_matrix_numcols(data);
    695 	height = jas_matrix_numrows(data);
    696 	frowstep = jas_matrix_rowstep(flags);
    697 	drowstep = jas_matrix_rowstep(data);
    698 	fstripestep = frowstep << 2;
    699 	dstripestep = drowstep << 2;
    700 
    701 	one = 1 << bitpos;
    702 	poshalf = one >> 1;
    703 	neghalf = (bitpos > 0) ? (-poshalf) : (-1);
    704 
    705 	fstripestart = jas_matrix_getref(flags, 1, 1);
    706 	dstripestart = jas_matrix_getref(data, 0, 0);
    707 	for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
    708 	  dstripestart += dstripestep) {
    709 		fvscanstart = fstripestart;
    710 		dvscanstart = dstripestart;
    711 		vscanlen = JAS_MIN(i, 4);
    712 		for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
    713 			fp = fvscanstart;
    714 			dp = dvscanstart;
    715 			k = vscanlen;
    716 
    717 			/* Process first sample in vertical scan. */
    718 			jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in,
    719 			  vcausalflag);
    720 			if (--k <= 0) {
    721 				continue;
    722 			}
    723 			fp += frowstep;
    724 			dp += drowstep;
    725 
    726 			/* Process second sample in vertical scan. */
    727 			jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
    728 			if (--k <= 0) {
    729 				continue;
    730 			}
    731 			fp += frowstep;
    732 			dp += drowstep;
    733 
    734 			/* Process third sample in vertical scan. */
    735 			jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
    736 			if (--k <= 0) {
    737 				continue;
    738 			}
    739 			fp += frowstep;
    740 			dp += drowstep;
    741 
    742 			/* Process fourth sample in vertical scan. */
    743 			jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
    744 		}
    745 	}
    746 	return 0;
    747 }
    748 
    749 /******************************************************************************\
    750 * Code for cleanup pass.
    751 \******************************************************************************/
    752 
    753 #define	jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient, mqdec, flabel, plabel, vcausalflag) \
    754 { \
    755 	int v; \
    756 flabel \
    757 	if (!((f) & (JPC_SIG | JPC_VISIT))) { \
    758 		jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO((f), (orient))); \
    759 		JPC_T1D_GETBIT((mqdec), v, "CLN", "ZC"); \
    760 		if (v) { \
    761 plabel \
    762 			/* Coefficient is significant. */ \
    763 			jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \
    764 			JPC_T1D_GETBIT((mqdec), v, "CLN", "SC"); \
    765 			v ^= JPC_GETSPB(f); \
    766 			*(dp) = (v) ? (-(oneplushalf)) : (oneplushalf); \
    767 			JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
    768 			*(fp) |= JPC_SIG; \
    769 		} \
    770 	} \
    771 	/* XXX - Is this correct?  Can aggregation cause some VISIT bits not to be reset?  Check. */ \
    772 	*(fp) &= ~JPC_VISIT; \
    773 }
    774 
    775 static int dec_clnpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos, int orient,
    776   int vcausalflag, int segsymflag, jas_matrix_t *flags, jas_matrix_t *data)
    777 {
    778 	int i;
    779 	int j;
    780 	int k;
    781 	int vscanlen;
    782 	int v;
    783 	int half;
    784 	int runlen;
    785 	int f;
    786 	int width;
    787 	int height;
    788 	int one;
    789 	int oneplushalf;
    790 
    791 	jpc_fix_t *fp;
    792 	int frowstep;
    793 	int fstripestep;
    794 	jpc_fix_t *fstripestart;
    795 	jpc_fix_t *fvscanstart;
    796 
    797 	jpc_fix_t *dp;
    798 	int drowstep;
    799 	int dstripestep;
    800 	jpc_fix_t *dstripestart;
    801 	jpc_fix_t *dvscanstart;
    802 
    803 	/* Avoid compiler warning about unused parameters. */
    804 	dec = 0;
    805 
    806 	one = 1 << bitpos;
    807 	half = one >> 1;
    808 	oneplushalf = one | half;
    809 
    810 	width = jas_matrix_numcols(data);
    811 	height = jas_matrix_numrows(data);
    812 
    813 	frowstep = jas_matrix_rowstep(flags);
    814 	drowstep = jas_matrix_rowstep(data);
    815 	fstripestep = frowstep << 2;
    816 	dstripestep = drowstep << 2;
    817 
    818 	fstripestart = jas_matrix_getref(flags, 1, 1);
    819 	dstripestart = jas_matrix_getref(data, 0, 0);
    820 	for (i = 0; i < height; i += 4, fstripestart += fstripestep,
    821 	  dstripestart += dstripestep) {
    822 		fvscanstart = fstripestart;
    823 		dvscanstart = dstripestart;
    824 		vscanlen = JAS_MIN(4, height - i);
    825 		for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
    826 			fp = fvscanstart;
    827 			if (vscanlen >= 4 && (!((*fp) & (JPC_SIG | JPC_VISIT |
    828 			  JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) & (JPC_SIG |
    829 			  JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) &
    830 			  (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep,
    831 			  !((*fp) & (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK)))) {
    832 
    833 				jpc_mqdec_setcurctx(mqdec, JPC_AGGCTXNO);
    834 				JPC_T1D_GETBIT(mqdec, v, "CLN", "AGG");
    835 				if (!v) {
    836 					continue;
    837 				}
    838 				jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
    839 				JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL");
    840 				runlen = v;
    841 				JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL");
    842 				runlen = (runlen << 1) | v;
    843 				f = *(fp = fvscanstart + frowstep * runlen);
    844 				dp = dvscanstart + drowstep * runlen;
    845 				k = vscanlen - runlen;
    846 				switch (runlen) {
    847 				case 0:
    848 					goto clnpass_partial0;
    849 					break;
    850 				case 1:
    851 					goto clnpass_partial1;
    852 					break;
    853 				case 2:
    854 					goto clnpass_partial2;
    855 					break;
    856 				case 3:
    857 					goto clnpass_partial3;
    858 					break;
    859 				}
    860 			} else {
    861 				f = *(fp = fvscanstart);
    862 				dp = dvscanstart;
    863 				k = vscanlen;
    864 				goto clnpass_full0;
    865 			}
    866 
    867 			/* Process first sample in vertical scan. */
    868 			jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
    869 			  mqdec, clnpass_full0:, clnpass_partial0:,
    870 			  vcausalflag);
    871 			if (--k <= 0) {
    872 				continue;
    873 			}
    874 			fp += frowstep;
    875 			dp += drowstep;
    876 
    877 			/* Process second sample in vertical scan. */
    878 			f = *fp;
    879 			jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
    880 				mqdec, ;, clnpass_partial1:, 0);
    881 			if (--k <= 0) {
    882 				continue;
    883 			}
    884 			fp += frowstep;
    885 			dp += drowstep;
    886 
    887 			/* Process third sample in vertical scan. */
    888 			f = *fp;
    889 			jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
    890 				mqdec, ;, clnpass_partial2:, 0);
    891 			if (--k <= 0) {
    892 				continue;
    893 			}
    894 			fp += frowstep;
    895 			dp += drowstep;
    896 
    897 			/* Process fourth sample in vertical scan. */
    898 			f = *fp;
    899 			jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
    900 				mqdec, ;, clnpass_partial3:, 0);
    901 		}
    902 	}
    903 
    904 	if (segsymflag) {
    905 		int segsymval;
    906 		segsymval = 0;
    907 		jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
    908 		JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
    909 		segsymval = (segsymval << 1) | (v & 1);
    910 		JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
    911 		segsymval = (segsymval << 1) | (v & 1);
    912 		JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
    913 		segsymval = (segsymval << 1) | (v & 1);
    914 		JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
    915 		segsymval = (segsymval << 1) | (v & 1);
    916 		if (segsymval != 0xa) {
    917 			fprintf(stderr, "warning: bad segmentation symbol\n");
    918 		}
    919 	}
    920 
    921 	return 0;
    922 }