Coverage Report

Created: 2026-10-28 07:26

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