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