~ubuntu-branches/ubuntu/precise/jasper/precise-updates

« back to all changes in this revision

Viewing changes to .pc/01-misc-fixes.patch/src/libjasper/jpc/jpc_t1enc.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2011-10-24 12:33:36 UTC
  • mfrom: (7.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20111024123336-fyqahayo6mm0q7ke
Tags: 1.900.1-10ubuntu1
* Resynchronise with Debian.  Remaining changes (revised for dh(1)):
  - Enable multiarch build.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 License Version 2.0
 
11
 * 
 
12
 * Copyright (c) 2001-2006 Michael David Adams
 
13
 * Copyright (c) 1999-2000 Image Power, Inc.
 
14
 * Copyright (c) 1999-2000 The University of British Columbia
 
15
 * 
 
16
 * All rights reserved.
 
17
 * 
 
18
 * Permission is hereby granted, free of charge, to any person (the
 
19
 * "User") obtaining a copy of this software and associated documentation
 
20
 * files (the "Software"), to deal in the Software without restriction,
 
21
 * including without limitation the rights to use, copy, modify, merge,
 
22
 * publish, distribute, and/or sell copies of the Software, and to permit
 
23
 * persons to whom the Software is furnished to do so, subject to the
 
24
 * following conditions:
 
25
 * 
 
26
 * 1.  The above copyright notices and this permission notice (which
 
27
 * includes the disclaimer below) shall be included in all copies or
 
28
 * substantial portions of the Software.
 
29
 * 
 
30
 * 2.  The name of a copyright holder shall not be used to endorse or
 
31
 * promote products derived from the Software without specific prior
 
32
 * written permission.
 
33
 * 
 
34
 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
 
35
 * LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
 
36
 * THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
 
37
 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 
38
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 
39
 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO
 
40
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
 
41
 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
 
42
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 
43
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 
44
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE
 
45
 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
 
46
 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
 
47
 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
 
48
 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
 
49
 * PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS
 
50
 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
 
51
 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE
 
52
 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
 
53
 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
 
54
 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
 
55
 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
 
56
 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
 
57
 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
 
58
 * RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
 
59
 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
 
60
 * 
 
61
 * __END_OF_JASPER_LICENSE__
 
62
 */
 
63
 
 
64
/*
 
65
 * Tier 1 Encoder
 
66
 *
 
67
 * $Id$
 
68
 */
 
69
 
 
70
/******************************************************************************\
 
71
* Includes.
 
72
\******************************************************************************/
 
73
 
 
74
#include <stdio.h>
 
75
#include <stdlib.h>
 
76
#include <assert.h>
 
77
 
 
78
#include "jasper/jas_fix.h"
 
79
#include "jasper/jas_malloc.h"
 
80
#include "jasper/jas_math.h"
 
81
 
 
82
#include "jpc_t1enc.h"
 
83
#include "jpc_t1cod.h"
 
84
#include "jpc_enc.h"
 
85
#include "jpc_cod.h"
 
86
#include "jpc_math.h"
 
87
 
 
88
static int jpc_encsigpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int,
 
89
  jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec);
 
90
 
 
91
static int jpc_encrefpass(jpc_mqenc_t *mqenc, int bitpos, int, jas_matrix_t *flags,
 
92
  jas_matrix_t *data, int term, long *nmsedec);
 
93
 
 
94
static int jpc_encclnpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int,
 
95
  int, jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec);
 
96
 
 
97
static int jpc_encrawsigpass(jpc_bitstream_t *out, int bitpos, int,
 
98
  jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec);
 
99
 
 
100
static int jpc_encrawrefpass(jpc_bitstream_t *out, int bitpos, int,
 
101
  jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec);
 
102
 
 
103
/******************************************************************************\
 
104
* Code for encoding code blocks.
 
105
\******************************************************************************/
 
106
 
 
107
/* Encode all of the code blocks associated with the current tile. */
 
108
int jpc_enc_enccblks(jpc_enc_t *enc)
 
109
{
 
110
        jpc_enc_tcmpt_t *tcmpt;
 
111
        jpc_enc_tcmpt_t *endcomps;
 
112
        jpc_enc_rlvl_t *lvl;
 
113
        jpc_enc_rlvl_t *endlvls;
 
114
        jpc_enc_band_t *band;
 
115
        jpc_enc_band_t *endbands;
 
116
        jpc_enc_cblk_t *cblk;
 
117
        jpc_enc_cblk_t *endcblks;
 
118
        int i;
 
119
        int j;
 
120
        int mx;
 
121
        int bmx;
 
122
        int v;
 
123
        jpc_enc_tile_t *tile;
 
124
        uint_fast32_t prcno;
 
125
        jpc_enc_prc_t *prc;
 
126
 
 
127
        tile = enc->curtile;
 
128
 
 
129
        endcomps = &tile->tcmpts[tile->numtcmpts];
 
130
        for (tcmpt = tile->tcmpts; tcmpt != endcomps; ++tcmpt) {
 
131
                endlvls = &tcmpt->rlvls[tcmpt->numrlvls];
 
132
                for (lvl = tcmpt->rlvls; lvl != endlvls; ++lvl) {
 
133
                        if (!lvl->bands) {
 
134
                                continue;
 
135
                        }
 
136
                        endbands = &lvl->bands[lvl->numbands];
 
137
                        for (band = lvl->bands; band != endbands; ++band) {
 
138
                                if (!band->data) {
 
139
                                        continue;
 
140
                                }
 
141
                                for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) {
 
142
                                        if (!prc->cblks) {
 
143
                                                continue;
 
144
                                        }
 
145
                                        bmx = 0;
 
146
                                        endcblks = &prc->cblks[prc->numcblks];
 
147
                                        for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
 
148
                                                mx = 0;
 
149
                                                for (i = 0; i < jas_matrix_numrows(cblk->data); ++i) {
 
150
                                                        for (j = 0; j < jas_matrix_numcols(cblk->data); ++j) {
 
151
                                                                v = abs(jas_matrix_get(cblk->data, i, j));
 
152
                                                                if (v > mx) {
 
153
                                                                        mx = v;
 
154
                                                                }
 
155
                                                        }
 
156
                                                }
 
157
                                                if (mx > bmx) {
 
158
                                                        bmx = mx;
 
159
                                                }
 
160
                                                cblk->numbps = JAS_MAX(jpc_firstone(mx) + 1 - JPC_NUMEXTRABITS, 0);
 
161
                                        }
 
162
 
 
163
                                        for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
 
164
                                                cblk->numimsbs = band->numbps - cblk->numbps;
 
165
                                                assert(cblk->numimsbs >= 0);
 
166
                                        }
 
167
 
 
168
                                        for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
 
169
                                                if (jpc_enc_enccblk(enc, cblk->stream, tcmpt, band, cblk)) {
 
170
                                                        return -1;
 
171
                                                }
 
172
                                        }
 
173
                                }
 
174
                        }
 
175
                }
 
176
        }
 
177
        return 0;
 
178
}
 
179
 
 
180
int getthebyte(jas_stream_t *in, long off)
 
181
{
 
182
        int c;
 
183
        long oldpos;
 
184
        oldpos = jas_stream_tell(in);
 
185
        assert(oldpos >= 0);
 
186
        jas_stream_seek(in, off, SEEK_SET);
 
187
        c = jas_stream_peekc(in);
 
188
        jas_stream_seek(in, oldpos, SEEK_SET);
 
189
        return c;
 
190
}
 
191
 
 
192
/* Encode a single code block. */
 
193
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)
 
194
{
 
195
        jpc_enc_pass_t *pass;
 
196
        jpc_enc_pass_t *endpasses;
 
197
        int bitpos;
 
198
        int n;
 
199
        int adjust;
 
200
        int ret;
 
201
        int passtype;
 
202
        int t;
 
203
        jpc_bitstream_t *bout;
 
204
        jpc_enc_pass_t *termpass;
 
205
        jpc_enc_rlvl_t *rlvl;
 
206
        int vcausal;
 
207
        int segsym;
 
208
        int termmode;
 
209
        int c;
 
210
 
 
211
        bout = 0;
 
212
        rlvl = band->rlvl;
 
213
 
 
214
        cblk->stream = jas_stream_memopen(0, 0);
 
215
        assert(cblk->stream);
 
216
        cblk->mqenc = jpc_mqenc_create(JPC_NUMCTXS, cblk->stream);
 
217
        assert(cblk->mqenc);
 
218
        jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs);
 
219
 
 
220
        cblk->numpasses = (cblk->numbps > 0) ? (3 * cblk->numbps - 2) : 0;
 
221
        if (cblk->numpasses > 0) {
 
222
                cblk->passes = jas_malloc(cblk->numpasses * sizeof(jpc_enc_pass_t));
 
223
                assert(cblk->passes);
 
224
        } else {
 
225
                cblk->passes = 0;
 
226
        }
 
227
        endpasses = &cblk->passes[cblk->numpasses];
 
228
        for (pass = cblk->passes; pass != endpasses; ++pass) {
 
229
                pass->start = 0;
 
230
                pass->end = 0;
 
231
                pass->term = JPC_ISTERMINATED(pass - cblk->passes, 0, cblk->numpasses, (tcmpt->cblksty & JPC_COX_TERMALL) != 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0);
 
232
                pass->type = JPC_SEGTYPE(pass - cblk->passes, 0, (tcmpt->cblksty & JPC_COX_LAZY) != 0);
 
233
                pass->lyrno = -1;
 
234
if (pass == endpasses - 1) {
 
235
assert(pass->term == 1);
 
236
        pass->term = 1;
 
237
}
 
238
        }
 
239
 
 
240
        cblk->flags = jas_matrix_create(jas_matrix_numrows(cblk->data) + 2,
 
241
          jas_matrix_numcols(cblk->data) + 2);
 
242
        assert(cblk->flags);
 
243
 
 
244
 
 
245
        bitpos = cblk->numbps - 1;
 
246
        pass = cblk->passes;
 
247
        n = cblk->numpasses;
 
248
        while (--n >= 0) {
 
249
 
 
250
                if (pass->type == JPC_SEG_MQ) {
 
251
                        /* NOP */
 
252
                } else {
 
253
                        assert(pass->type == JPC_SEG_RAW);
 
254
                        if (!bout) {
 
255
                                bout = jpc_bitstream_sopen(cblk->stream, "w");
 
256
                                assert(bout);
 
257
                        }
 
258
                }
 
259
 
 
260
#if 1
 
261
                passtype = (pass - cblk->passes + 2) % 3;
 
262
#else
 
263
                passtype = JPC_PASSTYPE(pass - cblk->passes + 2);
 
264
#endif
 
265
                pass->start = jas_stream_tell(cblk->stream);
 
266
#if 0
 
267
assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream));
 
268
#endif
 
269
                assert(bitpos >= 0);
 
270
                vcausal = (tcmpt->cblksty & JPC_COX_VSC) != 0;
 
271
                segsym = (tcmpt->cblksty & JPC_COX_SEGSYM) != 0;
 
272
                if (pass->term) {
 
273
                        termmode = ((tcmpt->cblksty & JPC_COX_PTERM) ?
 
274
                          JPC_MQENC_PTERM : JPC_MQENC_DEFTERM) + 1;
 
275
                } else {
 
276
                        termmode = 0;
 
277
                }
 
278
                switch (passtype) {
 
279
                case JPC_SIGPASS:
 
280
                        ret = (pass->type == JPC_SEG_MQ) ? jpc_encsigpass(cblk->mqenc,
 
281
                          bitpos, band->orient, vcausal, cblk->flags,
 
282
                          cblk->data, termmode, &pass->nmsedec) :
 
283
                          jpc_encrawsigpass(bout, bitpos, vcausal, cblk->flags,
 
284
                          cblk->data, termmode, &pass->nmsedec);
 
285
                        break;
 
286
                case JPC_REFPASS:
 
287
                        ret = (pass->type == JPC_SEG_MQ) ? jpc_encrefpass(cblk->mqenc,
 
288
                          bitpos, vcausal, cblk->flags, cblk->data, termmode,
 
289
                          &pass->nmsedec) : jpc_encrawrefpass(bout, bitpos,
 
290
                          vcausal, cblk->flags, cblk->data, termmode,
 
291
                          &pass->nmsedec);
 
292
                        break;
 
293
                case JPC_CLNPASS:
 
294
                        assert(pass->type == JPC_SEG_MQ);
 
295
                        ret = jpc_encclnpass(cblk->mqenc, bitpos, band->orient,
 
296
                          vcausal, segsym, cblk->flags, cblk->data, termmode,
 
297
                          &pass->nmsedec);
 
298
                        break;
 
299
                default:
 
300
                        assert(0);
 
301
                        break;
 
302
                }
 
303
 
 
304
                if (pass->type == JPC_SEG_MQ) {
 
305
                        if (pass->term) {
 
306
                                jpc_mqenc_init(cblk->mqenc);
 
307
                        }
 
308
                        jpc_mqenc_getstate(cblk->mqenc, &pass->mqencstate);
 
309
                        pass->end = jas_stream_tell(cblk->stream);
 
310
                        if (tcmpt->cblksty & JPC_COX_RESET) {
 
311
                                jpc_mqenc_setctxs(cblk->mqenc, JPC_NUMCTXS, jpc_mqctxs);
 
312
                        }
 
313
                } else {
 
314
                        if (pass->term) {
 
315
                                if (jpc_bitstream_pending(bout)) {
 
316
                                        jpc_bitstream_outalign(bout, 0x2a);
 
317
                                }
 
318
                                jpc_bitstream_close(bout);
 
319
                                bout = 0;
 
320
                                pass->end = jas_stream_tell(cblk->stream);
 
321
                        } else {
 
322
                                pass->end = jas_stream_tell(cblk->stream) +
 
323
                                  jpc_bitstream_pending(bout);
 
324
/* NOTE - This will not work.  need to adjust by # of pending output bytes */
 
325
                        }
 
326
                }
 
327
#if 0
 
328
/* XXX - This assertion fails sometimes when various coding modes are used.
 
329
This seems to be harmless, but why does it happen at all? */
 
330
assert(jas_stream_tell(cblk->stream) == jas_stream_getrwcount(cblk->stream));
 
331
#endif
 
332
 
 
333
                pass->wmsedec = jpc_fixtodbl(band->rlvl->tcmpt->synweight) *
 
334
                  jpc_fixtodbl(band->rlvl->tcmpt->synweight) *
 
335
                  jpc_fixtodbl(band->synweight) *
 
336
                  jpc_fixtodbl(band->synweight) *
 
337
                  jpc_fixtodbl(band->absstepsize) * jpc_fixtodbl(band->absstepsize) *
 
338
                  ((double) (1 << bitpos)) * ((double)(1 << bitpos)) *
 
339
                  jpc_fixtodbl(pass->nmsedec);
 
340
                pass->cumwmsedec = pass->wmsedec;
 
341
                if (pass != cblk->passes) {
 
342
                        pass->cumwmsedec += pass[-1].cumwmsedec;
 
343
                }
 
344
                if (passtype == JPC_CLNPASS) {
 
345
                        --bitpos;
 
346
                }
 
347
                ++pass;
 
348
        }
 
349
 
 
350
#if 0
 
351
dump_passes(cblk->passes, cblk->numpasses, cblk);
 
352
#endif
 
353
 
 
354
        n = 0;
 
355
        endpasses = &cblk->passes[cblk->numpasses];
 
356
        for (pass = cblk->passes; pass != endpasses; ++pass) {
 
357
                if (pass->start < n) {
 
358
                        pass->start = n;
 
359
                }
 
360
                if (pass->end < n) {
 
361
                        pass->end = n;
 
362
                }
 
363
                if (!pass->term) {
 
364
                        termpass = pass;
 
365
                        while (termpass - pass < cblk->numpasses &&
 
366
                          !termpass->term) {
 
367
                                ++termpass;
 
368
                        }
 
369
                        if (pass->type == JPC_SEG_MQ) {
 
370
                                t = (pass->mqencstate.lastbyte == 0xff) ? 1 : 0;
 
371
                                if (pass->mqencstate.ctreg >= 5) {
 
372
                                        adjust = 4 + t;
 
373
                                } else {
 
374
                                        adjust = 5 + t;
 
375
                                }
 
376
                                pass->end += adjust;
 
377
                        }
 
378
                        if (pass->end > termpass->end) {
 
379
                                pass->end = termpass->end;
 
380
                        }
 
381
                        if ((c = getthebyte(cblk->stream, pass->end - 1)) == EOF) {
 
382
                                abort();
 
383
                        }
 
384
                        if (c == 0xff) {
 
385
                                ++pass->end;
 
386
                        }
 
387
                        n = JAS_MAX(n, pass->end);
 
388
                } else {
 
389
                        n = JAS_MAX(n, pass->end);
 
390
                }
 
391
        }
 
392
 
 
393
#if 0
 
394
dump_passes(cblk->passes, cblk->numpasses, cblk);
 
395
#endif
 
396
 
 
397
        if (bout) {
 
398
                jpc_bitstream_close(bout);
 
399
        }
 
400
 
 
401
        return 0;
 
402
}
 
403
 
 
404
/******************************************************************************\
 
405
* Code for significance pass.
 
406
\******************************************************************************/
 
407
 
 
408
#define sigpass_step(fp, frowstep, dp, bitpos, one, nmsedec, orient, mqenc, vcausalflag) \
 
409
{ \
 
410
        int f; \
 
411
        int v; \
 
412
        f = *(fp); \
 
413
        if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
 
414
                v = (abs(*(dp)) & (one)) ? 1 : 0; \
 
415
                jpc_mqenc_setcurctx(mqenc, JPC_GETZCCTXNO(f, (orient))); \
 
416
                jpc_mqenc_putbit(mqenc, v); \
 
417
                if (v) { \
 
418
                        *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \
 
419
                        v = ((*(dp) < 0) ? 1 : 0); \
 
420
                        jpc_mqenc_setcurctx(mqenc, JPC_GETSCCTXNO(f)); \
 
421
                        jpc_mqenc_putbit(mqenc, v ^ JPC_GETSPB(f)); \
 
422
                        JPC_UPDATEFLAGS4(fp, frowstep, v, vcausalflag); \
 
423
                        *(fp) |= JPC_SIG; \
 
424
                } \
 
425
                *(fp) |= JPC_VISIT; \
 
426
        } \
 
427
}
 
428
 
 
429
static int jpc_encsigpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int vcausalflag,
 
430
  jas_matrix_t *flags, jas_matrix_t *data, int term, long *nmsedec)
 
431
{
 
432
        int i;
 
433
        int j;
 
434
        int one;
 
435
        int vscanlen;
 
436
        int width;
 
437
        int height;
 
438
        int frowstep;
 
439
        int drowstep;
 
440
        int fstripestep;
 
441
        int dstripestep;
 
442
        jpc_fix_t *fstripestart;
 
443
        jpc_fix_t *dstripestart;
 
444
        jpc_fix_t *fp;
 
445
        jpc_fix_t *dp;
 
446
        jpc_fix_t *fvscanstart;
 
447
        jpc_fix_t *dvscanstart;
 
448
        int k;
 
449
 
 
450
        *nmsedec = 0;
 
451
        width = jas_matrix_numcols(data);
 
452
        height = jas_matrix_numrows(data);
 
453
        frowstep = jas_matrix_rowstep(flags);
 
454
        drowstep = jas_matrix_rowstep(data);
 
455
        fstripestep = frowstep << 2;
 
456
        dstripestep = drowstep << 2;
 
457
 
 
458
        one = 1 << (bitpos + JPC_NUMEXTRABITS);
 
459
 
 
460
        fstripestart = jas_matrix_getref(flags, 1, 1);
 
461
        dstripestart = jas_matrix_getref(data, 0, 0);
 
462
        for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
 
463
          dstripestart += dstripestep) {
 
464
                fvscanstart = fstripestart;
 
465
                dvscanstart = dstripestart;
 
466
                vscanlen = JAS_MIN(i, 4);
 
467
                for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
 
468
                        fp = fvscanstart;
 
469
                        dp = dvscanstart;
 
470
                        k = vscanlen;
 
471
 
 
472
                        sigpass_step(fp, frowstep, dp, bitpos, one,
 
473
                          nmsedec, orient, mqenc, vcausalflag);
 
474
                        if (--k <= 0) {
 
475
                                continue;
 
476
                        }
 
477
                        fp += frowstep;
 
478
                        dp += drowstep;
 
479
                        sigpass_step(fp, frowstep, dp, bitpos, one,
 
480
                          nmsedec, orient, mqenc, 0);
 
481
                        if (--k <= 0) {
 
482
                                continue;
 
483
                        }
 
484
                        fp += frowstep;
 
485
                        dp += drowstep;
 
486
                        sigpass_step(fp, frowstep, dp, bitpos, one,
 
487
                          nmsedec, orient, mqenc, 0);
 
488
                        if (--k <= 0) {
 
489
                                continue;
 
490
                        }
 
491
                        fp += frowstep;
 
492
                        dp += drowstep;
 
493
                        sigpass_step(fp, frowstep, dp, bitpos, one,
 
494
                          nmsedec, orient, mqenc, 0);
 
495
 
 
496
                }
 
497
        }
 
498
 
 
499
        if (term) {
 
500
                jpc_mqenc_flush(mqenc, term - 1);
 
501
        }
 
502
 
 
503
        return jpc_mqenc_error(mqenc) ? (-1) : 0;
 
504
}
 
505
 
 
506
#define rawsigpass_step(fp, frowstep, dp, bitpos, one, nmsedec, out, vcausalflag) \
 
507
{ \
 
508
        jpc_fix_t f = *(fp); \
 
509
        jpc_fix_t v; \
 
510
        if ((f & JPC_OTHSIGMSK) && !(f & (JPC_SIG | JPC_VISIT))) { \
 
511
                v = (abs(*(dp)) & (one)) ? 1 : 0; \
 
512
                if ((jpc_bitstream_putbit((out), v)) == EOF) { \
 
513
                        return -1; \
 
514
                } \
 
515
                if (v) { \
 
516
                        *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \
 
517
                        v = ((*(dp) < 0) ? 1 : 0); \
 
518
                        if (jpc_bitstream_putbit(out, v) == EOF) { \
 
519
                                return -1; \
 
520
                        } \
 
521
                        JPC_UPDATEFLAGS4(fp, frowstep, v, vcausalflag); \
 
522
                        *(fp) |= JPC_SIG; \
 
523
                } \
 
524
                *(fp) |= JPC_VISIT; \
 
525
        } \
 
526
}
 
527
 
 
528
static int jpc_encrawsigpass(jpc_bitstream_t *out, int bitpos, int vcausalflag, jas_matrix_t *flags,
 
529
  jas_matrix_t *data, int term, long *nmsedec)
 
530
{
 
531
        int i;
 
532
        int j;
 
533
        int k;
 
534
        int one;
 
535
        int vscanlen;
 
536
        int width;
 
537
        int height;
 
538
        int frowstep;
 
539
        int drowstep;
 
540
        int fstripestep;
 
541
        int dstripestep;
 
542
        jpc_fix_t *fstripestart;
 
543
        jpc_fix_t *dstripestart;
 
544
        jpc_fix_t *fp;
 
545
        jpc_fix_t *dp;
 
546
        jpc_fix_t *fvscanstart;
 
547
        jpc_fix_t *dvscanstart;
 
548
 
 
549
        *nmsedec = 0;
 
550
        width = jas_matrix_numcols(data);
 
551
        height = jas_matrix_numrows(data);
 
552
        frowstep = jas_matrix_rowstep(flags);
 
553
        drowstep = jas_matrix_rowstep(data);
 
554
        fstripestep = frowstep << 2;
 
555
        dstripestep = drowstep << 2;
 
556
 
 
557
        one = 1 << (bitpos + JPC_NUMEXTRABITS);
 
558
 
 
559
        fstripestart = jas_matrix_getref(flags, 1, 1);
 
560
        dstripestart = jas_matrix_getref(data, 0, 0);
 
561
        for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
 
562
          dstripestart += dstripestep) {
 
563
                fvscanstart = fstripestart;
 
564
                dvscanstart = dstripestart;
 
565
                vscanlen = JAS_MIN(i, 4);
 
566
                for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
 
567
                        fp = fvscanstart;
 
568
                        dp = dvscanstart;
 
569
                        k = vscanlen;
 
570
 
 
571
                        rawsigpass_step(fp, frowstep, dp, bitpos, one,
 
572
                          nmsedec, out, vcausalflag);
 
573
                        if (--k <= 0) {
 
574
                                continue;
 
575
                        }
 
576
                        fp += frowstep;
 
577
                        dp += drowstep;
 
578
 
 
579
                        rawsigpass_step(fp, frowstep, dp, bitpos, one,
 
580
                          nmsedec, out, 0);
 
581
                        if (--k <= 0) {
 
582
                                continue;
 
583
                        }
 
584
                        fp += frowstep;
 
585
                        dp += drowstep;
 
586
 
 
587
                        rawsigpass_step(fp, frowstep, dp, bitpos, one,
 
588
                          nmsedec, out, 0);
 
589
                        if (--k <= 0) {
 
590
                                continue;
 
591
                        }
 
592
                        fp += frowstep;
 
593
                        dp += drowstep;
 
594
 
 
595
                        rawsigpass_step(fp, frowstep, dp, bitpos, one,
 
596
                          nmsedec, out, 0);
 
597
                        if (--k <= 0) {
 
598
                                continue;
 
599
                        }
 
600
                        fp += frowstep;
 
601
                        dp += drowstep;
 
602
 
 
603
                }
 
604
        }
 
605
 
 
606
        if (term) {
 
607
                jpc_bitstream_outalign(out, 0x2a);
 
608
        }
 
609
 
 
610
        return 0;
 
611
}
 
612
 
 
613
/******************************************************************************\
 
614
* Code for refinement pass.
 
615
\******************************************************************************/
 
616
 
 
617
#define refpass_step(fp, dp, bitpos, one, nmsedec, mqenc, vcausalflag) \
 
618
{ \
 
619
        int v; \
 
620
        if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
 
621
                (d) = *(dp); \
 
622
                *(nmsedec) += JPC_GETREFNMSEDEC(abs(d), (bitpos) + JPC_NUMEXTRABITS); \
 
623
                jpc_mqenc_setcurctx((mqenc), JPC_GETMAGCTXNO(*(fp))); \
 
624
                v = (abs(d) & (one)) ? 1 : 0; \
 
625
                jpc_mqenc_putbit((mqenc), v); \
 
626
                *(fp) |= JPC_REFINE; \
 
627
        } \
 
628
}
 
629
 
 
630
static int jpc_encrefpass(jpc_mqenc_t *mqenc, int bitpos, int vcausalflag, jas_matrix_t *flags, jas_matrix_t *data,
 
631
  int term, long *nmsedec)
 
632
{
 
633
        int i;
 
634
        int j;
 
635
        int one;
 
636
        int vscanlen;
 
637
        int d;
 
638
        int width;
 
639
        int height;
 
640
        int frowstep;
 
641
        int drowstep;
 
642
        int fstripestep;
 
643
        int dstripestep;
 
644
        jpc_fix_t *fstripestart;
 
645
        jpc_fix_t *dstripestart;
 
646
        jpc_fix_t *fvscanstart;
 
647
        jpc_fix_t *dvscanstart;
 
648
        jpc_fix_t *dp;
 
649
        jpc_fix_t *fp;
 
650
int k;
 
651
 
 
652
        *nmsedec = 0;
 
653
        width = jas_matrix_numcols(data);
 
654
        height = jas_matrix_numrows(data);
 
655
        frowstep = jas_matrix_rowstep(flags);
 
656
        drowstep = jas_matrix_rowstep(data);
 
657
        fstripestep = frowstep << 2;
 
658
        dstripestep = drowstep << 2;
 
659
 
 
660
        one = 1 << (bitpos + JPC_NUMEXTRABITS);
 
661
 
 
662
        fstripestart = jas_matrix_getref(flags, 1, 1);
 
663
        dstripestart = jas_matrix_getref(data, 0, 0);
 
664
        for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
 
665
          dstripestart += dstripestep) {
 
666
                fvscanstart = fstripestart;
 
667
                dvscanstart = dstripestart;
 
668
                vscanlen = JAS_MIN(i, 4);
 
669
                for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
 
670
                        fp = fvscanstart;
 
671
                        dp = dvscanstart;
 
672
                        k = vscanlen;
 
673
 
 
674
                        refpass_step(fp, dp, bitpos, one, nmsedec,
 
675
                          mqenc, vcausalflag);
 
676
                        if (--k <= 0) {
 
677
                                continue;
 
678
                        }
 
679
                        fp += frowstep;
 
680
                        dp += drowstep;
 
681
                        refpass_step(fp, dp, bitpos, one, nmsedec,
 
682
                          mqenc, 0);
 
683
                        if (--k <= 0) {
 
684
                                continue;
 
685
                        }
 
686
                        fp += frowstep;
 
687
                        dp += drowstep;
 
688
                        refpass_step(fp, dp, bitpos, one, nmsedec,
 
689
                          mqenc, 0);
 
690
                        if (--k <= 0) {
 
691
                                continue;
 
692
                        }
 
693
                        fp += frowstep;
 
694
                        dp += drowstep;
 
695
                        refpass_step(fp, dp, bitpos, one, nmsedec,
 
696
                          mqenc, 0);
 
697
 
 
698
                }
 
699
        }
 
700
 
 
701
        if (term) {
 
702
                jpc_mqenc_flush(mqenc, term - 1);
 
703
        }
 
704
 
 
705
        return jpc_mqenc_error(mqenc) ? (-1) : 0;
 
706
}
 
707
 
 
708
#define rawrefpass_step(fp, dp, bitpos, one, nmsedec, out, vcausalflag) \
 
709
{ \
 
710
        jpc_fix_t d; \
 
711
        jpc_fix_t v; \
 
712
        if (((*(fp)) & (JPC_SIG | JPC_VISIT)) == JPC_SIG) { \
 
713
                d = *(dp); \
 
714
                *(nmsedec) += JPC_GETREFNMSEDEC(abs(d), (bitpos) + JPC_NUMEXTRABITS); \
 
715
                v = (abs(d) & (one)) ? 1 : 0; \
 
716
                if (jpc_bitstream_putbit((out), v) == EOF) { \
 
717
                        return -1; \
 
718
                } \
 
719
                *(fp) |= JPC_REFINE; \
 
720
        } \
 
721
}
 
722
 
 
723
static int jpc_encrawrefpass(jpc_bitstream_t *out, int bitpos, int vcausalflag, jas_matrix_t *flags,
 
724
  jas_matrix_t *data, int term, long *nmsedec)
 
725
{
 
726
        int i;
 
727
        int j;
 
728
        int k;
 
729
        int one;
 
730
        int vscanlen;
 
731
        int width;
 
732
        int height;
 
733
        int frowstep;
 
734
        int drowstep;
 
735
        int fstripestep;
 
736
        int dstripestep;
 
737
        jpc_fix_t *fstripestart;
 
738
        jpc_fix_t *dstripestart;
 
739
        jpc_fix_t *fvscanstart;
 
740
        jpc_fix_t *dvscanstart;
 
741
        jpc_fix_t *dp;
 
742
        jpc_fix_t *fp;
 
743
 
 
744
        *nmsedec = 0;
 
745
        width = jas_matrix_numcols(data);
 
746
        height = jas_matrix_numrows(data);
 
747
        frowstep = jas_matrix_rowstep(flags);
 
748
        drowstep = jas_matrix_rowstep(data);
 
749
        fstripestep = frowstep << 2;
 
750
        dstripestep = drowstep << 2;
 
751
 
 
752
        one = 1 << (bitpos + JPC_NUMEXTRABITS);
 
753
 
 
754
        fstripestart = jas_matrix_getref(flags, 1, 1);
 
755
        dstripestart = jas_matrix_getref(data, 0, 0);
 
756
        for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
 
757
          dstripestart += dstripestep) {
 
758
                fvscanstart = fstripestart;
 
759
                dvscanstart = dstripestart;
 
760
                vscanlen = JAS_MIN(i, 4);
 
761
                for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
 
762
                        fp = fvscanstart;
 
763
                        dp = dvscanstart;
 
764
                        k = vscanlen;
 
765
 
 
766
                        rawrefpass_step(fp, dp, bitpos, one, nmsedec,
 
767
                          out, vcausalflag);
 
768
                        if (--k <= 0) {
 
769
                                continue;
 
770
                        }
 
771
                        fp += frowstep;
 
772
                        dp += drowstep;
 
773
                        rawrefpass_step(fp, dp, bitpos, one, nmsedec,
 
774
                          out, vcausalflag);
 
775
                        if (--k <= 0) {
 
776
                                continue;
 
777
                        }
 
778
                        fp += frowstep;
 
779
                        dp += drowstep;
 
780
                        rawrefpass_step(fp, dp, bitpos, one, nmsedec,
 
781
                          out, vcausalflag);
 
782
                        if (--k <= 0) {
 
783
                                continue;
 
784
                        }
 
785
                        fp += frowstep;
 
786
                        dp += drowstep;
 
787
                        rawrefpass_step(fp, dp, bitpos, one, nmsedec,
 
788
                          out, vcausalflag);
 
789
 
 
790
                }
 
791
        }
 
792
 
 
793
        if (term) {
 
794
                jpc_bitstream_outalign(out, 0x2a);
 
795
        }
 
796
 
 
797
        return 0;
 
798
}
 
799
 
 
800
/******************************************************************************\
 
801
* Code for cleanup pass.
 
802
\******************************************************************************/
 
803
 
 
804
#define clnpass_step(fp, frowstep, dp, bitpos, one, orient, nmsedec, mqenc, label1, label2, vcausalflag) \
 
805
{ \
 
806
        int f; \
 
807
        int v; \
 
808
label1 \
 
809
        f = *(fp); \
 
810
        if (!(f & (JPC_SIG | JPC_VISIT))) { \
 
811
                jpc_mqenc_setcurctx(mqenc, JPC_GETZCCTXNO(f, (orient))); \
 
812
                v = (abs(*(dp)) & (one)) ? 1 : 0; \
 
813
                jpc_mqenc_putbit((mqenc), v); \
 
814
                if (v) { \
 
815
label2 \
 
816
                        f = *(fp); \
 
817
                        /* Coefficient is significant. */ \
 
818
                        *(nmsedec) += JPC_GETSIGNMSEDEC(abs(*(dp)), (bitpos) + JPC_NUMEXTRABITS); \
 
819
                        jpc_mqenc_setcurctx((mqenc), JPC_GETSCCTXNO(f)); \
 
820
                        v = ((*(dp) < 0) ? 1 : 0); \
 
821
                        jpc_mqenc_putbit((mqenc), v ^ JPC_GETSPB(f)); \
 
822
                        JPC_UPDATEFLAGS4((fp), (frowstep), v, vcausalflag); \
 
823
                        *(fp) |= JPC_SIG; \
 
824
                } \
 
825
        } \
 
826
        *(fp) &= ~JPC_VISIT; \
 
827
}
 
828
 
 
829
static int jpc_encclnpass(jpc_mqenc_t *mqenc, int bitpos, int orient, int vcausalflag, int segsymflag, jas_matrix_t *flags,
 
830
  jas_matrix_t *data, int term, long *nmsedec)
 
831
{
 
832
        int i;
 
833
        int j;
 
834
        int k;
 
835
        int vscanlen;
 
836
        int v;
 
837
        int runlen;
 
838
        jpc_fix_t *fp;
 
839
        int width;
 
840
        int height;
 
841
        jpc_fix_t *dp;
 
842
        int one;
 
843
        int frowstep;
 
844
        int drowstep;
 
845
        int fstripestep;
 
846
        int dstripestep;
 
847
        jpc_fix_t *fstripestart;
 
848
        jpc_fix_t *dstripestart;
 
849
        jpc_fix_t *fvscanstart;
 
850
        jpc_fix_t *dvscanstart;
 
851
 
 
852
        *nmsedec = 0;
 
853
        width = jas_matrix_numcols(data);
 
854
        height = jas_matrix_numrows(data);
 
855
        frowstep = jas_matrix_rowstep(flags);
 
856
        drowstep = jas_matrix_rowstep(data);
 
857
        fstripestep = frowstep << 2;
 
858
        dstripestep = drowstep << 2;
 
859
 
 
860
        one = 1 << (bitpos + JPC_NUMEXTRABITS);
 
861
 
 
862
        fstripestart = jas_matrix_getref(flags, 1, 1);
 
863
        dstripestart = jas_matrix_getref(data, 0, 0);
 
864
        for (i = height; i > 0; i -= 4, fstripestart += fstripestep,
 
865
          dstripestart += dstripestep) {
 
866
                fvscanstart = fstripestart;
 
867
                dvscanstart = dstripestart;
 
868
                vscanlen = JAS_MIN(i, 4);
 
869
                for (j = width; j > 0; --j, ++fvscanstart, ++dvscanstart) {
 
870
 
 
871
                        fp = fvscanstart;
 
872
                        if (vscanlen >= 4 && !((*fp) & (JPC_SIG | JPC_VISIT |
 
873
                          JPC_OTHSIGMSK)) && (fp += frowstep, !((*fp) & (JPC_SIG |
 
874
                          JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep, !((*fp) &
 
875
                          (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK))) && (fp += frowstep,
 
876
                          !((*fp) & (JPC_SIG | JPC_VISIT | JPC_OTHSIGMSK)))) {
 
877
                                dp = dvscanstart;
 
878
                                for (k = 0; k < vscanlen; ++k) {
 
879
                                        v = (abs(*dp) & one) ? 1 : 0;
 
880
                                        if (v) {
 
881
                                                break;
 
882
                                        }
 
883
                                        dp += drowstep;
 
884
                                }
 
885
                                runlen = k;
 
886
                                if (runlen >= 4) {
 
887
                                        jpc_mqenc_setcurctx(mqenc, JPC_AGGCTXNO);
 
888
                                        jpc_mqenc_putbit(mqenc, 0);
 
889
                                        continue;
 
890
                                }
 
891
                                jpc_mqenc_setcurctx(mqenc, JPC_AGGCTXNO);
 
892
                                jpc_mqenc_putbit(mqenc, 1);
 
893
                                jpc_mqenc_setcurctx(mqenc, JPC_UCTXNO);
 
894
                                jpc_mqenc_putbit(mqenc, runlen >> 1);
 
895
                                jpc_mqenc_putbit(mqenc, runlen & 1);
 
896
                                fp = fvscanstart + frowstep * runlen;
 
897
                                dp = dvscanstart + drowstep * runlen;
 
898
                                k = vscanlen - runlen;
 
899
                                switch (runlen) {
 
900
                                case 0:
 
901
                                        goto clnpass_partial0;
 
902
                                        break;
 
903
                                case 1:
 
904
                                        goto clnpass_partial1;
 
905
                                        break;
 
906
                                case 2:
 
907
                                        goto clnpass_partial2;
 
908
                                        break;
 
909
                                case 3:
 
910
                                        goto clnpass_partial3;
 
911
                                        break;
 
912
                                }
 
913
                        } else {
 
914
                                runlen = 0;
 
915
                                fp = fvscanstart;
 
916
                                dp = dvscanstart;
 
917
                                k = vscanlen;
 
918
                                goto clnpass_full0;
 
919
                        }
 
920
                        clnpass_step(fp, frowstep, dp, bitpos, one,
 
921
                          orient, nmsedec, mqenc, clnpass_full0:, clnpass_partial0:, vcausalflag);
 
922
                        if (--k <= 0) {
 
923
                                continue;
 
924
                        }
 
925
                        fp += frowstep;
 
926
                        dp += drowstep;
 
927
                        clnpass_step(fp, frowstep, dp, bitpos, one,
 
928
                                orient, nmsedec, mqenc, ;, clnpass_partial1:, 0);
 
929
                        if (--k <= 0) {
 
930
                                continue;
 
931
                        }
 
932
                        fp += frowstep;
 
933
                        dp += drowstep;
 
934
                        clnpass_step(fp, frowstep, dp, bitpos, one,
 
935
                                orient, nmsedec, mqenc, ;, clnpass_partial2:, 0);
 
936
                        if (--k <= 0) {
 
937
                                continue;
 
938
                        }
 
939
                        fp += frowstep;
 
940
                        dp += drowstep;
 
941
                        clnpass_step(fp, frowstep, dp, bitpos, one,
 
942
                                orient, nmsedec, mqenc, ;, clnpass_partial3:, 0);
 
943
                }
 
944
        }
 
945
 
 
946
        if (segsymflag) {
 
947
                jpc_mqenc_setcurctx(mqenc, JPC_UCTXNO);
 
948
                jpc_mqenc_putbit(mqenc, 1);
 
949
                jpc_mqenc_putbit(mqenc, 0);
 
950
                jpc_mqenc_putbit(mqenc, 1);
 
951
                jpc_mqenc_putbit(mqenc, 0);
 
952
        }
 
953
 
 
954
        if (term) {
 
955
                jpc_mqenc_flush(mqenc, term - 1);
 
956
        }
 
957
 
 
958
        return jpc_mqenc_error(mqenc) ? (-1) : 0;
 
959
}