Coverage Report

Created: 2026-06-16 07:20

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
588M
{
111
588M
  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
588M
  JAS_UNUSED(passtypename);
120
588M
  JAS_UNUSED(symtypename);
121
588M
#endif
122
588M
  return v;
123
588M
}
124
125
JAS_FORCE_INLINE
126
static bool JPC_T1D_GETBITNOSKEW(jpc_mqdec_t *mqdec, const char *passtypename, const char *symtypename)
127
102M
{
128
102M
  return JPC_T1D_GETBIT(mqdec, passtypename, symtypename);
129
102M
}
130
131
JAS_FORCE_INLINE
132
static int JPC_T1D_RAWGETBIT(jpc_bitstream_t *bitstream, const char *passtypename, const char *symtypename)
133
56.4M
{
134
56.4M
  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
56.4M
  JAS_UNUSED(passtypename);
142
56.4M
  JAS_UNUSED(symtypename);
143
56.4M
#endif
144
56.4M
  return v;
145
56.4M
}
146
147
/******************************************************************************\
148
* Code.
149
\******************************************************************************/
150
151
int jpc_dec_decodecblks(jpc_dec_t *dec, jpc_dec_tile_t *tile)
152
9.31k
{
153
9.31k
  jpc_dec_tcomp_t *tcomp;
154
9.31k
  jpc_dec_rlvl_t *rlvl;
155
9.31k
  jpc_dec_band_t *band;
156
9.31k
  jpc_dec_prc_t *prc;
157
9.31k
  jpc_dec_cblk_t *cblk;
158
159
9.31k
  unsigned compcnt;
160
33.2k
  for (compcnt = dec->numcomps, tcomp = tile->tcomps; compcnt > 0;
161
23.9k
    --compcnt, ++tcomp) {
162
23.9k
    unsigned rlvlcnt;
163
23.9k
    for (rlvlcnt = tcomp->numrlvls, rlvl = tcomp->rlvls;
164
162k
      rlvlcnt > 0; --rlvlcnt, ++rlvl) {
165
138k
      if (!rlvl->bands) {
166
33.4k
        continue;
167
33.4k
      }
168
105k
      unsigned bandcnt;
169
105k
      for (bandcnt = rlvl->numbands, band = rlvl->bands;
170
393k
        bandcnt > 0; --bandcnt, ++band) {
171
288k
        if (!band->data) {
172
105k
          continue;
173
105k
        }
174
183k
        unsigned prccnt;
175
183k
        for (prccnt = rlvl->numprcs, prc = band->prcs;
176
4.45M
          prccnt > 0; --prccnt, ++prc) {
177
4.27M
          if (!prc->cblks) {
178
14.3k
            continue;
179
14.3k
          }
180
4.26M
          unsigned cblkcnt;
181
4.26M
          for (cblkcnt = prc->numcblks,
182
16.7M
            cblk = prc->cblks; cblkcnt > 0;
183
12.4M
            --cblkcnt, ++cblk) {
184
12.4M
            if (jpc_dec_decodecblk(tile, tcomp,
185
12.4M
              band, cblk, 1, JPC_MAXLYRS)) {
186
0
              return -1;
187
0
            }
188
12.4M
          }
189
4.26M
        }
190
191
183k
      }
192
105k
    }
193
23.9k
  }
194
195
9.31k
  return 0;
196
9.31k
}
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
12.4M
{
201
12.4M
  jpc_dec_seg_t *seg;
202
12.4M
  int bpno;
203
12.4M
  int ret;
204
12.4M
  int filldata;
205
12.4M
  int fillmask;
206
207
12.4M
  const size_t compno = tcomp - tile->tcomps;
208
12.4M
  const jpc_dec_ccp_t *const ccp = &tile->cp->ccps[compno];
209
210
  /* The MQ decoder. */
211
12.4M
  jpc_mqdec_t *mqdec = NULL;
212
213
  /* The raw bit stream decoder. */
214
12.4M
  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
12.4M
  jas_matrix_t *const flags = jas_matrix_create(jas_matrix_numrows(cblk->data) + 2, jas_matrix_numcols(cblk->data) + 2);
219
12.4M
  if (!flags)
220
0
    goto error;
221
222
12.4M
  seg = cblk->segs.head;
223
12.6M
  while (seg && (seg != cblk->curseg || dopartial) && (maxlyrs < 0 ||
224
196k
    seg->lyrno < (unsigned)maxlyrs)) {
225
196k
    assert(seg->numpasses >= seg->maxpasses || dopartial);
226
196k
    assert(seg->stream);
227
196k
    jas_stream_rewind(seg->stream);
228
196k
    jas_stream_setrwcount(seg->stream, 0);
229
196k
    if (seg->type == JPC_SEG_MQ) {
230
143k
      if (!mqdec) {
231
86.3k
        if (!(mqdec = jpc_mqdec_create(JPC_NUMCTXS, 0))) {
232
0
          goto error;
233
0
        }
234
86.3k
        jpc_mqdec_setctxs(mqdec, JPC_NUMCTXS, jpc_mqctxs);
235
86.3k
      }
236
143k
      jpc_mqdec_setinput(mqdec, seg->stream);
237
143k
      jpc_mqdec_init(mqdec);
238
143k
    } else {
239
52.8k
      assert(seg->type == JPC_SEG_RAW);
240
52.8k
      if (!nulldec) {
241
52.8k
        if (!(nulldec = jpc_bitstream_sopen(seg->stream, "r"))) {
242
0
          goto error;
243
0
        }
244
52.8k
      }
245
52.8k
    }
246
247
248
941k
    for (unsigned i = 0; i < seg->numpasses; ++i) {
249
755k
      if (cblk->numimsbs > band->numbps) {
250
6.74k
        if (ccp->roishift <= 0) {
251
2.92k
          jas_logwarnf("warning: corrupt code stream\n");
252
3.81k
        } else {
253
3.81k
          if (cblk->numimsbs < ccp->roishift - band->numbps) {
254
3.60k
            jas_logwarnf("warning: corrupt code stream\n");
255
3.60k
          }
256
3.81k
        }
257
6.74k
      }
258
755k
      bpno = band->roishift + band->numbps - 1 - (cblk->numimsbs +
259
755k
        (seg->passno + i - cblk->firstpassno + 2) / 3);
260
755k
if (bpno < 0) {
261
9.56k
  goto premature_exit;
262
9.56k
}
263
745k
      enum jpc_passtype passtype = JPC_PASSTYPE(seg->passno + i);
264
745k
      assert(bpno >= 0 && bpno < 31);
265
745k
      switch (passtype) {
266
237k
      case JPC_SIGPASS:
267
237k
        ret = (seg->type == JPC_SEG_MQ) ? dec_sigpass(mqdec, bpno, band->orient,
268
195k
          (ccp->cblkctx & JPC_COX_VSC) != 0,
269
195k
          flags, cblk->data) :
270
237k
          dec_rawsigpass(nulldec, bpno,
271
42.3k
          (ccp->cblkctx & JPC_COX_VSC) != 0,
272
42.3k
          flags, cblk->data);
273
237k
        break;
274
221k
      case JPC_REFPASS:
275
221k
        ret = (seg->type == JPC_SEG_MQ) ?
276
185k
          dec_refpass(mqdec, bpno,
277
185k
          flags, cblk->data) :
278
221k
          dec_rawrefpass(nulldec, bpno,
279
35.5k
          flags, cblk->data);
280
221k
        break;
281
286k
      case JPC_CLNPASS:
282
286k
        assert(seg->type == JPC_SEG_MQ);
283
286k
        ret = dec_clnpass(mqdec, bpno,
284
286k
          band->orient, (ccp->cblkctx &
285
286k
          JPC_COX_VSC) != 0, (ccp->cblkctx &
286
286k
          JPC_COX_SEGSYM) != 0, flags,
287
286k
          cblk->data);
288
286k
        break;
289
0
      default:
290
0
        assert(false);
291
0
        JAS_UNREACHABLE();
292
745k
      }
293
      /* Do we need to reset after each coding pass? */
294
745k
      if ((ccp->cblkctx & JPC_COX_RESET) && mqdec) {
295
30.9k
        jpc_mqdec_setctxs(mqdec, JPC_NUMCTXS, jpc_mqctxs);
296
30.9k
      }
297
298
745k
      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
745k
    }
304
305
186k
    if (seg->type == JPC_SEG_MQ) {
306
/* Note: dont destroy mq decoder because context info will be lost */
307
137k
    } else {
308
49.4k
      assert(seg->type == JPC_SEG_RAW);
309
49.4k
      if (ccp->cblkctx & JPC_COX_PTERM) {
310
26.8k
        fillmask = 0x7f;
311
26.8k
        filldata = 0x2a;
312
26.8k
      } else {
313
22.6k
        fillmask = 0;
314
22.6k
        filldata = 0;
315
22.6k
      }
316
49.4k
      if ((ret = jpc_bitstream_inalign(nulldec, fillmask,
317
49.4k
        filldata)) < 0) {
318
0
        goto error;
319
49.4k
      } else if (ret > 0) {
320
4.61k
        jas_logwarnf("warning: bad termination pattern detected\n");
321
4.61k
      }
322
49.4k
      jpc_bitstream_close(nulldec);
323
49.4k
      nulldec = 0;
324
49.4k
    }
325
326
186k
    cblk->curseg = seg->next;
327
186k
    jpc_seglist_remove(&cblk->segs, seg);
328
186k
    jpc_seg_destroy(seg);
329
186k
    seg = cblk->curseg;
330
186k
  }
331
332
12.4M
  assert(dopartial ? (!cblk->curseg) : 1);
333
334
12.4M
premature_exit:
335
12.4M
  if (mqdec)
336
86.3k
    jpc_mqdec_destroy(mqdec);
337
12.4M
  if (nulldec)
338
3.40k
    jpc_bitstream_close(nulldec);
339
12.4M
  if (flags)
340
12.4M
    jas_matrix_destroy(flags);
341
12.4M
  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
12.4M
}
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
261M
{
360
261M
  const jpc_fix_t f = *(fp);
361
261M
  if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) {
362
73.8M
    jpc_mqdec_setcurctx(mqdec, JPC_GETZCCTXNO(f, orient));
363
364
73.8M
    if (JPC_T1D_GETBIT(mqdec, "SIG", "ZC")) {
365
30.5M
      jpc_mqdec_setcurctx(mqdec, JPC_GETSCCTXNO(f));
366
30.5M
      bool v = JPC_T1D_GETBIT(mqdec, "SIG", "SC");
367
30.5M
      v ^= JPC_GETSPB(f);
368
30.5M
      JPC_UPDATEFLAGS4(fp, frowstep, v, vcausalflag);
369
30.5M
      *fp |= JPC_SIG;
370
30.5M
      *dp = v ? -oneplushalf : oneplushalf;
371
30.5M
    }
372
73.8M
    *fp |= JPC_VISIT;
373
73.8M
  }
374
261M
}
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
195k
{
379
195k
  int i;
380
195k
  jpc_fix_t *fp;
381
195k
  jpc_fix_t *fstripestart;
382
195k
  jpc_fix_t *fvscanstart;
383
195k
  jpc_fix_t *dp;
384
195k
  jpc_fix_t *dstripestart;
385
195k
  jpc_fix_t *dvscanstart;
386
387
195k
  const unsigned width = jas_matrix_numcols(data);
388
195k
  const unsigned height = jas_matrix_numrows(data);
389
195k
  const unsigned frowstep = jas_matrix_rowstep(flags);
390
195k
  const unsigned drowstep = jas_matrix_rowstep(data);
391
195k
  const unsigned fstripestep = frowstep << 2;
392
195k
  const unsigned dstripestep = drowstep << 2;
393
394
195k
  const jpc_fix_t one = (jpc_fix_t)1 << bitpos;
395
195k
  const jpc_fix_t half = one >> 1;
396
195k
  const jpc_fix_t oneplushalf = one | half;
397
398
195k
  fstripestart = jas_matrix_getref(flags, 1, 1);
399
195k
  dstripestart = jas_matrix_getref(data, 0, 0);
400
1.89M
  for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
401
1.69M
    dstripestart += dstripestep) {
402
1.69M
    fvscanstart = fstripestart;
403
1.69M
    dvscanstart = dstripestart;
404
1.69M
    const unsigned vscanlen = JAS_MIN(i, 4);
405
70.1M
    for (unsigned j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
406
68.4M
      fp = fvscanstart;
407
68.4M
      dp = dvscanstart;
408
68.4M
      unsigned k = vscanlen;
409
410
      /* Process first sample in vertical scan. */
411
68.4M
      jpc_sigpass_step(fp, frowstep, dp, oneplushalf,
412
68.4M
        orient, mqdec, vcausalflag);
413
68.4M
      if (--k <= 0) {
414
3.62M
        continue;
415
3.62M
      }
416
64.8M
      fp += frowstep;
417
64.8M
      dp += drowstep;
418
419
      /* Process second sample in vertical scan. */
420
64.8M
      jpc_sigpass_step(fp, frowstep, dp, oneplushalf,
421
64.8M
        orient, mqdec, 0);
422
64.8M
      if (--k <= 0) {
423
468k
        continue;
424
468k
      }
425
64.3M
      fp += frowstep;
426
64.3M
      dp += drowstep;
427
428
      /* Process third sample in vertical scan. */
429
64.3M
      jpc_sigpass_step(fp, frowstep, dp, oneplushalf,
430
64.3M
        orient, mqdec, 0);
431
64.3M
      if (--k <= 0) {
432
590k
        continue;
433
590k
      }
434
63.7M
      fp += frowstep;
435
63.7M
      dp += drowstep;
436
437
      /* Process fourth sample in vertical scan. */
438
63.7M
      jpc_sigpass_step(fp, frowstep, dp, oneplushalf,
439
63.7M
        orient, mqdec, 0);
440
63.7M
    }
441
1.69M
  }
442
195k
  return 0;
443
195k
}
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
61.4M
{
448
61.4M
  const jpc_fix_t f = *fp;
449
61.4M
  if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) {
450
2.64M
    int v = JPC_T1D_RAWGETBIT(in, "SIG", "ZC");
451
2.64M
    if (v < 0) {
452
0
      return -1;
453
0
    }
454
2.64M
    if (v) {
455
2.62M
      v = JPC_T1D_RAWGETBIT(in, "SIG", "SC");
456
2.62M
      if (v < 0) {
457
0
        return -1;
458
0
      }
459
2.62M
      JPC_UPDATEFLAGS4(fp, frowstep, v, vcausalflag);
460
2.62M
      *fp |= JPC_SIG;
461
2.62M
      *dp = v ? -oneplushalf : oneplushalf;
462
2.62M
    }
463
2.64M
    *fp |= JPC_VISIT;
464
2.64M
  }
465
466
61.4M
  return 0;
467
61.4M
}
468
469
static int dec_rawsigpass(jpc_bitstream_t *in, unsigned bitpos, bool vcausalflag,
470
  jas_matrix_t *flags, jas_matrix_t *data)
471
42.3k
{
472
42.3k
  int i;
473
42.3k
  jpc_fix_t *fp;
474
42.3k
  jpc_fix_t *fstripestart;
475
42.3k
  jpc_fix_t *fvscanstart;
476
42.3k
  jpc_fix_t *dp;
477
42.3k
  jpc_fix_t *dstripestart;
478
42.3k
  jpc_fix_t *dvscanstart;
479
480
42.3k
  const unsigned width = jas_matrix_numcols(data);
481
42.3k
  const unsigned height = jas_matrix_numrows(data);
482
42.3k
  const unsigned frowstep = jas_matrix_rowstep(flags);
483
42.3k
  const unsigned drowstep = jas_matrix_rowstep(data);
484
42.3k
  const unsigned fstripestep = frowstep << 2;
485
42.3k
  const unsigned dstripestep = drowstep << 2;
486
487
42.3k
  const jpc_fix_t one = (jpc_fix_t)1 << bitpos;
488
42.3k
  const jpc_fix_t half = one >> 1;
489
42.3k
  const jpc_fix_t oneplushalf = one | half;
490
491
42.3k
  fstripestart = jas_matrix_getref(flags, 1, 1);
492
42.3k
  dstripestart = jas_matrix_getref(data, 0, 0);
493
433k
  for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
494
391k
    dstripestart += dstripestep) {
495
391k
    fvscanstart = fstripestart;
496
391k
    dvscanstart = dstripestart;
497
391k
    const unsigned vscanlen = JAS_MIN(i, 4);
498
17.8M
    for (unsigned j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
499
17.4M
      fp = fvscanstart;
500
17.4M
      dp = dvscanstart;
501
17.4M
      unsigned k = vscanlen;
502
503
      /* Process first sample in vertical scan. */
504
17.4M
      if (jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, in, vcausalflag))
505
0
        return -1;
506
507
17.4M
      if (--k <= 0) {
508
2.42M
        continue;
509
2.42M
      }
510
15.0M
      fp += frowstep;
511
15.0M
      dp += drowstep;
512
513
      /* Process second sample in vertical scan. */
514
15.0M
      if (jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, in, 0))
515
0
        return -1;
516
517
15.0M
      if (--k <= 0) {
518
424k
        continue;
519
424k
      }
520
14.6M
      fp += frowstep;
521
14.6M
      dp += drowstep;
522
523
      /* Process third sample in vertical scan. */
524
14.6M
      if (jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, in, 0))
525
0
        return -1;
526
527
14.6M
      if (--k <= 0) {
528
427k
        continue;
529
427k
      }
530
14.2M
      fp += frowstep;
531
14.2M
      dp += drowstep;
532
533
      /* Process fourth sample in vertical scan. */
534
14.2M
      jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
535
14.2M
        in, 0);
536
537
14.2M
    }
538
391k
  }
539
42.3k
  return 0;
540
42.3k
}
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
252M
{
549
252M
  if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
550
93.0M
    jpc_mqdec_setcurctx(mqdec, JPC_GETMAGCTXNO(*fp));
551
93.0M
    const bool v = JPC_T1D_GETBITNOSKEW(mqdec, "REF", "MR");
552
93.0M
    const jpc_fix_t t = v ? poshalf : neghalf;
553
93.0M
    *dp += *dp < 0 ? -t : t;
554
93.0M
    *fp |= JPC_REFINE;
555
93.0M
  }
556
252M
}
557
558
static int dec_refpass(jpc_mqdec_t *mqdec, unsigned bitpos,
559
  jas_matrix_t *flags, jas_matrix_t *data)
560
185k
{
561
185k
  int i;
562
185k
  jpc_fix_t *fp;
563
185k
  jpc_fix_t *fstripestart;
564
185k
  jpc_fix_t *fvscanstart;
565
185k
  jpc_fix_t *dp;
566
185k
  jpc_fix_t *dstripestart;
567
185k
  jpc_fix_t *dvscanstart;
568
569
185k
  const unsigned width = jas_matrix_numcols(data);
570
185k
  const unsigned height = jas_matrix_numrows(data);
571
185k
  const unsigned frowstep = jas_matrix_rowstep(flags);
572
185k
  const unsigned drowstep = jas_matrix_rowstep(data);
573
185k
  const unsigned fstripestep = frowstep << 2;
574
185k
  const unsigned dstripestep = drowstep << 2;
575
576
185k
  const jpc_fix_t one = (jpc_fix_t)1 << bitpos;
577
185k
  const jpc_fix_t poshalf = one >> 1;
578
185k
  const jpc_fix_t neghalf = bitpos > 0 ? -poshalf : -1;
579
580
185k
  fstripestart = jas_matrix_getref(flags, 1, 1);
581
185k
  dstripestart = jas_matrix_getref(data, 0, 0);
582
1.70M
  for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
583
1.52M
    dstripestart += dstripestep) {
584
1.52M
    fvscanstart = fstripestart;
585
1.52M
    dvscanstart = dstripestart;
586
1.52M
    const unsigned vscanlen = JAS_MIN(i, 4);
587
67.5M
    for (unsigned j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
588
66.0M
      fp = fvscanstart;
589
66.0M
      dp = dvscanstart;
590
591
318M
      for (unsigned k = 0; k < vscanlen; ++k) {
592
252M
        jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec);
593
252M
        fp += frowstep;
594
252M
        dp += drowstep;
595
252M
      }
596
66.0M
    }
597
1.52M
  }
598
599
185k
  return 0;
600
185k
}
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
56.1M
{
604
56.1M
  if ((*fp & (JPC_SIG | JPC_VISIT)) == JPC_SIG) {
605
51.1M
    int v = JPC_T1D_RAWGETBIT(in, "REF", "MAGREF");
606
51.1M
    if (v < 0) {
607
0
      return -1;
608
0
    }
609
51.1M
    jpc_fix_t t = v ? poshalf : neghalf;
610
51.1M
    *dp += *dp < 0 ? -t : t;
611
51.1M
    *fp |= JPC_REFINE;
612
51.1M
  }
613
614
56.1M
  return 0;
615
56.1M
}
616
617
static int dec_rawrefpass(jpc_bitstream_t *in, unsigned bitpos,
618
  jas_matrix_t *flags, jas_matrix_t *data)
619
35.5k
{
620
35.5k
  int i;
621
35.5k
  jpc_fix_t *fp;
622
35.5k
  jpc_fix_t *fstripestart;
623
35.5k
  jpc_fix_t *fvscanstart;
624
35.5k
  jpc_fix_t *dp;
625
35.5k
  jpc_fix_t *dstripestart;
626
35.5k
  jpc_fix_t *dvscanstart;
627
628
35.5k
  const unsigned width = jas_matrix_numcols(data);
629
35.5k
  const unsigned height = jas_matrix_numrows(data);
630
35.5k
  const unsigned frowstep = jas_matrix_rowstep(flags);
631
35.5k
  const unsigned drowstep = jas_matrix_rowstep(data);
632
35.5k
  const unsigned fstripestep = frowstep << 2;
633
35.5k
  const unsigned dstripestep = drowstep << 2;
634
635
35.5k
  const jpc_fix_t one = (jpc_fix_t)1 << bitpos;
636
35.5k
  const jpc_fix_t poshalf = one >> 1;
637
35.5k
  const jpc_fix_t neghalf = bitpos > 0 ? -poshalf : -1;
638
639
35.5k
  fstripestart = jas_matrix_getref(flags, 1, 1);
640
35.5k
  dstripestart = jas_matrix_getref(data, 0, 0);
641
389k
  for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
642
354k
    dstripestart += dstripestep) {
643
354k
    fvscanstart = fstripestart;
644
354k
    dvscanstart = dstripestart;
645
354k
    const unsigned vscanlen = JAS_MIN(i, 4);
646
16.4M
    for (unsigned j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
647
16.1M
      fp = fvscanstart;
648
16.1M
      dp = dvscanstart;
649
650
72.3M
      for (unsigned k = 0; k < vscanlen; ++k) {
651
56.1M
        if (jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in))
652
0
          return -1;
653
56.1M
        fp += frowstep;
654
56.1M
        dp += drowstep;
655
56.1M
      }
656
16.1M
    }
657
354k
  }
658
35.5k
  return 0;
659
35.5k
}
660
661
/******************************************************************************\
662
* Code for cleanup pass.
663
\******************************************************************************/
664
665
316M
#define jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient, mqdec, flabel, plabel, vcausalflag) \
666
316M
{ \
667
111M
flabel \
668
427M
  if (!((f) & (JPC_SIG | JPC_VISIT))) { \
669
241M
    jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO((f), (orient))); \
670
241M
    if (JPC_T1D_GETBIT((mqdec), "CLN", "ZC")) { \
671
104M
plabel \
672
104M
      /* Coefficient is significant. */ \
673
104M
      jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \
674
104M
      bool v = JPC_T1D_GETBIT((mqdec), "CLN", "SC"); \
675
104M
      v ^= JPC_GETSPB(f); \
676
104M
      *(dp) = (v) ? (-(jpc_fix_t)(oneplushalf)) : (jpc_fix_t)(oneplushalf); \
677
104M
      JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
678
104M
      *(fp) |= JPC_SIG; \
679
104M
    } \
680
241M
  } \
681
111M
  /* XXX - Is this correct?  Can aggregation cause some VISIT bits not to be reset?  Check. */ \
682
432M
  *(fp) &= ~JPC_VISIT; \
683
432M
}
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
286k
{
688
286k
  int f;
689
690
286k
  jpc_fix_t *fp;
691
286k
  jpc_fix_t *fstripestart;
692
286k
  jpc_fix_t *fvscanstart;
693
694
286k
  jpc_fix_t *dp;
695
286k
  jpc_fix_t *dstripestart;
696
286k
  jpc_fix_t *dvscanstart;
697
698
286k
  const jpc_fix_t one = (jpc_fix_t)1 << bitpos;
699
286k
  const jpc_fix_t half = one >> 1;
700
286k
  const jpc_fix_t oneplushalf = one | half;
701
702
286k
  const unsigned width = jas_matrix_numcols(data);
703
286k
  const unsigned height = jas_matrix_numrows(data);
704
705
286k
  const unsigned frowstep = jas_matrix_rowstep(flags);
706
286k
  const unsigned drowstep = jas_matrix_rowstep(data);
707
286k
  const unsigned fstripestep = frowstep << 2;
708
286k
  const unsigned dstripestep = drowstep << 2;
709
710
286k
  fstripestart = jas_matrix_getref(flags, 1, 1);
711
286k
  dstripestart = jas_matrix_getref(data, 0, 0);
712
2.92M
  for (unsigned i = 0; i < height; i += 4, fstripestart += fstripestep,
713
2.63M
    dstripestart += dstripestep) {
714
2.63M
    fvscanstart = fstripestart;
715
2.63M
    dvscanstart = dstripestart;
716
2.63M
    const unsigned vscanlen = JAS_MIN(4, height - i);
717
149M
    for (unsigned j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
718
146M
      fp = fvscanstart;
719
146M
      unsigned k;
720
146M
      if (vscanlen >= 4 && (!((*fp) & (JPC_SIG | JPC_VISIT |
721
137M
        JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) & (JPC_SIG |
722
40.5M
        JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) &
723
37.7M
        (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep,
724
35.7M
        !((*fp) & (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK)))) {
725
726
35.5M
        jpc_mqdec_setcurctx(mqdec, JPC_AGGCTXNO);
727
35.5M
        if (!JPC_T1D_GETBIT(mqdec, "CLN", "AGG")) {
728
30.9M
          continue;
729
30.9M
        }
730
4.61M
        jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
731
4.61M
        unsigned runlen = JPC_T1D_GETBITNOSKEW(mqdec, "CLN", "RL");
732
4.61M
        runlen = (runlen << 1) | JPC_T1D_GETBITNOSKEW(mqdec, "CLN", "RL");
733
4.61M
        f = *(fp = fvscanstart + frowstep * runlen);
734
4.61M
        dp = dvscanstart + drowstep * runlen;
735
4.61M
        k = vscanlen - runlen;
736
4.61M
        switch (runlen) {
737
1.21M
        case 0:
738
1.21M
          goto clnpass_partial0;
739
1.15M
        case 1:
740
1.15M
          goto clnpass_partial1;
741
1.11M
        case 2:
742
1.11M
          goto clnpass_partial2;
743
1.12M
        case 3:
744
1.12M
          goto clnpass_partial3;
745
4.61M
        }
746
111M
      } else {
747
111M
        f = *(fp = fvscanstart);
748
111M
        dp = dvscanstart;
749
111M
        k = vscanlen;
750
111M
        goto clnpass_full0;
751
111M
      }
752
753
      /* Process first sample in vertical scan. */
754
223M
      jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
755
223M
        mqdec, clnpass_full0:, clnpass_partial0:,
756
223M
        vcausalflag);
757
223M
      if (--k <= 0) {
758
6.94M
        continue;
759
6.94M
      }
760
105M
      fp += frowstep;
761
105M
      dp += drowstep;
762
763
      /* Process second sample in vertical scan. */
764
105M
      f = *fp;
765
106M
      jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
766
106M
        mqdec, ;, clnpass_partial1:, 0);
767
106M
      if (--k <= 0) {
768
1.12M
        continue;
769
1.12M
      }
770
105M
      fp += frowstep;
771
105M
      dp += drowstep;
772
773
      /* Process third sample in vertical scan. */
774
105M
      f = *fp;
775
106M
      jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
776
106M
        mqdec, ;, clnpass_partial2:, 0);
777
106M
      if (--k <= 0) {
778
1.31M
        continue;
779
1.31M
      }
780
105M
      fp += frowstep;
781
105M
      dp += drowstep;
782
783
      /* Process fourth sample in vertical scan. */
784
105M
      f = *fp;
785
106M
      jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
786
106M
        mqdec, ;, clnpass_partial3:, 0);
787
106M
    }
788
2.63M
  }
789
790
286k
  if (segsymflag) {
791
72.4k
    unsigned segsymval = 0;
792
72.4k
    jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
793
72.4k
    segsymval = (segsymval << 1) | JPC_T1D_GETBITNOSKEW(mqdec, "CLN", "SEGSYM");
794
72.4k
    segsymval = (segsymval << 1) | JPC_T1D_GETBITNOSKEW(mqdec, "CLN", "SEGSYM");
795
72.4k
    segsymval = (segsymval << 1) | JPC_T1D_GETBITNOSKEW(mqdec, "CLN", "SEGSYM");
796
72.4k
    segsymval = (segsymval << 1) | JPC_T1D_GETBITNOSKEW(mqdec, "CLN", "SEGSYM");
797
72.4k
    if (segsymval != 0xa) {
798
52.4k
      jas_logwarnf("warning: bad segmentation symbol\n");
799
52.4k
    }
800
72.4k
  }
801
802
286k
  return 0;
803
286k
}