/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 | } |