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 <stdio.h>
75 #include <stdlib.h>
76 #include <assert.h>
77
78 #include "jasper/jas_debug.h"
79 #include "jasper/jas_fix.h"
80 #include "jasper/jas_stream.h"
81 #include "jasper/jas_math.h"
82
83 #include "jpc_bs.h"
84 #include "jpc_mqdec.h"
85 #include "jpc_t1dec.h"
86 #include "jpc_t1cod.h"
87 #include "jpc_dec.h"
88
89 /******************************************************************************\
90 *
91 \******************************************************************************/
92
93 static int jpc_dec_decodecblk(jpc_dec_t *dec, jpc_dec_tile_t *tile, jpc_dec_tcomp_t *tcomp, jpc_dec_band_t *band,
94 jpc_dec_cblk_t *cblk, int dopartial, int maxlyrs);
95 static int dec_sigpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int orient,
96 int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
97 static int dec_rawsigpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos,
98 int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
99 static int dec_refpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int vcausalflag,
100 jas_matrix_t *flags, jas_matrix_t *data);
101 static int dec_rawrefpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos,
102 int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data);
103 static int dec_clnpass(jpc_dec_t *dec, jpc_mqdec_t *mqdec, int bitpos, int orient,
104 int vcausalflag, int segsymflag, jas_matrix_t *flags, jas_matrix_t *data);
105
106 #if defined(DEBUG)
107 static long t1dec_cnt = 0;
108 #endif
109
110 #if !defined(DEBUG)
111 #define JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename) \
112 ((v) = jpc_mqdec_getbit(mqdec))
113 #else
114 #define JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename) \
115 { \
116 (v) = jpc_mqdec_getbit(mqdec); \
117 if (jas_getdbglevel() >= 100) { \
118 jas_eprintf("index = %ld; passtype = %s; symtype = %s; sym = %d\n", t1dec_cnt, passtypename, symtypename, v); \
119 ++t1dec_cnt; \
120 } \
121 }
122 #endif
123 #define JPC_T1D_GETBITNOSKEW(mqdec, v, passtypename, symtypename) \
124 JPC_T1D_GETBIT(mqdec, v, passtypename, symtypename)
125
126 #if !defined(DEBUG)
127 #define JPC_T1D_RAWGETBIT(bitstream, v, passtypename, symtypename) \
128 ((v) = jpc_bitstream_getbit(bitstream))
129 #else
130 #define JPC_T1D_RAWGETBIT(bitstream, v, passtypename, symtypename) \
131 { \
132 (v) = jpc_bitstream_getbit(bitstream); \
133 if (jas_getdbglevel() >= 100) { \
134 jas_eprintf("index = %ld; passtype = %s; symtype = %s; sym = %d\n", t1dec_cnt, passtypename, symtypename, v); \
135 ++t1dec_cnt; \
136 } \
137 }
138 #endif
139
140 /******************************************************************************\
141 * Code.
142 \******************************************************************************/
143
jpc_dec_decodecblks(jpc_dec_t * dec,jpc_dec_tile_t * tile)144 int jpc_dec_decodecblks(jpc_dec_t *dec, jpc_dec_tile_t *tile)
145 {
146 jpc_dec_tcomp_t *tcomp;
147 int compcnt;
148 jpc_dec_rlvl_t *rlvl;
149 int rlvlcnt;
150 jpc_dec_band_t *band;
151 int bandcnt;
152 jpc_dec_prc_t *prc;
153 int prccnt;
154 jpc_dec_cblk_t *cblk;
155 int cblkcnt;
156
157 for (compcnt = dec->numcomps, tcomp = tile->tcomps; compcnt > 0;
158 --compcnt, ++tcomp) {
159 for (rlvlcnt = tcomp->numrlvls, rlvl = tcomp->rlvls;
160 rlvlcnt > 0; --rlvlcnt, ++rlvl) {
161 if (!rlvl->bands) {
162 continue;
163 }
164 for (bandcnt = rlvl->numbands, band = rlvl->bands;
165 bandcnt > 0; --bandcnt, ++band) {
166 if (!band->data) {
167 continue;
168 }
169 for (prccnt = rlvl->numprcs, prc = band->prcs;
170 prccnt > 0; --prccnt, ++prc) {
171 if (!prc->cblks) {
172 continue;
173 }
174 for (cblkcnt = prc->numcblks,
175 cblk = prc->cblks; cblkcnt > 0;
176 --cblkcnt, ++cblk) {
177 if (jpc_dec_decodecblk(dec, tile, tcomp,
178 band, cblk, 1, JPC_MAXLYRS)) {
179 return -1;
180 }
181 }
182 }
183
184 }
185 }
186 }
187
188 return 0;
189 }
190
jpc_dec_decodecblk(jpc_dec_t * dec,jpc_dec_tile_t * tile,jpc_dec_tcomp_t * tcomp,jpc_dec_band_t * band,jpc_dec_cblk_t * cblk,int dopartial,int maxlyrs)191 static int jpc_dec_decodecblk(jpc_dec_t *dec, jpc_dec_tile_t *tile, jpc_dec_tcomp_t *tcomp, jpc_dec_band_t *band,
192 jpc_dec_cblk_t *cblk, int dopartial, int maxlyrs)
193 {
194 jpc_dec_seg_t *seg;
195 int i;
196 int bpno;
197 int passtype;
198 int ret;
199 int compno;
200 int filldata;
201 int fillmask;
202 jpc_dec_ccp_t *ccp;
203
204 compno = tcomp - tile->tcomps;
205
206 if (!cblk->flags) {
207 /* Note: matrix is assumed to be zeroed */
208 if (!(cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) +
209 2, jas_matrix_numcols(cblk->data) + 2))) {
210 return -1;
211 }
212 }
213
214 seg = cblk->segs.head;
215 while (seg && (seg != cblk->curseg || dopartial) && (maxlyrs < 0 ||
216 seg->lyrno < maxlyrs)) {
217 assert(seg->numpasses >= seg->maxpasses || dopartial);
218 assert(seg->stream);
219 jas_stream_rewind(seg->stream);
220 jas_stream_setrwcount(seg->stream, 0);
221 if (seg->type == JPC_SEG_MQ) {
222 if (!cblk->mqdec) {
223 if (!(cblk->mqdec = jpc_mqdec_create(JPC_NUMCTXS, 0))) {
224 return -1;
225 }
226 jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
227 }
228 jpc_mqdec_setinput(cblk->mqdec, seg->stream);
229 jpc_mqdec_init(cblk->mqdec);
230 } else {
231 assert(seg->type == JPC_SEG_RAW);
232 if (!cblk->nulldec) {
233 if (!(cblk->nulldec = jpc_bitstream_sopen(seg->stream, "r"))) {
234 assert(0);
235 }
236 }
237 }
238
239
240 for (i = 0; i < seg->numpasses; ++i) {
241 if (cblk->numimsbs > band->numbps) {
242 ccp = &tile->cp->ccps[compno];
243 if (ccp->roishift <= 0) {
244 jas_eprintf("warning: corrupt code stream\n");
245 } else {
246 if (cblk->numimsbs < ccp->roishift - band->numbps) {
247 jas_eprintf("warning: corrupt code stream\n");
248 }
249 }
250 }
251 bpno = band->roishift + band->numbps - 1 - (cblk->numimsbs +
252 (seg->passno + i - cblk->firstpassno + 2) / 3);
253 if (bpno < 0) {
254 goto premature_exit;
255 }
256 #if 1
257 passtype = (seg->passno + i + 2) % 3;
258 #else
259 passtype = JPC_PASSTYPE(seg->passno + i + 2);
260 #endif
261 assert(bpno >= 0 && bpno < 31);
262 switch (passtype) {
263 case JPC_SIGPASS:
264 ret = (seg->type == JPC_SEG_MQ) ? dec_sigpass(dec,
265 cblk->mqdec, bpno, band->orient,
266 (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
267 cblk->flags, cblk->data) :
268 dec_rawsigpass(dec, cblk->nulldec, bpno,
269 (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
270 cblk->flags, cblk->data);
271 break;
272 case JPC_REFPASS:
273 ret = (seg->type == JPC_SEG_MQ) ?
274 dec_refpass(dec, cblk->mqdec, bpno,
275 (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
276 cblk->flags, cblk->data) :
277 dec_rawrefpass(dec, cblk->nulldec, bpno,
278 (tile->cp->ccps[compno].cblkctx & JPC_COX_VSC) != 0,
279 cblk->flags, cblk->data);
280 break;
281 case JPC_CLNPASS:
282 assert(seg->type == JPC_SEG_MQ);
283 ret = dec_clnpass(dec, cblk->mqdec, bpno,
284 band->orient, (tile->cp->ccps[compno].cblkctx &
285 JPC_COX_VSC) != 0, (tile->cp->ccps[compno].cblkctx &
286 JPC_COX_SEGSYM) != 0, cblk->flags,
287 cblk->data);
288 break;
289 default:
290 ret = -1;
291 break;
292 }
293 /* Do we need to reset after each coding pass? */
294 if (tile->cp->ccps[compno].cblkctx & JPC_COX_RESET) {
295 jpc_mqdec_setctxs(cblk->mqdec, JPC_NUMCTXS, jpc_mqctxs);
296 }
297
298 if (ret) {
299 jas_eprintf("coding pass failed passtype=%d segtype=%d\n", passtype, seg->type);
300 return -1;
301 }
302
303 }
304
305 if (seg->type == JPC_SEG_MQ) {
306 /* Note: dont destroy mq decoder because context info will be lost */
307 } else {
308 assert(seg->type == JPC_SEG_RAW);
309 if (tile->cp->ccps[compno].cblkctx & JPC_COX_PTERM) {
310 fillmask = 0x7f;
311 filldata = 0x2a;
312 } else {
313 fillmask = 0;
314 filldata = 0;
315 }
316 if ((ret = jpc_bitstream_inalign(cblk->nulldec, fillmask,
317 filldata)) < 0) {
318 return -1;
319 } else if (ret > 0) {
320 jas_eprintf("warning: bad termination pattern detected\n");
321 }
322 jpc_bitstream_close(cblk->nulldec);
323 cblk->nulldec = 0;
324 }
325
326 cblk->curseg = seg->next;
327 jpc_seglist_remove(&cblk->segs, seg);
328 jpc_seg_destroy(seg);
329 seg = cblk->curseg;
330 }
331
332 assert(dopartial ? (!cblk->curseg) : 1);
333
334 premature_exit:
335 return 0;
336 }
337
338 /******************************************************************************\
339 * Code for significance pass.
340 \******************************************************************************/
341
342 #define jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf, orient, mqdec, vcausalflag) \
343 { \
344 int f; \
345 int v; \
346 f = *(fp); \
347 if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
348 jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO(f, (orient))); \
349 JPC_T1D_GETBIT((mqdec), v, "SIG", "ZC"); \
350 if (v) { \
351 jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \
352 JPC_T1D_GETBIT((mqdec), v, "SIG", "SC"); \
353 v ^= JPC_GETSPB(f); \
354 JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
355 *(fp) |= JPC_SIG; \
356 *(dp) = (v) ? (-(oneplushalf)) : (oneplushalf); \
357 } \
358 *(fp) |= JPC_VISIT; \
359 } \
360 }
361
dec_sigpass(jpc_dec_t * dec,register jpc_mqdec_t * mqdec,int bitpos,int orient,int vcausalflag,jas_matrix_t * flags,jas_matrix_t * data)362 static int dec_sigpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos, int orient,
363 int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data)
364 {
365 int i;
366 int j;
367 int one;
368 int half;
369 int oneplushalf;
370 int vscanlen;
371 int width;
372 int height;
373 jpc_fix_t *fp;
374 int frowstep;
375 int fstripestep;
376 jpc_fix_t *fstripestart;
377 jpc_fix_t *fvscanstart;
378 jpc_fix_t *dp;
379 int drowstep;
380 int dstripestep;
381 jpc_fix_t *dstripestart;
382 jpc_fix_t *dvscanstart;
383 int k;
384
385 /* Avoid compiler warning about unused parameters. */
386 dec = 0;
387
388 width = jas_matrix_numcols(data);
389 height = jas_matrix_numrows(data);
390 frowstep = jas_matrix_rowstep(flags);
391 drowstep = jas_matrix_rowstep(data);
392 fstripestep = frowstep << 2;
393 dstripestep = drowstep << 2;
394
395 one = 1 << bitpos;
396 half = one >> 1;
397 oneplushalf = one | half;
398
399 fstripestart = jas_matrix_getref(flags, 1, 1);
400 dstripestart = jas_matrix_getref(data, 0, 0);
401 for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
402 dstripestart += dstripestep) {
403 fvscanstart = fstripestart;
404 dvscanstart = dstripestart;
405 vscanlen = JAS_MIN(i, 4);
406 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
407 fp = fvscanstart;
408 dp = dvscanstart;
409 k = vscanlen;
410
411 /* Process first sample in vertical scan. */
412 jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
413 orient, mqdec, vcausalflag);
414 if (--k <= 0) {
415 continue;
416 }
417 fp += frowstep;
418 dp += drowstep;
419
420 /* Process second sample in vertical scan. */
421 jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
422 orient, mqdec, 0);
423 if (--k <= 0) {
424 continue;
425 }
426 fp += frowstep;
427 dp += drowstep;
428
429 /* Process third sample in vertical scan. */
430 jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
431 orient, mqdec, 0);
432 if (--k <= 0) {
433 continue;
434 }
435 fp += frowstep;
436 dp += drowstep;
437
438 /* Process fourth sample in vertical scan. */
439 jpc_sigpass_step(fp, frowstep, dp, bitpos, oneplushalf,
440 orient, mqdec, 0);
441 }
442 }
443 return 0;
444 }
445
446 #define jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf, in, vcausalflag) \
447 { \
448 jpc_fix_t f = *(fp); \
449 jpc_fix_t v; \
450 if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
451 JPC_T1D_RAWGETBIT(in, v, "SIG", "ZC"); \
452 if (v < 0) { \
453 return -1; \
454 } \
455 if (v) { \
456 JPC_T1D_RAWGETBIT(in, v, "SIG", "SC"); \
457 if (v < 0) { \
458 return -1; \
459 } \
460 JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
461 *(fp) |= JPC_SIG; \
462 *(dp) = v ? (-oneplushalf) : (oneplushalf); \
463 } \
464 *(fp) |= JPC_VISIT; \
465 } \
466 }
467
dec_rawsigpass(jpc_dec_t * dec,jpc_bitstream_t * in,int bitpos,int vcausalflag,jas_matrix_t * flags,jas_matrix_t * data)468 static int dec_rawsigpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, int vcausalflag,
469 jas_matrix_t *flags, jas_matrix_t *data)
470 {
471 int i;
472 int j;
473 int k;
474 int one;
475 int half;
476 int oneplushalf;
477 int vscanlen;
478 int width;
479 int height;
480 jpc_fix_t *fp;
481 int frowstep;
482 int fstripestep;
483 jpc_fix_t *fstripestart;
484 jpc_fix_t *fvscanstart;
485 jpc_fix_t *dp;
486 int drowstep;
487 int dstripestep;
488 jpc_fix_t *dstripestart;
489 jpc_fix_t *dvscanstart;
490
491 /* Avoid compiler warning about unused parameters. */
492 dec = 0;
493
494 width = jas_matrix_numcols(data);
495 height = jas_matrix_numrows(data);
496 frowstep = jas_matrix_rowstep(flags);
497 drowstep = jas_matrix_rowstep(data);
498 fstripestep = frowstep << 2;
499 dstripestep = drowstep << 2;
500
501 one = 1 << bitpos;
502 half = one >> 1;
503 oneplushalf = one | half;
504
505 fstripestart = jas_matrix_getref(flags, 1, 1);
506 dstripestart = jas_matrix_getref(data, 0, 0);
507 for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
508 dstripestart += dstripestep) {
509 fvscanstart = fstripestart;
510 dvscanstart = dstripestart;
511 vscanlen = JAS_MIN(i, 4);
512 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
513 fp = fvscanstart;
514 dp = dvscanstart;
515 k = vscanlen;
516
517 /* Process first sample in vertical scan. */
518 jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
519 in, vcausalflag);
520 if (--k <= 0) {
521 continue;
522 }
523 fp += frowstep;
524 dp += drowstep;
525
526 /* Process second sample in vertical scan. */
527 jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
528 in, 0);
529 if (--k <= 0) {
530 continue;
531 }
532 fp += frowstep;
533 dp += drowstep;
534
535 /* Process third sample in vertical scan. */
536 jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
537 in, 0);
538 if (--k <= 0) {
539 continue;
540 }
541 fp += frowstep;
542 dp += drowstep;
543
544 /* Process fourth sample in vertical scan. */
545 jpc_rawsigpass_step(fp, frowstep, dp, oneplushalf,
546 in, 0);
547
548 }
549 }
550 return 0;
551 }
552
553 /******************************************************************************\
554 * Code for refinement pass.
555 \******************************************************************************/
556
557 #define jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, vcausalflag) \
558 { \
559 int v; \
560 int t; \
561 if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
562 jpc_mqdec_setcurctx((mqdec), JPC_GETMAGCTXNO(*(fp))); \
563 JPC_T1D_GETBITNOSKEW((mqdec), v, "REF", "MR"); \
564 t = (v ? (poshalf) : (neghalf)); \
565 *(dp) += (*(dp) < 0) ? (-t) : t; \
566 *(fp) |= JPC_REFINE; \
567 } \
568 }
569
dec_refpass(jpc_dec_t * dec,register jpc_mqdec_t * mqdec,int bitpos,int vcausalflag,jas_matrix_t * flags,jas_matrix_t * data)570 static int dec_refpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos,
571 int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data)
572 {
573 int i;
574 int j;
575 int vscanlen;
576 int width;
577 int height;
578 int one;
579 int poshalf;
580 int neghalf;
581 jpc_fix_t *fp;
582 int frowstep;
583 int fstripestep;
584 jpc_fix_t *fstripestart;
585 jpc_fix_t *fvscanstart;
586 jpc_fix_t *dp;
587 int drowstep;
588 int dstripestep;
589 jpc_fix_t *dstripestart;
590 jpc_fix_t *dvscanstart;
591 int k;
592
593 /* Avoid compiler warning about unused parameters. */
594 dec = 0;
595 vcausalflag = 0;
596
597 width = jas_matrix_numcols(data);
598 height = jas_matrix_numrows(data);
599 frowstep = jas_matrix_rowstep(flags);
600 drowstep = jas_matrix_rowstep(data);
601 fstripestep = frowstep << 2;
602 dstripestep = drowstep << 2;
603
604 one = 1 << bitpos;
605 poshalf = one >> 1;
606 neghalf = (bitpos > 0) ? (-poshalf) : (-1);
607
608 fstripestart = jas_matrix_getref(flags, 1, 1);
609 dstripestart = jas_matrix_getref(data, 0, 0);
610 for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
611 dstripestart += dstripestep) {
612 fvscanstart = fstripestart;
613 dvscanstart = dstripestart;
614 vscanlen = JAS_MIN(i, 4);
615 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
616 fp = fvscanstart;
617 dp = dvscanstart;
618 k = vscanlen;
619
620 /* Process first sample in vertical scan. */
621 jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec,
622 vcausalflag);
623 if (--k <= 0) {
624 continue;
625 }
626 fp += frowstep;
627 dp += drowstep;
628
629 /* Process second sample in vertical scan. */
630 jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
631 if (--k <= 0) {
632 continue;
633 }
634 fp += frowstep;
635 dp += drowstep;
636
637 /* Process third sample in vertical scan. */
638 jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
639 if (--k <= 0) {
640 continue;
641 }
642 fp += frowstep;
643 dp += drowstep;
644
645 /* Process fourth sample in vertical scan. */
646 jpc_refpass_step(fp, dp, poshalf, neghalf, mqdec, 0);
647 }
648 }
649
650 return 0;
651 }
652
653 #define jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, vcausalflag) \
654 { \
655 jpc_fix_t v; \
656 jpc_fix_t t; \
657 if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
658 JPC_T1D_RAWGETBIT(in, v, "REF", "MAGREF"); \
659 if (v < 0) { \
660 return -1; \
661 } \
662 t = (v ? poshalf : neghalf); \
663 *(dp) += (*(dp) < 0) ? (-t) : t; \
664 *(fp) |= JPC_REFINE; \
665 } \
666 }
667
dec_rawrefpass(jpc_dec_t * dec,jpc_bitstream_t * in,int bitpos,int vcausalflag,jas_matrix_t * flags,jas_matrix_t * data)668 static int dec_rawrefpass(jpc_dec_t *dec, jpc_bitstream_t *in, int bitpos, int vcausalflag,
669 jas_matrix_t *flags, jas_matrix_t *data)
670 {
671 int i;
672 int j;
673 int k;
674 int vscanlen;
675 int width;
676 int height;
677 int one;
678 int poshalf;
679 int neghalf;
680 jpc_fix_t *fp;
681 int frowstep;
682 int fstripestep;
683 jpc_fix_t *fstripestart;
684 jpc_fix_t *fvscanstart;
685 jpc_fix_t *dp;
686 int drowstep;
687 int dstripestep;
688 jpc_fix_t *dstripestart;
689 jpc_fix_t *dvscanstart;
690
691 /* Avoid compiler warning about unused parameters. */
692 dec = 0;
693 vcausalflag = 0;
694
695 width = jas_matrix_numcols(data);
696 height = jas_matrix_numrows(data);
697 frowstep = jas_matrix_rowstep(flags);
698 drowstep = jas_matrix_rowstep(data);
699 fstripestep = frowstep << 2;
700 dstripestep = drowstep << 2;
701
702 one = 1 << bitpos;
703 poshalf = one >> 1;
704 neghalf = (bitpos > 0) ? (-poshalf) : (-1);
705
706 fstripestart = jas_matrix_getref(flags, 1, 1);
707 dstripestart = jas_matrix_getref(data, 0, 0);
708 for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
709 dstripestart += dstripestep) {
710 fvscanstart = fstripestart;
711 dvscanstart = dstripestart;
712 vscanlen = JAS_MIN(i, 4);
713 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
714 fp = fvscanstart;
715 dp = dvscanstart;
716 k = vscanlen;
717
718 /* Process first sample in vertical scan. */
719 jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in,
720 vcausalflag);
721 if (--k <= 0) {
722 continue;
723 }
724 fp += frowstep;
725 dp += drowstep;
726
727 /* Process second sample in vertical scan. */
728 jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
729 if (--k <= 0) {
730 continue;
731 }
732 fp += frowstep;
733 dp += drowstep;
734
735 /* Process third sample in vertical scan. */
736 jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
737 if (--k <= 0) {
738 continue;
739 }
740 fp += frowstep;
741 dp += drowstep;
742
743 /* Process fourth sample in vertical scan. */
744 jpc_rawrefpass_step(fp, dp, poshalf, neghalf, in, 0);
745 }
746 }
747 return 0;
748 }
749
750 /******************************************************************************\
751 * Code for cleanup pass.
752 \******************************************************************************/
753
754 #define jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient, mqdec, flabel, plabel, vcausalflag) \
755 { \
756 int v; \
757 flabel \
758 if (!((f) & (JPC_SIG | JPC_VISIT))) { \
759 jpc_mqdec_setcurctx((mqdec), JPC_GETZCCTXNO((f), (orient))); \
760 JPC_T1D_GETBIT((mqdec), v, "CLN", "ZC"); \
761 if (v) { \
762 plabel \
763 /* Coefficient is significant. */ \
764 jpc_mqdec_setcurctx((mqdec), JPC_GETSCCTXNO(f)); \
765 JPC_T1D_GETBIT((mqdec), v, "CLN", "SC"); \
766 v ^= JPC_GETSPB(f); \
767 *(dp) = (v) ? (-(oneplushalf)) : (oneplushalf); \
768 JPC_UPDATEFLAGS4((fp), (frowstep), v, (vcausalflag)); \
769 *(fp) |= JPC_SIG; \
770 } \
771 } \
772 /* XXX - Is this correct? Can aggregation cause some VISIT bits not to be reset? Check. */ \
773 *(fp) &= ~JPC_VISIT; \
774 }
775
dec_clnpass(jpc_dec_t * dec,register jpc_mqdec_t * mqdec,int bitpos,int orient,int vcausalflag,int segsymflag,jas_matrix_t * flags,jas_matrix_t * data)776 static int dec_clnpass(jpc_dec_t *dec, register jpc_mqdec_t *mqdec, int bitpos, int orient,
777 int vcausalflag, int segsymflag, jas_matrix_t *flags, jas_matrix_t *data)
778 {
779 int i;
780 int j;
781 int k;
782 int vscanlen;
783 int v;
784 int half;
785 int runlen;
786 int f;
787 int width;
788 int height;
789 int one;
790 int oneplushalf;
791
792 jpc_fix_t *fp;
793 int frowstep;
794 int fstripestep;
795 jpc_fix_t *fstripestart;
796 jpc_fix_t *fvscanstart;
797
798 jpc_fix_t *dp;
799 int drowstep;
800 int dstripestep;
801 jpc_fix_t *dstripestart;
802 jpc_fix_t *dvscanstart;
803
804 /* Avoid compiler warning about unused parameters. */
805 dec = 0;
806
807 one = 1 << bitpos;
808 half = one >> 1;
809 oneplushalf = one | half;
810
811 width = jas_matrix_numcols(data);
812 height = jas_matrix_numrows(data);
813
814 frowstep = jas_matrix_rowstep(flags);
815 drowstep = jas_matrix_rowstep(data);
816 fstripestep = frowstep << 2;
817 dstripestep = drowstep << 2;
818
819 fstripestart = jas_matrix_getref(flags, 1, 1);
820 dstripestart = jas_matrix_getref(data, 0, 0);
821 for (i = 0; i < height; i += 4, fstripestart += fstripestep,
822 dstripestart += dstripestep) {
823 fvscanstart = fstripestart;
824 dvscanstart = dstripestart;
825 vscanlen = JAS_MIN(4, height - i);
826 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
827 fp = fvscanstart;
828 if (vscanlen >= 4 && (!((*fp) & (JPC_SIG | JPC_VISIT |
829 JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) & (JPC_SIG |
830 JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) &
831 (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep,
832 !((*fp) & (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK)))) {
833
834 jpc_mqdec_setcurctx(mqdec, JPC_AGGCTXNO);
835 JPC_T1D_GETBIT(mqdec, v, "CLN", "AGG");
836 if (!v) {
837 continue;
838 }
839 jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
840 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL");
841 runlen = v;
842 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "RL");
843 runlen = (runlen << 1) | v;
844 f = *(fp = fvscanstart + frowstep * runlen);
845 dp = dvscanstart + drowstep * runlen;
846 k = vscanlen - runlen;
847 switch (runlen) {
848 case 0:
849 goto clnpass_partial0;
850 break;
851 case 1:
852 goto clnpass_partial1;
853 break;
854 case 2:
855 goto clnpass_partial2;
856 break;
857 case 3:
858 goto clnpass_partial3;
859 break;
860 }
861 } else {
862 f = *(fp = fvscanstart);
863 dp = dvscanstart;
864 k = vscanlen;
865 goto clnpass_full0;
866 }
867
868 /* Process first sample in vertical scan. */
869 jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
870 mqdec, clnpass_full0:, clnpass_partial0:,
871 vcausalflag);
872 if (--k <= 0) {
873 continue;
874 }
875 fp += frowstep;
876 dp += drowstep;
877
878 /* Process second sample in vertical scan. */
879 f = *fp;
880 jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
881 mqdec, ;, clnpass_partial1:, 0);
882 if (--k <= 0) {
883 continue;
884 }
885 fp += frowstep;
886 dp += drowstep;
887
888 /* Process third sample in vertical scan. */
889 f = *fp;
890 jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
891 mqdec, ;, clnpass_partial2:, 0);
892 if (--k <= 0) {
893 continue;
894 }
895 fp += frowstep;
896 dp += drowstep;
897
898 /* Process fourth sample in vertical scan. */
899 f = *fp;
900 jpc_clnpass_step(f, fp, frowstep, dp, oneplushalf, orient,
901 mqdec, ;, clnpass_partial3:, 0);
902 }
903 }
904
905 if (segsymflag) {
906 int segsymval;
907 segsymval = 0;
908 jpc_mqdec_setcurctx(mqdec, JPC_UCTXNO);
909 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
910 segsymval = (segsymval << 1) | (v & 1);
911 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
912 segsymval = (segsymval << 1) | (v & 1);
913 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
914 segsymval = (segsymval << 1) | (v & 1);
915 JPC_T1D_GETBITNOSKEW(mqdec, v, "CLN", "SEGSYM");
916 segsymval = (segsymval << 1) | (v & 1);
917 if (segsymval != 0xa) {
918 jas_eprintf("warning: bad segmentation symbol\n");
919 }
920 }
921
922 return 0;
923 }
924