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