Home | History | Annotate | Download | only in libjasper
      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 
    143 int jpc_dec_decodecblks(jpc_dec_t *dec, jpc_dec_tile_t *tile)
    144 {
    145     jpc_dec_tcomp_t *tcomp;
    146     int compcnt;
    147     jpc_dec_rlvl_t *rlvl;
    148     int rlvlcnt;
    149     jpc_dec_band_t *band;
    150     int bandcnt;
    151     jpc_dec_prc_t *prc;
    152     int prccnt;
    153     jpc_dec_cblk_t *cblk;
    154     int cblkcnt;
    155 
    156     for (compcnt = dec->numcomps, tcomp = tile->tcomps; compcnt > 0;
    157       --compcnt, ++tcomp) {
    158         for (rlvlcnt = tcomp->numrlvls, rlvl = tcomp->rlvls;
    159           rlvlcnt > 0; --rlvlcnt, ++rlvl) {
    160             if (!rlvl->bands) {
    161                 continue;
    162             }
    163             for (bandcnt = rlvl->numbands, band = rlvl->bands;
    164               bandcnt > 0; --bandcnt, ++band) {
    165                 if (!band->data) {
    166                     continue;
    167                 }
    168                 for (prccnt = rlvl->numprcs, prc = band->prcs;
    169                   prccnt > 0; --prccnt, ++prc) {
    170                     if (!prc->cblks) {
    171                         continue;
    172                     }
    173                     for (cblkcnt = prc->numcblks,
    174                       cblk = prc->cblks; cblkcnt > 0;
    175                       --cblkcnt, ++cblk) {
    176                         if (jpc_dec_decodecblk(dec, tile, tcomp,
    177                           band, cblk, 1, JPC_MAXLYRS)) {
    178                             return -1;
    179                         }
    180                     }
    181                 }
    182 
    183             }
    184         }
    185     }
    186 
    187     return 0;
    188 }
    189 
    190 static int jpc_dec_decodecblk(jpc_dec_t *dec, jpc_dec_tile_t *tile, jpc_dec_tcomp_t *tcomp, jpc_dec_band_t *band,
    191   jpc_dec_cblk_t *cblk, int dopartial, int maxlyrs)
    192 {
    193     jpc_dec_seg_t *seg;
    194     int i;
    195     int bpno;
    196     int passtype;
    197     int ret;
    198     int compno;
    199     int filldata;
    200     int fillmask;
    201     jpc_dec_ccp_t *ccp;
    202 
    203     compno = tcomp - tile->tcomps;
    204 
    205     if (!cblk->flags) {
    206         /* Note: matrix is assumed to be zeroed */
    207         if (!(cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) +
    208           2, jas_matrix_numcols(cblk->data) + 2))) {
    209             return -1;
    210         }
    211     }
    212 
    213     seg = cblk->segs.head;
    214     while (seg && (seg != cblk->curseg || dopartial) && (maxlyrs < 0 ||
    215       seg->lyrno < maxlyrs)) {
    216         assert(seg->numpasses >= seg->maxpasses || dopartial);
    217         assert(seg->stream);
    218         jas_stream_rewind(seg->stream);
    219         jas_stream_setrwcount(seg->stream, 0);
    220         if (seg->type == JPC_SEG_MQ) {
    221             if (!cblk->mqdec) {
    222                 if (!(cblk->mqdec = jpc_mqdec_create(JPC_NUMCTXS, 0))) {
    223                     return -1;
    224                 }
    225                 jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
    226             }
    227             jpc_mqdec_setinput(cblk->mqdec, seg->stream);
    228             jpc_mqdec_init(cblk->mqdec);
    229         } else {
    230             assert(seg->type == JPC_SEG_RAW);
    231             if (!cblk->nulldec) {
    232                 if (!(cblk->nulldec = jpc_bitstream_sopen(seg->stream, "r"))) {
    233                     assert(0);
    234                 }
    235             }
    236         }
    237 
    238 
    239         for (i = 0; i < seg->numpasses; ++i) {
    240             if (cblk->numimsbs > band->numbps) {
    241                 ccp = &tile->cp->ccps[compno];
    242                 if (ccp->roishift <= 0) {
    243                     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 
    361 static int dec_sigpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos, int orient,
    362   int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data)
    363 {
    364     int i;
    365     int j;
    366     int one;
    367     int half;
    368     int oneplushalf;
    369     int vscanlen;
    370     int width;
    371     int height;
    372     jpc_fix_t *fp;
    373     int frowstep;
    374     int fstripestep;
    375     jpc_fix_t *fstripestart;
    376     jpc_fix_t *fvscanstart;
    377     jpc_fix_t *dp;
    378     int drowstep;
    379     int dstripestep;
    380     jpc_fix_t *dstripestart;
    381     jpc_fix_t *dvscanstart;
    382     int k;
    383 
    384     /* Avoid compiler warning about unused parameters. */
    385     dec = 0;
    386 
    387     width = jas_matrix_numcols(data);
    388     height = jas_matrix_numrows(data);
    389     frowstep = jas_matrix_rowstep(flags);
    390     drowstep = jas_matrix_rowstep(data);
    391     fstripestep = frowstep << 2;
    392     dstripestep = drowstep << 2;
    393 
    394     one = 1 << bitpos;
    395     half = one >> 1;
    396     oneplushalf = one | half;
    397 
    398     fstripestart = jas_matrix_getref(flags, 1, 1);
    399     dstripestart = jas_matrix_getref(data, 0, 0);
    400     for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
    401       dstripestart += dstripestep) {
    402         fvscanstart = fstripestart;
    403         dvscanstart = dstripestart;
    404         vscanlen = JAS_MIN(i, 4);
    405         for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
    406             fp = fvscanstart;
    407             dp = dvscanstart;
    408             k = vscanlen;
    409 
    410             /* Process first sample in vertical scan. */
    411             jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
    412               orient, mqdec, vcausalflag);
    413             if (--k <= 0) {
    414                 continue;
    415             }
    416             fp += frowstep;
    417             dp += drowstep;
    418 
    419             /* Process second sample in vertical scan. */
    420             jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
    421               orient, mqdec, 0);
    422             if (--k <= 0) {
    423                 continue;
    424             }
    425             fp += frowstep;
    426             dp += drowstep;
    427 
    428             /* Process third sample in vertical scan. */
    429             jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
    430               orient, mqdec, 0);
    431             if (--k <= 0) {
    432                 continue;
    433             }
    434             fp += frowstep;
    435             dp += drowstep;
    436 
    437             /* Process fourth sample in vertical scan. */
    438             jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
    439               orient, mqdec, 0);
    440         }
    441     }
    442     return 0;
    443 }
    444 
    445 #define	jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, in, vcausalflag) \
    446 { \
    447     jpc_fix_t f = *(fp); \
    448     jpc_fix_t v; \
    449     if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
    450         JPC_T1D_RAWGETBIT(in, v, "SIG", "ZC"); \
    451         if (v < 0) { \
    452             return -1; \
    453         } \
    454         if (v) { \
    455             JPC_T1D_RAWGETBIT(in, v, "SIG", "SC"); \
    456             if (v < 0) { \
    457                 return -1; \
    458             } \
    459             JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
    460             *(fp) |= JPC_SIG; \
    461             *(dp) = v ? (-oneplushalf) : (oneplushalf); \
    462         } \
    463         *(fp) |= JPC_VISIT; \
    464     } \
    465 }
    466 
    467 static int dec_rawsigpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, int vcausalflag,
    468   jas_matrix_t *flags, jas_matrix_t *data)
    469 {
    470     int i;
    471     int j;
    472     int k;
    473     int one;
    474     int half;
    475     int oneplushalf;
    476     int vscanlen;
    477     int width;
    478     int height;
    479     jpc_fix_t *fp;
    480     int frowstep;
    481     int fstripestep;
    482     jpc_fix_t *fstripestart;
    483     jpc_fix_t *fvscanstart;
    484     jpc_fix_t *dp;
    485     int drowstep;
    486     int dstripestep;
    487     jpc_fix_t *dstripestart;
    488     jpc_fix_t *dvscanstart;
    489 
    490     /* Avoid compiler warning about unused parameters. */
    491     dec = 0;
    492 
    493     width = jas_matrix_numcols(data);
    494     height = jas_matrix_numrows(data);
    495     frowstep = jas_matrix_rowstep(flags);
    496     drowstep = jas_matrix_rowstep(data);
    497     fstripestep = frowstep << 2;
    498     dstripestep = drowstep << 2;
    499 
    500     one = 1 << bitpos;
    501     half = one >> 1;
    502     oneplushalf = one | half;
    503 
    504     fstripestart = jas_matrix_getref(flags, 1, 1);
    505     dstripestart = jas_matrix_getref(data, 0, 0);
    506     for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
    507       dstripestart += dstripestep) {
    508         fvscanstart = fstripestart;
    509         dvscanstart = dstripestart;
    510         vscanlen = JAS_MIN(i, 4);
    511         for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
    512             fp = fvscanstart;
    513             dp = dvscanstart;
    514             k = vscanlen;
    515 
    516             /* Process first sample in vertical scan. */
    517             jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
    518               in, vcausalflag);
    519             if (--k <= 0) {
    520                 continue;
    521             }
    522             fp += frowstep;
    523             dp += drowstep;
    524 
    525             /* Process second sample in vertical scan. */
    526             jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
    527               in, 0);
    528             if (--k <= 0) {
    529                 continue;
    530             }
    531             fp += frowstep;
    532             dp += drowstep;
    533 
    534             /* Process third sample in vertical scan. */
    535             jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
    536               in, 0);
    537             if (--k <= 0) {
    538                 continue;
    539             }
    540             fp += frowstep;
    541             dp += drowstep;
    542 
    543             /* Process fourth sample in vertical scan. */
    544             jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
    545               in, 0);
    546 
    547         }
    548     }
    549     return 0;
    550 }
    551 
    552 /******************************************************************************\
    553 * Code for refinement pass.
    554 \******************************************************************************/
    555 
    556 #define	jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, vcausalflag) \
    557 { \
    558     int v; \
    559     int t; \
    560     if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
    561         jpc_mqdec_setcurctx((mqdec), JPC_GETMAGCTXNO(*(fp))); \
    562         JPC_T1D_GETBITNOSKEW((mqdec), v, "REF", "MR"); \
    563         t = (v ? (poshalf) : (neghalf)); \
    564         *(dp) += (*(dp) < 0) ? (-t) : t; \
    565         *(fp) |= JPC_REFINE; \
    566     } \
    567 }
    568 
    569 static int dec_refpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos,
    570   int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data)
    571 {
    572     int i;
    573     int j;
    574     int vscanlen;
    575     int width;
    576     int height;
    577     int one;
    578     int poshalf;
    579     int neghalf;
    580     jpc_fix_t *fp;
    581     int frowstep;
    582     int fstripestep;
    583     jpc_fix_t *fstripestart;
    584     jpc_fix_t *fvscanstart;
    585     jpc_fix_t *dp;
    586     int drowstep;
    587     int dstripestep;
    588     jpc_fix_t *dstripestart;
    589     jpc_fix_t *dvscanstart;
    590     int k;
    591 
    592     /* Avoid compiler warning about unused parameters. */
    593     dec = 0;
    594     vcausalflag = 0;
    595 
    596     width = jas_matrix_numcols(data);
    597     height = jas_matrix_numrows(data);
    598     frowstep = jas_matrix_rowstep(flags);
    599     drowstep = jas_matrix_rowstep(data);
    600     fstripestep = frowstep << 2;
    601     dstripestep = drowstep << 2;
    602 
    603     one = 1 << bitpos;
    604     poshalf = one >> 1;
    605     neghalf = (bitpos > 0) ? (-poshalf) : (-1);
    606 
    607     fstripestart = jas_matrix_getref(flags, 1, 1);
    608     dstripestart = jas_matrix_getref(data, 0, 0);
    609     for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
    610       dstripestart += dstripestep) {
    611         fvscanstart = fstripestart;
    612         dvscanstart = dstripestart;
    613         vscanlen = JAS_MIN(i, 4);
    614         for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
    615             fp = fvscanstart;
    616             dp = dvscanstart;
    617             k = vscanlen;
    618 
    619             /* Process first sample in vertical scan. */
    620             jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec,
    621               vcausalflag);
    622             if (--k <= 0) {
    623                 continue;
    624             }
    625             fp += frowstep;
    626             dp += drowstep;
    627 
    628             /* Process second sample in vertical scan. */
    629             jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
    630             if (--k <= 0) {
    631                 continue;
    632             }
    633             fp += frowstep;
    634             dp += drowstep;
    635 
    636             /* Process third sample in vertical scan. */
    637             jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
    638             if (--k <= 0) {
    639                 continue;
    640             }
    641             fp += frowstep;
    642             dp += drowstep;
    643 
    644             /* Process fourth sample in vertical scan. */
    645             jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
    646         }
    647     }
    648 
    649     return 0;
    650 }
    651 
    652 #define	jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, vcausalflag) \
    653 { \
    654     jpc_fix_t v; \
    655     jpc_fix_t t; \
    656     if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
    657         JPC_T1D_RAWGETBIT(in, v, "REF", "MAGREF"); \
    658         if (v < 0) { \
    659             return -1; \
    660         } \
    661         t = (v ? poshalf : neghalf); \
    662         *(dp) += (*(dp) < 0) ? (-t) : t; \
    663         *(fp) |= JPC_REFINE; \
    664     } \
    665 }
    666 
    667 static int dec_rawrefpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, int vcausalflag,
    668   jas_matrix_t *flags, jas_matrix_t *data)
    669 {
    670     int i;
    671     int j;
    672     int k;
    673     int vscanlen;
    674     int width;
    675     int height;
    676     int one;
    677     int poshalf;
    678     int neghalf;
    679     jpc_fix_t *fp;
    680     int frowstep;
    681     int fstripestep;
    682     jpc_fix_t *fstripestart;
    683     jpc_fix_t *fvscanstart;
    684     jpc_fix_t *dp;
    685     int drowstep;
    686     int dstripestep;
    687     jpc_fix_t *dstripestart;
    688     jpc_fix_t *dvscanstart;
    689 
    690     /* Avoid compiler warning about unused parameters. */
    691     dec = 0;
    692     vcausalflag = 0;
    693 
    694     width = jas_matrix_numcols(data);
    695     height = jas_matrix_numrows(data);
    696     frowstep = jas_matrix_rowstep(flags);
    697     drowstep = jas_matrix_rowstep(data);
    698     fstripestep = frowstep << 2;
    699     dstripestep = drowstep << 2;
    700 
    701     one = 1 << bitpos;
    702     poshalf = one >> 1;
    703     neghalf = (bitpos > 0) ? (-poshalf) : (-1);
    704 
    705     fstripestart = jas_matrix_getref(flags, 1, 1);
    706     dstripestart = jas_matrix_getref(data, 0, 0);
    707     for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
    708       dstripestart += dstripestep) {
    709         fvscanstart = fstripestart;
    710         dvscanstart = dstripestart;
    711         vscanlen = JAS_MIN(i, 4);
    712         for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
    713             fp = fvscanstart;
    714             dp = dvscanstart;
    715             k = vscanlen;
    716 
    717             /* Process first sample in vertical scan. */
    718             jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in,
    719               vcausalflag);
    720             if (--k <= 0) {
    721                 continue;
    722             }
    723             fp += frowstep;
    724             dp += drowstep;
    725 
    726             /* Process second sample in vertical scan. */
    727             jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
    728             if (--k <= 0) {
    729                 continue;
    730             }
    731             fp += frowstep;
    732             dp += drowstep;
    733 
    734             /* Process third sample in vertical scan. */
    735             jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
    736             if (--k <= 0) {
    737                 continue;
    738             }
    739             fp += frowstep;
    740             dp += drowstep;
    741 
    742             /* Process fourth sample in vertical scan. */
    743             jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
    744         }
    745     }
    746     return 0;
    747 }
    748 
    749 /******************************************************************************\
    750 * Code for cleanup pass.
    751 \******************************************************************************/
    752 
    753 #define	jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient, mqdec, flabel, plabel, vcausalflag) \
    754 { \
    755     int v; \
    756 flabel \
    757     if (!((f) & (JPC_SIG | JPC_VISIT))) { \
    758         jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO((f), (orient))); \
    759         JPC_T1D_GETBIT((mqdec), v, "CLN", "ZC"); \
    760         if (v) { \
    761 plabel \
    762             /* Coefficient is significant. */ \
    763             jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \
    764             JPC_T1D_GETBIT((mqdec), v, "CLN", "SC"); \
    765             v ^= JPC_GETSPB(f); \
    766             *(dp) = (v) ? (-(oneplushalf)) : (oneplushalf); \
    767             JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
    768             *(fp) |= JPC_SIG; \
    769         } \
    770     } \
    771     /* XXX - Is this correct?  Can aggregation cause some VISIT bits not to be reset?  Check. */ \
    772     *(fp) &= ~JPC_VISIT; \
    773 }
    774 
    775 static int dec_clnpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos, int orient,
    776   int vcausalflag, int segsymflag, jas_matrix_t *flags, jas_matrix_t *data)
    777 {
    778     int i;
    779     int j;
    780     int k;
    781     int vscanlen;
    782     int v;
    783     int half;
    784     int runlen;
    785     int f;
    786     int width;
    787     int height;
    788     int one;
    789     int oneplushalf;
    790 
    791     jpc_fix_t *fp;
    792     int frowstep;
    793     int fstripestep;
    794     jpc_fix_t *fstripestart;
    795     jpc_fix_t *fvscanstart;
    796 
    797     jpc_fix_t *dp;
    798     int drowstep;
    799     int dstripestep;
    800     jpc_fix_t *dstripestart;
    801     jpc_fix_t *dvscanstart;
    802 
    803     /* Avoid compiler warning about unused parameters. */
    804     dec = 0;
    805 
    806     one = 1 << bitpos;
    807     half = one >> 1;
    808     oneplushalf = one | half;
    809 
    810     width = jas_matrix_numcols(data);
    811     height = jas_matrix_numrows(data);
    812 
    813     frowstep = jas_matrix_rowstep(flags);
    814     drowstep = jas_matrix_rowstep(data);
    815     fstripestep = frowstep << 2;
    816     dstripestep = drowstep << 2;
    817 
    818     fstripestart = jas_matrix_getref(flags, 1, 1);
    819     dstripestart = jas_matrix_getref(data, 0, 0);
    820     for (i = 0; i < height; i += 4, fstripestart += fstripestep,
    821       dstripestart += dstripestep) {
    822         fvscanstart = fstripestart;
    823         dvscanstart = dstripestart;
    824         vscanlen = JAS_MIN(4, height - i);
    825         for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
    826             fp = fvscanstart;
    827             if (vscanlen >= 4 && (!((*fp) & (JPC_SIG | JPC_VISIT |
    828               JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) & (JPC_SIG |
    829               JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) &
    830               (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep,
    831               !((*fp) & (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK)))) {
    832 
    833                 jpc_mqdec_setcurctx(mqdec, JPC_AGGCTXNO);
    834                 JPC_T1D_GETBIT(mqdec, v, "CLN", "AGG");
    835                 if (!v) {
    836                     continue;
    837                 }
    838                 jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
    839                 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL");
    840                 runlen = v;
    841                 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL");
    842                 runlen = (runlen << 1) | v;
    843                 f = *(fp = fvscanstart + frowstep * runlen);
    844                 dp = dvscanstart + drowstep * runlen;
    845                 k = vscanlen - runlen;
    846                 switch (runlen) {
    847                 case 0:
    848                     goto clnpass_partial0;
    849                     break;
    850                 case 1:
    851                     goto clnpass_partial1;
    852                     break;
    853                 case 2:
    854                     goto clnpass_partial2;
    855                     break;
    856                 case 3:
    857                     goto clnpass_partial3;
    858                     break;
    859                 }
    860             } else {
    861                 f = *(fp = fvscanstart);
    862                 dp = dvscanstart;
    863                 k = vscanlen;
    864                 goto clnpass_full0;
    865             }
    866 
    867             /* Process first sample in vertical scan. */
    868             jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
    869               mqdec, clnpass_full0:, clnpass_partial0:,
    870               vcausalflag);
    871             if (--k <= 0) {
    872                 continue;
    873             }
    874             fp += frowstep;
    875             dp += drowstep;
    876 
    877             /* Process second sample in vertical scan. */
    878             f = *fp;
    879             jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
    880                 mqdec, ;, clnpass_partial1:, 0);
    881             if (--k <= 0) {
    882                 continue;
    883             }
    884             fp += frowstep;
    885             dp += drowstep;
    886 
    887             /* Process third sample in vertical scan. */
    888             f = *fp;
    889             jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
    890                 mqdec, ;, clnpass_partial2:, 0);
    891             if (--k <= 0) {
    892                 continue;
    893             }
    894             fp += frowstep;
    895             dp += drowstep;
    896 
    897             /* Process fourth sample in vertical scan. */
    898             f = *fp;
    899             jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
    900                 mqdec, ;, clnpass_partial3:, 0);
    901         }
    902     }
    903 
    904     if (segsymflag) {
    905         int segsymval;
    906         segsymval = 0;
    907         jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
    908         JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
    909         segsymval = (segsymval << 1) | (v & 1);
    910         JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
    911         segsymval = (segsymval << 1) | (v & 1);
    912         JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
    913         segsymval = (segsymval << 1) | (v & 1);
    914         JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
    915         segsymval = (segsymval << 1) | (v & 1);
    916         if (segsymval != 0xa) {
    917             jas_eprintf("warning: bad segmentation symbol\n");
    918         }
    919     }
    920 
    921     return 0;
    922 }
    923