jpc_t1dec.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       jpc_t1dec.c (25593B)
       ---
            1 /*
            2  * Copyright (c) 1999-2000 Image Power, Inc. and the University of
            3  *   British Columbia.
            4  * Copyright (c) 2001-2003 Michael David Adams.
            5  * All rights reserved.
            6  */
            7 
            8 /* __START_OF_JASPER_LICENSE__
            9  * 
           10  * JasPer License Version 2.0
           11  * 
           12  * Copyright (c) 1999-2000 Image Power, Inc.
           13  * Copyright (c) 1999-2000 The University of British Columbia
           14  * Copyright (c) 2001-2003 Michael David Adams
           15  * 
           16  * All rights reserved.
           17  * 
           18  * Permission is hereby granted, free of charge, to any person (the
           19  * "User") obtaining a copy of this software and associated documentation
           20  * files (the "Software"), to deal in the Software without restriction,
           21  * including without limitation the rights to use, copy, modify, merge,
           22  * publish, distribute, and/or sell copies of the Software, and to permit
           23  * persons to whom the Software is furnished to do so, subject to the
           24  * following conditions:
           25  * 
           26  * 1.  The above copyright notices and this permission notice (which
           27  * includes the disclaimer below) shall be included in all copies or
           28  * substantial portions of the Software.
           29  * 
           30  * 2.  The name of a copyright holder shall not be used to endorse or
           31  * promote products derived from the Software without specific prior
           32  * written permission.
           33  * 
           34  * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
           35  * LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
           36  * THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
           37  * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
           38  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
           39  * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO
           40  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
           41  * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
           42  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
           43  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
           44  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE
           45  * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
           46  * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
           47  * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
           48  * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
           49  * PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS
           50  * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
           51  * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE
           52  * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
           53  * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
           54  * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
           55  * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
           56  * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
           57  * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
           58  * RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
           59  * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
           60  * 
           61  * __END_OF_JASPER_LICENSE__
           62  */
           63 
           64 /*
           65  * Tier 1 Decoder
           66  *
           67  * $Id: jpc_t1dec.c 1918 2005-07-24 14:12:08Z baford $
           68  */
           69 
           70 /******************************************************************************\
           71 * Includes.
           72 \******************************************************************************/
           73 
           74 #include <stdio.h>
           75 #include <stdlib.h>
           76 #include <assert.h>
           77 
           78 #include "jasper/jas_fix.h"
           79 #include "jasper/jas_stream.h"
           80 #include "jasper/jas_math.h"
           81 
           82 #include "jpc_bs.h"
           83 #include "jpc_mqdec.h"
           84 #include "jpc_t1dec.h"
           85 #include "jpc_t1cod.h"
           86 #include "jpc_dec.h"
           87 
           88 /******************************************************************************\
           89 *
           90 \******************************************************************************/
           91 
           92 static int jpc_dec_decodecblk(jpc_dec_t *dec, jpc_dec_tile_t *tile, jpc_dec_tcomp_t *tcomp, jpc_dec_band_t *band,
           93   jpc_dec_cblk_t *cblk, int dopartial, int maxlyrs);
           94 static int dec_sigpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int orient,
           95   int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
           96 static int dec_rawsigpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos,
           97   int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
           98 static int dec_refpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int vcausalflag,
           99   jas_matrix_t *flags, jas_matrix_t *data);
          100 static int dec_rawrefpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos,
          101   int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
          102 static int dec_clnpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int orient,
          103   int vcausalflag, int segsymflag, jas_matrix_t *flags, jas_matrix_t *data);
          104 
          105 #if defined(DEBUG)
          106 static long t1dec_cnt = 0;
          107 #endif
          108 
          109 #if !defined(DEBUG)
          110 #define        JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename) \
          111         ((v) = jpc_mqdec_getbit(mqdec))
          112 #else
          113 #define        JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename) \
          114 { \
          115         (v) = jpc_mqdec_getbit(mqdec); \
          116         if (jas_getdbglevel() >= 100) { \
          117                 fprintf(stderr, "index = %ld; passtype = %s; symtype = %s; sym = %d\n", t1dec_cnt, passtypename, symtypename, v); \
          118                 ++t1dec_cnt; \
          119         } \
          120 }
          121 #endif
          122 #define        JPC_T1D_GETBITNOSKEW(mqdec, v, passtypename, symtypename) \
          123         JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename)
          124 
          125 #if !defined(DEBUG)
          126 #define        JPC_T1D_RAWGETBIT(bitstream, v, passtypename, symtypename) \
          127         ((v) = jpc_bitstream_getbit(bitstream))
          128 #else
          129 #define        JPC_T1D_RAWGETBIT(bitstream, v, passtypename, symtypename) \
          130 { \
          131         (v) = jpc_bitstream_getbit(bitstream); \
          132         if (jas_getdbglevel() >= 100) { \
          133                 fprintf(stderr, "index = %ld; passtype = %s; symtype = %s; sym = %d\n", t1dec_cnt, passtypename, symtypename, v); \
          134                 ++t1dec_cnt; \
          135         } \
          136 }
          137 #endif
          138 
          139 /******************************************************************************\
          140 * Code.
          141 \******************************************************************************/
          142 
          143 int jpc_dec_decodecblks(jpc_dec_t *dec, jpc_dec_tile_t *tile)
          144 {
          145         jpc_dec_tcomp_t *tcomp;
          146         int compcnt;
          147         jpc_dec_rlvl_t *rlvl;
          148         int rlvlcnt;
          149         jpc_dec_band_t *band;
          150         int bandcnt;
          151         jpc_dec_prc_t *prc;
          152         int prccnt;
          153         jpc_dec_cblk_t *cblk;
          154         int cblkcnt;
          155 
          156         for (compcnt = dec->numcomps, tcomp = tile->tcomps; compcnt > 0;
          157           --compcnt, ++tcomp) {
          158                 for (rlvlcnt = tcomp->numrlvls, rlvl = tcomp->rlvls;
          159                   rlvlcnt > 0; --rlvlcnt, ++rlvl) {
          160                         if (!rlvl->bands) {
          161                                 continue;
          162                         }
          163                         for (bandcnt = rlvl->numbands, band = rlvl->bands;
          164                           bandcnt > 0; --bandcnt, ++band) {
          165                                 if (!band->data) {
          166                                         continue;
          167                                 }
          168                                 for (prccnt = rlvl->numprcs, prc = band->prcs;
          169                                   prccnt > 0; --prccnt, ++prc) {
          170                                         if (!prc->cblks) {
          171                                                 continue;
          172                                         }
          173                                         for (cblkcnt = prc->numcblks,
          174                                           cblk = prc->cblks; cblkcnt > 0;
          175                                           --cblkcnt, ++cblk) {
          176                                                 if (jpc_dec_decodecblk(dec, tile, tcomp,
          177                                                   band, cblk, 1, JPC_MAXLYRS)) {
          178                                                         return -1;
          179                                                 }
          180                                         }
          181                                 }
          182 
          183                         }
          184                 }
          185         }
          186 
          187         return 0;
          188 }
          189 
          190 static int jpc_dec_decodecblk(jpc_dec_t *dec, jpc_dec_tile_t *tile, jpc_dec_tcomp_t *tcomp, jpc_dec_band_t *band,
          191   jpc_dec_cblk_t *cblk, int dopartial, int maxlyrs)
          192 {
          193         jpc_dec_seg_t *seg;
          194         int i;
          195         int bpno;
          196         int passtype;
          197         int ret;
          198         int compno;
          199         int filldata;
          200         int fillmask;
          201         jpc_dec_ccp_t *ccp;
          202 
          203         compno = tcomp - tile->tcomps;
          204 
          205         if (!cblk->flags) {
          206                 /* Note: matrix is assumed to be zeroed */
          207                 if (!(cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) +
          208                   2, jas_matrix_numcols(cblk->data) + 2))) {
          209                         return -1;
          210                 }
          211         }
          212 
          213         seg = cblk->segs.head;
          214         while (seg && (seg != cblk->curseg || dopartial) && (maxlyrs < 0 ||
          215           seg->lyrno < maxlyrs)) {
          216                 assert(seg->numpasses >= seg->maxpasses || dopartial);
          217                 assert(seg->stream);
          218                 jas_stream_rewind(seg->stream);
          219                 jas_stream_setrwcount(seg->stream, 0);
          220                 if (seg->type == JPC_SEG_MQ) {
          221                         if (!cblk->mqdec) {
          222                                 if (!(cblk->mqdec = jpc_mqdec_create(JPC_NUMCTXS, 0))) {
          223                                         return -1;
          224                                 }
          225                                 jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
          226                         }
          227                         jpc_mqdec_setinput(cblk->mqdec, seg->stream);
          228                         jpc_mqdec_init(cblk->mqdec);
          229                 } else {
          230                         assert(seg->type == JPC_SEG_RAW);
          231                         if (!cblk->nulldec) {
          232                                 if (!(cblk->nulldec = jpc_bitstream_sopen(seg->stream, "r"))) {
          233                                         assert(0);
          234                                 }
          235                         }
          236                 }
          237 
          238 
          239                 for (i = 0; i < seg->numpasses; ++i) {
          240                         if (cblk->numimsbs > band->numbps) {
          241                                 ccp = &tile->cp->ccps[compno];
          242                                 if (ccp->roishift <= 0) {
          243                                         fprintf(stderr, "warning: corrupt code stream\n");
          244                                 } else {
          245                                         if (cblk->numimsbs < ccp->roishift - band->numbps) {
          246                                                 fprintf(stderr, "warning: corrupt code stream\n");
          247                                         }
          248                                 }
          249                         }
          250                         bpno = band->roishift + band->numbps - 1 - (cblk->numimsbs +
          251                           (seg->passno + i - cblk->firstpassno + 2) / 3);
          252 if (bpno < 0) {
          253         goto premature_exit;
          254 }
          255 #if 1
          256                         passtype = (seg->passno + i + 2) % 3;
          257 #else
          258                         passtype = JPC_PASSTYPE(seg->passno + i + 2);
          259 #endif
          260                         assert(bpno >= 0 && bpno < 31);
          261                         switch (passtype) {
          262                         case JPC_SIGPASS:
          263                                 ret = (seg->type == JPC_SEG_MQ) ? dec_sigpass(dec,
          264                                   cblk->mqdec, bpno, band->orient,
          265                                   (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
          266                                   cblk->flags, cblk->data) :
          267                                   dec_rawsigpass(dec, cblk->nulldec, bpno,
          268                                   (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
          269                                   cblk->flags, cblk->data);
          270                                 break;
          271                         case JPC_REFPASS:
          272                                 ret = (seg->type == JPC_SEG_MQ) ?
          273                                   dec_refpass(dec, cblk->mqdec, bpno,
          274                                   (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
          275                                   cblk->flags, cblk->data) :
          276                                   dec_rawrefpass(dec, cblk->nulldec, bpno,
          277                                   (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
          278                                   cblk->flags, cblk->data);
          279                                 break;
          280                         case JPC_CLNPASS:
          281                                 assert(seg->type == JPC_SEG_MQ);
          282                                 ret = dec_clnpass(dec, cblk->mqdec, bpno,
          283                                   band->orient, (tile->cp->ccps[compno].cblkctx &
          284                                   JPC_COX_VSC) != 0, (tile->cp->ccps[compno].cblkctx &
          285                                   JPC_COX_SEGSYM) != 0, cblk->flags,
          286                                   cblk->data);
          287                                 break;
          288                         default:
          289                                 ret = -1;
          290                                 break;
          291                         }
          292                         /* Do we need to reset after each coding pass? */
          293                         if (tile->cp->ccps[compno].cblkctx & JPC_COX_RESET) {
          294                                 jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
          295                         }
          296 
          297                         if (ret) {
          298                                 fprintf(stderr, "coding pass failed passtype=%d segtype=%d\n", passtype, seg->type);
          299                                 return -1;
          300                         }
          301 
          302                 }
          303 
          304                 if (seg->type == JPC_SEG_MQ) {
          305 /* Note: dont destroy mq decoder because context info will be lost */
          306                 } else {
          307                         assert(seg->type == JPC_SEG_RAW);
          308                         if (tile->cp->ccps[compno].cblkctx & JPC_COX_PTERM) {
          309                                 fillmask = 0x7f;
          310                                 filldata = 0x2a;
          311                         } else {
          312                                 fillmask = 0;
          313                                 filldata = 0;
          314                         }
          315                         if ((ret = jpc_bitstream_inalign(cblk->nulldec, fillmask,
          316                           filldata)) < 0) {
          317                                 return -1;
          318                         } else if (ret > 0) {
          319                                 fprintf(stderr, "warning: bad termination pattern detected\n");
          320                         }
          321                         jpc_bitstream_close(cblk->nulldec);
          322                         cblk->nulldec = 0;
          323                 }
          324 
          325                 cblk->curseg = seg->next;
          326                 jpc_seglist_remove(&cblk->segs, seg);
          327                 jpc_seg_destroy(seg);
          328                 seg = cblk->curseg;
          329         }
          330 
          331         assert(dopartial ? (!cblk->curseg) : 1);
          332 
          333 premature_exit:
          334         return 0;
          335 }
          336 
          337 /******************************************************************************\
          338 * Code for significance pass.
          339 \******************************************************************************/
          340 
          341 #define        jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf, orient, mqdec, vcausalflag) \
          342 { \
          343         int f; \
          344         int v; \
          345         f = *(fp); \
          346         if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
          347                 jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO(f, (orient))); \
          348                 JPC_T1D_GETBIT((mqdec), v, "SIG", "ZC"); \
          349                 if (v) { \
          350                         jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \
          351                         JPC_T1D_GETBIT((mqdec), v, "SIG", "SC"); \
          352                         v ^= JPC_GETSPB(f); \
          353                         JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
          354                         *(fp) |= JPC_SIG; \
          355                         *(dp) = (v) ? (-(oneplushalf)) : (oneplushalf); \
          356                 } \
          357                 *(fp) |= JPC_VISIT; \
          358         } \
          359 }
          360 
          361 static int dec_sigpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos, int orient,
          362   int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data)
          363 {
          364         int i;
          365         int j;
          366         int one;
          367         int half;
          368         int oneplushalf;
          369         int vscanlen;
          370         int width;
          371         int height;
          372         jpc_fix_t *fp;
          373         int frowstep;
          374         int fstripestep;
          375         jpc_fix_t *fstripestart;
          376         jpc_fix_t *fvscanstart;
          377         jpc_fix_t *dp;
          378         int drowstep;
          379         int dstripestep;
          380         jpc_fix_t *dstripestart;
          381         jpc_fix_t *dvscanstart;
          382         int k;
          383 
          384         /* Avoid compiler warning about unused parameters. */
          385         dec = 0;
          386 
          387         width = jas_matrix_numcols(data);
          388         height = jas_matrix_numrows(data);
          389         frowstep = jas_matrix_rowstep(flags);
          390         drowstep = jas_matrix_rowstep(data);
          391         fstripestep = frowstep << 2;
          392         dstripestep = drowstep << 2;
          393 
          394         one = 1 << bitpos;
          395         half = one >> 1;
          396         oneplushalf = one | half;
          397 
          398         fstripestart = jas_matrix_getref(flags, 1, 1);
          399         dstripestart = jas_matrix_getref(data, 0, 0);
          400         for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
          401           dstripestart += dstripestep) {
          402                 fvscanstart = fstripestart;
          403                 dvscanstart = dstripestart;
          404                 vscanlen = JAS_MIN(i, 4);
          405                 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
          406                         fp = fvscanstart;
          407                         dp = dvscanstart;
          408                         k = vscanlen;
          409 
          410                         /* Process first sample in vertical scan. */
          411                         jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
          412                           orient, mqdec, vcausalflag);
          413                         if (--k <= 0) {
          414                                 continue;
          415                         }
          416                         fp += frowstep;
          417                         dp += drowstep;
          418 
          419                         /* Process second sample in vertical scan. */
          420                         jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
          421                           orient, mqdec, 0);
          422                         if (--k <= 0) {
          423                                 continue;
          424                         }
          425                         fp += frowstep;
          426                         dp += drowstep;
          427 
          428                         /* Process third sample in vertical scan. */
          429                         jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
          430                           orient, mqdec, 0);
          431                         if (--k <= 0) {
          432                                 continue;
          433                         }
          434                         fp += frowstep;
          435                         dp += drowstep;
          436 
          437                         /* Process fourth sample in vertical scan. */
          438                         jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
          439                           orient, mqdec, 0);
          440                 }
          441         }
          442         return 0;
          443 }
          444 
          445 #define        jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, in, vcausalflag) \
          446 { \
          447         jpc_fix_t f = *(fp); \
          448         jpc_fix_t v; \
          449         if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
          450                 JPC_T1D_RAWGETBIT(in, v, "SIG", "ZC"); \
          451                 if (v < 0) { \
          452                         return -1; \
          453                 } \
          454                 if (v) { \
          455                         JPC_T1D_RAWGETBIT(in, v, "SIG", "SC"); \
          456                         if (v < 0) { \
          457                                 return -1; \
          458                         } \
          459                         JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
          460                         *(fp) |= JPC_SIG; \
          461                         *(dp) = v ? (-oneplushalf) : (oneplushalf); \
          462                 } \
          463                 *(fp) |= JPC_VISIT; \
          464         } \
          465 }
          466 
          467 static int dec_rawsigpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, int vcausalflag,
          468   jas_matrix_t *flags, jas_matrix_t *data)
          469 {
          470         int i;
          471         int j;
          472         int k;
          473         int one;
          474         int half;
          475         int oneplushalf;
          476         int vscanlen;
          477         int width;
          478         int height;
          479         jpc_fix_t *fp;
          480         int frowstep;
          481         int fstripestep;
          482         jpc_fix_t *fstripestart;
          483         jpc_fix_t *fvscanstart;
          484         jpc_fix_t *dp;
          485         int drowstep;
          486         int dstripestep;
          487         jpc_fix_t *dstripestart;
          488         jpc_fix_t *dvscanstart;
          489 
          490         /* Avoid compiler warning about unused parameters. */
          491         dec = 0;
          492 
          493         width = jas_matrix_numcols(data);
          494         height = jas_matrix_numrows(data);
          495         frowstep = jas_matrix_rowstep(flags);
          496         drowstep = jas_matrix_rowstep(data);
          497         fstripestep = frowstep << 2;
          498         dstripestep = drowstep << 2;
          499 
          500         one = 1 << bitpos;
          501         half = one >> 1;
          502         oneplushalf = one | half;
          503 
          504         fstripestart = jas_matrix_getref(flags, 1, 1);
          505         dstripestart = jas_matrix_getref(data, 0, 0);
          506         for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
          507           dstripestart += dstripestep) {
          508                 fvscanstart = fstripestart;
          509                 dvscanstart = dstripestart;
          510                 vscanlen = JAS_MIN(i, 4);
          511                 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
          512                         fp = fvscanstart;
          513                         dp = dvscanstart;
          514                         k = vscanlen;
          515 
          516                         /* Process first sample in vertical scan. */
          517                         jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
          518                           in, vcausalflag);
          519                         if (--k <= 0) {
          520                                 continue;
          521                         }
          522                         fp += frowstep;
          523                         dp += drowstep;
          524 
          525                         /* Process second sample in vertical scan. */
          526                         jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
          527                           in, 0);
          528                         if (--k <= 0) {
          529                                 continue;
          530                         }
          531                         fp += frowstep;
          532                         dp += drowstep;
          533 
          534                         /* Process third sample in vertical scan. */
          535                         jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
          536                           in, 0);
          537                         if (--k <= 0) {
          538                                 continue;
          539                         }
          540                         fp += frowstep;
          541                         dp += drowstep;
          542 
          543                         /* Process fourth sample in vertical scan. */
          544                         jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
          545                           in, 0);
          546 
          547                 }
          548         }
          549         return 0;
          550 }
          551 
          552 /******************************************************************************\
          553 * Code for refinement pass.
          554 \******************************************************************************/
          555 
          556 #define        jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, vcausalflag) \
          557 { \
          558         int v; \
          559         int t; \
          560         if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
          561                 jpc_mqdec_setcurctx((mqdec), JPC_GETMAGCTXNO(*(fp))); \
          562                 JPC_T1D_GETBITNOSKEW((mqdec), v, "REF", "MR"); \
          563                 t = (v ? (poshalf) : (neghalf)); \
          564                 *(dp) += (*(dp) < 0) ? (-t) : t; \
          565                 *(fp) |= JPC_REFINE; \
          566         } \
          567 }
          568 
          569 static int dec_refpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos,
          570   int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data)
          571 {
          572         int i;
          573         int j;
          574         int vscanlen;
          575         int width;
          576         int height;
          577         int one;
          578         int poshalf;
          579         int neghalf;
          580         jpc_fix_t *fp;
          581         int frowstep;
          582         int fstripestep;
          583         jpc_fix_t *fstripestart;
          584         jpc_fix_t *fvscanstart;
          585         jpc_fix_t *dp;
          586         int drowstep;
          587         int dstripestep;
          588         jpc_fix_t *dstripestart;
          589         jpc_fix_t *dvscanstart;
          590         int k;
          591 
          592         /* Avoid compiler warning about unused parameters. */
          593         dec = 0;
          594         vcausalflag = 0;
          595 
          596         width = jas_matrix_numcols(data);
          597         height = jas_matrix_numrows(data);
          598         frowstep = jas_matrix_rowstep(flags);
          599         drowstep = jas_matrix_rowstep(data);
          600         fstripestep = frowstep << 2;
          601         dstripestep = drowstep << 2;
          602 
          603         one = 1 << bitpos;
          604         poshalf = one >> 1;
          605         neghalf = (bitpos > 0) ? (-poshalf) : (-1);
          606 
          607         fstripestart = jas_matrix_getref(flags, 1, 1);
          608         dstripestart = jas_matrix_getref(data, 0, 0);
          609         for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
          610           dstripestart += dstripestep) {
          611                 fvscanstart = fstripestart;
          612                 dvscanstart = dstripestart;
          613                 vscanlen = JAS_MIN(i, 4);
          614                 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
          615                         fp = fvscanstart;
          616                         dp = dvscanstart;
          617                         k = vscanlen;
          618 
          619                         /* Process first sample in vertical scan. */
          620                         jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec,
          621                           vcausalflag);
          622                         if (--k <= 0) {
          623                                 continue;
          624                         }
          625                         fp += frowstep;
          626                         dp += drowstep;
          627 
          628                         /* Process second sample in vertical scan. */
          629                         jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
          630                         if (--k <= 0) {
          631                                 continue;
          632                         }
          633                         fp += frowstep;
          634                         dp += drowstep;
          635 
          636                         /* Process third sample in vertical scan. */
          637                         jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
          638                         if (--k <= 0) {
          639                                 continue;
          640                         }
          641                         fp += frowstep;
          642                         dp += drowstep;
          643 
          644                         /* Process fourth sample in vertical scan. */
          645                         jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
          646                 }
          647         }
          648 
          649         return 0;
          650 }
          651 
          652 #define        jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, vcausalflag) \
          653 { \
          654         jpc_fix_t v; \
          655         jpc_fix_t t; \
          656         if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
          657                 JPC_T1D_RAWGETBIT(in, v, "REF", "MAGREF"); \
          658                 if (v < 0) { \
          659                         return -1; \
          660                 } \
          661                 t = (v ? poshalf : neghalf); \
          662                 *(dp) += (*(dp) < 0) ? (-t) : t; \
          663                 *(fp) |= JPC_REFINE; \
          664         } \
          665 }
          666 
          667 static int dec_rawrefpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, int vcausalflag,
          668   jas_matrix_t *flags, jas_matrix_t *data)
          669 {
          670         int i;
          671         int j;
          672         int k;
          673         int vscanlen;
          674         int width;
          675         int height;
          676         int one;
          677         int poshalf;
          678         int neghalf;
          679         jpc_fix_t *fp;
          680         int frowstep;
          681         int fstripestep;
          682         jpc_fix_t *fstripestart;
          683         jpc_fix_t *fvscanstart;
          684         jpc_fix_t *dp;
          685         int drowstep;
          686         int dstripestep;
          687         jpc_fix_t *dstripestart;
          688         jpc_fix_t *dvscanstart;
          689 
          690         /* Avoid compiler warning about unused parameters. */
          691         dec = 0;
          692         vcausalflag = 0;
          693 
          694         width = jas_matrix_numcols(data);
          695         height = jas_matrix_numrows(data);
          696         frowstep = jas_matrix_rowstep(flags);
          697         drowstep = jas_matrix_rowstep(data);
          698         fstripestep = frowstep << 2;
          699         dstripestep = drowstep << 2;
          700 
          701         one = 1 << bitpos;
          702         poshalf = one >> 1;
          703         neghalf = (bitpos > 0) ? (-poshalf) : (-1);
          704 
          705         fstripestart = jas_matrix_getref(flags, 1, 1);
          706         dstripestart = jas_matrix_getref(data, 0, 0);
          707         for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
          708           dstripestart += dstripestep) {
          709                 fvscanstart = fstripestart;
          710                 dvscanstart = dstripestart;
          711                 vscanlen = JAS_MIN(i, 4);
          712                 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
          713                         fp = fvscanstart;
          714                         dp = dvscanstart;
          715                         k = vscanlen;
          716 
          717                         /* Process first sample in vertical scan. */
          718                         jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in,
          719                           vcausalflag);
          720                         if (--k <= 0) {
          721                                 continue;
          722                         }
          723                         fp += frowstep;
          724                         dp += drowstep;
          725 
          726                         /* Process second sample in vertical scan. */
          727                         jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
          728                         if (--k <= 0) {
          729                                 continue;
          730                         }
          731                         fp += frowstep;
          732                         dp += drowstep;
          733 
          734                         /* Process third sample in vertical scan. */
          735                         jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
          736                         if (--k <= 0) {
          737                                 continue;
          738                         }
          739                         fp += frowstep;
          740                         dp += drowstep;
          741 
          742                         /* Process fourth sample in vertical scan. */
          743                         jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
          744                 }
          745         }
          746         return 0;
          747 }
          748 
          749 /******************************************************************************\
          750 * Code for cleanup pass.
          751 \******************************************************************************/
          752 
          753 #define        jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient, mqdec, flabel, plabel, vcausalflag) \
          754 { \
          755         int v; \
          756 flabel \
          757         if (!((f) & (JPC_SIG | JPC_VISIT))) { \
          758                 jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO((f), (orient))); \
          759                 JPC_T1D_GETBIT((mqdec), v, "CLN", "ZC"); \
          760                 if (v) { \
          761 plabel \
          762                         /* Coefficient is significant. */ \
          763                         jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \
          764                         JPC_T1D_GETBIT((mqdec), v, "CLN", "SC"); \
          765                         v ^= JPC_GETSPB(f); \
          766                         *(dp) = (v) ? (-(oneplushalf)) : (oneplushalf); \
          767                         JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
          768                         *(fp) |= JPC_SIG; \
          769                 } \
          770         } \
          771         /* XXX - Is this correct?  Can aggregation cause some VISIT bits not to be reset?  Check. */ \
          772         *(fp) &= ~JPC_VISIT; \
          773 }
          774 
          775 static int dec_clnpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos, int orient,
          776   int vcausalflag, int segsymflag, jas_matrix_t *flags, jas_matrix_t *data)
          777 {
          778         int i;
          779         int j;
          780         int k;
          781         int vscanlen;
          782         int v;
          783         int half;
          784         int runlen;
          785         int f;
          786         int width;
          787         int height;
          788         int one;
          789         int oneplushalf;
          790 
          791         jpc_fix_t *fp;
          792         int frowstep;
          793         int fstripestep;
          794         jpc_fix_t *fstripestart;
          795         jpc_fix_t *fvscanstart;
          796 
          797         jpc_fix_t *dp;
          798         int drowstep;
          799         int dstripestep;
          800         jpc_fix_t *dstripestart;
          801         jpc_fix_t *dvscanstart;
          802 
          803         /* Avoid compiler warning about unused parameters. */
          804         dec = 0;
          805 
          806         one = 1 << bitpos;
          807         half = one >> 1;
          808         oneplushalf = one | half;
          809 
          810         width = jas_matrix_numcols(data);
          811         height = jas_matrix_numrows(data);
          812 
          813         frowstep = jas_matrix_rowstep(flags);
          814         drowstep = jas_matrix_rowstep(data);
          815         fstripestep = frowstep << 2;
          816         dstripestep = drowstep << 2;
          817 
          818         fstripestart = jas_matrix_getref(flags, 1, 1);
          819         dstripestart = jas_matrix_getref(data, 0, 0);
          820         for (i = 0; i < height; i += 4, fstripestart += fstripestep,
          821           dstripestart += dstripestep) {
          822                 fvscanstart = fstripestart;
          823                 dvscanstart = dstripestart;
          824                 vscanlen = JAS_MIN(4, height - i);
          825                 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
          826                         fp = fvscanstart;
          827                         if (vscanlen >= 4 && (!((*fp) & (JPC_SIG | JPC_VISIT |
          828                           JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) & (JPC_SIG |
          829                           JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) &
          830                           (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep,
          831                           !((*fp) & (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK)))) {
          832 
          833                                 jpc_mqdec_setcurctx(mqdec, JPC_AGGCTXNO);
          834                                 JPC_T1D_GETBIT(mqdec, v, "CLN", "AGG");
          835                                 if (!v) {
          836                                         continue;
          837                                 }
          838                                 jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
          839                                 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL");
          840                                 runlen = v;
          841                                 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL");
          842                                 runlen = (runlen << 1) | v;
          843                                 f = *(fp = fvscanstart + frowstep * runlen);
          844                                 dp = dvscanstart + drowstep * runlen;
          845                                 k = vscanlen - runlen;
          846                                 switch (runlen) {
          847                                 case 0:
          848                                         goto clnpass_partial0;
          849                                         break;
          850                                 case 1:
          851                                         goto clnpass_partial1;
          852                                         break;
          853                                 case 2:
          854                                         goto clnpass_partial2;
          855                                         break;
          856                                 case 3:
          857                                         goto clnpass_partial3;
          858                                         break;
          859                                 }
          860                         } else {
          861                                 f = *(fp = fvscanstart);
          862                                 dp = dvscanstart;
          863                                 k = vscanlen;
          864                                 goto clnpass_full0;
          865                         }
          866 
          867                         /* Process first sample in vertical scan. */
          868                         jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
          869                           mqdec, clnpass_full0:, clnpass_partial0:,
          870                           vcausalflag);
          871                         if (--k <= 0) {
          872                                 continue;
          873                         }
          874                         fp += frowstep;
          875                         dp += drowstep;
          876 
          877                         /* Process second sample in vertical scan. */
          878                         f = *fp;
          879                         jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
          880                                 mqdec, ;, clnpass_partial1:, 0);
          881                         if (--k <= 0) {
          882                                 continue;
          883                         }
          884                         fp += frowstep;
          885                         dp += drowstep;
          886 
          887                         /* Process third sample in vertical scan. */
          888                         f = *fp;
          889                         jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
          890                                 mqdec, ;, clnpass_partial2:, 0);
          891                         if (--k <= 0) {
          892                                 continue;
          893                         }
          894                         fp += frowstep;
          895                         dp += drowstep;
          896 
          897                         /* Process fourth sample in vertical scan. */
          898                         f = *fp;
          899                         jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
          900                                 mqdec, ;, clnpass_partial3:, 0);
          901                 }
          902         }
          903 
          904         if (segsymflag) {
          905                 int segsymval;
          906                 segsymval = 0;
          907                 jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
          908                 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
          909                 segsymval = (segsymval << 1) | (v & 1);
          910                 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
          911                 segsymval = (segsymval << 1) | (v & 1);
          912                 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
          913                 segsymval = (segsymval << 1) | (v & 1);
          914                 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
          915                 segsymval = (segsymval << 1) | (v & 1);
          916                 if (segsymval != 0xa) {
          917                         fprintf(stderr, "warning: bad segmentation symbol\n");
          918                 }
          919         }
          920 
          921         return 0;
          922 }