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