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