1/* 2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of 3 * British Columbia. 4 * Copyright (c) 2001-2002 Michael David Adams. 5 * All rights reserved. 6 */ 7 8/* __START_OF_JASPER_LICENSE__ 9 * 10 * JasPer Software License 11 * 12 * IMAGE POWER JPEG-2000 PUBLIC LICENSE 13 * ************************************ 14 * 15 * GRANT: 16 * 17 * Permission is hereby granted, free of charge, to any person (the "User") 18 * obtaining a copy of this software and associated documentation, to deal 19 * in the JasPer Software without restriction, including without limitation 20 * the right to use, copy, modify, merge, publish, distribute, sublicense, 21 * and/or sell copies of the JasPer Software (in source and binary forms), 22 * and to permit persons to whom the JasPer Software is furnished to do so, 23 * provided further that the License Conditions below are met. 24 * 25 * License Conditions 26 * ****************** 27 * 28 * A. Redistributions of source code must retain the above copyright notice, 29 * and this list of conditions, and the following disclaimer. 30 * 31 * B. Redistributions in binary form must reproduce the above copyright 32 * notice, and this list of conditions, and the following disclaimer in 33 * the documentation and/or other materials provided with the distribution. 34 * 35 * C. Neither the name of Image Power, Inc. nor any other contributor 36 * (including, but not limited to, the University of British Columbia and 37 * Michael David Adams) may be used to endorse or promote products derived 38 * from this software without specific prior written permission. 39 * 40 * D. User agrees that it shall not commence any action against Image Power, 41 * Inc., the University of British Columbia, Michael David Adams, or any 42 * other contributors (collectively "Licensors") for infringement of any 43 * intellectual property rights ("IPR") held by the User in respect of any 44 * technology that User owns or has a right to license or sublicense and 45 * which is an element required in order to claim compliance with ISO/IEC 46 * 15444-1 (i.e., JPEG-2000 Part 1). "IPR" means all intellectual property 47 * rights worldwide arising under statutory or common law, and whether 48 * or not perfected, including, without limitation, all (i) patents and 49 * patent applications owned or licensable by User; (ii) rights associated 50 * with works of authorship including copyrights, copyright applications, 51 * copyright registrations, mask work rights, mask work applications, 52 * mask work registrations; (iii) rights relating to the protection of 53 * trade secrets and confidential information; (iv) any right analogous 54 * to those set forth in subsections (i), (ii), or (iii) and any other 55 * proprietary rights relating to intangible property (other than trademark, 56 * trade dress, or service mark rights); and (v) divisions, continuations, 57 * renewals, reissues and extensions of the foregoing (as and to the extent 58 * applicable) now existing, hereafter filed, issued or acquired. 59 * 60 * E. If User commences an infringement action against any Licensor(s) then 61 * such Licensor(s) shall have the right to terminate User's license and 62 * all sublicenses that have been granted hereunder by User to other parties. 63 * 64 * F. This software is for use only in hardware or software products that 65 * are compliant with ISO/IEC 15444-1 (i.e., JPEG-2000 Part 1). No license 66 * or right to this Software is granted for products that do not comply 67 * with ISO/IEC 15444-1. The JPEG-2000 Part 1 standard can be purchased 68 * from the ISO. 69 * 70 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. 71 * NO USE OF THE JASPER SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER 72 * THIS DISCLAIMER. THE JASPER SOFTWARE IS PROVIDED BY THE LICENSORS AND 73 * CONTRIBUTORS UNDER THIS LICENSE ON AN ``AS-IS'' BASIS, WITHOUT WARRANTY 74 * OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, 75 * WARRANTIES THAT THE JASPER SOFTWARE IS FREE OF DEFECTS, IS MERCHANTABLE, 76 * IS FIT FOR A PARTICULAR PURPOSE OR IS NON-INFRINGING. THOSE INTENDING 77 * TO USE THE JASPER SOFTWARE OR MODIFICATIONS THEREOF FOR USE IN HARDWARE 78 * OR SOFTWARE PRODUCTS ARE ADVISED THAT THEIR USE MAY INFRINGE EXISTING 79 * PATENTS, COPYRIGHTS, TRADEMARKS, OR OTHER INTELLECTUAL PROPERTY RIGHTS. 80 * THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE JASPER SOFTWARE 81 * IS WITH THE USER. SHOULD ANY PART OF THE JASPER SOFTWARE PROVE DEFECTIVE 82 * IN ANY RESPECT, THE USER (AND NOT THE INITIAL DEVELOPERS, THE UNIVERSITY 83 * OF BRITISH COLUMBIA, IMAGE POWER, INC., MICHAEL DAVID ADAMS, OR ANY 84 * OTHER CONTRIBUTOR) SHALL ASSUME THE COST OF ANY NECESSARY SERVICING, 85 * REPAIR OR CORRECTION. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, 86 * WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE 87 * INITIAL DEVELOPER, THE UNIVERSITY OF BRITISH COLUMBIA, IMAGE POWER, INC., 88 * MICHAEL DAVID ADAMS, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF THE 89 * JASPER SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO 90 * THE USER OR ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR 91 * CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, 92 * DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR 93 * MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF 94 * SUCH PARTY HAD BEEN INFORMED, OR OUGHT TO HAVE KNOWN, OF THE POSSIBILITY 95 * OF SUCH DAMAGES. THE JASPER SOFTWARE AND UNDERLYING TECHNOLOGY ARE NOT 96 * FAULT-TOLERANT AND ARE NOT DESIGNED, MANUFACTURED OR INTENDED FOR USE OR 97 * RESALE AS ON-LINE CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING 98 * FAIL-SAFE PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, 99 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT 100 * LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE 101 * JASPER SOFTWARE OR UNDERLYING TECHNOLOGY OR PRODUCT COULD LEAD DIRECTLY 102 * TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE 103 * ("HIGH RISK ACTIVITIES"). LICENSOR SPECIFICALLY DISCLAIMS ANY EXPRESS 104 * OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES. USER WILL NOT 105 * KNOWINGLY USE, DISTRIBUTE OR RESELL THE JASPER SOFTWARE OR UNDERLYING 106 * TECHNOLOGY OR PRODUCTS FOR HIGH RISK ACTIVITIES AND WILL ENSURE THAT ITS 107 * CUSTOMERS AND END-USERS OF ITS PRODUCTS ARE PROVIDED WITH A COPY OF THE 108 * NOTICE SPECIFIED IN THIS SECTION. 109 * 110 * __END_OF_JASPER_LICENSE__ 111 */ 112 113/* 114 * Tier 1 Encoder 115 * 116 * $Id: jpc_t1enc.c 14449 2005-10-20 12:15:56Z stippi $ 117 */ 118 119/******************************************************************************\ 120* Includes. 121\******************************************************************************/ 122 123#include <stdio.h> 124#include <stdlib.h> 125#include <assert.h> 126 127#include "jasper/jas_fix.h" 128#include "jasper/jas_malloc.h" 129#include "jasper/jas_math.h" 130 131#include "jpc_t1enc.h" 132#include "jpc_t1cod.h" 133#include "jpc_enc.h" 134#include "jpc_cod.h" 135#include "jpc_math.h" 136 137static int jpc_encsigpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int, 138 jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec); 139 140static int jpc_encrefpass(jpc_mqenc_t *mqenc, int bitpos, int, jas_matrix_t *flags, 141 jas_matrix_t *data, int term, long *nmsedec); 142 143static int jpc_encclnpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int, 144 int, jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec); 145 146static int jpc_encrawsigpass(jpc_bitstream_t *out, int bitpos, int, 147 jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec); 148 149static int jpc_encrawrefpass(jpc_bitstream_t *out, int bitpos, int, 150 jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec); 151 152/******************************************************************************\ 153* Code for encoding code blocks. 154\******************************************************************************/ 155 156/* Encode all of the code blocks associated with the current tile. */ 157int jpc_enc_enccblks(jpc_enc_t *enc) 158{ 159 jpc_enc_tcmpt_t *tcmpt; 160 jpc_enc_tcmpt_t *endcomps; 161 jpc_enc_rlvl_t *lvl; 162 jpc_enc_rlvl_t *endlvls; 163 jpc_enc_band_t *band; 164 jpc_enc_band_t *endbands; 165 jpc_enc_cblk_t *cblk; 166 jpc_enc_cblk_t *endcblks; 167 int i; 168 int j; 169 int mx; 170 int bmx; 171 int v; 172 jpc_enc_tile_t *tile; 173 uint_fast32_t prcno; 174 jpc_enc_prc_t *prc; 175 176 tile = enc->curtile; 177 178 endcomps = &tile->tcmpts[tile->numtcmpts]; 179 for (tcmpt = tile->tcmpts; tcmpt != endcomps; ++tcmpt) { 180 endlvls = &tcmpt->rlvls[tcmpt->numrlvls]; 181 for (lvl = tcmpt->rlvls; lvl != endlvls; ++lvl) { 182 if (!lvl->bands) { 183 continue; 184 } 185 endbands = &lvl->bands[lvl->numbands]; 186 for (band = lvl->bands; band != endbands; ++band) { 187 if (!band->data) { 188 continue; 189 } 190 for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) { 191 if (!prc->cblks) { 192 continue; 193 } 194 bmx = 0; 195 endcblks = &prc->cblks[prc->numcblks]; 196 for (cblk = prc->cblks; cblk != endcblks; ++cblk) { 197 mx = 0; 198 for (i = 0; i < jas_matrix_numrows(cblk->data); ++i) { 199 for (j = 0; j < jas_matrix_numcols(cblk->data); ++j) { 200 v = abs(jas_matrix_get(cblk->data, i, j)); 201 if (v > mx) { 202 mx = v; 203 } 204 } 205 } 206 if (mx > bmx) { 207 bmx = mx; 208 } 209 cblk->numbps = JAS_MAX(jpc_firstone(mx) + 1 - JPC_NUMEXTRABITS, 0); 210 } 211 212 for (cblk = prc->cblks; cblk != endcblks; ++cblk) { 213 cblk->numimsbs = band->numbps - cblk->numbps; 214 assert(cblk->numimsbs >= 0); 215 } 216 217 for (cblk = prc->cblks; cblk != endcblks; ++cblk) { 218 if (jpc_enc_enccblk(enc, cblk->stream, tcmpt, band, cblk)) { 219 return -1; 220 } 221 } 222 } 223 } 224 } 225 } 226 return 0; 227} 228 229int getthebyte(jas_stream_t *in, long off) 230{ 231 int c; 232 long oldpos; 233 oldpos = jas_stream_tell(in); 234 assert(oldpos >= 0); 235 jas_stream_seek(in, off, SEEK_SET); 236 c = jas_stream_peekc(in); 237 jas_stream_seek(in, oldpos, SEEK_SET); 238 return c; 239} 240 241/* Encode a single code block. */ 242int jpc_enc_enccblk(jpc_enc_t *enc, jas_stream_t *out, jpc_enc_tcmpt_t *tcmpt, jpc_enc_band_t *band, jpc_enc_cblk_t *cblk) 243{ 244 jpc_enc_pass_t *pass; 245 jpc_enc_pass_t *endpasses; 246 int bitpos; 247 int n; 248 int adjust; 249 int ret; 250 int passtype; 251 int t; 252 jpc_bitstream_t *bout; 253 jpc_enc_pass_t *termpass; 254 jpc_enc_rlvl_t *rlvl; 255 int vcausal; 256 int segsym; 257 int termmode; 258 int c; 259 260 bout = 0; 261 rlvl = band->rlvl; 262 263 cblk->stream = jas_stream_memopen(0, 0); 264 assert(cblk->stream); 265 cblk->mqenc = jpc_mqenc_create(JPC_NUMCTXS, cblk->stream); 266 assert(cblk->mqenc); 267 jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs); 268 269 cblk->numpasses = (cblk->numbps > 0) ? (3 * cblk->numbps - 2) : 0; 270 if (cblk->numpasses > 0) { 271 cblk->passes = jas_malloc(cblk->numpasses * sizeof(jpc_enc_pass_t)); 272 assert(cblk->passes); 273 } else { 274 cblk->passes = 0; 275 } 276 endpasses = &cblk->passes[cblk->numpasses]; 277 for (pass = cblk->passes; pass != endpasses; ++pass) { 278 pass->start = 0; 279 pass->end = 0; 280 pass->term = JPC_ISTERMINATED(pass - cblk->passes, 0, cblk->numpasses, (tcmpt->cblksty & JPC_COX_TERMALL) != 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0); 281 pass->type = JPC_SEGTYPE(pass - cblk->passes, 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0); 282 pass->lyrno = -1; 283if (pass == endpasses - 1) { 284assert(pass->term == 1); 285 pass->term = 1; 286} 287 } 288 289 cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) + 2, 290 jas_matrix_numcols(cblk->data) + 2); 291 assert(cblk->flags); 292 293 294 bitpos = cblk->numbps - 1; 295 pass = cblk->passes; 296 n = cblk->numpasses; 297 while (--n >= 0) { 298 299 if (pass->type == JPC_SEG_MQ) { 300 /* NOP */ 301 } else { 302 assert(pass->type == JPC_SEG_RAW); 303 if (!bout) { 304 bout = jpc_bitstream_sopen(cblk->stream, "w"); 305 assert(bout); 306 } 307 } 308 309#if 1 310 passtype = (pass - cblk->passes + 2) % 3; 311#else 312 passtype = JPC_PASSTYPE(pass - cblk->passes + 2); 313#endif 314 pass->start = jas_stream_tell(cblk->stream); 315#if 0 316assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream)); 317#endif 318 assert(bitpos >= 0); 319 vcausal = (tcmpt->cblksty & JPC_COX_VSC) != 0; 320 segsym = (tcmpt->cblksty & JPC_COX_SEGSYM) != 0; 321 if (pass->term) { 322 termmode = ((tcmpt->cblksty & JPC_COX_PTERM) ? 323 JPC_MQENC_PTERM : JPC_MQENC_DEFTERM) + 1; 324 } else { 325 termmode = 0; 326 } 327 switch (passtype) { 328 case JPC_SIGPASS: 329 ret = (pass->type == JPC_SEG_MQ) ? jpc_encsigpass(cblk->mqenc, 330 bitpos, band->orient, vcausal, cblk->flags, 331 cblk->data, termmode, &pass->nmsedec) : 332 jpc_encrawsigpass(bout, bitpos, vcausal, cblk->flags, 333 cblk->data, termmode, &pass->nmsedec); 334 break; 335 case JPC_REFPASS: 336 ret = (pass->type == JPC_SEG_MQ) ? jpc_encrefpass(cblk->mqenc, 337 bitpos, vcausal, cblk->flags, cblk->data, termmode, 338 &pass->nmsedec) : jpc_encrawrefpass(bout, bitpos, 339 vcausal, cblk->flags, cblk->data, termmode, 340 &pass->nmsedec); 341 break; 342 case JPC_CLNPASS: 343 assert(pass->type == JPC_SEG_MQ); 344 ret = jpc_encclnpass(cblk->mqenc, bitpos, band->orient, 345 vcausal, segsym, cblk->flags, cblk->data, termmode, 346 &pass->nmsedec); 347 break; 348 default: 349 assert(0); 350 break; 351 } 352 353 if (pass->type == JPC_SEG_MQ) { 354 if (pass->term) { 355 jpc_mqenc_init(cblk->mqenc); 356 } 357 jpc_mqenc_getstate(cblk->mqenc, &pass->mqencstate); 358 pass->end = jas_stream_tell(cblk->stream); 359 if (tcmpt->cblksty & JPC_COX_RESET) { 360 jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs); 361 } 362 } else { 363 if (pass->term) { 364 if (jpc_bitstream_pending(bout)) { 365 jpc_bitstream_outalign(bout, 0x2a); 366 } 367 jpc_bitstream_close(bout); 368 bout = 0; 369 pass->end = jas_stream_tell(cblk->stream); 370 } else { 371 pass->end = jas_stream_tell(cblk->stream) + 372 jpc_bitstream_pending(bout); 373/* NOTE - This will not work. need to adjust by # of pending output bytes */ 374 } 375 } 376#if 0 377/* XXX - This assertion fails sometimes when various coding modes are used. 378This seems to be harmless, but why does it happen at all? */ 379assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream)); 380#endif 381 382 pass->wmsedec = jpc_fixtodbl(band->rlvl->tcmpt->synweight) * 383 jpc_fixtodbl(band->rlvl->tcmpt->synweight) * 384 jpc_fixtodbl(band->synweight) * 385 jpc_fixtodbl(band->synweight) * 386 jpc_fixtodbl(band->absstepsize) * jpc_fixtodbl(band->absstepsize) * 387 ((double) (1 << bitpos)) * ((double)(1 << bitpos)) * 388 jpc_fixtodbl(pass->nmsedec); 389 pass->cumwmsedec = pass->wmsedec; 390 if (pass != cblk->passes) { 391 pass->cumwmsedec += pass[-1].cumwmsedec; 392 } 393 if (passtype == JPC_CLNPASS) { 394 --bitpos; 395 } 396 ++pass; 397 } 398 399#if 0 400dump_passes(cblk->passes, cblk->numpasses, cblk); 401#endif 402 403 n = 0; 404 endpasses = &cblk->passes[cblk->numpasses]; 405 for (pass = cblk->passes; pass != endpasses; ++pass) { 406 if (pass->start < n) { 407 pass->start = n; 408 } 409 if (pass->end < n) { 410 pass->end = n; 411 } 412 if (!pass->term) { 413 termpass = pass; 414 while (termpass - pass < cblk->numpasses && 415 !termpass->term) { 416 ++termpass; 417 } 418 if (pass->type == JPC_SEG_MQ) { 419 t = (pass->mqencstate.lastbyte == 0xff) ? 1 : 0; 420 if (pass->mqencstate.ctreg >= 5) { 421 adjust = 4 + t; 422 } else { 423 adjust = 5 + t; 424 } 425 pass->end += adjust; 426 } 427 if (pass->end > termpass->end) { 428 pass->end = termpass->end; 429 } 430 if ((c = getthebyte(cblk->stream, pass->end - 1)) == EOF) { 431 abort(); 432 } 433 if (c == 0xff) { 434 ++pass->end; 435 } 436 n = JAS_MAX(n, pass->end); 437 } else { 438 n = JAS_MAX(n, pass->end); 439 } 440 } 441 442#if 0 443dump_passes(cblk->passes, cblk->numpasses, cblk); 444#endif 445 446 if (bout) { 447 jpc_bitstream_close(bout); 448 } 449 450 return 0; 451} 452 453/******************************************************************************\ 454* Code for significance pass. 455\******************************************************************************/ 456 457#define sigpass_step(fp, frowstep, dp, bitpos, one, nmsedec, orient, mqenc, vcausalflag) \ 458{ \ 459 int f; \ 460 int v; \ 461 f = *(fp); \ 462 if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \ 463 v = (abs(*(dp)) & (one)) ? 1 : 0; \ 464 jpc_mqenc_setcurctx(mqenc, JPC_GETZCCTXNO(f, (orient))); \ 465 jpc_mqenc_putbit(mqenc, v); \ 466 if (v) { \ 467 *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \ 468 v = ((*(dp) < 0) ? 1 : 0); \ 469 jpc_mqenc_setcurctx(mqenc, JPC_GETSCCTXNO(f)); \ 470 jpc_mqenc_putbit(mqenc, v ^ JPC_GETSPB(f)); \ 471 JPC_UPDATEFLAGS4(fp, frowstep, v, vcausalflag); \ 472 *(fp) |= JPC_SIG; \ 473 } \ 474 *(fp) |= JPC_VISIT; \ 475 } \ 476} 477 478static int jpc_encsigpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int vcausalflag, 479 jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec) 480{ 481 int i; 482 int j; 483 int one; 484 int vscanlen; 485 int width; 486 int height; 487 int frowstep; 488 int drowstep; 489 int fstripestep; 490 int dstripestep; 491 jpc_fix_t *fstripestart; 492 jpc_fix_t *dstripestart; 493 jpc_fix_t *fp; 494 jpc_fix_t *dp; 495 jpc_fix_t *fvscanstart; 496 jpc_fix_t *dvscanstart; 497 int k; 498 499 *nmsedec = 0; 500 width = jas_matrix_numcols(data); 501 height = jas_matrix_numrows(data); 502 frowstep = jas_matrix_rowstep(flags); 503 drowstep = jas_matrix_rowstep(data); 504 fstripestep = frowstep << 2; 505 dstripestep = drowstep << 2; 506 507 one = 1 << (bitpos + JPC_NUMEXTRABITS); 508 509 fstripestart = jas_matrix_getref(flags, 1, 1); 510 dstripestart = jas_matrix_getref(data, 0, 0); 511 for (i = height; i > 0; i -= 4, fstripestart += fstripestep, 512 dstripestart += dstripestep) { 513 fvscanstart = fstripestart; 514 dvscanstart = dstripestart; 515 vscanlen = JAS_MIN(i, 4); 516 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { 517 fp = fvscanstart; 518 dp = dvscanstart; 519 k = vscanlen; 520 521 sigpass_step(fp, frowstep, dp, bitpos, one, 522 nmsedec, orient, mqenc, vcausalflag); 523 if (--k <= 0) { 524 continue; 525 } 526 fp += frowstep; 527 dp += drowstep; 528 sigpass_step(fp, frowstep, dp, bitpos, one, 529 nmsedec, orient, mqenc, 0); 530 if (--k <= 0) { 531 continue; 532 } 533 fp += frowstep; 534 dp += drowstep; 535 sigpass_step(fp, frowstep, dp, bitpos, one, 536 nmsedec, orient, mqenc, 0); 537 if (--k <= 0) { 538 continue; 539 } 540 fp += frowstep; 541 dp += drowstep; 542 sigpass_step(fp, frowstep, dp, bitpos, one, 543 nmsedec, orient, mqenc, 0); 544 545 } 546 } 547 548 if (term) { 549 jpc_mqenc_flush(mqenc, term - 1); 550 } 551 552 return jpc_mqenc_error(mqenc) ? (-1) : 0; 553} 554 555#define rawsigpass_step(fp, frowstep, dp, bitpos, one, nmsedec, out, vcausalflag) \ 556{ \ 557 jpc_fix_t f = *(fp); \ 558 jpc_fix_t v; \ 559 if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \ 560 v = (abs(*(dp)) & (one)) ? 1 : 0; \ 561 if ((jpc_bitstream_putbit((out), v)) == EOF) { \ 562 return -1; \ 563 } \ 564 if (v) { \ 565 *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \ 566 v = ((*(dp) < 0) ? 1 : 0); \ 567 if (jpc_bitstream_putbit(out, v) == EOF) { \ 568 return -1; \ 569 } \ 570 JPC_UPDATEFLAGS4(fp, frowstep, v, vcausalflag); \ 571 *(fp) |= JPC_SIG; \ 572 } \ 573 *(fp) |= JPC_VISIT; \ 574 } \ 575} 576 577static int jpc_encrawsigpass(jpc_bitstream_t *out, int bitpos, int vcausalflag, jas_matrix_t *flags, 578 jas_matrix_t *data, int term, long *nmsedec) 579{ 580 int i; 581 int j; 582 int k; 583 int one; 584 int vscanlen; 585 int width; 586 int height; 587 int frowstep; 588 int drowstep; 589 int fstripestep; 590 int dstripestep; 591 jpc_fix_t *fstripestart; 592 jpc_fix_t *dstripestart; 593 jpc_fix_t *fp; 594 jpc_fix_t *dp; 595 jpc_fix_t *fvscanstart; 596 jpc_fix_t *dvscanstart; 597 598 *nmsedec = 0; 599 width = jas_matrix_numcols(data); 600 height = jas_matrix_numrows(data); 601 frowstep = jas_matrix_rowstep(flags); 602 drowstep = jas_matrix_rowstep(data); 603 fstripestep = frowstep << 2; 604 dstripestep = drowstep << 2; 605 606 one = 1 << (bitpos + JPC_NUMEXTRABITS); 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 rawsigpass_step(fp, frowstep, dp, bitpos, one, 621 nmsedec, out, vcausalflag); 622 if (--k <= 0) { 623 continue; 624 } 625 fp += frowstep; 626 dp += drowstep; 627 628 rawsigpass_step(fp, frowstep, dp, bitpos, one, 629 nmsedec, out, 0); 630 if (--k <= 0) { 631 continue; 632 } 633 fp += frowstep; 634 dp += drowstep; 635 636 rawsigpass_step(fp, frowstep, dp, bitpos, one, 637 nmsedec, out, 0); 638 if (--k <= 0) { 639 continue; 640 } 641 fp += frowstep; 642 dp += drowstep; 643 644 rawsigpass_step(fp, frowstep, dp, bitpos, one, 645 nmsedec, out, 0); 646 if (--k <= 0) { 647 continue; 648 } 649 fp += frowstep; 650 dp += drowstep; 651 652 } 653 } 654 655 if (term) { 656 jpc_bitstream_outalign(out, 0x2a); 657 } 658 659 return 0; 660} 661 662/******************************************************************************\ 663* Code for refinement pass. 664\******************************************************************************/ 665 666#define refpass_step(fp, dp, bitpos, one, nmsedec, mqenc, vcausalflag) \ 667{ \ 668 int v; \ 669 if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \ 670 (d) = *(dp); \ 671 *(nmsedec) += JPC_GETREFNMSEDEC(abs(d), (bitpos) + JPC_NUMEXTRABITS); \ 672 jpc_mqenc_setcurctx((mqenc), JPC_GETMAGCTXNO(*(fp))); \ 673 v = (abs(d) & (one)) ? 1 : 0; \ 674 jpc_mqenc_putbit((mqenc), v); \ 675 *(fp) |= JPC_REFINE; \ 676 } \ 677} 678 679static int jpc_encrefpass(jpc_mqenc_t *mqenc, int bitpos, int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data, 680 int term, long *nmsedec) 681{ 682 int i; 683 int j; 684 int one; 685 int vscanlen; 686 int d; 687 int width; 688 int height; 689 int frowstep; 690 int drowstep; 691 int fstripestep; 692 int dstripestep; 693 jpc_fix_t *fstripestart; 694 jpc_fix_t *dstripestart; 695 jpc_fix_t *fvscanstart; 696 jpc_fix_t *dvscanstart; 697 jpc_fix_t *dp; 698 jpc_fix_t *fp; 699int k; 700 701 *nmsedec = 0; 702 width = jas_matrix_numcols(data); 703 height = jas_matrix_numrows(data); 704 frowstep = jas_matrix_rowstep(flags); 705 drowstep = jas_matrix_rowstep(data); 706 fstripestep = frowstep << 2; 707 dstripestep = drowstep << 2; 708 709 one = 1 << (bitpos + JPC_NUMEXTRABITS); 710 711 fstripestart = jas_matrix_getref(flags, 1, 1); 712 dstripestart = jas_matrix_getref(data, 0, 0); 713 for (i = height; i > 0; i -= 4, fstripestart += fstripestep, 714 dstripestart += dstripestep) { 715 fvscanstart = fstripestart; 716 dvscanstart = dstripestart; 717 vscanlen = JAS_MIN(i, 4); 718 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { 719 fp = fvscanstart; 720 dp = dvscanstart; 721 k = vscanlen; 722 723 refpass_step(fp, dp, bitpos, one, nmsedec, 724 mqenc, vcausalflag); 725 if (--k <= 0) { 726 continue; 727 } 728 fp += frowstep; 729 dp += drowstep; 730 refpass_step(fp, dp, bitpos, one, nmsedec, 731 mqenc, 0); 732 if (--k <= 0) { 733 continue; 734 } 735 fp += frowstep; 736 dp += drowstep; 737 refpass_step(fp, dp, bitpos, one, nmsedec, 738 mqenc, 0); 739 if (--k <= 0) { 740 continue; 741 } 742 fp += frowstep; 743 dp += drowstep; 744 refpass_step(fp, dp, bitpos, one, nmsedec, 745 mqenc, 0); 746 747 } 748 } 749 750 if (term) { 751 jpc_mqenc_flush(mqenc, term - 1); 752 } 753 754 return jpc_mqenc_error(mqenc) ? (-1) : 0; 755} 756 757#define rawrefpass_step(fp, dp, bitpos, one, nmsedec, out, vcausalflag) \ 758{ \ 759 jpc_fix_t d; \ 760 jpc_fix_t v; \ 761 if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \ 762 d = *(dp); \ 763 *(nmsedec) += JPC_GETREFNMSEDEC(abs(d), (bitpos) + JPC_NUMEXTRABITS); \ 764 v = (abs(d) & (one)) ? 1 : 0; \ 765 if (jpc_bitstream_putbit((out), v) == EOF) { \ 766 return -1; \ 767 } \ 768 *(fp) |= JPC_REFINE; \ 769 } \ 770} 771 772static int jpc_encrawrefpass(jpc_bitstream_t *out, int bitpos, int vcausalflag, jas_matrix_t *flags, 773 jas_matrix_t *data, int term, long *nmsedec) 774{ 775 int i; 776 int j; 777 int k; 778 int one; 779 int vscanlen; 780 int width; 781 int height; 782 int frowstep; 783 int drowstep; 784 int fstripestep; 785 int dstripestep; 786 jpc_fix_t *fstripestart; 787 jpc_fix_t *dstripestart; 788 jpc_fix_t *fvscanstart; 789 jpc_fix_t *dvscanstart; 790 jpc_fix_t *dp; 791 jpc_fix_t *fp; 792 793 *nmsedec = 0; 794 width = jas_matrix_numcols(data); 795 height = jas_matrix_numrows(data); 796 frowstep = jas_matrix_rowstep(flags); 797 drowstep = jas_matrix_rowstep(data); 798 fstripestep = frowstep << 2; 799 dstripestep = drowstep << 2; 800 801 one = 1 << (bitpos + JPC_NUMEXTRABITS); 802 803 fstripestart = jas_matrix_getref(flags, 1, 1); 804 dstripestart = jas_matrix_getref(data, 0, 0); 805 for (i = height; i > 0; i -= 4, fstripestart += fstripestep, 806 dstripestart += dstripestep) { 807 fvscanstart = fstripestart; 808 dvscanstart = dstripestart; 809 vscanlen = JAS_MIN(i, 4); 810 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { 811 fp = fvscanstart; 812 dp = dvscanstart; 813 k = vscanlen; 814 815 rawrefpass_step(fp, dp, bitpos, one, nmsedec, 816 out, vcausalflag); 817 if (--k <= 0) { 818 continue; 819 } 820 fp += frowstep; 821 dp += drowstep; 822 rawrefpass_step(fp, dp, bitpos, one, nmsedec, 823 out, vcausalflag); 824 if (--k <= 0) { 825 continue; 826 } 827 fp += frowstep; 828 dp += drowstep; 829 rawrefpass_step(fp, dp, bitpos, one, nmsedec, 830 out, vcausalflag); 831 if (--k <= 0) { 832 continue; 833 } 834 fp += frowstep; 835 dp += drowstep; 836 rawrefpass_step(fp, dp, bitpos, one, nmsedec, 837 out, vcausalflag); 838 839 } 840 } 841 842 if (term) { 843 jpc_bitstream_outalign(out, 0x2a); 844 } 845 846 return 0; 847} 848 849/******************************************************************************\ 850* Code for cleanup pass. 851\******************************************************************************/ 852 853#define clnpass_step(fp, frowstep, dp, bitpos, one, orient, nmsedec, mqenc, label1, label2, vcausalflag) \ 854{ \ 855 int f; \ 856 int v; \ 857label1 \ 858 f = *(fp); \ 859 if (!(f & (JPC_SIG | JPC_VISIT))) { \ 860 jpc_mqenc_setcurctx(mqenc, JPC_GETZCCTXNO(f, (orient))); \ 861 v = (abs(*(dp)) & (one)) ? 1 : 0; \ 862 jpc_mqenc_putbit((mqenc), v); \ 863 if (v) { \ 864label2 \ 865 f = *(fp); \ 866 /* Coefficient is significant. */ \ 867 *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \ 868 jpc_mqenc_setcurctx((mqenc), JPC_GETSCCTXNO(f)); \ 869 v = ((*(dp) < 0) ? 1 : 0); \ 870 jpc_mqenc_putbit((mqenc), v ^ JPC_GETSPB(f)); \ 871 JPC_UPDATEFLAGS4((fp), (frowstep), v, vcausalflag); \ 872 *(fp) |= JPC_SIG; \ 873 } \ 874 } \ 875 *(fp) &= ~JPC_VISIT; \ 876} 877 878static int jpc_encclnpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int vcausalflag, int segsymflag, jas_matrix_t *flags, 879 jas_matrix_t *data, int term, long *nmsedec) 880{ 881 int i; 882 int j; 883 int k; 884 int vscanlen; 885 int v; 886 int runlen; 887 jpc_fix_t *fp; 888 int width; 889 int height; 890 jpc_fix_t *dp; 891 int one; 892 int frowstep; 893 int drowstep; 894 int fstripestep; 895 int dstripestep; 896 jpc_fix_t *fstripestart; 897 jpc_fix_t *dstripestart; 898 jpc_fix_t *fvscanstart; 899 jpc_fix_t *dvscanstart; 900 901 *nmsedec = 0; 902 width = jas_matrix_numcols(data); 903 height = jas_matrix_numrows(data); 904 frowstep = jas_matrix_rowstep(flags); 905 drowstep = jas_matrix_rowstep(data); 906 fstripestep = frowstep << 2; 907 dstripestep = drowstep << 2; 908 909 one = 1 << (bitpos + JPC_NUMEXTRABITS); 910 911 fstripestart = jas_matrix_getref(flags, 1, 1); 912 dstripestart = jas_matrix_getref(data, 0, 0); 913 for (i = height; i > 0; i -= 4, fstripestart += fstripestep, 914 dstripestart += dstripestep) { 915 fvscanstart = fstripestart; 916 dvscanstart = dstripestart; 917 vscanlen = JAS_MIN(i, 4); 918 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) { 919 920 fp = fvscanstart; 921 if (vscanlen >= 4 && !((*fp) & (JPC_SIG | JPC_VISIT | 922 JPC_OTHSIGMSK)) && (fp += frowstep, !((*fp) & (JPC_SIG | 923 JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) & 924 (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, 925 !((*fp) & (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK)))) { 926 dp = dvscanstart; 927 for (k = 0; k < vscanlen; ++k) { 928 v = (abs(*dp) & one) ? 1 : 0; 929 if (v) { 930 break; 931 } 932 dp += drowstep; 933 } 934 runlen = k; 935 if (runlen >= 4) { 936 jpc_mqenc_setcurctx(mqenc, JPC_AGGCTXNO); 937 jpc_mqenc_putbit(mqenc, 0); 938 continue; 939 } 940 jpc_mqenc_setcurctx(mqenc, JPC_AGGCTXNO); 941 jpc_mqenc_putbit(mqenc, 1); 942 jpc_mqenc_setcurctx(mqenc, JPC_UCTXNO); 943 jpc_mqenc_putbit(mqenc, runlen >> 1); 944 jpc_mqenc_putbit(mqenc, runlen & 1); 945 fp = fvscanstart + frowstep * runlen; 946 dp = dvscanstart + drowstep * runlen; 947 k = vscanlen - runlen; 948 switch (runlen) { 949 case 0: 950 goto clnpass_partial0; 951 break; 952 case 1: 953 goto clnpass_partial1; 954 break; 955 case 2: 956 goto clnpass_partial2; 957 break; 958 case 3: 959 goto clnpass_partial3; 960 break; 961 } 962 } else { 963 runlen = 0; 964 fp = fvscanstart; 965 dp = dvscanstart; 966 k = vscanlen; 967 goto clnpass_full0; 968 } 969 clnpass_step(fp, frowstep, dp, bitpos, one, 970 orient, nmsedec, mqenc, clnpass_full0:, clnpass_partial0:, vcausalflag); 971 if (--k <= 0) { 972 continue; 973 } 974 fp += frowstep; 975 dp += drowstep; 976 clnpass_step(fp, frowstep, dp, bitpos, one, 977 orient, nmsedec, mqenc, ;, clnpass_partial1:, 0); 978 if (--k <= 0) { 979 continue; 980 } 981 fp += frowstep; 982 dp += drowstep; 983 clnpass_step(fp, frowstep, dp, bitpos, one, 984 orient, nmsedec, mqenc, ;, clnpass_partial2:, 0); 985 if (--k <= 0) { 986 continue; 987 } 988 fp += frowstep; 989 dp += drowstep; 990 clnpass_step(fp, frowstep, dp, bitpos, one, 991 orient, nmsedec, mqenc, ;, clnpass_partial3:, 0); 992 } 993 } 994 995 if (segsymflag) { 996 jpc_mqenc_setcurctx(mqenc, JPC_UCTXNO); 997 jpc_mqenc_putbit(mqenc, 1); 998 jpc_mqenc_putbit(mqenc, 0); 999 jpc_mqenc_putbit(mqenc, 1); 1000 jpc_mqenc_putbit(mqenc, 0); 1001 } 1002 1003 if (term) { 1004 jpc_mqenc_flush(mqenc, term - 1); 1005 } 1006 1007 return jpc_mqenc_error(mqenc) ? (-1) : 0; 1008} 1009