Coverage Report

Created: 2025-08-11 08:01

/src/jasper/src/libjasper/jpc/jpc_enc.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3
 *   British Columbia.
4
 * Copyright (c) 2001-2003 Michael David Adams.
5
 * All rights reserved.
6
 */
7
8
/* __START_OF_JASPER_LICENSE__
9
 * 
10
 * JasPer License Version 2.0
11
 * 
12
 * Copyright (c) 2001-2006 Michael David Adams
13
 * Copyright (c) 1999-2000 Image Power, Inc.
14
 * Copyright (c) 1999-2000 The University of British Columbia
15
 * 
16
 * All rights reserved.
17
 * 
18
 * Permission is hereby granted, free of charge, to any person (the
19
 * "User") obtaining a copy of this software and associated documentation
20
 * files (the "Software"), to deal in the Software without restriction,
21
 * including without limitation the rights to use, copy, modify, merge,
22
 * publish, distribute, and/or sell copies of the Software, and to permit
23
 * persons to whom the Software is furnished to do so, subject to the
24
 * following conditions:
25
 * 
26
 * 1.  The above copyright notices and this permission notice (which
27
 * includes the disclaimer below) shall be included in all copies or
28
 * substantial portions of the Software.
29
 * 
30
 * 2.  The name of a copyright holder shall not be used to endorse or
31
 * promote products derived from the Software without specific prior
32
 * written permission.
33
 * 
34
 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35
 * LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36
 * THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37
 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39
 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO
40
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41
 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE
45
 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46
 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47
 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48
 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49
 * PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS
50
 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51
 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE
52
 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53
 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54
 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55
 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56
 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57
 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58
 * RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59
 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60
 * 
61
 * __END_OF_JASPER_LICENSE__
62
 */
63
64
/*
65
 * $Id$
66
 */
67
68
/******************************************************************************\
69
* Includes.
70
\******************************************************************************/
71
72
#include "jpc_enc.h"
73
#include "jpc_flt.h"
74
#include "jpc_fix.h"
75
#include "jpc_tagtree.h"
76
#include "jpc_cs.h"
77
#include "jpc_mct.h"
78
#include "jpc_tsfb.h"
79
#include "jpc_t1cod.h"
80
#include "jpc_t1enc.h"
81
#include "jpc_t2enc.h"
82
#include "jpc_math.h"
83
#include "jpc_util.h"
84
85
#include "jasper/jas_types.h"
86
#include "jasper/jas_string.h"
87
#include "jasper/jas_malloc.h"
88
#include "jasper/jas_image.h"
89
#include "jasper/jas_tvp.h"
90
#include "jasper/jas_version.h"
91
#include "jasper/jas_math.h"
92
#include "jasper/jas_debug.h"
93
94
#include <stdio.h>
95
#include <stdlib.h>
96
#include <string.h>
97
#include <assert.h>
98
#include <math.h>
99
#include <float.h>
100
101
/******************************************************************************\
102
*
103
\******************************************************************************/
104
105
#define JPC_POW2(n) \
106
  (1 << (n))
107
108
#define JPC_FLOORTOMULTPOW2(x, n) \
109
0
  (((n) > 0) ? ((x) & (~((1 << n) - 1))) : (x))
110
/* Round to the nearest multiple of the specified power of two in the
111
  direction of negative infinity. */
112
113
#define JPC_CEILTOMULTPOW2(x, n) \
114
0
  (((n) > 0) ? JPC_FLOORTOMULTPOW2(((x) + (1 << (n)) - 1), n) : (x))
115
/* Round to the nearest multiple of the specified power of two in the
116
  direction of positive infinity. */
117
118
#define JPC_POW2(n) \
119
0
  (1 << (n))
120
121
/******************************************************************************\
122
* Local prototypes.
123
\******************************************************************************/
124
125
static jpc_enc_tile_t *jpc_enc_tile_create(jpc_enc_cp_t *cp, jas_image_t *image, int tileno);
126
static void jpc_enc_tile_destroy(jpc_enc_tile_t *tile);
127
128
static jpc_enc_tcmpt_t *tcmpt_create(jpc_enc_tcmpt_t *tcmpt, jpc_enc_cp_t *cp,
129
  jas_image_t *image, jpc_enc_tile_t *tile);
130
static void tcmpt_destroy(jpc_enc_tcmpt_t *tcmpt);
131
static jpc_enc_rlvl_t *rlvl_create(jpc_enc_rlvl_t *rlvl, jpc_enc_cp_t *cp,
132
  jpc_enc_tcmpt_t *tcmpt, jpc_tsfb_band_t *bandinfos);
133
static void rlvl_destroy(jpc_enc_rlvl_t *rlvl);
134
static jpc_enc_band_t *band_create(jpc_enc_band_t *band, jpc_enc_cp_t *cp,
135
  jpc_enc_rlvl_t *rlvl, jpc_tsfb_band_t *bandinfos);
136
static void band_destroy(jpc_enc_band_t *bands);
137
static jpc_enc_prc_t *prc_create(jpc_enc_prc_t *prc,
138
  jpc_enc_band_t *band);
139
static void prc_destroy(jpc_enc_prc_t *prcs);
140
static jpc_enc_cblk_t *cblk_create(jpc_enc_cblk_t *cblk,
141
  jpc_enc_prc_t *prc);
142
static void cblk_destroy(jpc_enc_cblk_t *cblks);
143
static int ratestrtosize(const char *s, uint_fast32_t rawsize, uint_fast32_t *size);
144
static void pass_destroy(jpc_enc_pass_t *pass);
145
static void jpc_enc_dump(jpc_enc_t *enc);
146
147
static void calcrdslopes(jpc_enc_cblk_t *cblk);
148
static void dump_layeringinfo(jpc_enc_t *enc);
149
static void jpc_quantize(jas_matrix_t *data, jpc_fix_t stepsize);
150
static jpc_enc_t *jpc_enc_create(jpc_enc_cp_t *cp, jas_stream_t *out, jas_image_t *image);
151
static void jpc_enc_destroy(jpc_enc_t *enc);
152
static int jpc_enc_encodemainhdr(jpc_enc_t *enc);
153
static int jpc_enc_encodemainbody(jpc_enc_t *enc);
154
static int jpc_enc_encodetiledata(jpc_enc_t *enc);
155
static int rateallocate(jpc_enc_t *enc, unsigned numlyrs, uint_fast32_t *cumlens);
156
static jpc_enc_cp_t *cp_create(const char *optstr, jas_image_t *image);
157
static void jpc_enc_cp_destroy(jpc_enc_cp_t *cp);
158
static uint_fast32_t jpc_abstorelstepsize(jpc_fix_t absdelta, int scaleexpn);
159
160
/******************************************************************************\
161
* Types.
162
\******************************************************************************/
163
164
typedef enum {
165
  OPT_DEBUG,
166
  OPT_IMGAREAOFFX,
167
  OPT_IMGAREAOFFY,
168
  OPT_TILEGRDOFFX,
169
  OPT_TILEGRDOFFY,
170
  OPT_TILEWIDTH,
171
  OPT_TILEHEIGHT,
172
  OPT_PRCWIDTH,
173
  OPT_PRCHEIGHT,
174
  OPT_CBLKWIDTH,
175
  OPT_CBLKHEIGHT,
176
  OPT_MODE,
177
  OPT_PRG,
178
  OPT_NOMCT,
179
  OPT_MAXRLVLS,
180
  OPT_SOP,
181
  OPT_EPH,
182
  OPT_LAZY,
183
  OPT_TERMALL,
184
  OPT_SEGSYM,
185
  OPT_VCAUSAL,
186
  OPT_RESET,
187
  OPT_PTERM,
188
  OPT_NUMGBITS,
189
  OPT_RATE,
190
  OPT_ILYRRATES,
191
  OPT_JP2OVERHEAD
192
} optid_t;
193
194
typedef enum {
195
  PO_L = 0,
196
  PO_R
197
} poid_t;
198
199
typedef enum {
200
  MODE_INT,
201
  MODE_REAL
202
} modeid_t;
203
204
/******************************************************************************\
205
* Data.
206
\******************************************************************************/
207
208
static const jas_taginfo_t encopts[] = {
209
  {OPT_DEBUG, "debug"},
210
  {OPT_IMGAREAOFFX, "imgareatlx"},
211
  {OPT_IMGAREAOFFY, "imgareatly"},
212
  {OPT_TILEGRDOFFX, "tilegrdtlx"},
213
  {OPT_TILEGRDOFFY, "tilegrdtly"},
214
  {OPT_TILEWIDTH, "tilewidth"},
215
  {OPT_TILEHEIGHT, "tileheight"},
216
  {OPT_PRCWIDTH, "prcwidth"},
217
  {OPT_PRCHEIGHT, "prcheight"},
218
  {OPT_CBLKWIDTH, "cblkwidth"},
219
  {OPT_CBLKHEIGHT, "cblkheight"},
220
  {OPT_MODE, "mode"},
221
  {OPT_PRG, "prg"},
222
  {OPT_NOMCT, "nomct"},
223
  {OPT_MAXRLVLS, "numrlvls"},
224
  {OPT_SOP, "sop"},
225
  {OPT_EPH, "eph"},
226
  {OPT_LAZY, "lazy"},
227
  {OPT_TERMALL, "termall"},
228
  {OPT_SEGSYM, "segsym"},
229
  {OPT_VCAUSAL, "vcausal"},
230
  {OPT_PTERM, "pterm"},
231
  {OPT_RESET, "resetprob"},
232
  {OPT_NUMGBITS, "numgbits"},
233
  {OPT_RATE, "rate"},
234
  {OPT_ILYRRATES, "ilyrrates"},
235
  {OPT_JP2OVERHEAD, "_jp2overhead"},
236
  {-1, 0}
237
};
238
239
static const jas_taginfo_t prgordtab[] = {
240
  {JPC_COD_LRCPPRG, "lrcp"},
241
  {JPC_COD_RLCPPRG, "rlcp"},
242
  {JPC_COD_RPCLPRG, "rpcl"},
243
  {JPC_COD_PCRLPRG, "pcrl"},
244
  {JPC_COD_CPRLPRG, "cprl"},
245
  {-1, 0}
246
};
247
248
static const jas_taginfo_t modetab[] = {
249
  {MODE_INT, "int"},
250
  {MODE_REAL, "real"},
251
  {-1, 0}
252
};
253
254
/******************************************************************************\
255
\******************************************************************************/
256
257
/**
258
 * @return UINT_FAST32_MAX on error
259
 */
260
static uint_fast32_t jpc_abstorelstepsize(jpc_fix_t absdelta, int scaleexpn)
261
0
{
262
0
  int p;
263
0
  uint_fast32_t mant;
264
0
  uint_fast32_t expn;
265
0
  int n;
266
267
0
  if (absdelta < 0) {
268
0
    return UINT_FAST32_MAX;
269
0
  }
270
271
0
  p = jpc_fix_firstone(absdelta) - JPC_FIX_FRACBITS;
272
0
  n = 11 - jpc_fix_firstone(absdelta);
273
0
  mant = ((n < 0) ? (absdelta >> (-n)) : (absdelta << n)) & 0x7ff;
274
0
  expn = scaleexpn - p;
275
0
  if (scaleexpn < p) {
276
0
    return UINT_FAST32_MAX;
277
0
  }
278
0
  if (expn >= 0x1f)
279
0
    return UINT_FAST32_MAX;
280
0
  return JPC_QCX_EXPN(expn) | JPC_QCX_MANT(mant);
281
0
}
282
283
/******************************************************************************\
284
* The main encoder entry point.
285
\******************************************************************************/
286
287
int jpc_encode(jas_image_t *image, jas_stream_t *out, const char *optstr)
288
0
{
289
0
  jpc_enc_t *enc;
290
0
  jpc_enc_cp_t *cp;
291
292
0
  enc = 0;
293
0
  cp = 0;
294
295
0
  jpc_init();
296
297
0
  if (!(cp = cp_create(optstr, image))) {
298
0
    jas_logerrorf("invalid JP encoder options\n");
299
0
    goto error;
300
0
  }
301
302
0
  if (!(enc = jpc_enc_create(cp, out, image))) {
303
0
    jas_logerrorf("jpc_enc_create failed\n");
304
0
    goto error;
305
0
  }
306
0
  cp = 0;
307
308
  /* Encode the main header. */
309
0
  if (jpc_enc_encodemainhdr(enc)) {
310
0
    jas_logerrorf("cannot encode main header\n");
311
0
    goto error;
312
0
  }
313
314
  /* Encode the main body.  This constitutes most of the encoding work. */
315
0
  if (jpc_enc_encodemainbody(enc)) {
316
0
    jas_logerrorf("cannot encode main body\n");
317
0
    goto error;
318
0
  }
319
320
  /* Write EOC marker segment. */
321
0
  if (!(enc->mrk = jpc_ms_create(JPC_MS_EOC))) {
322
0
    jas_logerrorf("cannot create EOC marker\n");
323
0
    goto error;
324
0
  }
325
0
  if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
326
0
    jas_logerrorf("cannot write EOC marker\n");
327
0
    goto error;
328
0
  }
329
0
  jpc_ms_destroy(enc->mrk);
330
0
  enc->mrk = 0;
331
332
0
  if (jas_stream_flush(enc->out)) {
333
0
    jas_logerrorf("stream flush failed\n");
334
0
    goto error;
335
0
  }
336
337
0
  jpc_enc_destroy(enc);
338
339
0
  return 0;
340
341
0
error:
342
0
  if (cp) {
343
0
    jpc_enc_cp_destroy(cp);
344
0
  }
345
0
  if (enc) {
346
0
    jpc_enc_destroy(enc);
347
0
  }
348
0
  jas_logerrorf("jpc_encode failed\n");
349
0
  return -1;
350
0
}
351
352
/******************************************************************************\
353
* Option parsing code.
354
\******************************************************************************/
355
356
static jpc_enc_cp_t *cp_create(const char *optstr, jas_image_t *image)
357
0
{
358
0
  jpc_enc_cp_t *cp;
359
0
  jas_tvparser_t *tvp;
360
0
  int ret;
361
0
  int numilyrrates;
362
0
  double *ilyrrates;
363
0
  int i;
364
0
  int tagid;
365
0
  jpc_enc_tcp_t *tcp;
366
0
  jpc_enc_tccp_t *tccp;
367
0
  jpc_enc_ccp_t *ccp;
368
0
  uint_fast16_t rlvlno;
369
0
  uint_fast16_t prcwidthexpn;
370
0
  uint_fast16_t prcheightexpn;
371
0
  bool enablemct;
372
0
  uint_fast32_t jp2overhead;
373
0
  uint_fast16_t lyrno;
374
0
  uint_fast32_t hsteplcm;
375
0
  uint_fast32_t vsteplcm;
376
0
  bool mctvalid;
377
378
0
  tvp = 0;
379
0
  cp = 0;
380
0
  ilyrrates = 0;
381
0
  numilyrrates = 0;
382
383
0
  if (!(cp = jas_malloc(sizeof(jpc_enc_cp_t)))) {
384
0
    goto error;
385
0
  }
386
387
0
  prcwidthexpn = 15;
388
0
  prcheightexpn = 15;
389
0
  enablemct = true;
390
0
  jp2overhead = 0;
391
392
0
  cp->ccps = 0;
393
0
  cp->debug = 0;
394
0
  cp->imgareatlx = UINT_FAST32_MAX;
395
0
  cp->imgareatly = UINT_FAST32_MAX;
396
0
  cp->refgrdwidth = 0;
397
0
  cp->refgrdheight = 0;
398
0
  cp->tilegrdoffx = UINT_FAST32_MAX;
399
0
  cp->tilegrdoffy = UINT_FAST32_MAX;
400
0
  cp->tilewidth = 0;
401
0
  cp->tileheight = 0;
402
0
  cp->numcmpts = jas_image_numcmpts(image);
403
0
  cp->tcp.ilyrrates = NULL;
404
405
0
  hsteplcm = 1;
406
0
  vsteplcm = 1;
407
0
  for (unsigned cmptno = 0; cmptno < jas_image_numcmpts(image); ++cmptno) {
408
0
    if (jas_image_cmptbrx(image, cmptno) + jas_image_cmpthstep(image, cmptno) <=
409
0
      jas_image_brx(image) || jas_image_cmptbry(image, cmptno) +
410
0
      jas_image_cmptvstep(image, cmptno) <= jas_image_bry(image)) {
411
0
      jas_logerrorf("unsupported image type\n");
412
0
      goto error;
413
0
    }
414
    /* Note: We ought to be calculating the LCMs here.  Fix some day. */
415
0
    hsteplcm *= jas_image_cmpthstep(image, cmptno);
416
0
    vsteplcm *= jas_image_cmptvstep(image, cmptno);
417
0
  }
418
419
0
  if (!(cp->ccps = jas_alloc2(cp->numcmpts, sizeof(jpc_enc_ccp_t)))) {
420
0
    goto error;
421
0
  }
422
0
  unsigned cmptno;
423
0
  for (cmptno = 0, ccp = cp->ccps; cmptno < cp->numcmpts; ++cmptno,
424
0
    ++ccp) {
425
0
    ccp->sampgrdstepx = jas_image_cmpthstep(image, cmptno);
426
0
    ccp->sampgrdstepy = jas_image_cmptvstep(image, cmptno);
427
    /* XXX - this isn't quite correct for more general image */
428
0
    ccp->sampgrdsubstepx = 0;
429
0
    ccp->sampgrdsubstepx = 0;
430
0
    ccp->prec = jas_image_cmptprec(image, cmptno);
431
0
    ccp->sgnd = jas_image_cmptsgnd(image, cmptno);
432
0
    ccp->numstepsizes = 0;
433
0
    memset(ccp->stepsizes, 0, sizeof(ccp->stepsizes));
434
0
  }
435
436
0
  cp->rawsize = jas_image_rawsize(image);
437
0
  if (cp->rawsize == 0) {
438
    /* prevent division by zero in cp_create() */
439
0
    goto error;
440
0
  }
441
0
  cp->totalsize = UINT_FAST32_MAX;
442
443
0
  tcp = &cp->tcp;
444
0
  tcp->csty = 0;
445
0
  tcp->intmode = true;
446
0
  tcp->prg = JPC_COD_LRCPPRG;
447
0
  tcp->numlyrs = 1;
448
0
  tcp->ilyrrates = 0;
449
450
0
  tccp = &cp->tccp;
451
0
  tccp->csty = 0;
452
0
  tccp->maxrlvls = 6;
453
0
  tccp->cblkwidthexpn = 6;
454
0
  tccp->cblkheightexpn = 6;
455
0
  tccp->cblksty = 0;
456
0
  tccp->numgbits = 2;
457
458
0
  if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) {
459
0
    goto error;
460
0
  }
461
462
0
  while (!(ret = jas_tvparser_next(tvp))) {
463
0
    switch (jas_taginfo_nonull(jas_taginfos_lookup(encopts,
464
0
      jas_tvparser_gettag(tvp)))->id) {
465
0
    case OPT_DEBUG:
466
0
      cp->debug = atoi(jas_tvparser_getval(tvp));
467
0
      break;
468
0
    case OPT_IMGAREAOFFX:
469
0
      cp->imgareatlx = atoi(jas_tvparser_getval(tvp));
470
0
      break;
471
0
    case OPT_IMGAREAOFFY:
472
0
      cp->imgareatly = atoi(jas_tvparser_getval(tvp));
473
0
      break;
474
0
    case OPT_TILEGRDOFFX:
475
0
      cp->tilegrdoffx = atoi(jas_tvparser_getval(tvp));
476
0
      break;
477
0
    case OPT_TILEGRDOFFY:
478
0
      cp->tilegrdoffy = atoi(jas_tvparser_getval(tvp));
479
0
      break;
480
0
    case OPT_TILEWIDTH:
481
0
      cp->tilewidth = atoi(jas_tvparser_getval(tvp));
482
0
      break;
483
0
    case OPT_TILEHEIGHT:
484
0
      cp->tileheight = atoi(jas_tvparser_getval(tvp));
485
0
      break;
486
0
    case OPT_PRCWIDTH:
487
0
      i = atoi(jas_tvparser_getval(tvp));
488
0
      if (i <= 0) {
489
0
        jas_logerrorf("invalid precinct width (%d)\n", i);
490
0
        goto error;
491
0
      }
492
0
      prcwidthexpn = jpc_floorlog2(i);
493
0
      break;
494
0
    case OPT_PRCHEIGHT:
495
0
      i = atoi(jas_tvparser_getval(tvp));
496
0
      if (i <= 0) {
497
0
        jas_logerrorf("invalid precinct height (%d)\n", i);
498
0
        goto error;
499
0
      }
500
0
      prcheightexpn = jpc_floorlog2(i);
501
0
      break;
502
0
    case OPT_CBLKWIDTH:
503
0
      i = atoi(jas_tvparser_getval(tvp));
504
0
      if (i <= 0) {
505
0
        jas_logerrorf("invalid code block width (%d)\n", i);
506
0
        goto error;
507
0
      }
508
0
      tccp->cblkwidthexpn = jpc_floorlog2(i);
509
0
      break;
510
0
    case OPT_CBLKHEIGHT:
511
0
      i = atoi(jas_tvparser_getval(tvp));
512
0
      if (i <= 0) {
513
0
        jas_logerrorf("invalid code block height (%d)\n", i);
514
0
        goto error;
515
0
      }
516
0
      tccp->cblkheightexpn = jpc_floorlog2(i);
517
0
      break;
518
0
    case OPT_MODE:
519
0
      if ((tagid = jas_taginfo_nonull(jas_taginfos_lookup(modetab,
520
0
        jas_tvparser_getval(tvp)))->id) < 0) {
521
0
        jas_logwarnf("ignoring invalid mode %s\n",
522
0
          jas_tvparser_getval(tvp));
523
0
      } else {
524
0
        tcp->intmode = (tagid == MODE_INT);
525
0
      }
526
0
      break;
527
0
    case OPT_PRG:
528
0
      if ((tagid = jas_taginfo_nonull(jas_taginfos_lookup(prgordtab,
529
0
        jas_tvparser_getval(tvp)))->id) < 0) {
530
0
        jas_logwarnf("ignoring invalid progression order %s\n",
531
0
          jas_tvparser_getval(tvp));
532
0
      } else {
533
0
        tcp->prg = tagid;
534
0
      }
535
0
      break;
536
0
    case OPT_NOMCT:
537
0
      enablemct = false;
538
0
      break;
539
0
    case OPT_MAXRLVLS:
540
0
      tccp->maxrlvls = atoi(jas_tvparser_getval(tvp));
541
0
      if (tccp->maxrlvls > JPC_MAXRLVLS) {
542
0
        jas_logerrorf("number of resolution levels exceeds maximum %d\n",
543
0
          JPC_MAXRLVLS);
544
0
        goto error;
545
0
      }
546
0
      break;
547
0
    case OPT_SOP:
548
0
      cp->tcp.csty |= JPC_COD_SOP;
549
0
      break;
550
0
    case OPT_EPH:
551
0
      cp->tcp.csty |= JPC_COD_EPH;
552
0
      break;
553
0
    case OPT_LAZY:
554
0
      tccp->cblksty |= JPC_COX_LAZY;
555
0
      break;
556
0
    case OPT_TERMALL:
557
0
      tccp->cblksty |= JPC_COX_TERMALL;
558
0
      break;
559
0
    case OPT_SEGSYM:
560
0
      tccp->cblksty |= JPC_COX_SEGSYM;
561
0
      break;
562
0
    case OPT_VCAUSAL:
563
0
      tccp->cblksty |= JPC_COX_VSC;
564
0
      break;
565
0
    case OPT_RESET:
566
0
      tccp->cblksty |= JPC_COX_RESET;
567
0
      break;
568
0
    case OPT_PTERM:
569
0
      tccp->cblksty |= JPC_COX_PTERM;
570
0
      break;
571
0
    case OPT_NUMGBITS:
572
0
      cp->tccp.numgbits = atoi(jas_tvparser_getval(tvp));
573
0
      break;
574
0
    case OPT_RATE:
575
0
      if (ratestrtosize(jas_tvparser_getval(tvp), cp->rawsize,
576
0
        &cp->totalsize)) {
577
0
        jas_logwarnf("ignoring bad rate specifier %s\n",
578
0
          jas_tvparser_getval(tvp));
579
0
      }
580
0
      break;
581
0
    case OPT_ILYRRATES:
582
0
      if (jpc_atoaf(jas_tvparser_getval(tvp), &numilyrrates,
583
0
        &ilyrrates)) {
584
0
        jas_logwarnf("warning: invalid intermediate layer rates specifier ignored (%s)\n",
585
0
          jas_tvparser_getval(tvp));
586
0
      }
587
      /* Ensure that the intermediate layer rates are nonnegative. */
588
0
      for (i = 0; i < numilyrrates; ++i) {
589
0
        if (ilyrrates[i] < 0) {
590
0
          jas_logerrorf(
591
0
            "intermediate layer rate must be nonnegative\n");
592
0
          goto error;
593
0
        }
594
0
      }
595
0
      break;
596
597
0
    case OPT_JP2OVERHEAD:
598
0
      jp2overhead = atoi(jas_tvparser_getval(tvp));
599
0
      break;
600
0
    default:
601
0
      jas_logwarnf("warning: ignoring invalid option %s\n",
602
0
       jas_tvparser_gettag(tvp));
603
0
      break;
604
0
    }
605
0
  }
606
607
0
  jas_tvparser_destroy(tvp);
608
0
  tvp = 0;
609
610
0
  if (cp->totalsize != UINT_FAST32_MAX) {
611
0
    cp->totalsize = (cp->totalsize > jp2overhead) ?
612
0
      (cp->totalsize - jp2overhead) : 0;
613
0
  }
614
615
0
  if (cp->imgareatlx == UINT_FAST32_MAX) {
616
0
    cp->imgareatlx = 0;
617
0
  } else {
618
0
    if (hsteplcm != 1) {
619
0
      jas_logwarnf("warning: overriding imgareatlx value\n");
620
0
    }
621
0
    cp->imgareatlx *= hsteplcm;
622
0
  }
623
0
  if (cp->imgareatly == UINT_FAST32_MAX) {
624
0
    cp->imgareatly = 0;
625
0
  } else {
626
0
    if (vsteplcm != 1) {
627
0
      jas_logwarnf("warning: overriding imgareatly value\n");
628
0
    }
629
0
    cp->imgareatly *= vsteplcm;
630
0
  }
631
0
  cp->refgrdwidth = cp->imgareatlx + jas_image_width(image);
632
0
  cp->refgrdheight = cp->imgareatly + jas_image_height(image);
633
0
  if (cp->tilegrdoffx == UINT_FAST32_MAX) {
634
0
    cp->tilegrdoffx = cp->imgareatlx;
635
0
  }
636
0
  if (cp->tilegrdoffy == UINT_FAST32_MAX) {
637
0
    cp->tilegrdoffy = cp->imgareatly;
638
0
  }
639
0
  if (!cp->tilewidth) {
640
0
    cp->tilewidth = cp->refgrdwidth - cp->tilegrdoffx;
641
0
  }
642
0
  if (!cp->tileheight) {
643
0
    cp->tileheight = cp->refgrdheight - cp->tilegrdoffy;
644
0
  }
645
646
0
  if (cp->numcmpts == 3) {
647
0
    mctvalid = true;
648
0
    for (cmptno = 0; cmptno < jas_image_numcmpts(image); ++cmptno) {
649
0
      if (jas_image_cmptprec(image, cmptno) != jas_image_cmptprec(image, 0) ||
650
0
        jas_image_cmptsgnd(image, cmptno) != jas_image_cmptsgnd(image, 0) ||
651
0
        jas_image_cmptwidth(image, cmptno) != jas_image_cmptwidth(image, 0) ||
652
0
        jas_image_cmptheight(image, cmptno) != jas_image_cmptheight(image, 0)) {
653
0
        mctvalid = false;
654
0
      }
655
0
    }
656
0
  } else {
657
0
    mctvalid = false;
658
0
  }
659
0
  if (mctvalid && enablemct && jas_clrspc_fam(jas_image_clrspc(image)) != JAS_CLRSPC_FAM_RGB) {
660
0
    jas_logwarnf("warning: color space apparently not RGB\n");
661
0
  }
662
0
  if (mctvalid && enablemct && jas_clrspc_fam(jas_image_clrspc(image)) == JAS_CLRSPC_FAM_RGB) {
663
0
    tcp->mctid = (tcp->intmode) ? (JPC_MCT_RCT) : (JPC_MCT_ICT);
664
0
  } else {
665
0
    tcp->mctid = JPC_MCT_NONE;
666
0
  }
667
0
  tccp->qmfbid = (tcp->intmode) ? (JPC_COX_RFT) : (JPC_COX_INS);
668
669
0
  for (rlvlno = 0; rlvlno < tccp->maxrlvls; ++rlvlno) {
670
0
    tccp->prcwidthexpns[rlvlno] = prcwidthexpn;
671
0
    tccp->prcheightexpns[rlvlno] = prcheightexpn;
672
0
  }
673
0
  if (prcwidthexpn != 15 || prcheightexpn != 15) {
674
0
    tccp->csty |= JPC_COX_PRT;
675
0
  }
676
677
  /* Ensure that the tile width and height is valid. */
678
0
  if (!cp->tilewidth) {
679
0
    jas_logerrorf("invalid tile width %lu\n", (unsigned long)
680
0
      cp->tilewidth);
681
0
    goto error;
682
0
  }
683
0
  if (!cp->tileheight) {
684
0
    jas_logerrorf("invalid tile height %lu\n", (unsigned long)
685
0
      cp->tileheight);
686
0
    goto error;
687
0
  }
688
689
  /* Ensure that the tile grid offset is valid. */
690
0
  if (cp->tilegrdoffx > cp->imgareatlx ||
691
0
    cp->tilegrdoffy > cp->imgareatly ||
692
0
    cp->tilegrdoffx + cp->tilewidth < cp->imgareatlx ||
693
0
    cp->tilegrdoffy + cp->tileheight < cp->imgareatly) {
694
0
    jas_logerrorf("invalid tile grid offset (%lu, %lu)\n",
695
0
      (unsigned long) cp->tilegrdoffx, (unsigned long)
696
0
      cp->tilegrdoffy);
697
0
    goto error;
698
0
  }
699
700
0
  cp->numhtiles = JPC_CEILDIV(cp->refgrdwidth - cp->tilegrdoffx,
701
0
    cp->tilewidth);
702
0
  cp->numvtiles = JPC_CEILDIV(cp->refgrdheight - cp->tilegrdoffy,
703
0
    cp->tileheight);
704
0
  cp->numtiles = cp->numhtiles * cp->numvtiles;
705
706
0
  if (ilyrrates && numilyrrates > 0) {
707
0
    tcp->numlyrs = numilyrrates + 1;
708
0
    if (!(tcp->ilyrrates = jas_alloc2((tcp->numlyrs - 1),
709
0
      sizeof(jpc_fix_t)))) {
710
0
      goto error;
711
0
    }
712
0
    for (i = 0; i < JAS_CAST(int, tcp->numlyrs - 1); ++i) {
713
0
      tcp->ilyrrates[i] = jpc_dbltofix(ilyrrates[i]);
714
0
    }
715
0
  }
716
717
  /* Ensure that the integer mode is used in the case of lossless
718
    coding. */
719
0
  if (cp->totalsize == UINT_FAST32_MAX && (!cp->tcp.intmode)) {
720
0
    jas_logerrorf("cannot use real mode for lossless coding\n");
721
0
    goto error;
722
0
  }
723
724
  /* Ensure that the precinct width is valid. */
725
0
  if (prcwidthexpn > 15) {
726
0
    jas_logerrorf("invalid precinct width\n");
727
0
    goto error;
728
0
  }
729
730
  /* Ensure that the precinct height is valid. */
731
0
  if (prcheightexpn > 15) {
732
0
    jas_logerrorf("invalid precinct height\n");
733
0
    goto error;
734
0
  }
735
736
  /* Ensure that the code block width is valid. */
737
0
  if (cp->tccp.cblkwidthexpn < 2 || cp->tccp.cblkwidthexpn > 12) {
738
0
    jas_logerrorf("invalid code block width %d\n",
739
0
      JPC_POW2(cp->tccp.cblkwidthexpn));
740
0
    goto error;
741
0
  }
742
743
  /* Ensure that the code block height is valid. */
744
0
  if (cp->tccp.cblkheightexpn < 2 || cp->tccp.cblkheightexpn > 12) {
745
0
    jas_logerrorf("invalid code block height %d\n",
746
0
      JPC_POW2(cp->tccp.cblkheightexpn));
747
0
    goto error;
748
0
  }
749
750
  /* Ensure that the code block size is not too large. */
751
0
  if (cp->tccp.cblkwidthexpn + cp->tccp.cblkheightexpn > 12) {
752
0
    jas_logerrorf("code block size too large\n");
753
0
    goto error;
754
0
  }
755
756
  /* Ensure that the number of layers is valid. */
757
0
  if (cp->tcp.numlyrs > 16384) {
758
0
    jas_logerrorf("too many layers\n");
759
0
    goto error;
760
0
  }
761
762
  /* There must be at least one resolution level. */
763
0
  if (cp->tccp.maxrlvls < 1) {
764
0
    jas_logerrorf("must be at least one resolution level\n");
765
0
    goto error;
766
0
  }
767
768
  /* Ensure that the number of guard bits is valid. */
769
0
  if (cp->tccp.numgbits > 8) {
770
0
    jas_logerrorf("invalid number of guard bits\n");
771
0
    goto error;
772
0
  }
773
774
  /* Ensure that the rate is within the legal range. */
775
0
  if (cp->totalsize != UINT_FAST32_MAX && cp->totalsize > cp->rawsize) {
776
0
    jas_logwarnf("warning: specified rate is unreasonably large (%lu > %lu)\n", (unsigned long) cp->totalsize, (unsigned long) cp->rawsize);
777
0
  }
778
779
  /* Ensure that the intermediate layer rates are valid. */
780
0
  if (tcp->numlyrs > 1) {
781
    /* The intermediate layers rates must increase monotonically. */
782
0
    for (lyrno = 0; lyrno + 2 < tcp->numlyrs; ++lyrno) {
783
0
      if (tcp->ilyrrates[lyrno] >= tcp->ilyrrates[lyrno + 1]) {
784
0
        jas_logerrorf("intermediate layer rates must increase monotonically\n");
785
0
        goto error;
786
0
      }
787
0
    }
788
    /* The intermediate layer rates must be less than the overall rate. */
789
0
    if (cp->totalsize != UINT_FAST32_MAX) {
790
0
      for (lyrno = 0; lyrno < tcp->numlyrs - 1; ++lyrno) {
791
0
        if (jpc_fixtodbl(tcp->ilyrrates[lyrno]) > ((double) cp->totalsize)
792
0
          / cp->rawsize) {
793
0
          jas_logerrorf("warning: intermediate layer rates must be less than overall rate\n");
794
0
          goto error;
795
0
        }
796
0
      }
797
0
    }
798
0
  }
799
800
0
  if (ilyrrates) {
801
0
    jas_free(ilyrrates);
802
0
  }
803
804
0
  return cp;
805
806
0
error:
807
808
0
  if (ilyrrates) {
809
0
    jas_free(ilyrrates);
810
0
  }
811
0
  if (tvp) {
812
0
    jas_tvparser_destroy(tvp);
813
0
  }
814
0
  if (cp) {
815
0
    jpc_enc_cp_destroy(cp);
816
0
  }
817
0
  return 0;
818
0
}
819
820
void jpc_enc_cp_destroy(jpc_enc_cp_t *cp)
821
0
{
822
0
  if (cp->ccps) {
823
0
    if (cp->tcp.ilyrrates) {
824
0
      jas_free(cp->tcp.ilyrrates);
825
0
    }
826
0
    jas_free(cp->ccps);
827
0
  }
828
0
  jas_free(cp);
829
0
}
830
831
int ratestrtosize(const char *s, uint_fast32_t rawsize, uint_fast32_t *size)
832
0
{
833
0
  jpc_flt_t f;
834
835
  /* Note: This function must not modify output size on failure. */
836
0
  if (strchr(s, 'B')) {
837
0
    *size = atoi(s);
838
0
  } else {
839
0
    f = atof(s);
840
0
    if (f < 0) {
841
0
      *size = 0;
842
0
    } else if (f > 1.0) {
843
0
      *size = rawsize + 1;
844
0
    } else {
845
0
      *size = f * rawsize;
846
0
    }
847
0
  }
848
0
  return 0;
849
0
}
850
851
/******************************************************************************\
852
* Encoder constructor and destructor.
853
\******************************************************************************/
854
855
jpc_enc_t *jpc_enc_create(jpc_enc_cp_t *cp, jas_stream_t *out, jas_image_t *image)
856
0
{
857
0
  jpc_enc_t *enc;
858
859
0
  enc = 0;
860
861
0
  if (!(enc = jas_malloc(sizeof(jpc_enc_t)))) {
862
0
    goto error;
863
0
  }
864
865
0
  enc->image = image;
866
0
  enc->out = out;
867
0
  enc->cp = cp;
868
0
  enc->cstate = 0;
869
0
  enc->tmpstream = 0;
870
0
  enc->mrk = 0;
871
0
  enc->curtile = 0;
872
873
0
  if (!(enc->cstate = jpc_cstate_create())) {
874
0
    goto error;
875
0
  }
876
0
  enc->len = 0;
877
0
  enc->mainbodysize = 0;
878
879
0
  return enc;
880
881
0
error:
882
883
0
  if (enc) {
884
0
    jpc_enc_destroy(enc);
885
0
  }
886
0
  return 0;
887
0
}
888
889
void jpc_enc_destroy(jpc_enc_t *enc)
890
0
{
891
  /* The image object (i.e., enc->image) and output stream object
892
  (i.e., enc->out) are created outside of the encoder.
893
  Therefore, they must not be destroyed here. */
894
895
0
  if (enc->curtile) {
896
0
    jpc_enc_tile_destroy(enc->curtile);
897
0
  }
898
0
  if (enc->cp) {
899
0
    jpc_enc_cp_destroy(enc->cp);
900
0
  }
901
0
  if (enc->cstate) {
902
0
    jpc_cstate_destroy(enc->cstate);
903
0
  }
904
0
  if (enc->tmpstream) {
905
0
    jas_stream_close(enc->tmpstream);
906
0
  }
907
0
  if (enc->mrk) {
908
0
    jpc_ms_destroy(enc->mrk);
909
0
  }
910
911
0
  jas_free(enc);
912
0
}
913
914
/******************************************************************************\
915
* Code.
916
\******************************************************************************/
917
918
static int jpc_enc_encodemainhdr(jpc_enc_t *enc)
919
0
{
920
0
  jpc_siz_t *siz;
921
0
  jpc_cod_t *cod;
922
0
  jpc_qcd_t *qcd;
923
0
  int i;
924
0
  long startoff;
925
0
  long mainhdrlen;
926
0
  jpc_enc_cp_t *cp;
927
0
  jpc_qcc_t *qcc;
928
0
  jpc_enc_tccp_t *tccp;
929
0
  uint_fast16_t cmptno;
930
0
  jpc_tsfb_band_t bandinfos[JPC_MAXBANDS];
931
0
  jpc_enc_tcp_t *tcp;
932
0
  jpc_tsfb_t *tsfb;
933
0
  jpc_tsfb_band_t *bandinfo;
934
0
  uint_fast16_t numbands;
935
0
  uint_fast16_t bandno;
936
0
  uint_fast16_t rlvlno;
937
0
  uint_fast16_t analgain;
938
0
  jpc_fix_t absstepsize;
939
0
  char buf[1024];
940
0
  jpc_com_t *com;
941
942
0
  cp = enc->cp;
943
944
0
  startoff = jas_stream_getrwcount(enc->out);
945
946
  /* Write SOC marker segment. */
947
0
  if (!(enc->mrk = jpc_ms_create(JPC_MS_SOC))) {
948
0
    jas_logerrorf("cannot create SOC marker\n");
949
0
    return -1;
950
0
  }
951
0
  if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
952
0
    jas_logerrorf("cannot write SOC marker\n");
953
0
    return -1;
954
0
  }
955
0
  jpc_ms_destroy(enc->mrk);
956
0
  enc->mrk = 0;
957
958
  /* Write SIZ marker segment. */
959
0
  if (!(enc->mrk = jpc_ms_create(JPC_MS_SIZ))) {
960
0
    jas_logerrorf("cannot create SIZ marker\n");
961
0
    return -1;
962
0
  }
963
0
  siz = &enc->mrk->parms.siz;
964
0
  siz->caps = 0;
965
0
  siz->xoff = cp->imgareatlx;
966
0
  siz->yoff = cp->imgareatly;
967
0
  siz->width = cp->refgrdwidth;
968
0
  siz->height = cp->refgrdheight;
969
0
  siz->tilexoff = cp->tilegrdoffx;
970
0
  siz->tileyoff = cp->tilegrdoffy;
971
0
  siz->tilewidth = cp->tilewidth;
972
0
  siz->tileheight = cp->tileheight;
973
0
  siz->numcomps = cp->numcmpts;
974
0
  siz->comps = jas_alloc2(siz->numcomps, sizeof(jpc_sizcomp_t));
975
0
  assert(siz->comps);
976
0
  for (i = 0; i < JAS_CAST(int, cp->numcmpts); ++i) {
977
0
    siz->comps[i].prec = cp->ccps[i].prec;
978
0
    siz->comps[i].sgnd = cp->ccps[i].sgnd;
979
0
    siz->comps[i].hsamp = cp->ccps[i].sampgrdstepx;
980
0
    siz->comps[i].vsamp = cp->ccps[i].sampgrdstepy;
981
0
  }
982
0
  if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
983
0
    jas_logerrorf("cannot write SIZ marker\n");
984
0
    return -1;
985
0
  }
986
0
  jpc_ms_destroy(enc->mrk);
987
0
  enc->mrk = 0;
988
989
0
  if (!(enc->mrk = jpc_ms_create(JPC_MS_COM))) {
990
0
    jas_logerrorf("cannot create COM marker\n");
991
0
    return -1;
992
0
  }
993
0
  sprintf(buf, "Creator: JasPer Version %s", jas_getversion());
994
0
  com = &enc->mrk->parms.com;
995
0
  com->len = JAS_CAST(uint_fast16_t, strlen(buf));
996
0
  com->regid = JPC_COM_LATIN;
997
0
  if (!(com->data = JAS_CAST(jas_uchar *, jas_strdup(buf)))) {
998
0
    return -1;
999
0
  }
1000
0
  if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
1001
0
    jas_logerrorf("cannot write COM marker\n");
1002
0
    return -1;
1003
0
  }
1004
0
  jpc_ms_destroy(enc->mrk);
1005
0
  enc->mrk = 0;
1006
1007
#if 0
1008
  if (!(enc->mrk = jpc_ms_create(JPC_MS_CRG))) {
1009
    return -1;
1010
  }
1011
  crg = &enc->mrk->parms.crg;
1012
  crg->comps = jas_alloc2(crg->numcomps, sizeof(jpc_crgcomp_t));
1013
  if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
1014
    jas_logerrorf("cannot write CRG marker\n");
1015
    return -1;
1016
  }
1017
  jpc_ms_destroy(enc->mrk);
1018
  enc->mrk = 0;
1019
#endif
1020
1021
0
  tcp = &cp->tcp;
1022
0
  tccp = &cp->tccp;
1023
0
  for (cmptno = 0; cmptno < cp->numcmpts; ++cmptno) {
1024
0
    tsfb = jpc_cod_gettsfb(tccp->qmfbid, tccp->maxrlvls - 1);
1025
0
    jpc_tsfb_getbands(tsfb, 0, 0, 1 << tccp->maxrlvls, 1 << tccp->maxrlvls,
1026
0
      bandinfos);
1027
0
    jpc_tsfb_destroy(tsfb);
1028
0
    numbands = 3 * tccp->maxrlvls - 2;
1029
0
    for (bandno = 0, bandinfo = bandinfos; bandno < numbands;
1030
0
      ++bandno, ++bandinfo) {
1031
0
      rlvlno = (bandno) ? ((bandno - 1) / 3 + 1) : 0;
1032
0
      analgain = JPC_NOMINALGAIN(tccp->qmfbid, tccp->maxrlvls,
1033
0
        rlvlno, bandinfo->orient);
1034
0
      if (!tcp->intmode) {
1035
0
        absstepsize = jpc_fix_div(jpc_inttofix(1 <<
1036
0
          (analgain + 1)), bandinfo->synenergywt);
1037
0
      } else {
1038
0
        absstepsize = jpc_inttofix(1);
1039
0
      }  
1040
0
      const uint_fast32_t stepsize =
1041
0
        jpc_abstorelstepsize(absstepsize,
1042
0
        cp->ccps[cmptno].prec + analgain);
1043
0
      if (stepsize == UINT_FAST32_MAX)
1044
0
        return -1;
1045
0
      cp->ccps[cmptno].stepsizes[bandno] = stepsize;
1046
0
    }
1047
0
    cp->ccps[cmptno].numstepsizes = numbands;
1048
0
  }
1049
1050
0
  if (!(enc->mrk = jpc_ms_create(JPC_MS_COD))) {
1051
0
    jas_logerrorf("cannot create COD marker\n");
1052
0
    return -1;
1053
0
  }
1054
0
  cod = &enc->mrk->parms.cod;
1055
0
  cod->csty = cp->tccp.csty | cp->tcp.csty;
1056
0
  cod->compparms.csty = cp->tccp.csty | cp->tcp.csty;
1057
0
  cod->compparms.numdlvls = cp->tccp.maxrlvls - 1;
1058
0
  cod->compparms.numrlvls = cp->tccp.maxrlvls;
1059
0
  cod->prg = cp->tcp.prg;
1060
0
  cod->numlyrs = cp->tcp.numlyrs;
1061
0
  cod->compparms.cblkwidthval = JPC_COX_CBLKSIZEEXPN(cp->tccp.cblkwidthexpn);
1062
0
  cod->compparms.cblkheightval = JPC_COX_CBLKSIZEEXPN(cp->tccp.cblkheightexpn);
1063
0
  cod->compparms.cblksty = cp->tccp.cblksty;
1064
0
  cod->compparms.qmfbid = cp->tccp.qmfbid;
1065
0
  cod->mctrans = (cp->tcp.mctid != JPC_MCT_NONE);
1066
0
  if (tccp->csty & JPC_COX_PRT) {
1067
0
    for (rlvlno = 0; rlvlno < tccp->maxrlvls; ++rlvlno) {
1068
0
      cod->compparms.rlvls[rlvlno].parwidthval = tccp->prcwidthexpns[rlvlno];
1069
0
      cod->compparms.rlvls[rlvlno].parheightval = tccp->prcheightexpns[rlvlno];
1070
0
    }
1071
0
  }
1072
0
  if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
1073
0
    jas_logerrorf("cannot write COD marker\n");
1074
0
    return -1;
1075
0
  }
1076
0
  jpc_ms_destroy(enc->mrk);
1077
0
  enc->mrk = 0;
1078
1079
0
  if (!(enc->mrk = jpc_ms_create(JPC_MS_QCD))) {
1080
0
    jas_logerrorf("cannot create QCD marker\n");
1081
0
    return -1;
1082
0
  }
1083
0
  qcd = &enc->mrk->parms.qcd;
1084
0
  qcd->compparms.qntsty = (tccp->qmfbid == JPC_COX_INS) ?
1085
0
    JPC_QCX_SEQNT : JPC_QCX_NOQNT;
1086
0
  qcd->compparms.numstepsizes = cp->ccps[0].numstepsizes;
1087
0
  qcd->compparms.numguard = cp->tccp.numgbits;
1088
0
  qcd->compparms.stepsizes = cp->ccps[0].stepsizes;
1089
0
  if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
1090
0
    jas_logerrorf("cannot write marker\n");
1091
0
    return -1;
1092
0
  }
1093
  /* We do not want the step size array to be freed! */
1094
0
  qcd->compparms.stepsizes = 0;
1095
0
  jpc_ms_destroy(enc->mrk);
1096
0
  enc->mrk = 0;
1097
1098
0
  tccp = &cp->tccp;
1099
0
  for (cmptno = 1; cmptno < cp->numcmpts; ++cmptno) {
1100
0
    if (!(enc->mrk = jpc_ms_create(JPC_MS_QCC))) {
1101
0
      jas_logerrorf("cannot create QCC marker\n");
1102
0
      return -1;
1103
0
    }
1104
0
    qcc = &enc->mrk->parms.qcc;
1105
0
    qcc->compno = cmptno;
1106
0
    qcc->compparms.qntsty = (tccp->qmfbid == JPC_COX_INS) ?
1107
0
      JPC_QCX_SEQNT : JPC_QCX_NOQNT;
1108
0
    qcc->compparms.numstepsizes = cp->ccps[cmptno].numstepsizes;
1109
0
    qcc->compparms.numguard = cp->tccp.numgbits;
1110
0
    qcc->compparms.stepsizes = cp->ccps[cmptno].stepsizes;
1111
0
    if (jpc_putms(enc->out, enc->cstate, enc->mrk)) {
1112
0
      jas_logerrorf("cannot write marker\n");
1113
0
      return -1;
1114
0
    }
1115
    /* We do not want the step size array to be freed! */
1116
0
    qcc->compparms.stepsizes = 0;
1117
0
    jpc_ms_destroy(enc->mrk);
1118
0
    enc->mrk = 0;
1119
0
  }
1120
1121
0
#define MAINTLRLEN  2
1122
0
  mainhdrlen = jas_stream_getrwcount(enc->out) - startoff;
1123
0
  enc->len += mainhdrlen;
1124
0
  if (enc->cp->totalsize != UINT_FAST32_MAX) {
1125
0
    uint_fast32_t overhead;
1126
0
    overhead = mainhdrlen + MAINTLRLEN;
1127
0
    enc->mainbodysize = (enc->cp->totalsize >= overhead) ?
1128
0
      (enc->cp->totalsize - overhead) : 0;
1129
0
  } else {
1130
0
    enc->mainbodysize = UINT_FAST32_MAX;
1131
0
  }
1132
1133
0
  return 0;
1134
0
}
1135
1136
static int jpc_enc_encodemainbody(jpc_enc_t *enc)
1137
0
{
1138
0
  int tileno;
1139
0
  jpc_sot_t *sot;
1140
0
  jpc_enc_tcmpt_t *comp;
1141
0
  jpc_enc_tcmpt_t *endcomps;
1142
0
  jpc_enc_band_t *band;
1143
0
  jpc_enc_band_t *endbands;
1144
0
  jpc_enc_rlvl_t *lvl;
1145
0
  unsigned rlvlno;
1146
0
  jpc_qcc_t *qcc;
1147
0
  jpc_cod_t *cod;
1148
0
  int adjust;
1149
0
  int absbandno;
1150
0
  long tilehdrlen;
1151
0
  long tilelen;
1152
0
  jpc_enc_tile_t *tile;
1153
0
  jpc_enc_cp_t *cp;
1154
0
  double rho;
1155
0
  unsigned cmptno;
1156
0
  int samestepsizes;
1157
0
  jpc_enc_ccp_t *ccps;
1158
0
  jpc_enc_tccp_t *tccp;
1159
0
  int bandno;
1160
0
  int mingbits;
1161
0
  int actualnumbps;
1162
0
  jpc_fix_t mxmag;
1163
0
  jpc_fix_t mag;
1164
0
  int numgbits;
1165
1166
0
  cp = enc->cp;
1167
1168
0
  for (tileno = 0; tileno < JAS_CAST(int, cp->numtiles); ++tileno) {
1169
0
    if (!(enc->curtile = jpc_enc_tile_create(enc->cp, enc->image,
1170
0
      tileno))) {
1171
0
      jas_logerrorf("cannot create tile\n");
1172
0
      return -1;
1173
0
    }
1174
1175
0
    tile = enc->curtile;
1176
1177
0
    if (jas_get_debug_level() >= 10) {
1178
0
      jpc_enc_dump(enc);
1179
0
    }
1180
1181
0
    endcomps = &tile->tcmpts[tile->numtcmpts];
1182
0
    for (cmptno = 0, comp = tile->tcmpts; cmptno < tile->numtcmpts; ++cmptno, ++comp) {
1183
0
      if (!cp->ccps[cmptno].sgnd) {
1184
0
        adjust = 1 << (cp->ccps[cmptno].prec - 1);
1185
0
        for (jas_matind_t i = 0; i < jas_matrix_numrows(comp->data); ++i) {
1186
0
          for (jas_matind_t j = 0; j < jas_matrix_numcols(comp->data); ++j) {
1187
0
            *jas_matrix_getref(comp->data, i, j) -= adjust;
1188
0
          }
1189
0
        }
1190
0
      }
1191
0
    }
1192
1193
0
    if (!tile->intmode) {
1194
0
        endcomps = &tile->tcmpts[tile->numtcmpts];
1195
0
        for (comp = tile->tcmpts; comp != endcomps; ++comp) {
1196
0
          jas_matrix_asl(comp->data, JPC_FIX_FRACBITS);
1197
0
        }
1198
0
    }
1199
1200
0
    switch (tile->mctid) {
1201
0
    case JPC_MCT_RCT:
1202
0
assert(jas_image_numcmpts(enc->image) == 3);
1203
0
      jpc_rct(tile->tcmpts[0].data, tile->tcmpts[1].data,
1204
0
        tile->tcmpts[2].data);
1205
0
      break;
1206
0
    case JPC_MCT_ICT:
1207
0
assert(jas_image_numcmpts(enc->image) == 3);
1208
0
      jpc_ict(tile->tcmpts[0].data, tile->tcmpts[1].data,
1209
0
        tile->tcmpts[2].data);
1210
0
      break;
1211
0
    default:
1212
0
      break;
1213
0
    }
1214
1215
0
    for (unsigned  i = 0; i < jas_image_numcmpts(enc->image); ++i) {
1216
0
      comp = &tile->tcmpts[i];
1217
0
      jpc_tsfb_analyze(comp->tsfb, comp->data);
1218
1219
0
    }
1220
1221
1222
0
    endcomps = &tile->tcmpts[tile->numtcmpts];
1223
0
    for (cmptno = 0, comp = tile->tcmpts; comp != endcomps; ++cmptno, ++comp) {
1224
0
      mingbits = 0;
1225
0
      absbandno = 0;
1226
      /* All bands must have a corresponding quantizer step size,
1227
        even if they contain no samples and are never coded. */
1228
      /* Some bands may not be hit by the loop below, so we must
1229
        initialize all of the step sizes to a sane value. */
1230
0
      memset(comp->stepsizes, 0, sizeof(comp->stepsizes));
1231
0
      for (rlvlno = 0, lvl = comp->rlvls; rlvlno < comp->numrlvls; ++rlvlno, ++lvl) {
1232
0
        if (!lvl->bands) {
1233
0
          absbandno += rlvlno ? 3 : 1;
1234
0
          continue;
1235
0
        }
1236
0
        endbands = &lvl->bands[lvl->numbands];
1237
0
        for (band = lvl->bands; band != endbands; ++band) {
1238
0
          if (!band->data) {
1239
0
            ++absbandno;
1240
0
            continue;
1241
0
          }
1242
0
          actualnumbps = 0;
1243
0
          mxmag = 0;
1244
0
          for (jas_matind_t y = 0; y < jas_matrix_numrows(band->data); ++y) {
1245
0
            for (jas_matind_t x = 0; x < jas_matrix_numcols(band->data); ++x) {
1246
0
              mag = JAS_ABS(jas_matrix_get(band->data, y, x));
1247
0
              if (mag > mxmag) {
1248
0
                mxmag = mag;
1249
0
              }
1250
0
            }
1251
0
          }
1252
0
          if (tile->intmode) {
1253
0
            actualnumbps = jpc_fix_firstone(mxmag) + 1;
1254
0
          } else {
1255
0
            actualnumbps = jpc_fix_firstone(mxmag) + 1 - JPC_FIX_FRACBITS;
1256
0
          }
1257
0
          numgbits = actualnumbps - (cp->ccps[cmptno].prec - 1 +
1258
0
            band->analgain);
1259
#if 0
1260
          jas_eprintf("%d %d mag=%d actual=%d numgbits=%d\n",
1261
            cp->ccps[cmptno].prec, band->analgain, mxmag,
1262
            actualnumbps, numgbits);
1263
#endif
1264
0
          if (numgbits > mingbits) {
1265
0
            mingbits = numgbits;
1266
0
          }
1267
0
          if (!tile->intmode) {
1268
0
            band->absstepsize = jpc_fix_div(jpc_inttofix(1
1269
0
              << (band->analgain + 1)),
1270
0
              band->synweight);
1271
0
          } else {
1272
0
            band->absstepsize = jpc_inttofix(1);
1273
0
          }
1274
0
          const uint_fast32_t stepsize = jpc_abstorelstepsize(
1275
0
            band->absstepsize, cp->ccps[cmptno].prec +
1276
0
            band->analgain);
1277
0
          if (stepsize == UINT_FAST32_MAX)
1278
0
            return -1;
1279
0
          band->stepsize = stepsize;
1280
0
          band->numbps = cp->tccp.numgbits +
1281
0
            JPC_QCX_GETEXPN(band->stepsize) - 1;
1282
1283
0
          if ((!tile->intmode) && band->data) {
1284
0
            jpc_quantize(band->data, band->absstepsize);
1285
0
          }
1286
1287
0
          comp->stepsizes[absbandno] = band->stepsize;
1288
0
          ++absbandno;
1289
0
        }
1290
0
      }
1291
1292
0
      assert(JPC_FIX_FRACBITS >= JPC_NUMEXTRABITS);
1293
0
      if (!tile->intmode) {
1294
0
        jas_matrix_divpow2(comp->data, JPC_FIX_FRACBITS - JPC_NUMEXTRABITS);
1295
0
      } else {
1296
0
        jas_matrix_asl(comp->data, JPC_NUMEXTRABITS);
1297
0
      }
1298
1299
#if 0
1300
      jas_eprintf("numgbits %d mingbits %d\n", cp->tccp.numgbits,
1301
        mingbits);
1302
#endif
1303
0
      if (mingbits > cp->tccp.numgbits) {
1304
0
        jas_logerrorf("error: too few guard bits (%d < %d)\n",
1305
0
          cp->tccp.numgbits, mingbits);
1306
0
        return -1;
1307
0
      }
1308
0
    }
1309
1310
0
    if (!(enc->tmpstream = jas_stream_memopen(0, 0))) {
1311
0
      jas_logerrorf("cannot open tmp file\n");
1312
0
      return -1;
1313
0
    }
1314
1315
    /* Write the tile header. */
1316
0
    if (!(enc->mrk = jpc_ms_create(JPC_MS_SOT))) {
1317
0
      return -1;
1318
0
    }
1319
0
    sot = &enc->mrk->parms.sot;
1320
0
    sot->len = 0;
1321
0
    sot->tileno = tileno;
1322
0
    sot->partno = 0;
1323
0
    sot->numparts = 1;
1324
0
    if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) {
1325
0
      jas_logerrorf("cannot write SOT marker\n");
1326
0
      return -1;
1327
0
    }
1328
0
    jpc_ms_destroy(enc->mrk);
1329
0
    enc->mrk = 0;
1330
1331
/************************************************************************/
1332
/************************************************************************/
1333
/************************************************************************/
1334
1335
0
    tccp = &cp->tccp;
1336
0
    for (cmptno = 0; cmptno < cp->numcmpts; ++cmptno) {
1337
0
      comp = &tile->tcmpts[cmptno];
1338
0
      if (comp->numrlvls != tccp->maxrlvls) {
1339
0
        if (!(enc->mrk = jpc_ms_create(JPC_MS_COD))) {
1340
0
          return -1;
1341
0
        }
1342
/* XXX = this is not really correct. we are using comp #0's precint sizes
1343
and other characteristics */
1344
0
        comp = &tile->tcmpts[0];
1345
0
        cod = &enc->mrk->parms.cod;
1346
0
        cod->compparms.csty = 0;
1347
0
        cod->compparms.numdlvls = comp->numrlvls - 1;
1348
0
        cod->prg = tile->prg;
1349
0
        cod->numlyrs = tile->numlyrs;
1350
0
        cod->compparms.cblkwidthval = JPC_COX_CBLKSIZEEXPN(comp->cblkwidthexpn);
1351
0
        cod->compparms.cblkheightval = JPC_COX_CBLKSIZEEXPN(comp->cblkheightexpn);
1352
0
        cod->compparms.cblksty = comp->cblksty;
1353
0
        cod->compparms.qmfbid = comp->qmfbid;
1354
0
        cod->mctrans = (tile->mctid != JPC_MCT_NONE);
1355
0
        for (unsigned i = 0; i < comp->numrlvls; ++i) {
1356
0
          cod->compparms.rlvls[i].parwidthval = comp->rlvls[i].prcwidthexpn;
1357
0
          cod->compparms.rlvls[i].parheightval = comp->rlvls[i].prcheightexpn;
1358
0
        }
1359
0
        if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) {
1360
0
          return -1;
1361
0
        }
1362
0
        jpc_ms_destroy(enc->mrk);
1363
0
        enc->mrk = 0;
1364
0
      }
1365
0
    }
1366
1367
0
    for (cmptno = 0, comp = tile->tcmpts; cmptno < cp->numcmpts; ++cmptno, ++comp) {
1368
0
      ccps = &cp->ccps[cmptno];
1369
0
      if (JAS_CAST(int, ccps->numstepsizes) == comp->numstepsizes) {
1370
0
        samestepsizes = 1;
1371
0
        for (bandno = 0; bandno < JAS_CAST(int, ccps->numstepsizes);
1372
0
          ++bandno) {
1373
0
          if (ccps->stepsizes[bandno] != comp->stepsizes[bandno]) {
1374
0
            samestepsizes = 0;
1375
0
            break;
1376
0
          }
1377
0
        }
1378
0
      } else {
1379
0
        samestepsizes = 0;
1380
0
      }
1381
0
      if (!samestepsizes) {
1382
0
        if (!(enc->mrk = jpc_ms_create(JPC_MS_QCC))) {
1383
0
          return -1;
1384
0
        }
1385
0
        qcc = &enc->mrk->parms.qcc;
1386
0
        qcc->compno = cmptno;
1387
0
        qcc->compparms.numguard = cp->tccp.numgbits;
1388
0
        qcc->compparms.qntsty = (comp->qmfbid == JPC_COX_INS) ?
1389
0
          JPC_QCX_SEQNT : JPC_QCX_NOQNT;
1390
0
        qcc->compparms.numstepsizes = comp->numstepsizes;
1391
0
        qcc->compparms.stepsizes = comp->stepsizes;
1392
0
        if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) {
1393
0
          return -1;
1394
0
        }
1395
0
        qcc->compparms.stepsizes = 0;
1396
0
        jpc_ms_destroy(enc->mrk);
1397
0
        enc->mrk = 0;
1398
0
      }
1399
0
    }
1400
1401
    /* Write a SOD marker to indicate the end of the tile header. */
1402
0
    if (!(enc->mrk = jpc_ms_create(JPC_MS_SOD))) {
1403
0
      return -1;
1404
0
    }
1405
0
    if (jpc_putms(enc->tmpstream, enc->cstate, enc->mrk)) {
1406
0
      jas_logerrorf("cannot write SOD marker\n");
1407
0
      return -1;
1408
0
    }
1409
0
    jpc_ms_destroy(enc->mrk);
1410
0
    enc->mrk = 0;
1411
0
    tilehdrlen = jas_stream_getrwcount(enc->tmpstream);
1412
0
    assert(tilehdrlen >= 0);
1413
1414
/************************************************************************/
1415
/************************************************************************/
1416
/************************************************************************/
1417
1418
0
    if (jpc_enc_enccblks(enc)) {
1419
0
      return -1;
1420
0
    }
1421
1422
0
    cp = enc->cp;
1423
0
    rho = (double) (tile->brx - tile->tlx) * (tile->bry - tile->tly) /
1424
0
      ((cp->refgrdwidth - cp->imgareatlx) * (cp->refgrdheight -
1425
0
      cp->imgareatly));
1426
0
    tile->rawsize = cp->rawsize * rho;
1427
1428
0
    for (unsigned lyrno = 0; lyrno < tile->numlyrs - 1; ++lyrno) {
1429
0
      tile->lyrsizes[lyrno] = tile->rawsize * jpc_fixtodbl(
1430
0
        cp->tcp.ilyrrates[lyrno]);
1431
0
    }
1432
1433
0
    if (cp->totalsize != UINT_FAST32_MAX) {
1434
0
      tile->lyrsizes[tile->numlyrs - 1] = (rho * enc->mainbodysize);
1435
0
    } else {
1436
0
      tile->lyrsizes[tile->numlyrs - 1] = UINT_FAST32_MAX;
1437
0
    }
1438
1439
#if 0
1440
    jas_eprintf("TESTING %ld %ld\n", cp->totalsize != UINT_FAST32_MAX,
1441
      tile->lyrsizes[0]);
1442
#endif
1443
0
    for (unsigned lyrno = 0; lyrno < tile->numlyrs; ++lyrno) {
1444
0
      if (tile->lyrsizes[lyrno] != UINT_FAST32_MAX) {
1445
0
        if (JAS_CAST(uint_fast32_t, tilehdrlen) <= tile->lyrsizes[lyrno]) {
1446
0
          tile->lyrsizes[lyrno] -= tilehdrlen;
1447
0
        } else {
1448
0
          tile->lyrsizes[lyrno] = 0;
1449
0
        }
1450
0
      }
1451
0
    }
1452
1453
0
    if (rateallocate(enc, tile->numlyrs, tile->lyrsizes)) {
1454
0
      return -1;
1455
0
    }
1456
1457
#if 0
1458
    jas_eprintf("ENCODE TILE DATA\n");
1459
#endif
1460
0
    if (jpc_enc_encodetiledata(enc)) {
1461
0
      jas_logerrorf("dotile failed\n");
1462
0
      return -1;
1463
0
    }
1464
1465
/************************************************************************/
1466
/************************************************************************/
1467
/************************************************************************/
1468
1469
/************************************************************************/
1470
/************************************************************************/
1471
/************************************************************************/
1472
1473
0
    tilelen = jas_stream_tell(enc->tmpstream);
1474
1475
0
    if (jas_stream_seek(enc->tmpstream, 6, SEEK_SET) < 0) {
1476
0
      return -1;
1477
0
    }
1478
0
    jpc_putuint32(enc->tmpstream, tilelen);
1479
1480
0
    if (jas_stream_seek(enc->tmpstream, 0, SEEK_SET) < 0) {
1481
0
      return -1;
1482
0
    }
1483
0
    if (jpc_putdata(enc->out, enc->tmpstream, -1)) {
1484
0
      return -1;
1485
0
    }
1486
0
    enc->len += tilelen;
1487
1488
0
    jas_stream_close(enc->tmpstream);
1489
0
    enc->tmpstream = 0;
1490
1491
0
    jpc_enc_tile_destroy(enc->curtile);
1492
0
    enc->curtile = 0;
1493
1494
0
  }
1495
1496
0
  return 0;
1497
0
}
1498
1499
int jpc_enc_encodetiledata(jpc_enc_t *enc)
1500
0
{
1501
0
assert(enc->tmpstream);
1502
0
  if (jpc_enc_encpkts(enc, enc->tmpstream)) {
1503
0
    return -1;
1504
0
  }
1505
0
  return 0;
1506
0
}
1507
1508
void jpc_quantize(jas_matrix_t *data, jpc_fix_t stepsize)
1509
0
{
1510
0
  jpc_fix_t t;
1511
1512
0
  if (stepsize == jpc_inttofix(1)) {
1513
0
    return;
1514
0
  }
1515
1516
0
  for (jas_matind_t i = 0; i < jas_matrix_numrows(data); ++i) {
1517
0
    for (jas_matind_t j = 0; j < jas_matrix_numcols(data); ++j) {
1518
0
      t = jas_matrix_get(data, i, j);
1519
1520
0
{
1521
0
  if (t < 0) {
1522
0
    t = jpc_fix_neg(jpc_fix_div(jpc_fix_neg(t), stepsize));
1523
0
  } else {
1524
0
    t = jpc_fix_div(t, stepsize);
1525
0
  }
1526
0
}
1527
1528
0
      jas_matrix_set(data, i, j, t);
1529
0
    }
1530
0
  }
1531
0
}
1532
1533
void calcrdslopes(jpc_enc_cblk_t *cblk)
1534
0
{
1535
0
  jpc_enc_pass_t *endpasses;
1536
0
  jpc_enc_pass_t *pass0;
1537
0
  jpc_enc_pass_t *pass1;
1538
0
  jpc_enc_pass_t *pass2;
1539
0
  jpc_flt_t slope0;
1540
0
  jpc_flt_t slope;
1541
0
  jpc_flt_t dd;
1542
0
  long dr;
1543
1544
0
  endpasses = &cblk->passes[cblk->numpasses];
1545
0
  pass2 = cblk->passes;
1546
0
  slope0 = 0;
1547
0
  while (pass2 != endpasses) {
1548
0
    pass0 = 0;
1549
0
    for (pass1 = cblk->passes; pass1 != endpasses; ++pass1) {
1550
0
      dd = pass1->cumwmsedec;
1551
0
      dr = pass1->end;
1552
0
      if (pass0) {
1553
0
        dd -= pass0->cumwmsedec;
1554
0
        dr -= pass0->end;
1555
0
      }
1556
0
      if (dd <= 0) {
1557
0
        pass1->rdslope = JPC_BADRDSLOPE;
1558
0
        if (pass1 >= pass2) {
1559
0
          pass2 = &pass1[1];
1560
0
        }
1561
0
        continue;
1562
0
      }
1563
0
      if (pass1 < pass2 && pass1->rdslope <= 0) {
1564
0
        continue;
1565
0
      }
1566
0
      if (!dr) {
1567
0
        assert(pass0);
1568
0
        pass0->rdslope = 0;
1569
0
        break;
1570
0
      }
1571
0
      slope = dd / dr;
1572
0
      if (pass0 && slope >= slope0) {
1573
0
        pass0->rdslope = 0;
1574
0
        break;
1575
0
      }
1576
0
      pass1->rdslope = slope;
1577
0
      if (pass1 >= pass2) {
1578
0
        pass2 = &pass1[1];
1579
0
      }
1580
0
      pass0 = pass1;
1581
0
      slope0 = slope;
1582
0
    }
1583
0
  }
1584
1585
#if 0
1586
  for (pass0 = cblk->passes; pass0 != endpasses; ++pass0) {
1587
if (pass0->rdslope > 0.0) {
1588
    jas_eprintf("pass %02d nmsedec=%lf dec=%lf end=%d %lf\n", pass0 - cblk->passes,
1589
      fixtodbl(pass0->nmsedec), pass0->wmsedec, pass0->end, pass0->rdslope);
1590
}
1591
  }
1592
#endif
1593
0
}
1594
1595
void dump_layeringinfo(jpc_enc_t *enc)
1596
0
{
1597
1598
0
  jpc_enc_tcmpt_t *tcmpt;
1599
0
  unsigned tcmptno;
1600
0
  jpc_enc_rlvl_t *rlvl;
1601
0
  unsigned rlvlno;
1602
0
  jpc_enc_band_t *band;
1603
0
  unsigned bandno;
1604
0
  jpc_enc_prc_t *prc;
1605
0
  unsigned prcno;
1606
0
  jpc_enc_cblk_t *cblk;
1607
0
  unsigned cblkno;
1608
0
  jpc_enc_pass_t *pass;
1609
0
  unsigned passno;
1610
0
  jpc_enc_tile_t *tile;
1611
1612
0
  tile = enc->curtile;
1613
1614
0
  for (unsigned lyrno = 0; lyrno < tile->numlyrs; ++lyrno) {
1615
0
    jas_loginfof("lyrno = %02u\n", lyrno);
1616
0
    for (tcmptno = 0, tcmpt = tile->tcmpts; tcmptno < tile->numtcmpts;
1617
0
      ++tcmptno, ++tcmpt) {
1618
0
      for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
1619
0
        ++rlvlno, ++rlvl) {
1620
0
        if (!rlvl->bands) {
1621
0
          continue;
1622
0
        }
1623
0
        for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
1624
0
          ++bandno, ++band) {
1625
0
          if (!band->data) {
1626
0
            continue;
1627
0
          }
1628
0
          for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs;
1629
0
            ++prcno, ++prc) {
1630
0
            if (!prc->cblks) {
1631
0
              continue;
1632
0
            }
1633
0
            for (cblkno = 0, cblk = prc->cblks; cblkno <
1634
0
              prc->numcblks; ++cblkno, ++cblk) {
1635
0
              for (passno = 0, pass = cblk->passes; passno <
1636
0
                cblk->numpasses && pass->lyrno == lyrno;
1637
0
                ++passno, ++pass) {
1638
0
                jas_loginfof("lyrno=%02d cmptno=%02d rlvlno=%02d bandno=%02d prcno=%02d cblkno=%03d passno=%03d\n",
1639
0
                  lyrno, tcmptno, rlvlno, bandno, prcno,
1640
0
                  cblkno, passno);
1641
0
              }
1642
0
            }
1643
0
          }
1644
0
        }
1645
0
      }
1646
0
    }
1647
0
  }
1648
0
}
1649
1650
int rateallocate(jpc_enc_t *enc, unsigned numlyrs, uint_fast32_t *cumlens)
1651
0
{
1652
0
  int ret = 0;
1653
0
  jpc_flt_t lo;
1654
0
  jpc_flt_t hi;
1655
0
  jas_stream_t *out = 0;
1656
0
  uint_fast32_t cumlen;
1657
0
  jpc_flt_t thresh;
1658
0
  jpc_flt_t goodthresh;
1659
0
  int success;
1660
0
  long pos;
1661
0
  long oldpos;
1662
0
  int numiters;
1663
1664
0
  jpc_enc_tcmpt_t *comp;
1665
0
  jpc_enc_tcmpt_t *endcomps;
1666
0
  jpc_enc_rlvl_t *lvl;
1667
0
  jpc_enc_rlvl_t *endlvls;
1668
0
  jpc_enc_band_t *band;
1669
0
  jpc_enc_band_t *endbands;
1670
0
  jpc_enc_cblk_t *cblk;
1671
0
  jpc_enc_cblk_t *endcblks;
1672
0
  jpc_enc_pass_t *pass;
1673
0
  jpc_enc_pass_t *endpasses;
1674
0
  jpc_enc_pass_t *pass1;
1675
0
  jpc_flt_t mxrdslope;
1676
0
  jpc_flt_t mnrdslope;
1677
0
  jpc_enc_tile_t *tile;
1678
0
  jpc_enc_prc_t *prc;
1679
0
  unsigned prcno;
1680
1681
0
  JAS_LOGDEBUGF(10, "starting rate allocation\n");
1682
1683
0
  tile = enc->curtile;
1684
1685
0
  for (unsigned lyrno = 1; lyrno < numlyrs - 1; ++lyrno) {
1686
0
    assert(cumlens[lyrno - 1] <= cumlens[lyrno]);
1687
0
  }
1688
1689
0
  if (!(out = jas_stream_memopen(0, 0))) {
1690
0
    ret = -1;
1691
0
    goto done;
1692
0
  }
1693
1694
  /* Find minimum and maximum R-D slope values. */
1695
0
  mnrdslope = DBL_MAX;
1696
0
  mxrdslope = 0;
1697
0
  endcomps = &tile->tcmpts[tile->numtcmpts];
1698
0
  for (comp = tile->tcmpts; comp != endcomps; ++comp) {
1699
0
    endlvls = &comp->rlvls[comp->numrlvls];
1700
0
    for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
1701
0
      if (!lvl->bands) {
1702
0
        continue;
1703
0
      }
1704
0
      endbands = &lvl->bands[lvl->numbands];
1705
0
      for (band = lvl->bands; band != endbands; ++band) {
1706
0
        if (!band->data) {
1707
0
          continue;
1708
0
        }
1709
0
        for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs;
1710
0
          ++prcno, ++prc) {
1711
0
          if (!prc->cblks) {
1712
0
            continue;
1713
0
          }
1714
0
          endcblks = &prc->cblks[prc->numcblks];
1715
0
          for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
1716
0
            calcrdslopes(cblk);
1717
0
            endpasses = &cblk->passes[cblk->numpasses];
1718
0
            for (pass = cblk->passes; pass != endpasses; ++pass) {
1719
0
              if (pass->rdslope > 0) {
1720
0
                if (pass->rdslope < mnrdslope) {
1721
0
                  mnrdslope = pass->rdslope;
1722
0
                }
1723
0
                if (pass->rdslope > mxrdslope) {
1724
0
                  mxrdslope = pass->rdslope;
1725
0
                }
1726
0
              }
1727
0
            }
1728
0
          }
1729
0
        }
1730
0
      }
1731
0
    }
1732
0
  }
1733
0
  JAS_LOGDEBUGF(10, "min rdslope = %f max rdslope = %f\n", mnrdslope,
1734
0
    mxrdslope);
1735
1736
0
  jpc_init_t2state(enc, true);
1737
1738
0
  for (unsigned lyrno = 0; lyrno < numlyrs; ++lyrno) {
1739
1740
0
    lo = mnrdslope;
1741
0
    hi = mxrdslope;
1742
1743
0
    success = 0;
1744
0
    goodthresh = 0;
1745
0
    numiters = 0;
1746
1747
0
    do {
1748
1749
0
      cumlen = cumlens[lyrno];
1750
0
      if (cumlen == UINT_FAST32_MAX) {
1751
        /* Only the last layer can be free of a rate
1752
          constraint (e.g., for lossless coding). */
1753
0
        assert(lyrno == numlyrs - 1);
1754
0
        goodthresh = -1;
1755
0
        success = 1;
1756
0
        break;
1757
0
      }
1758
1759
0
      thresh = (lo + hi) / 2;
1760
1761
      /* Save the tier 2 coding state. */
1762
0
      jpc_save_t2state(enc);
1763
0
      oldpos = jas_stream_tell(out);
1764
0
      assert(oldpos >= 0);
1765
1766
      /* Assign all passes with R-D slopes greater than or
1767
        equal to the current threshold to this layer. */
1768
0
      endcomps = &tile->tcmpts[tile->numtcmpts];
1769
0
      for (comp = tile->tcmpts; comp != endcomps; ++comp) {
1770
0
        endlvls = &comp->rlvls[comp->numrlvls];
1771
0
        for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
1772
0
          if (!lvl->bands) {
1773
0
            continue;
1774
0
          }
1775
0
          endbands = &lvl->bands[lvl->numbands];
1776
0
          for (band = lvl->bands; band != endbands; ++band) {
1777
0
            if (!band->data) {
1778
0
              continue;
1779
0
            }
1780
0
            for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs;
1781
0
              ++prcno, ++prc) {
1782
0
              if (!prc->cblks) {
1783
0
                continue;
1784
0
              }
1785
0
              endcblks = &prc->cblks[prc->numcblks];
1786
0
              for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
1787
0
                if (cblk->curpass) {
1788
0
                  endpasses = &cblk->passes[cblk->numpasses];
1789
0
                  pass1 = cblk->curpass;
1790
0
                  for (pass = cblk->curpass; pass !=
1791
0
                    endpasses; ++pass) {
1792
0
                    if (pass->rdslope >= thresh) {
1793
0
                      pass1 = &pass[1];
1794
0
                    }
1795
0
                  }
1796
0
                  for (pass = cblk->curpass; pass != pass1;
1797
0
                    ++pass) {
1798
0
                    pass->lyrno = lyrno;
1799
0
                  }
1800
0
                  for (; pass != endpasses; ++pass) {
1801
0
                    pass->lyrno = -1;
1802
0
                  }
1803
0
                }
1804
0
              }
1805
0
            }
1806
0
          }
1807
0
        }
1808
0
      }
1809
1810
      /* Perform tier 2 coding. */
1811
0
      endcomps = &tile->tcmpts[tile->numtcmpts];
1812
0
      for (comp = tile->tcmpts; comp != endcomps; ++comp) {
1813
0
        endlvls = &comp->rlvls[comp->numrlvls];
1814
0
        for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
1815
0
          if (!lvl->bands) {
1816
0
            continue;
1817
0
          }
1818
0
          for (prcno = 0; prcno < lvl->numprcs; ++prcno) {
1819
0
            if (jpc_enc_encpkt(enc, out, comp - tile->tcmpts,
1820
0
              lvl - comp->rlvls, prcno, lyrno)) {
1821
0
              ret = -1;
1822
0
              goto done;
1823
0
            }
1824
0
          }
1825
0
        }
1826
0
      }
1827
1828
0
      pos = jas_stream_tell(out);
1829
1830
      /* Check the rate constraint. */
1831
0
      assert(pos >= 0);
1832
0
      if ((uint_fast32_t)pos > cumlen) {
1833
        /* The rate is too high. */
1834
0
        lo = thresh;
1835
0
      } else if ((uint_fast32_t)pos <= cumlen) {
1836
        /* The rate is low enough, so try higher. */
1837
0
        hi = thresh;
1838
0
        if (!success || thresh < goodthresh) {
1839
0
          goodthresh = thresh;
1840
0
          success = 1;
1841
0
        }
1842
0
      }
1843
1844
      /* Save the tier 2 coding state. */
1845
0
      jpc_restore_t2state(enc);
1846
0
      if (jas_stream_seek(out, oldpos, SEEK_SET) < 0) {
1847
0
        ret = -1;
1848
0
        goto done;
1849
0
      }
1850
1851
0
      JAS_LOGDEBUGF(10, "maxlen=%08ld actuallen=%08ld thresh=%f\n",
1852
0
        cumlen, pos, thresh);
1853
1854
0
      ++numiters;
1855
0
    } while (lo < hi - 1e-3 && numiters < 32);
1856
1857
0
    if (!success) {
1858
0
      jas_logwarnf("warning: empty layer generated\n");
1859
0
    }
1860
1861
0
    JAS_LOGDEBUGF(10, "success %d goodthresh %f\n", success, goodthresh);
1862
1863
    /* Assign all passes with R-D slopes greater than or
1864
      equal to the selected threshold to this layer. */
1865
0
    endcomps = &tile->tcmpts[tile->numtcmpts];
1866
0
    for (comp = tile->tcmpts; comp != endcomps; ++comp) {
1867
0
      endlvls = &comp->rlvls[comp->numrlvls];
1868
0
      for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
1869
0
        if (!lvl->bands) {
1870
0
          continue;
1871
0
        }
1872
0
        endbands = &lvl->bands[lvl->numbands];
1873
0
        for (band = lvl->bands; band != endbands; ++band) {
1874
0
          if (!band->data) {
1875
0
            continue;
1876
0
          }
1877
0
          for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs;
1878
0
            ++prcno, ++prc) {
1879
0
            if (!prc->cblks) {
1880
0
              continue;
1881
0
            }
1882
0
            endcblks = &prc->cblks[prc->numcblks];
1883
0
            for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
1884
0
              if (cblk->curpass) {
1885
0
                endpasses = &cblk->passes[cblk->numpasses];
1886
0
                pass1 = cblk->curpass;
1887
0
                if (success) {
1888
0
                  for (pass = cblk->curpass; pass !=
1889
0
                    endpasses; ++pass) {
1890
0
                    if (pass->rdslope >= goodthresh) {
1891
0
                      pass1 = &pass[1];
1892
0
                    }
1893
0
                  }
1894
0
                }
1895
0
                for (pass = cblk->curpass; pass != pass1;
1896
0
                  ++pass) {
1897
0
                  pass->lyrno = lyrno;
1898
0
                }
1899
0
                for (; pass != endpasses; ++pass) {
1900
0
                  pass->lyrno = -1;
1901
0
                }
1902
0
              }
1903
0
            }
1904
0
          }
1905
0
        }
1906
0
      }
1907
0
    }
1908
1909
    /* Perform tier 2 coding. */
1910
0
    endcomps = &tile->tcmpts[tile->numtcmpts];
1911
0
    for (comp = tile->tcmpts; comp != endcomps; ++comp) {
1912
0
      endlvls = &comp->rlvls[comp->numrlvls];
1913
0
      for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
1914
0
        if (!lvl->bands) {
1915
0
          continue;
1916
0
        }
1917
0
        for (prcno = 0; prcno < lvl->numprcs; ++prcno) {
1918
0
          if (jpc_enc_encpkt(enc, out, comp - tile->tcmpts,
1919
0
            lvl - comp->rlvls, prcno, lyrno)) {
1920
0
            ret = -1;
1921
0
            goto done;
1922
0
          }
1923
0
        }
1924
0
      }
1925
0
    }
1926
0
  }
1927
1928
0
  if (jas_get_debug_level() >= 5) {
1929
0
    dump_layeringinfo(enc);
1930
0
  }
1931
1932
0
  jas_stream_close(out);
1933
0
  out = 0;
1934
1935
0
done:
1936
1937
0
  if (out) {
1938
0
    jas_stream_close(out);
1939
0
  }
1940
1941
0
  JAS_LOGDEBUGF(10, "finished rate allocation\n");
1942
1943
0
  return ret;
1944
0
}
1945
1946
/******************************************************************************\
1947
* Tile constructors and destructors.
1948
\******************************************************************************/
1949
1950
static jpc_enc_tile_t *jpc_enc_tile_create(jpc_enc_cp_t *cp, jas_image_t *image, int tileno)
1951
0
{
1952
0
  jpc_enc_tile_t *tile;
1953
0
  uint_fast32_t htileno;
1954
0
  uint_fast32_t vtileno;
1955
0
  uint_fast16_t lyrno;
1956
0
  uint_fast16_t cmptno;
1957
0
  jpc_enc_tcmpt_t *tcmpt;
1958
1959
0
  if (!(tile = jas_malloc(sizeof(jpc_enc_tile_t)))) {
1960
0
    goto error;
1961
0
  }
1962
1963
  /* Initialize a few members used in error recovery. */
1964
0
  tile->tcmpts = 0;
1965
0
  tile->lyrsizes = 0;
1966
0
  tile->numtcmpts = cp->numcmpts;
1967
0
  tile->pi = 0;
1968
1969
0
  tile->tileno = tileno;
1970
0
  htileno = tileno % cp->numhtiles;
1971
0
  vtileno = tileno / cp->numhtiles;
1972
1973
  /* Calculate the coordinates of the top-left and bottom-right
1974
    corners of the tile. */
1975
0
  tile->tlx = JAS_MAX(cp->tilegrdoffx + htileno * cp->tilewidth,
1976
0
    cp->imgareatlx);
1977
0
  tile->tly = JAS_MAX(cp->tilegrdoffy + vtileno * cp->tileheight,
1978
0
    cp->imgareatly);
1979
0
  tile->brx = JAS_MIN(cp->tilegrdoffx + (htileno + 1) * cp->tilewidth,
1980
0
    cp->refgrdwidth);
1981
0
  tile->bry = JAS_MIN(cp->tilegrdoffy + (vtileno + 1) * cp->tileheight,
1982
0
    cp->refgrdheight);
1983
1984
  /* Initialize some tile coding parameters. */
1985
0
  tile->intmode = cp->tcp.intmode;
1986
0
  tile->csty = cp->tcp.csty;
1987
0
  tile->prg = cp->tcp.prg;
1988
0
  tile->mctid = cp->tcp.mctid;
1989
1990
0
  tile->numlyrs = cp->tcp.numlyrs;
1991
0
  if (!(tile->lyrsizes = jas_alloc2(tile->numlyrs,
1992
0
    sizeof(uint_fast32_t)))) {
1993
0
    goto error;
1994
0
  }
1995
0
  for (lyrno = 0; lyrno < tile->numlyrs; ++lyrno) {
1996
0
    tile->lyrsizes[lyrno] = 0;
1997
0
  }
1998
1999
  /* Allocate an array for the per-tile-component information. */
2000
0
  if (!(tile->tcmpts = jas_alloc2(cp->numcmpts, sizeof(jpc_enc_tcmpt_t)))) {
2001
0
    goto error;
2002
0
  }
2003
  /* Initialize a few members critical for error recovery. */
2004
0
  for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts;
2005
0
    ++cmptno, ++tcmpt) {
2006
0
    tcmpt->rlvls = 0;
2007
0
    tcmpt->tsfb = 0;
2008
0
    tcmpt->data = 0;
2009
0
  }
2010
  /* Initialize the per-tile-component information. */
2011
0
  for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts;
2012
0
    ++cmptno, ++tcmpt) {
2013
0
    if (!tcmpt_create(tcmpt, cp, image, tile)) {
2014
0
      goto error;
2015
0
    }
2016
0
  }
2017
2018
  /* Initialize the synthesis weights for the MCT. */
2019
0
  switch (tile->mctid) {
2020
0
  case JPC_MCT_RCT:
2021
0
    tile->tcmpts[0].synweight = jpc_dbltofix(sqrt(3.0));
2022
0
    tile->tcmpts[1].synweight = jpc_dbltofix(sqrt(0.6875));
2023
0
    tile->tcmpts[2].synweight = jpc_dbltofix(sqrt(0.6875));
2024
0
    break;
2025
0
  case JPC_MCT_ICT:
2026
0
    tile->tcmpts[0].synweight = jpc_dbltofix(sqrt(3.0000));
2027
0
    tile->tcmpts[1].synweight = jpc_dbltofix(sqrt(3.2584));
2028
0
    tile->tcmpts[2].synweight = jpc_dbltofix(sqrt(2.4755));
2029
0
    break;
2030
0
  default:
2031
0
  case JPC_MCT_NONE:
2032
0
    for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < cp->numcmpts;
2033
0
      ++cmptno, ++tcmpt) {
2034
0
      tcmpt->synweight = JPC_FIX_ONE;
2035
0
    }
2036
0
    break;
2037
0
  }
2038
2039
0
  if (!(tile->pi = jpc_enc_pi_create(cp, tile))) {
2040
0
    goto error;
2041
0
  }
2042
2043
0
  return tile;
2044
2045
0
error:
2046
2047
0
  if (tile) {
2048
0
    jpc_enc_tile_destroy(tile);
2049
0
  }
2050
0
  return 0;
2051
0
}
2052
2053
/* Note: I don't think that it is necessary to marked destroyed subobjects
2054
as such in this function. */
2055
static void jpc_enc_tile_destroy(jpc_enc_tile_t *tile)
2056
0
{
2057
0
  jpc_enc_tcmpt_t *tcmpt;
2058
0
  uint_fast16_t cmptno;
2059
2060
0
  if (tile->tcmpts) {
2061
0
    for (cmptno = 0, tcmpt = tile->tcmpts; cmptno <
2062
0
      tile->numtcmpts; ++cmptno, ++tcmpt) {
2063
0
      tcmpt_destroy(tcmpt);
2064
0
    }
2065
0
    jas_free(tile->tcmpts);
2066
    /* tile->tcmpts = NULL; */
2067
0
  }
2068
0
  if (tile->lyrsizes) {
2069
0
    jas_free(tile->lyrsizes);
2070
    /* tile->lyrsizes = NULL; */
2071
0
  }
2072
0
  if (tile->pi) {
2073
0
    jpc_pi_destroy(tile->pi);
2074
    /* tile->pi = NULL; */
2075
0
  }
2076
0
  jas_free(tile);
2077
  /* tile = NULL; */
2078
0
}
2079
2080
/* Note: This constructor creates the object in place. */
2081
static jpc_enc_tcmpt_t *tcmpt_create(jpc_enc_tcmpt_t *tcmpt, jpc_enc_cp_t *cp,
2082
  jas_image_t *image, jpc_enc_tile_t *tile)
2083
0
{
2084
0
  uint_fast16_t cmptno;
2085
0
  uint_fast16_t rlvlno;
2086
0
  jpc_enc_rlvl_t *rlvl;
2087
0
  uint_fast32_t tlx;
2088
0
  uint_fast32_t tly;
2089
0
  uint_fast32_t brx;
2090
0
  uint_fast32_t bry;
2091
0
  uint_fast32_t cmpttlx;
2092
0
  uint_fast32_t cmpttly;
2093
0
  jpc_enc_ccp_t *ccp;
2094
0
  jpc_tsfb_band_t bandinfos[JPC_MAXBANDS];
2095
2096
0
  tcmpt->tile = tile;
2097
0
  tcmpt->tsfb = 0;
2098
0
  tcmpt->data = 0;
2099
0
  tcmpt->rlvls = 0;
2100
2101
  /* Deduce the component number. */
2102
0
  cmptno = tcmpt - tile->tcmpts;
2103
2104
0
  ccp = &cp->ccps[cmptno];
2105
2106
  /* Compute the coordinates of the top-left and bottom-right
2107
    corners of this tile-component. */
2108
0
  tlx = JPC_CEILDIV(tile->tlx, ccp->sampgrdstepx);
2109
0
  tly = JPC_CEILDIV(tile->tly, ccp->sampgrdstepy);
2110
0
  brx = JPC_CEILDIV(tile->brx, ccp->sampgrdstepx);
2111
0
  bry = JPC_CEILDIV(tile->bry, ccp->sampgrdstepy);
2112
2113
  /* Create a sequence to hold the tile-component sample data. */
2114
0
  if (!(tcmpt->data = jas_seq2d_create(tlx, tly, brx, bry))) {
2115
0
    goto error;
2116
0
  }
2117
2118
  /* Get the image data associated with this tile-component. */
2119
0
  cmpttlx = JPC_CEILDIV(cp->imgareatlx, ccp->sampgrdstepx);
2120
0
  cmpttly = JPC_CEILDIV(cp->imgareatly, ccp->sampgrdstepy);
2121
0
  if (jas_image_readcmpt(image, cmptno, tlx - cmpttlx, tly - cmpttly,
2122
0
    brx - tlx, bry - tly, tcmpt->data)) {
2123
0
    goto error;
2124
0
  }
2125
2126
0
  tcmpt->synweight = 0;
2127
0
  tcmpt->qmfbid = cp->tccp.qmfbid;
2128
0
  tcmpt->numrlvls = cp->tccp.maxrlvls;
2129
0
  tcmpt->numbands = 3 * tcmpt->numrlvls - 2;
2130
0
  if (!(tcmpt->tsfb = jpc_cod_gettsfb(tcmpt->qmfbid, tcmpt->numrlvls - 1))) {
2131
0
    goto error;
2132
0
  }
2133
2134
0
  for (rlvlno = 0; rlvlno < tcmpt->numrlvls; ++rlvlno) {
2135
0
    tcmpt->prcwidthexpns[rlvlno] = cp->tccp.prcwidthexpns[rlvlno];
2136
0
    tcmpt->prcheightexpns[rlvlno] = cp->tccp.prcheightexpns[rlvlno];
2137
0
  }
2138
0
  tcmpt->cblkwidthexpn = cp->tccp.cblkwidthexpn;
2139
0
  tcmpt->cblkheightexpn = cp->tccp.cblkheightexpn;
2140
0
  tcmpt->cblksty = cp->tccp.cblksty;
2141
0
  tcmpt->csty = cp->tccp.csty;
2142
2143
0
  tcmpt->numstepsizes = tcmpt->numbands;
2144
0
  assert(tcmpt->numstepsizes <= JPC_MAXBANDS);
2145
0
  memset(tcmpt->stepsizes, 0, tcmpt->numstepsizes * sizeof(uint_fast16_t));
2146
2147
  /* Retrieve information about the various bands. */
2148
0
  jpc_tsfb_getbands(tcmpt->tsfb, jas_seq2d_xstart(tcmpt->data),
2149
0
    jas_seq2d_ystart(tcmpt->data), jas_seq2d_xend(tcmpt->data),
2150
0
    jas_seq2d_yend(tcmpt->data), bandinfos);
2151
2152
0
  if (!(tcmpt->rlvls = jas_alloc2(tcmpt->numrlvls, sizeof(jpc_enc_rlvl_t)))) {
2153
0
    goto error;
2154
0
  }
2155
0
  for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
2156
0
    ++rlvlno, ++rlvl) {
2157
0
    rlvl->bands = 0;
2158
0
    rlvl->tcmpt = tcmpt;
2159
0
  }
2160
0
  for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
2161
0
    ++rlvlno, ++rlvl) {
2162
0
    if (!rlvl_create(rlvl, cp, tcmpt, bandinfos)) {
2163
0
      goto error;
2164
0
    }
2165
0
  }
2166
2167
0
  return tcmpt;
2168
2169
0
error:
2170
2171
0
  tcmpt_destroy(tcmpt);
2172
0
  return 0;
2173
2174
0
}
2175
2176
/* Note: Since jpc_enc_tcmpt_t objects are created in-place, they might
2177
potentially be destroyed multiple times at different levels in the call
2178
chain.  So, destroyed subobjects must be marked as destroyed to prevent
2179
problems such as double frees. */
2180
static void tcmpt_destroy(jpc_enc_tcmpt_t *tcmpt)
2181
0
{
2182
0
  jpc_enc_rlvl_t *rlvl;
2183
0
  uint_fast16_t rlvlno;
2184
2185
0
  if (tcmpt->rlvls) {
2186
0
    for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
2187
0
      ++rlvlno, ++rlvl) {
2188
0
      rlvl_destroy(rlvl);
2189
0
    }
2190
0
    jas_free(tcmpt->rlvls);
2191
0
    tcmpt->rlvls = NULL;
2192
0
  }
2193
2194
0
  if (tcmpt->data) {
2195
0
    jas_seq2d_destroy(tcmpt->data);
2196
0
    tcmpt->data = NULL;
2197
0
  }
2198
0
  if (tcmpt->tsfb) {
2199
0
    jpc_tsfb_destroy(tcmpt->tsfb);
2200
0
    tcmpt->tsfb = NULL;
2201
0
  }
2202
0
}
2203
2204
/* Note: This constructor creates the object in place. */
2205
static jpc_enc_rlvl_t *rlvl_create(jpc_enc_rlvl_t *rlvl, jpc_enc_cp_t *cp,
2206
  jpc_enc_tcmpt_t *tcmpt, jpc_tsfb_band_t *bandinfos)
2207
0
{
2208
0
  uint_fast16_t rlvlno;
2209
0
  uint_fast32_t tlprctlx;
2210
0
  uint_fast32_t tlprctly;
2211
0
  uint_fast32_t brprcbrx;
2212
0
  uint_fast32_t brprcbry;
2213
0
  uint_fast16_t bandno;
2214
0
  jpc_enc_band_t *band;
2215
2216
  /* Deduce the resolution level. */
2217
0
  rlvlno = rlvl - tcmpt->rlvls;
2218
2219
  /* Initialize members required for error recovery. */
2220
0
  rlvl->bands = 0;
2221
0
  rlvl->tcmpt = tcmpt;
2222
2223
  /* Compute the coordinates of the top-left and bottom-right
2224
    corners of the tile-component at this resolution. */
2225
0
  rlvl->tlx = JPC_CEILDIVPOW2(JAS_CAST(uint_fast32_t,
2226
0
    jas_seq2d_xstart(tcmpt->data)), tcmpt->numrlvls - 1 - rlvlno);
2227
0
  rlvl->tly = JPC_CEILDIVPOW2(JAS_CAST(uint_fast32_t,
2228
0
    jas_seq2d_ystart(tcmpt->data)), tcmpt->numrlvls - 1 - rlvlno);
2229
0
  rlvl->brx = JPC_CEILDIVPOW2(JAS_CAST(uint_fast32_t,
2230
0
    jas_seq2d_xend(tcmpt->data)), tcmpt->numrlvls - 1 - rlvlno);
2231
0
  rlvl->bry = JPC_CEILDIVPOW2(JAS_CAST(uint_fast32_t,
2232
0
    jas_seq2d_yend(tcmpt->data)), tcmpt->numrlvls - 1 - rlvlno);
2233
2234
0
  if (rlvl->tlx >= rlvl->brx || rlvl->tly >= rlvl->bry) {
2235
0
    rlvl->numhprcs = 0;
2236
0
    rlvl->numvprcs = 0;
2237
0
    rlvl->numprcs = 0;
2238
0
    return rlvl;
2239
0
  }
2240
2241
0
  rlvl->numbands = (!rlvlno) ? 1 : 3;
2242
0
  rlvl->prcwidthexpn = cp->tccp.prcwidthexpns[rlvlno];
2243
0
  rlvl->prcheightexpn = cp->tccp.prcheightexpns[rlvlno];
2244
0
  if (!rlvlno) {
2245
0
    rlvl->cbgwidthexpn = rlvl->prcwidthexpn;
2246
0
    rlvl->cbgheightexpn = rlvl->prcheightexpn;
2247
0
  } else {
2248
0
    rlvl->cbgwidthexpn = rlvl->prcwidthexpn - 1;
2249
0
    rlvl->cbgheightexpn = rlvl->prcheightexpn - 1;
2250
0
  }
2251
0
  rlvl->cblkwidthexpn = JAS_MIN(cp->tccp.cblkwidthexpn, rlvl->cbgwidthexpn);
2252
0
  rlvl->cblkheightexpn = JAS_MIN(cp->tccp.cblkheightexpn, rlvl->cbgheightexpn);
2253
2254
  /* Compute the number of precincts. */
2255
0
  tlprctlx = JPC_FLOORTOMULTPOW2(rlvl->tlx, rlvl->prcwidthexpn);
2256
0
  tlprctly = JPC_FLOORTOMULTPOW2(rlvl->tly, rlvl->prcheightexpn);
2257
0
  brprcbrx = JPC_CEILTOMULTPOW2(rlvl->brx, rlvl->prcwidthexpn);
2258
0
  brprcbry = JPC_CEILTOMULTPOW2(rlvl->bry, rlvl->prcheightexpn);
2259
0
  rlvl->numhprcs = JPC_FLOORDIVPOW2(brprcbrx - tlprctlx, rlvl->prcwidthexpn);
2260
0
  rlvl->numvprcs = JPC_FLOORDIVPOW2(brprcbry - tlprctly, rlvl->prcheightexpn);
2261
0
  rlvl->numprcs = rlvl->numhprcs * rlvl->numvprcs;
2262
2263
0
  if (!(rlvl->bands = jas_alloc2(rlvl->numbands, sizeof(jpc_enc_band_t)))) {
2264
0
    goto error;
2265
0
  }
2266
0
  for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
2267
0
    ++bandno, ++band) {
2268
0
    band->prcs = 0;
2269
0
    band->data = 0;
2270
0
    band->rlvl = rlvl;
2271
0
  }
2272
0
  for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
2273
0
    ++bandno, ++band) {
2274
0
    if (!band_create(band, cp, rlvl, bandinfos)) {
2275
0
      goto error;
2276
0
    }
2277
0
  }
2278
2279
0
  return rlvl;
2280
0
error:
2281
2282
0
  rlvl_destroy(rlvl);
2283
0
  return 0;
2284
0
}
2285
2286
/* Note: Since jpc_enc_rlvl_t objects are created in-place, they might
2287
potentially be destroyed multiple times at different levels in the call
2288
chain.  So, destroyed subobjects must be marked as destroyed to prevent
2289
problems such as double frees. */
2290
static void rlvl_destroy(jpc_enc_rlvl_t *rlvl)
2291
0
{
2292
0
  jpc_enc_band_t *band;
2293
0
  uint_fast16_t bandno;
2294
2295
0
  if (rlvl->bands) {
2296
0
    for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
2297
0
      ++bandno, ++band) {
2298
0
      band_destroy(band);
2299
0
    }
2300
0
    jas_free(rlvl->bands);
2301
0
    rlvl->bands = NULL;
2302
0
  }
2303
0
}
2304
2305
/* Note: This constructor creates the object in place. */
2306
static jpc_enc_band_t *band_create(jpc_enc_band_t *band, jpc_enc_cp_t *cp,
2307
  jpc_enc_rlvl_t *rlvl, jpc_tsfb_band_t *bandinfos)
2308
0
{
2309
0
  uint_fast16_t bandno;
2310
0
  uint_fast16_t gblbandno;
2311
0
  uint_fast16_t rlvlno;
2312
0
  jpc_tsfb_band_t *bandinfo;
2313
0
  jpc_enc_tcmpt_t *tcmpt;
2314
0
  uint_fast32_t prcno;
2315
0
  jpc_enc_prc_t *prc;
2316
2317
0
  tcmpt = rlvl->tcmpt;
2318
0
  band->data = 0;
2319
0
  band->prcs = 0;
2320
0
  band->rlvl = rlvl;
2321
2322
  /* Deduce the resolution level and band number. */
2323
0
  rlvlno = rlvl - rlvl->tcmpt->rlvls;
2324
0
  bandno = band - rlvl->bands;
2325
0
  gblbandno = (!rlvlno) ? 0 : (3 * (rlvlno - 1) + bandno + 1);
2326
2327
0
  bandinfo = &bandinfos[gblbandno];
2328
2329
0
if (bandinfo->xstart != bandinfo->xend && bandinfo->ystart != bandinfo->yend) {
2330
0
  if (!(band->data = jas_seq2d_create(0, 0, 0, 0))) {
2331
0
    goto error;
2332
0
  }
2333
0
  if (jas_seq2d_bindsub(band->data, tcmpt->data, bandinfo->locxstart,
2334
0
            bandinfo->locystart, bandinfo->locxend, bandinfo->locyend)) {
2335
0
    goto error;
2336
0
  }
2337
0
  jas_seq2d_setshift(band->data, bandinfo->xstart, bandinfo->ystart);
2338
0
}
2339
0
  band->orient = bandinfo->orient;
2340
0
  band->analgain = JPC_NOMINALGAIN(cp->tccp.qmfbid, tcmpt->numrlvls, rlvlno,
2341
0
    band->orient);
2342
0
  band->numbps = 0;
2343
0
  band->absstepsize = 0;
2344
0
  band->stepsize = 0;
2345
0
  band->synweight = bandinfo->synenergywt;
2346
2347
0
if (band->data) {
2348
0
  if (!(band->prcs = jas_alloc2(rlvl->numprcs, sizeof(jpc_enc_prc_t)))) {
2349
0
    goto error;
2350
0
  }
2351
0
  for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs; ++prcno,
2352
0
    ++prc) {
2353
0
    prc->cblks = 0;
2354
0
    prc->incltree = 0;
2355
0
    prc->nlibtree = 0;
2356
0
    prc->savincltree = 0;
2357
0
    prc->savnlibtree = 0;
2358
0
    prc->band = band;
2359
0
  }
2360
0
  for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs; ++prcno,
2361
0
    ++prc) {
2362
0
    if (!prc_create(prc, band)) {
2363
0
      goto error;
2364
0
    }
2365
0
  }
2366
0
}
2367
2368
0
  return band;
2369
2370
0
error:
2371
0
  band_destroy(band);
2372
0
  return 0;
2373
0
}
2374
2375
/* Note: Since jpc_enc_band_t objects are created in-place, they might
2376
potentially be destroyed multiple times at different levels in the call
2377
chain.  So, destroyed subobjects must be marked as destroyed to prevent
2378
problems such as double frees. */
2379
static void band_destroy(jpc_enc_band_t *band)
2380
0
{
2381
0
  jpc_enc_prc_t *prc;
2382
0
  jpc_enc_rlvl_t *rlvl;
2383
0
  uint_fast32_t prcno;
2384
2385
0
  if (band->prcs) {
2386
0
    rlvl = band->rlvl;
2387
0
    for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs;
2388
0
      ++prcno, ++prc) {
2389
0
      prc_destroy(prc);
2390
0
    }
2391
0
    jas_free(band->prcs);
2392
0
    band->prcs = NULL;
2393
0
  }
2394
0
  if (band->data) {
2395
0
    jas_seq2d_destroy(band->data);
2396
0
    band->data = NULL;
2397
0
  }
2398
0
}
2399
2400
/* Note: This constructor creates the object in place. */
2401
static jpc_enc_prc_t *prc_create(jpc_enc_prc_t *prc, jpc_enc_band_t *band)
2402
0
{
2403
0
  uint_fast32_t prcno;
2404
0
  uint_fast32_t prcxind;
2405
0
  uint_fast32_t prcyind;
2406
0
  uint_fast32_t cbgtlx;
2407
0
  uint_fast32_t cbgtly;
2408
0
  uint_fast32_t tlprctlx;
2409
0
  uint_fast32_t tlprctly;
2410
0
  uint_fast32_t tlcbgtlx;
2411
0
  uint_fast32_t tlcbgtly;
2412
0
  uint_fast16_t rlvlno;
2413
0
  jpc_enc_rlvl_t *rlvl;
2414
0
  uint_fast32_t tlcblktlx;
2415
0
  uint_fast32_t tlcblktly;
2416
0
  uint_fast32_t brcblkbrx;
2417
0
  uint_fast32_t brcblkbry;
2418
0
  uint_fast32_t cblkno;
2419
0
  jpc_enc_cblk_t *cblk;
2420
0
  jpc_enc_tcmpt_t *tcmpt;
2421
2422
0
  prc->cblks = 0;
2423
0
  prc->incltree = 0;
2424
0
  prc->savincltree = 0;
2425
0
  prc->nlibtree = 0;
2426
0
  prc->savnlibtree = 0;
2427
2428
0
  rlvl = band->rlvl;
2429
0
  tcmpt = rlvl->tcmpt;
2430
0
  rlvlno = rlvl - tcmpt->rlvls;
2431
0
  prcno = prc - band->prcs;
2432
0
  prcxind = prcno % rlvl->numhprcs;
2433
0
  prcyind = prcno / rlvl->numhprcs;
2434
0
  prc->band = band;
2435
2436
0
  tlprctlx = JPC_FLOORTOMULTPOW2(rlvl->tlx, rlvl->prcwidthexpn);
2437
0
  tlprctly = JPC_FLOORTOMULTPOW2(rlvl->tly, rlvl->prcheightexpn);
2438
0
  if (!rlvlno) {
2439
0
    tlcbgtlx = tlprctlx;
2440
0
    tlcbgtly = tlprctly;
2441
0
  } else {
2442
0
    tlcbgtlx = JPC_CEILDIVPOW2(tlprctlx, 1);
2443
0
    tlcbgtly = JPC_CEILDIVPOW2(tlprctly, 1);
2444
0
  }
2445
2446
  /* Compute the coordinates of the top-left and bottom-right
2447
    corners of the precinct. */
2448
0
  cbgtlx = tlcbgtlx + (prcxind << rlvl->cbgwidthexpn);
2449
0
  cbgtly = tlcbgtly + (prcyind << rlvl->cbgheightexpn);
2450
0
  prc->tlx = JAS_MAX(jas_seq2d_xstart(band->data), (jas_matind_t)cbgtlx);
2451
0
  prc->tly = JAS_MAX(jas_seq2d_ystart(band->data), (jas_matind_t)cbgtly);
2452
0
  prc->brx = JAS_MIN(jas_seq2d_xend(band->data), (jas_matind_t)(cbgtlx +
2453
0
    (1 << rlvl->cbgwidthexpn)));
2454
0
  prc->bry = JAS_MIN(jas_seq2d_yend(band->data), (jas_matind_t)(cbgtly +
2455
0
    (1 << rlvl->cbgheightexpn)));
2456
2457
0
  if (prc->tlx < prc->brx && prc->tly < prc->bry) {
2458
    /* The precinct contains at least one code block. */
2459
2460
0
    tlcblktlx = JPC_FLOORTOMULTPOW2(prc->tlx, rlvl->cblkwidthexpn);
2461
0
    tlcblktly = JPC_FLOORTOMULTPOW2(prc->tly, rlvl->cblkheightexpn);
2462
0
    brcblkbrx = JPC_CEILTOMULTPOW2(prc->brx, rlvl->cblkwidthexpn);
2463
0
    brcblkbry = JPC_CEILTOMULTPOW2(prc->bry, rlvl->cblkheightexpn);
2464
0
    prc->numhcblks = JPC_FLOORDIVPOW2(brcblkbrx - tlcblktlx,
2465
0
      rlvl->cblkwidthexpn);
2466
0
    prc->numvcblks = JPC_FLOORDIVPOW2(brcblkbry - tlcblktly,
2467
0
      rlvl->cblkheightexpn);
2468
0
    prc->numcblks = prc->numhcblks * prc->numvcblks;
2469
2470
0
    if (!(prc->incltree = jpc_tagtree_create(prc->numhcblks,
2471
0
      prc->numvcblks))) {
2472
0
      goto error;
2473
0
    }
2474
0
    if (!(prc->nlibtree = jpc_tagtree_create(prc->numhcblks,
2475
0
      prc->numvcblks))) {
2476
0
      goto error;
2477
0
    }
2478
0
    if (!(prc->savincltree = jpc_tagtree_create(prc->numhcblks,
2479
0
      prc->numvcblks))) {
2480
0
      goto error;
2481
0
    }
2482
0
    if (!(prc->savnlibtree = jpc_tagtree_create(prc->numhcblks,
2483
0
      prc->numvcblks))) {
2484
0
      goto error;
2485
0
    }
2486
2487
0
    if (!(prc->cblks = jas_alloc2(prc->numcblks, sizeof(jpc_enc_cblk_t)))) {
2488
0
      goto error;
2489
0
    }
2490
0
    for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks;
2491
0
      ++cblkno, ++cblk) {
2492
0
      cblk->passes = 0;
2493
0
      cblk->stream = 0;
2494
0
      cblk->mqenc = 0;
2495
0
      cblk->data = 0;
2496
0
      cblk->flags = 0;
2497
0
      cblk->prc = prc;
2498
0
    }
2499
0
    for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks;
2500
0
      ++cblkno, ++cblk) {
2501
0
      if (!cblk_create(cblk, prc)) {
2502
0
        goto error;
2503
0
      }
2504
0
    }
2505
0
  } else {
2506
    /* The precinct does not contain any code blocks. */
2507
0
    prc->tlx = prc->brx;
2508
0
    prc->tly = prc->bry;
2509
0
    prc->numcblks = 0;
2510
0
    prc->numhcblks = 0;
2511
0
    prc->numvcblks = 0;
2512
0
    prc->cblks = 0;
2513
0
    prc->incltree = 0;
2514
0
    prc->nlibtree = 0;
2515
0
    prc->savincltree = 0;
2516
0
    prc->savnlibtree = 0;
2517
0
  }
2518
2519
0
  return prc;
2520
2521
0
error:
2522
0
  prc_destroy(prc);
2523
0
  return 0;
2524
0
}
2525
2526
/* Note: Since jpc_enc_prc_t objects are created in-place, they might
2527
potentially be destroyed multiple times at different levels in the call
2528
chain.  So, destroyed subobjects must be marked as destroyed to prevent
2529
problems such as double frees. */
2530
static void prc_destroy(jpc_enc_prc_t *prc)
2531
0
{
2532
0
  jpc_enc_cblk_t *cblk;
2533
0
  uint_fast32_t cblkno;
2534
2535
0
  if (prc->cblks) {
2536
0
    for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks;
2537
0
      ++cblkno, ++cblk) {
2538
0
      cblk_destroy(cblk);
2539
0
    }
2540
0
    jas_free(prc->cblks);
2541
0
    prc->cblks = NULL;
2542
0
  }
2543
0
  if (prc->incltree) {
2544
0
    jpc_tagtree_destroy(prc->incltree);
2545
0
    prc->incltree = NULL;
2546
0
  }
2547
0
  if (prc->nlibtree) {
2548
0
    jpc_tagtree_destroy(prc->nlibtree);
2549
0
    prc->nlibtree = NULL;
2550
0
  }
2551
0
  if (prc->savincltree) {
2552
0
    jpc_tagtree_destroy(prc->savincltree);
2553
0
    prc->savincltree = NULL;
2554
0
  }
2555
0
  if (prc->savnlibtree) {
2556
0
    jpc_tagtree_destroy(prc->savnlibtree);
2557
0
    prc->savnlibtree = NULL;
2558
0
  }
2559
0
}
2560
2561
/* Note: This constructor creates the object in place. */
2562
static jpc_enc_cblk_t *cblk_create(jpc_enc_cblk_t *cblk,
2563
  jpc_enc_prc_t *prc)
2564
0
{
2565
0
  jpc_enc_band_t *band;
2566
0
  uint_fast32_t cblktlx;
2567
0
  uint_fast32_t cblktly;
2568
0
  uint_fast32_t cblkbrx;
2569
0
  uint_fast32_t cblkbry;
2570
0
  jpc_enc_rlvl_t *rlvl;
2571
0
  uint_fast32_t cblkxind;
2572
0
  uint_fast32_t cblkyind;
2573
0
  uint_fast32_t cblkno;
2574
0
  uint_fast32_t tlcblktlx;
2575
0
  uint_fast32_t tlcblktly;
2576
2577
0
  cblkno = cblk - prc->cblks;
2578
0
  cblkxind = cblkno % prc->numhcblks;
2579
0
  cblkyind = cblkno / prc->numhcblks;
2580
0
  rlvl = prc->band->rlvl;
2581
0
  cblk->prc = prc;
2582
2583
0
  cblk->numpasses = 0;
2584
0
  cblk->passes = 0;
2585
0
  cblk->numencpasses = 0;
2586
0
  cblk->numimsbs = 0;
2587
0
  cblk->numlenbits = 0;
2588
0
  cblk->stream = 0;
2589
0
  cblk->mqenc = 0;
2590
0
  cblk->flags = 0;
2591
0
  cblk->numbps = 0;
2592
0
  cblk->curpass = 0;
2593
0
  cblk->data = 0;
2594
0
  cblk->savedcurpass = 0;
2595
0
  cblk->savednumlenbits = 0;
2596
0
  cblk->savednumencpasses = 0;
2597
2598
0
  band = prc->band;
2599
0
  tlcblktlx = JPC_FLOORTOMULTPOW2(prc->tlx, rlvl->cblkwidthexpn);
2600
0
  tlcblktly = JPC_FLOORTOMULTPOW2(prc->tly, rlvl->cblkheightexpn);
2601
0
  cblktlx = JAS_MAX(tlcblktlx + (cblkxind << rlvl->cblkwidthexpn), prc->tlx);
2602
0
  cblktly = JAS_MAX(tlcblktly + (cblkyind << rlvl->cblkheightexpn), prc->tly);
2603
0
  cblkbrx = JAS_MIN(tlcblktlx + ((cblkxind + 1) << rlvl->cblkwidthexpn),
2604
0
    prc->brx);
2605
0
  cblkbry = JAS_MIN(tlcblktly + ((cblkyind + 1) << rlvl->cblkheightexpn),
2606
0
    prc->bry);
2607
2608
0
  assert(cblktlx < cblkbrx && cblktly < cblkbry);
2609
0
  if (!(cblk->data = jas_seq2d_create(0, 0, 0, 0))) {
2610
0
    goto error;
2611
0
  }
2612
0
  if (jas_seq2d_bindsub(cblk->data, band->data, cblktlx, cblktly, cblkbrx, cblkbry)) {
2613
0
    goto error;
2614
0
  }
2615
2616
0
  return cblk;
2617
2618
0
error:
2619
0
  cblk_destroy(cblk);
2620
0
  return 0;
2621
0
}
2622
2623
/* Note: Since jpc_enc_cblk_t objects are created in-place, they might
2624
potentially be destroyed multiple times at different levels in the call
2625
chain.  So, destroyed subobjects must be marked as destroyed to prevent
2626
problems such as double frees. */
2627
static void cblk_destroy(jpc_enc_cblk_t *cblk)
2628
0
{
2629
0
  uint_fast16_t passno;
2630
0
  jpc_enc_pass_t *pass;
2631
0
  if (cblk->passes) {
2632
0
    for (passno = 0, pass = cblk->passes; passno < cblk->numpasses;
2633
0
      ++passno, ++pass) {
2634
0
      pass_destroy(pass);
2635
0
    }
2636
0
    jas_free(cblk->passes);
2637
0
    cblk->passes = NULL;
2638
0
  }
2639
0
  if (cblk->stream) {
2640
0
    jas_stream_close(cblk->stream);
2641
0
    cblk->stream = NULL;
2642
0
  }
2643
0
  if (cblk->mqenc) {
2644
0
    jpc_mqenc_destroy(cblk->mqenc);
2645
0
    cblk->mqenc = NULL;
2646
0
  }
2647
0
  if (cblk->data) {
2648
0
    jas_seq2d_destroy(cblk->data);
2649
0
    cblk->data = NULL;
2650
0
  }
2651
0
  if (cblk->flags) {
2652
0
    jas_seq2d_destroy(cblk->flags);
2653
0
    cblk->flags = NULL;
2654
0
  }
2655
0
}
2656
2657
static void pass_destroy(jpc_enc_pass_t *pass)
2658
0
{
2659
  /* XXX - need to free resources here */
2660
0
  JAS_UNUSED(pass);
2661
0
}
2662
2663
void jpc_enc_dump(jpc_enc_t *enc)
2664
0
{
2665
0
  jpc_enc_tile_t *tile;
2666
0
  jpc_enc_tcmpt_t *tcmpt;
2667
0
  jpc_enc_rlvl_t *rlvl;
2668
0
  jpc_enc_band_t *band;
2669
0
  jpc_enc_prc_t *prc;
2670
0
  jpc_enc_cblk_t *cblk;
2671
0
  uint_fast16_t cmptno;
2672
0
  uint_fast16_t rlvlno;
2673
0
  uint_fast16_t bandno;
2674
0
  uint_fast32_t prcno;
2675
0
  uint_fast32_t cblkno;
2676
2677
0
  tile = enc->curtile;
2678
2679
0
  for (cmptno = 0, tcmpt = tile->tcmpts; cmptno < tile->numtcmpts; ++cmptno,
2680
0
    ++tcmpt) {
2681
0
    jas_loginfof("  tcmpt %5d %5d %5d %5d\n", jas_seq2d_xstart(tcmpt->data), jas_seq2d_ystart(tcmpt->data), jas_seq2d_xend(tcmpt->data), jas_seq2d_yend(tcmpt->data));
2682
0
    for (rlvlno = 0, rlvl = tcmpt->rlvls; rlvlno < tcmpt->numrlvls;
2683
0
      ++rlvlno, ++rlvl) {
2684
0
      jas_loginfof("    rlvl %5d %5d %5d %5d\n", rlvl->tlx, rlvl->tly, rlvl->brx, rlvl->bry);
2685
0
      for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands;
2686
0
        ++bandno, ++band) {
2687
0
        if (!band->data) {
2688
0
          continue;
2689
0
        }
2690
0
        jas_loginfof("      band %5d %5d %5d %5d\n", jas_seq2d_xstart(band->data), jas_seq2d_ystart(band->data), jas_seq2d_xend(band->data), jas_seq2d_yend(band->data));
2691
0
        for (prcno = 0, prc = band->prcs; prcno < rlvl->numprcs;
2692
0
          ++prcno, ++prc) {
2693
0
          jas_loginfof("        prc %5d %5d %5d %5d (%5d %5d)\n", prc->tlx, prc->tly, prc->brx, prc->bry, prc->brx - prc->tlx, prc->bry - prc->tly);
2694
0
          if (!prc->cblks) {
2695
0
            continue;
2696
0
          }
2697
0
          for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks;
2698
0
            ++cblkno, ++cblk) {
2699
0
            jas_loginfof("         cblk %5d %5d %5d %5d\n", jas_seq2d_xstart(cblk->data), jas_seq2d_ystart(cblk->data), jas_seq2d_xend(cblk->data), jas_seq2d_yend(cblk->data));
2700
0
          }
2701
0
        }
2702
0
      }
2703
0
    }
2704
0
  }
2705
0
}