Coverage Report

Created: 2025-11-16 07:22

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