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$
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
137 static 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
140 static int jpc_encrefpass(jpc_mqenc_t *mqenc, int bitpos, int, jas_matrix_t *flags,
141 jas_matrix_t *data, int term, long *nmsedec);
142
143 static 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
146 static int jpc_encrawsigpass(jpc_bitstream_t *out, int bitpos, int,
147 jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec);
148
149 static 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. */
jpc_enc_enccblks(jpc_enc_t * enc)157 int 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
getthebyte(jas_stream_t * in,long off)229 static int 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
242
243 int
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)244 jpc_enc_enccblk(jpc_enc_t *enc, jas_stream_t *out, jpc_enc_tcmpt_t *tcmpt,
245 jpc_enc_band_t *band, jpc_enc_cblk_t *cblk) {
246 /*----------------------------------------------------------------------------
247 Encode a single code block.
248 -----------------------------------------------------------------------------*/
249 jpc_enc_pass_t *pass;
250 jpc_enc_pass_t *endpasses;
251 int bitpos;
252 int n;
253 int adjust;
254 int passtype;
255 int t;
256 jpc_bitstream_t *bout;
257 jpc_enc_pass_t *termpass;
258 int vcausal;
259 int segsym;
260 int termmode;
261 int c;
262
263 bout = 0;
264
265 cblk->stream = jas_stream_memopen(0, 0);
266 assert(cblk->stream);
267 cblk->mqenc = jpc_mqenc_create(JPC_NUMCTXS, cblk->stream);
268 assert(cblk->mqenc);
269 jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs);
270
271 cblk->numpasses = (cblk->numbps > 0) ? (3 * cblk->numbps - 2) : 0;
272 if (cblk->numpasses > 0) {
273 cblk->passes = jas_malloc(cblk->numpasses * sizeof(jpc_enc_pass_t));
274 assert(cblk->passes);
275 } else {
276 cblk->passes = 0;
277 }
278 endpasses = &cblk->passes[cblk->numpasses];
279 for (pass = cblk->passes; pass != endpasses; ++pass) {
280 pass->start = 0;
281 pass->end = 0;
282 pass->term =
283 JPC_ISTERMINATED(pass - cblk->passes, 0,
284 cblk->numpasses,
285 (tcmpt->cblksty & JPC_COX_TERMALL) != 0,
286 (tcmpt->cblksty & JPC_COX_LAZY) != 0);
287 pass->type = JPC_SEGTYPE(pass - cblk->passes, 0,
288 (tcmpt->cblksty & JPC_COX_LAZY) != 0);
289 pass->lyrno = -1;
290 if (pass == endpasses - 1) {
291 assert(pass->term == 1);
292 pass->term = 1;
293 }
294 }
295
296 cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) + 2,
297 jas_matrix_numcols(cblk->data) + 2);
298 assert(cblk->flags);
299
300
301 bitpos = cblk->numbps - 1;
302 pass = cblk->passes;
303 n = cblk->numpasses;
304 while (--n >= 0) {
305
306 if (pass->type == JPC_SEG_MQ) {
307 /* NOP */
308 } else {
309 assert(pass->type == JPC_SEG_RAW);
310 if (!bout) {
311 bout = jpc_bitstream_sopen(cblk->stream, "w");
312 assert(bout);
313 }
314 }
315
316 #if 1
317 passtype = (pass - cblk->passes + 2) % 3;
318 #else
319 passtype = JPC_PASSTYPE(pass - cblk->passes + 2);
320 #endif
321 pass->start = jas_stream_tell(cblk->stream);
322 #if 0
323 assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream));
324 #endif
325 assert(bitpos >= 0);
326 vcausal = (tcmpt->cblksty & JPC_COX_VSC) != 0;
327 segsym = (tcmpt->cblksty & JPC_COX_SEGSYM) != 0;
328 if (pass->term) {
329 termmode = ((tcmpt->cblksty & JPC_COX_PTERM) ?
330 JPC_MQENC_PTERM : JPC_MQENC_DEFTERM) + 1;
331 } else {
332 termmode = 0;
333 }
334 switch (passtype) {
335 case JPC_SIGPASS:
336 if (pass->type == JPC_SEG_MQ)
337 jpc_encsigpass(cblk->mqenc,
338 bitpos, band->orient, vcausal, cblk->flags,
339 cblk->data, termmode, &pass->nmsedec);
340 else
341 jpc_encrawsigpass(bout, bitpos, vcausal, cblk->flags,
342 cblk->data, termmode, &pass->nmsedec);
343 break;
344 case JPC_REFPASS:
345 if (pass->type == JPC_SEG_MQ)
346 jpc_encrefpass(
347 cblk->mqenc,
348 bitpos, vcausal, cblk->flags, cblk->data, termmode,
349 &pass->nmsedec);
350 else
351 jpc_encrawrefpass(bout, bitpos,
352 vcausal, cblk->flags, cblk->data, termmode,
353 &pass->nmsedec);
354 break;
355 case JPC_CLNPASS:
356 assert(pass->type == JPC_SEG_MQ);
357 jpc_encclnpass(
358 cblk->mqenc, bitpos, band->orient,
359 vcausal, segsym, cblk->flags, cblk->data, termmode,
360 &pass->nmsedec);
361 break;
362 default:
363 assert(false);
364 break;
365 }
366
367 if (pass->type == JPC_SEG_MQ) {
368 if (pass->term) {
369 jpc_mqenc_init(cblk->mqenc);
370 }
371 jpc_mqenc_getstate(cblk->mqenc, &pass->mqencstate);
372 pass->end = jas_stream_tell(cblk->stream);
373 if (tcmpt->cblksty & JPC_COX_RESET) {
374 jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs);
375 }
376 } else {
377 if (pass->term) {
378 if (jpc_bitstream_pending(bout)) {
379 jpc_bitstream_outalign(bout, 0x2a);
380 }
381 jpc_bitstream_close(bout);
382 bout = 0;
383 pass->end = jas_stream_tell(cblk->stream);
384 } else {
385 pass->end = jas_stream_tell(cblk->stream) +
386 jpc_bitstream_pending(bout);
387 /* NOTE - This will not work. need to adjust by # of pending
388 output bytes
389 */
390 }
391 }
392 #if 0
393 /* XXX - This assertion fails sometimes when various coding modes are used.
394 This seems to be harmless, but why does it happen at all? */
395 assert(jas_stream_tell(cblk->stream) ==
396 jas_stream_getrwcount(cblk->stream));
397 #endif
398
399 pass->wmsedec = jpc_fixtodbl(band->rlvl->tcmpt->synweight) *
400 jpc_fixtodbl(band->rlvl->tcmpt->synweight) *
401 jpc_fixtodbl(band->synweight) *
402 jpc_fixtodbl(band->synweight) *
403 jpc_fixtodbl(band->absstepsize) * jpc_fixtodbl(band->absstepsize) *
404 ((double) (1 << bitpos)) * ((double)(1 << bitpos)) *
405 jpc_fixtodbl(pass->nmsedec);
406 pass->cumwmsedec = pass->wmsedec;
407 if (pass != cblk->passes) {
408 pass->cumwmsedec += pass[-1].cumwmsedec;
409 }
410 if (passtype == JPC_CLNPASS) {
411 --bitpos;
412 }
413 ++pass;
414 }
415
416 #if 0
417 dump_passes(cblk->passes, cblk->numpasses, cblk);
418 #endif
419
420 n = 0;
421 endpasses = &cblk->passes[cblk->numpasses];
422 for (pass = cblk->passes; pass != endpasses; ++pass) {
423 if (pass->start < n) {
424 pass->start = n;
425 }
426 if (pass->end < n) {
427 pass->end = n;
428 }
429 if (!pass->term) {
430 termpass = pass;
431 while (termpass - pass < cblk->numpasses &&
432 !termpass->term) {
433 ++termpass;
434 }
435 if (pass->type == JPC_SEG_MQ) {
436 t = (pass->mqencstate.lastbyte == 0xff) ? 1 : 0;
437 if (pass->mqencstate.ctreg >= 5) {
438 adjust = 4 + t;
439 } else {
440 adjust = 5 + t;
441 }
442 pass->end += adjust;
443 }
444 if (pass->end > termpass->end) {
445 pass->end = termpass->end;
446 }
447 if ((c = getthebyte(cblk->stream, pass->end - 1)) == EOF) {
448 abort();
449 }
450 if (c == 0xff) {
451 ++pass->end;
452 }
453 n = JAS_MAX(n, pass->end);
454 } else {
455 n = JAS_MAX(n, pass->end);
456 }
457 }
458
459 #if 0
460 dump_passes(cblk->passes, cblk->numpasses, cblk);
461 #endif
462
463 if (bout) {
464 jpc_bitstream_close(bout);
465 }
466
467 return 0;
468 }
469
470
471
472 /*****************************************************************************\
473 * Code for significance pass.
474 \*****************************************************************************/
475
476 #define sigpass_step(fp, frowstep, dp, bitpos, one, nmsedec, orient, mqenc, vcausalflag) \
477 { \
478 int f; \
479 int v; \
480 f = *(fp); \
481 if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
482 v = (abs(*(dp)) & (one)) ? 1 : 0; \
483 jpc_mqenc_setcurctx(mqenc, JPC_GETZCCTXNO(f, (orient))); \
484 jpc_mqenc_putbit(mqenc, v); \
485 if (v) { \
486 *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \
487 v = ((*(dp) < 0) ? 1 : 0); \
488 jpc_mqenc_setcurctx(mqenc, JPC_GETSCCTXNO(f)); \
489 jpc_mqenc_putbit(mqenc, v ^ JPC_GETSPB(f)); \
490 JPC_UPDATEFLAGS4(fp, frowstep, v, vcausalflag); \
491 *(fp) |= JPC_SIG; \
492 } \
493 *(fp) |= JPC_VISIT; \
494 } \
495 }
496
jpc_encsigpass(jpc_mqenc_t * mqenc,int bitpos,int orient,int vcausalflag,jas_matrix_t * flags,jas_matrix_t * data,int term,long * nmsedec)497 static int jpc_encsigpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int vcausalflag,
498 jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec)
499 {
500 int i;
501 int j;
502 int one;
503 int vscanlen;
504 int width;
505 int height;
506 int frowstep;
507 int drowstep;
508 int fstripestep;
509 int dstripestep;
510 jpc_fix_t *fstripestart;
511 jpc_fix_t *dstripestart;
512 jpc_fix_t *fp;
513 jpc_fix_t *dp;
514 jpc_fix_t *fvscanstart;
515 jpc_fix_t *dvscanstart;
516 int k;
517
518 *nmsedec = 0;
519 width = jas_matrix_numcols(data);
520 height = jas_matrix_numrows(data);
521 frowstep = jas_matrix_rowstep(flags);
522 drowstep = jas_matrix_rowstep(data);
523 fstripestep = frowstep << 2;
524 dstripestep = drowstep << 2;
525
526 one = 1 << (bitpos + JPC_NUMEXTRABITS);
527
528 fstripestart = jas_matrix_getref(flags, 1, 1);
529 dstripestart = jas_matrix_getref(data, 0, 0);
530 for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
531 dstripestart += dstripestep) {
532 fvscanstart = fstripestart;
533 dvscanstart = dstripestart;
534 vscanlen = JAS_MIN(i, 4);
535 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
536 fp = fvscanstart;
537 dp = dvscanstart;
538 k = vscanlen;
539
540 sigpass_step(fp, frowstep, dp, bitpos, one,
541 nmsedec, orient, mqenc, vcausalflag);
542 if (--k <= 0) {
543 continue;
544 }
545 fp += frowstep;
546 dp += drowstep;
547 sigpass_step(fp, frowstep, dp, bitpos, one,
548 nmsedec, orient, mqenc, 0);
549 if (--k <= 0) {
550 continue;
551 }
552 fp += frowstep;
553 dp += drowstep;
554 sigpass_step(fp, frowstep, dp, bitpos, one,
555 nmsedec, orient, mqenc, 0);
556 if (--k <= 0) {
557 continue;
558 }
559 fp += frowstep;
560 dp += drowstep;
561 sigpass_step(fp, frowstep, dp, bitpos, one,
562 nmsedec, orient, mqenc, 0);
563
564 }
565 }
566
567 if (term) {
568 jpc_mqenc_flush(mqenc, term - 1);
569 }
570
571 return jpc_mqenc_error(mqenc) ? (-1) : 0;
572 }
573
574 #define rawsigpass_step(fp, frowstep, dp, bitpos, one, nmsedec, out, vcausalflag) \
575 { \
576 jpc_fix_t f = *(fp); \
577 jpc_fix_t v; \
578 if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
579 v = (abs(*(dp)) & (one)) ? 1 : 0; \
580 if ((jpc_bitstream_putbit((out), v)) == EOF) { \
581 return -1; \
582 } \
583 if (v) { \
584 *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \
585 v = ((*(dp) < 0) ? 1 : 0); \
586 if (jpc_bitstream_putbit(out, v) == EOF) { \
587 return -1; \
588 } \
589 JPC_UPDATEFLAGS4(fp, frowstep, v, vcausalflag); \
590 *(fp) |= JPC_SIG; \
591 } \
592 *(fp) |= JPC_VISIT; \
593 } \
594 }
595
jpc_encrawsigpass(jpc_bitstream_t * out,int bitpos,int vcausalflag,jas_matrix_t * flags,jas_matrix_t * data,int term,long * nmsedec)596 static int jpc_encrawsigpass(jpc_bitstream_t *out, int bitpos, int vcausalflag, jas_matrix_t *flags,
597 jas_matrix_t *data, int term, long *nmsedec)
598 {
599 int i;
600 int j;
601 int k;
602 int one;
603 int vscanlen;
604 int width;
605 int height;
606 int frowstep;
607 int drowstep;
608 int fstripestep;
609 int dstripestep;
610 jpc_fix_t *fstripestart;
611 jpc_fix_t *dstripestart;
612 jpc_fix_t *fp;
613 jpc_fix_t *dp;
614 jpc_fix_t *fvscanstart;
615 jpc_fix_t *dvscanstart;
616
617 *nmsedec = 0;
618 width = jas_matrix_numcols(data);
619 height = jas_matrix_numrows(data);
620 frowstep = jas_matrix_rowstep(flags);
621 drowstep = jas_matrix_rowstep(data);
622 fstripestep = frowstep << 2;
623 dstripestep = drowstep << 2;
624
625 one = 1 << (bitpos + JPC_NUMEXTRABITS);
626
627 fstripestart = jas_matrix_getref(flags, 1, 1);
628 dstripestart = jas_matrix_getref(data, 0, 0);
629 for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
630 dstripestart += dstripestep) {
631 fvscanstart = fstripestart;
632 dvscanstart = dstripestart;
633 vscanlen = JAS_MIN(i, 4);
634 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
635 fp = fvscanstart;
636 dp = dvscanstart;
637 k = vscanlen;
638
639 rawsigpass_step(fp, frowstep, dp, bitpos, one,
640 nmsedec, out, vcausalflag);
641 if (--k <= 0) {
642 continue;
643 }
644 fp += frowstep;
645 dp += drowstep;
646
647 rawsigpass_step(fp, frowstep, dp, bitpos, one,
648 nmsedec, out, 0);
649 if (--k <= 0) {
650 continue;
651 }
652 fp += frowstep;
653 dp += drowstep;
654
655 rawsigpass_step(fp, frowstep, dp, bitpos, one,
656 nmsedec, out, 0);
657 if (--k <= 0) {
658 continue;
659 }
660 fp += frowstep;
661 dp += drowstep;
662
663 rawsigpass_step(fp, frowstep, dp, bitpos, one,
664 nmsedec, out, 0);
665 if (--k <= 0) {
666 continue;
667 }
668 fp += frowstep;
669 dp += drowstep;
670
671 }
672 }
673
674 if (term) {
675 jpc_bitstream_outalign(out, 0x2a);
676 }
677
678 return 0;
679 }
680
681 /******************************************************************************\
682 * Code for refinement pass.
683 \******************************************************************************/
684
685 #define refpass_step(fp, dp, bitpos, one, nmsedec, mqenc, vcausalflag) \
686 { \
687 int v; \
688 if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
689 (d) = *(dp); \
690 *(nmsedec) += JPC_GETREFNMSEDEC(abs(d), (bitpos) + JPC_NUMEXTRABITS); \
691 jpc_mqenc_setcurctx((mqenc), JPC_GETMAGCTXNO(*(fp))); \
692 v = (abs(d) & (one)) ? 1 : 0; \
693 jpc_mqenc_putbit((mqenc), v); \
694 *(fp) |= JPC_REFINE; \
695 } \
696 }
697
jpc_encrefpass(jpc_mqenc_t * mqenc,int bitpos,int vcausalflag,jas_matrix_t * flags,jas_matrix_t * data,int term,long * nmsedec)698 static int jpc_encrefpass(jpc_mqenc_t *mqenc, int bitpos, int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data,
699 int term, long *nmsedec)
700 {
701 int i;
702 int j;
703 int one;
704 int vscanlen;
705 int d;
706 int width;
707 int height;
708 int frowstep;
709 int drowstep;
710 int fstripestep;
711 int dstripestep;
712 jpc_fix_t *fstripestart;
713 jpc_fix_t *dstripestart;
714 jpc_fix_t *fvscanstart;
715 jpc_fix_t *dvscanstart;
716 jpc_fix_t *dp;
717 jpc_fix_t *fp;
718 int k;
719
720 *nmsedec = 0;
721 width = jas_matrix_numcols(data);
722 height = jas_matrix_numrows(data);
723 frowstep = jas_matrix_rowstep(flags);
724 drowstep = jas_matrix_rowstep(data);
725 fstripestep = frowstep << 2;
726 dstripestep = drowstep << 2;
727
728 one = 1 << (bitpos + JPC_NUMEXTRABITS);
729
730 fstripestart = jas_matrix_getref(flags, 1, 1);
731 dstripestart = jas_matrix_getref(data, 0, 0);
732 for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
733 dstripestart += dstripestep) {
734 fvscanstart = fstripestart;
735 dvscanstart = dstripestart;
736 vscanlen = JAS_MIN(i, 4);
737 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
738 fp = fvscanstart;
739 dp = dvscanstart;
740 k = vscanlen;
741
742 refpass_step(fp, dp, bitpos, one, nmsedec,
743 mqenc, vcausalflag);
744 if (--k <= 0) {
745 continue;
746 }
747 fp += frowstep;
748 dp += drowstep;
749 refpass_step(fp, dp, bitpos, one, nmsedec,
750 mqenc, 0);
751 if (--k <= 0) {
752 continue;
753 }
754 fp += frowstep;
755 dp += drowstep;
756 refpass_step(fp, dp, bitpos, one, nmsedec,
757 mqenc, 0);
758 if (--k <= 0) {
759 continue;
760 }
761 fp += frowstep;
762 dp += drowstep;
763 refpass_step(fp, dp, bitpos, one, nmsedec,
764 mqenc, 0);
765
766 }
767 }
768
769 if (term) {
770 jpc_mqenc_flush(mqenc, term - 1);
771 }
772
773 return jpc_mqenc_error(mqenc) ? (-1) : 0;
774 }
775
776 #define rawrefpass_step(fp, dp, bitpos, one, nmsedec, out, vcausalflag) \
777 { \
778 jpc_fix_t d; \
779 jpc_fix_t v; \
780 if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
781 d = *(dp); \
782 *(nmsedec) += JPC_GETREFNMSEDEC(abs(d), (bitpos) + JPC_NUMEXTRABITS); \
783 v = (abs(d) & (one)) ? 1 : 0; \
784 if (jpc_bitstream_putbit((out), v) == EOF) { \
785 return -1; \
786 } \
787 *(fp) |= JPC_REFINE; \
788 } \
789 }
790
jpc_encrawrefpass(jpc_bitstream_t * out,int bitpos,int vcausalflag,jas_matrix_t * flags,jas_matrix_t * data,int term,long * nmsedec)791 static int jpc_encrawrefpass(jpc_bitstream_t *out, int bitpos, int vcausalflag, jas_matrix_t *flags,
792 jas_matrix_t *data, int term, long *nmsedec)
793 {
794 int i;
795 int j;
796 int k;
797 int one;
798 int vscanlen;
799 int width;
800 int height;
801 int frowstep;
802 int drowstep;
803 int fstripestep;
804 int dstripestep;
805 jpc_fix_t *fstripestart;
806 jpc_fix_t *dstripestart;
807 jpc_fix_t *fvscanstart;
808 jpc_fix_t *dvscanstart;
809 jpc_fix_t *dp;
810 jpc_fix_t *fp;
811
812 *nmsedec = 0;
813 width = jas_matrix_numcols(data);
814 height = jas_matrix_numrows(data);
815 frowstep = jas_matrix_rowstep(flags);
816 drowstep = jas_matrix_rowstep(data);
817 fstripestep = frowstep << 2;
818 dstripestep = drowstep << 2;
819
820 one = 1 << (bitpos + JPC_NUMEXTRABITS);
821
822 fstripestart = jas_matrix_getref(flags, 1, 1);
823 dstripestart = jas_matrix_getref(data, 0, 0);
824 for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
825 dstripestart += dstripestep) {
826 fvscanstart = fstripestart;
827 dvscanstart = dstripestart;
828 vscanlen = JAS_MIN(i, 4);
829 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
830 fp = fvscanstart;
831 dp = dvscanstart;
832 k = vscanlen;
833
834 rawrefpass_step(fp, dp, bitpos, one, nmsedec,
835 out, vcausalflag);
836 if (--k <= 0) {
837 continue;
838 }
839 fp += frowstep;
840 dp += drowstep;
841 rawrefpass_step(fp, dp, bitpos, one, nmsedec,
842 out, vcausalflag);
843 if (--k <= 0) {
844 continue;
845 }
846 fp += frowstep;
847 dp += drowstep;
848 rawrefpass_step(fp, dp, bitpos, one, nmsedec,
849 out, vcausalflag);
850 if (--k <= 0) {
851 continue;
852 }
853 fp += frowstep;
854 dp += drowstep;
855 rawrefpass_step(fp, dp, bitpos, one, nmsedec,
856 out, vcausalflag);
857
858 }
859 }
860
861 if (term) {
862 jpc_bitstream_outalign(out, 0x2a);
863 }
864
865 return 0;
866 }
867
868 /******************************************************************************\
869 * Code for cleanup pass.
870 \******************************************************************************/
871
872 #define clnpass_step(fp, frowstep, dp, bitpos, one, orient, nmsedec, mqenc, label1, label2, vcausalflag) \
873 { \
874 int f; \
875 int v; \
876 label1 \
877 f = *(fp); \
878 if (!(f & (JPC_SIG | JPC_VISIT))) { \
879 jpc_mqenc_setcurctx(mqenc, JPC_GETZCCTXNO(f, (orient))); \
880 v = (abs(*(dp)) & (one)) ? 1 : 0; \
881 jpc_mqenc_putbit((mqenc), v); \
882 if (v) { \
883 label2 \
884 f = *(fp); \
885 /* Coefficient is significant. */ \
886 *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \
887 jpc_mqenc_setcurctx((mqenc), JPC_GETSCCTXNO(f)); \
888 v = ((*(dp) < 0) ? 1 : 0); \
889 jpc_mqenc_putbit((mqenc), v ^ JPC_GETSPB(f)); \
890 JPC_UPDATEFLAGS4((fp), (frowstep), v, vcausalflag); \
891 *(fp) |= JPC_SIG; \
892 } \
893 } \
894 *(fp) &= ~JPC_VISIT; \
895 }
896
jpc_encclnpass(jpc_mqenc_t * mqenc,int bitpos,int orient,int vcausalflag,int segsymflag,jas_matrix_t * flags,jas_matrix_t * data,int term,long * nmsedec)897 static int jpc_encclnpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int vcausalflag, int segsymflag, jas_matrix_t *flags,
898 jas_matrix_t *data, int term, long *nmsedec)
899 {
900 int i;
901 int j;
902 int k;
903 int vscanlen;
904 int v;
905 int runlen;
906 jpc_fix_t *fp;
907 int width;
908 int height;
909 jpc_fix_t *dp;
910 int one;
911 int frowstep;
912 int drowstep;
913 int fstripestep;
914 int dstripestep;
915 jpc_fix_t *fstripestart;
916 jpc_fix_t *dstripestart;
917 jpc_fix_t *fvscanstart;
918 jpc_fix_t *dvscanstart;
919
920 *nmsedec = 0;
921 width = jas_matrix_numcols(data);
922 height = jas_matrix_numrows(data);
923 frowstep = jas_matrix_rowstep(flags);
924 drowstep = jas_matrix_rowstep(data);
925 fstripestep = frowstep << 2;
926 dstripestep = drowstep << 2;
927
928 one = 1 << (bitpos + JPC_NUMEXTRABITS);
929
930 fstripestart = jas_matrix_getref(flags, 1, 1);
931 dstripestart = jas_matrix_getref(data, 0, 0);
932 for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
933 dstripestart += dstripestep) {
934 fvscanstart = fstripestart;
935 dvscanstart = dstripestart;
936 vscanlen = JAS_MIN(i, 4);
937 for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
938
939 fp = fvscanstart;
940 if (vscanlen >= 4 && !((*fp) & (JPC_SIG | JPC_VISIT |
941 JPC_OTHSIGMSK)) && (fp += frowstep, !((*fp) & (JPC_SIG |
942 JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) &
943 (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep,
944 !((*fp) & (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK)))) {
945 dp = dvscanstart;
946 for (k = 0; k < vscanlen; ++k) {
947 v = (abs(*dp) & one) ? 1 : 0;
948 if (v) {
949 break;
950 }
951 dp += drowstep;
952 }
953 runlen = k;
954 if (runlen >= 4) {
955 jpc_mqenc_setcurctx(mqenc, JPC_AGGCTXNO);
956 jpc_mqenc_putbit(mqenc, 0);
957 continue;
958 }
959 jpc_mqenc_setcurctx(mqenc, JPC_AGGCTXNO);
960 jpc_mqenc_putbit(mqenc, 1);
961 jpc_mqenc_setcurctx(mqenc, JPC_UCTXNO);
962 jpc_mqenc_putbit(mqenc, runlen >> 1);
963 jpc_mqenc_putbit(mqenc, runlen & 1);
964 fp = fvscanstart + frowstep * runlen;
965 dp = dvscanstart + drowstep * runlen;
966 k = vscanlen - runlen;
967 switch (runlen) {
968 case 0:
969 goto clnpass_partial0;
970 break;
971 case 1:
972 goto clnpass_partial1;
973 break;
974 case 2:
975 goto clnpass_partial2;
976 break;
977 case 3:
978 goto clnpass_partial3;
979 break;
980 }
981 } else {
982 runlen = 0;
983 fp = fvscanstart;
984 dp = dvscanstart;
985 k = vscanlen;
986 goto clnpass_full0;
987 }
988 clnpass_step(fp, frowstep, dp, bitpos, one,
989 orient, nmsedec, mqenc, clnpass_full0:, clnpass_partial0:, vcausalflag);
990 if (--k <= 0) {
991 continue;
992 }
993 fp += frowstep;
994 dp += drowstep;
995 clnpass_step(fp, frowstep, dp, bitpos, one,
996 orient, nmsedec, mqenc, ;, clnpass_partial1:, 0);
997 if (--k <= 0) {
998 continue;
999 }
1000 fp += frowstep;
1001 dp += drowstep;
1002 clnpass_step(fp, frowstep, dp, bitpos, one,
1003 orient, nmsedec, mqenc, ;, clnpass_partial2:, 0);
1004 if (--k <= 0) {
1005 continue;
1006 }
1007 fp += frowstep;
1008 dp += drowstep;
1009 clnpass_step(fp, frowstep, dp, bitpos, one,
1010 orient, nmsedec, mqenc, ;, clnpass_partial3:, 0);
1011 }
1012 }
1013
1014 if (segsymflag) {
1015 jpc_mqenc_setcurctx(mqenc, JPC_UCTXNO);
1016 jpc_mqenc_putbit(mqenc, 1);
1017 jpc_mqenc_putbit(mqenc, 0);
1018 jpc_mqenc_putbit(mqenc, 1);
1019 jpc_mqenc_putbit(mqenc, 0);
1020 }
1021
1022 if (term) {
1023 jpc_mqenc_flush(mqenc, term - 1);
1024 }
1025
1026 return jpc_mqenc_error(mqenc) ? (-1) : 0;
1027 }
1028