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