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: jpc_t1dec.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $
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         jas_eprintf("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         jas_eprintf("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 
jpc_dec_decodecblks(jpc_dec_t * dec,jpc_dec_tile_t * tile)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 
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)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                     jas_eprintf("warning: corrupt code stream\n");
244                 } else {
245                     if (cblk->numimsbs < ccp->roishift - band->numbps) {
246                         jas_eprintf("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                 jas_eprintf("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                 jas_eprintf("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 
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)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 
dec_rawsigpass(jpc_dec_t * dec,jpc_bitstream_t * in,int bitpos,int vcausalflag,jas_matrix_t * flags,jas_matrix_t * data)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 
dec_refpass(jpc_dec_t * dec,register jpc_mqdec_t * mqdec,int bitpos,int vcausalflag,jas_matrix_t * flags,jas_matrix_t * data)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 
dec_rawrefpass(jpc_dec_t * dec,jpc_bitstream_t * in,int bitpos,int vcausalflag,jas_matrix_t * flags,jas_matrix_t * data)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 
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)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             jas_eprintf("warning: bad segmentation symbol\n");
918         }
919     }
920 
921     return 0;
922 }
923