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
92static 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);
94static 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);
96static int dec_rawsigpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos,
97  int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
98static int dec_refpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int vcausalflag,
99  jas_matrix_t *flags, jas_matrix_t *data);
100static int dec_rawrefpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos,
101  int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
102static 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)
106static 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
143int 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
190static 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);
252if (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
333premature_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
361static 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
467static 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
569static 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
667static 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; \
756flabel \
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) { \
761plabel \
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
775static 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