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: jpc_dec.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $
66 */
67
68 /******************************************************************************\
69 * Includes.
70 \******************************************************************************/
71
72 #include <stdio.h>
73 #include <stdlib.h>
74 #include <assert.h>
75
76 #include "jasper/jas_types.h"
77 #include "jasper/jas_math.h"
78 #include "jasper/jas_tvp.h"
79 #include "jasper/jas_malloc.h"
80 #include "jasper/jas_debug.h"
81
82 #include "jpc_fix.h"
83 #include "jpc_dec.h"
84 #include "jpc_cs.h"
85 #include "jpc_mct.h"
86 #include "jpc_t2dec.h"
87 #include "jpc_t1dec.h"
88 #include "jpc_math.h"
89
90 /******************************************************************************\
91 *
92 \******************************************************************************/
93
94 #define JPC_MHSOC 0x0001
95 /* In the main header, expecting a SOC marker segment. */
96 #define JPC_MHSIZ 0x0002
97 /* In the main header, expecting a SIZ marker segment. */
98 #define JPC_MH 0x0004
99 /* In the main header, expecting "other" marker segments. */
100 #define JPC_TPHSOT 0x0008
101 /* In a tile-part header, expecting a SOT marker segment. */
102 #define JPC_TPH 0x0010
103 /* In a tile-part header, expecting "other" marker segments. */
104 #define JPC_MT 0x0020
105 /* In the main trailer. */
106
107 typedef struct {
108
109 uint_fast16_t id;
110 /* The marker segment type. */
111
112 int validstates;
113 /* The states in which this type of marker segment can be
114 validly encountered. */
115
116 int (*action)(jpc_dec_t *dec, jpc_ms_t *ms);
117 /* The action to take upon encountering this type of marker segment. */
118
119 } jpc_dec_mstabent_t;
120
121 /******************************************************************************\
122 *
123 \******************************************************************************/
124
125 /* COD/COC parameters have been specified. */
126 #define JPC_CSET 0x0001
127 /* QCD/QCC parameters have been specified. */
128 #define JPC_QSET 0x0002
129 /* COD/COC parameters set from a COC marker segment. */
130 #define JPC_COC 0x0004
131 /* QCD/QCC parameters set from a QCC marker segment. */
132 #define JPC_QCC 0x0008
133
134 /******************************************************************************\
135 * Local function prototypes.
136 \******************************************************************************/
137
138 static int jpc_dec_dump(jpc_dec_t *dec, FILE *out);
139
140 jpc_ppxstab_t *jpc_ppxstab_create(void);
141 void jpc_ppxstab_destroy(jpc_ppxstab_t *tab);
142 int jpc_ppxstab_grow(jpc_ppxstab_t *tab, int maxents);
143 int jpc_ppxstab_insert(jpc_ppxstab_t *tab, jpc_ppxstabent_t *ent);
144 jpc_streamlist_t *jpc_ppmstabtostreams(jpc_ppxstab_t *tab);
145 int jpc_pptstabwrite(jas_stream_t *out, jpc_ppxstab_t *tab);
146 jpc_ppxstabent_t *jpc_ppxstabent_create(void);
147 void jpc_ppxstabent_destroy(jpc_ppxstabent_t *ent);
148
149 int jpc_streamlist_numstreams(jpc_streamlist_t *streamlist);
150 jpc_streamlist_t *jpc_streamlist_create(void);
151 int jpc_streamlist_insert(jpc_streamlist_t *streamlist, int streamno,
152 jas_stream_t *stream);
153 jas_stream_t *jpc_streamlist_remove(jpc_streamlist_t *streamlist, int streamno);
154 void jpc_streamlist_destroy(jpc_streamlist_t *streamlist);
155 jas_stream_t *jpc_streamlist_get(jpc_streamlist_t *streamlist, int streamno);
156
157 static void jpc_dec_cp_resetflags(jpc_dec_cp_t *cp);
158 static jpc_dec_cp_t *jpc_dec_cp_create(uint_fast16_t numcomps);
159 static int jpc_dec_cp_isvalid(jpc_dec_cp_t *cp);
160 static jpc_dec_cp_t *jpc_dec_cp_copy(jpc_dec_cp_t *cp);
161 static int jpc_dec_cp_setfromcod(jpc_dec_cp_t *cp, jpc_cod_t *cod);
162 static int jpc_dec_cp_setfromcoc(jpc_dec_cp_t *cp, jpc_coc_t *coc);
163 static int jpc_dec_cp_setfromcox(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp,
164 jpc_coxcp_t *compparms, int flags);
165 static int jpc_dec_cp_setfromqcd(jpc_dec_cp_t *cp, jpc_qcd_t *qcd);
166 static int jpc_dec_cp_setfromqcc(jpc_dec_cp_t *cp, jpc_qcc_t *qcc);
167 static int jpc_dec_cp_setfromqcx(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp,
168 jpc_qcxcp_t *compparms, int flags);
169 static int jpc_dec_cp_setfromrgn(jpc_dec_cp_t *cp, jpc_rgn_t *rgn);
170 static int jpc_dec_cp_prepare(jpc_dec_cp_t *cp);
171 static void jpc_dec_cp_destroy(jpc_dec_cp_t *cp);
172 static int jpc_dec_cp_setfrompoc(jpc_dec_cp_t *cp, jpc_poc_t *poc, int reset);
173 static int jpc_pi_addpchgfrompoc(jpc_pi_t *pi, jpc_poc_t *poc);
174
175 static int jpc_dec_decode(jpc_dec_t *dec);
176 static jpc_dec_t *jpc_dec_create(jpc_dec_importopts_t *impopts, jas_stream_t *in);
177 static void jpc_dec_destroy(jpc_dec_t *dec);
178 static void jpc_dequantize(jas_matrix_t *x, jpc_fix_t absstepsize);
179 static void jpc_undo_roi(jas_matrix_t *x, int roishift, int bgshift, int numbps);
180 static jpc_fix_t jpc_calcabsstepsize(int stepsize, int numbits);
181 static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile);
182 static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile);
183 static int jpc_dec_tilefini(jpc_dec_t *dec, jpc_dec_tile_t *tile);
184 static int jpc_dec_process_soc(jpc_dec_t *dec, jpc_ms_t *ms);
185 static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms);
186 static int jpc_dec_process_sod(jpc_dec_t *dec, jpc_ms_t *ms);
187 static int jpc_dec_process_eoc(jpc_dec_t *dec, jpc_ms_t *ms);
188 static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms);
189 static int jpc_dec_process_cod(jpc_dec_t *dec, jpc_ms_t *ms);
190 static int jpc_dec_process_coc(jpc_dec_t *dec, jpc_ms_t *ms);
191 static int jpc_dec_process_rgn(jpc_dec_t *dec, jpc_ms_t *ms);
192 static int jpc_dec_process_qcd(jpc_dec_t *dec, jpc_ms_t *ms);
193 static int jpc_dec_process_qcc(jpc_dec_t *dec, jpc_ms_t *ms);
194 static int jpc_dec_process_poc(jpc_dec_t *dec, jpc_ms_t *ms);
195 static int jpc_dec_process_ppm(jpc_dec_t *dec, jpc_ms_t *ms);
196 static int jpc_dec_process_ppt(jpc_dec_t *dec, jpc_ms_t *ms);
197 static int jpc_dec_process_com(jpc_dec_t *dec, jpc_ms_t *ms);
198 static int jpc_dec_process_unk(jpc_dec_t *dec, jpc_ms_t *ms);
199 static int jpc_dec_process_crg(jpc_dec_t *dec, jpc_ms_t *ms);
200 static int jpc_dec_parseopts(char *optstr, jpc_dec_importopts_t *opts);
201
202 static jpc_dec_mstabent_t *jpc_dec_mstab_lookup(uint_fast16_t id);
203
204 /******************************************************************************\
205 * Global data.
206 \******************************************************************************/
207
208 jpc_dec_mstabent_t jpc_dec_mstab[] = {
209 {JPC_MS_SOC, JPC_MHSOC, jpc_dec_process_soc},
210 {JPC_MS_SOT, JPC_MH | JPC_TPHSOT, jpc_dec_process_sot},
211 {JPC_MS_SOD, JPC_TPH, jpc_dec_process_sod},
212 {JPC_MS_EOC, JPC_TPHSOT, jpc_dec_process_eoc},
213 {JPC_MS_SIZ, JPC_MHSIZ, jpc_dec_process_siz},
214 {JPC_MS_COD, JPC_MH | JPC_TPH, jpc_dec_process_cod},
215 {JPC_MS_COC, JPC_MH | JPC_TPH, jpc_dec_process_coc},
216 {JPC_MS_RGN, JPC_MH | JPC_TPH, jpc_dec_process_rgn},
217 {JPC_MS_QCD, JPC_MH | JPC_TPH, jpc_dec_process_qcd},
218 {JPC_MS_QCC, JPC_MH | JPC_TPH, jpc_dec_process_qcc},
219 {JPC_MS_POC, JPC_MH | JPC_TPH, jpc_dec_process_poc},
220 {JPC_MS_TLM, JPC_MH, 0},
221 {JPC_MS_PLM, JPC_MH, 0},
222 {JPC_MS_PLT, JPC_TPH, 0},
223 {JPC_MS_PPM, JPC_MH, jpc_dec_process_ppm},
224 {JPC_MS_PPT, JPC_TPH, jpc_dec_process_ppt},
225 {JPC_MS_SOP, 0, 0},
226 {JPC_MS_CRG, JPC_MH, jpc_dec_process_crg},
227 {JPC_MS_COM, JPC_MH | JPC_TPH, jpc_dec_process_com},
228 {0, JPC_MH | JPC_TPH, jpc_dec_process_unk}
229 };
230
231 /******************************************************************************\
232 * The main entry point for the JPEG-2000 decoder.
233 \******************************************************************************/
234
jpc_decode(jas_stream_t * in,char * optstr)235 jas_image_t *jpc_decode(jas_stream_t *in, char *optstr)
236 {
237 jpc_dec_importopts_t opts;
238 jpc_dec_t *dec;
239 jas_image_t *image;
240
241 dec = 0;
242
243 if (jpc_dec_parseopts(optstr, &opts)) {
244 goto error;
245 }
246
247 jpc_initluts();
248
249 if (!(dec = jpc_dec_create(&opts, in))) {
250 goto error;
251 }
252
253 /* Do most of the work. */
254 if (jpc_dec_decode(dec)) {
255 goto error;
256 }
257
258 if (jas_image_numcmpts(dec->image) >= 3) {
259 jas_image_setclrspc(dec->image, JAS_CLRSPC_SRGB);
260 jas_image_setcmpttype(dec->image, 0,
261 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_R));
262 jas_image_setcmpttype(dec->image, 1,
263 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_G));
264 jas_image_setcmpttype(dec->image, 2,
265 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_RGB_B));
266 } else {
267 jas_image_setclrspc(dec->image, JAS_CLRSPC_SGRAY);
268 jas_image_setcmpttype(dec->image, 0,
269 JAS_IMAGE_CT_COLOR(JAS_CLRSPC_CHANIND_GRAY_Y));
270 }
271
272 /* Save the return value. */
273 image = dec->image;
274
275 /* Stop the image from being discarded. */
276 dec->image = 0;
277
278 /* Destroy decoder. */
279 jpc_dec_destroy(dec);
280
281 return image;
282
283 error:
284 if (dec) {
285 jpc_dec_destroy(dec);
286 }
287 return 0;
288 }
289
290 typedef enum {
291 OPT_MAXLYRS,
292 OPT_MAXPKTS,
293 OPT_DEBUG
294 } optid_t;
295
296 jas_taginfo_t decopts[] = {
297 {OPT_MAXLYRS, "maxlyrs"},
298 {OPT_MAXPKTS, "maxpkts"},
299 {OPT_DEBUG, "debug"},
300 {-1, 0}
301 };
302
jpc_dec_parseopts(char * optstr,jpc_dec_importopts_t * opts)303 static int jpc_dec_parseopts(char *optstr, jpc_dec_importopts_t *opts)
304 {
305 jas_tvparser_t *tvp;
306
307 opts->debug = 0;
308 opts->maxlyrs = JPC_MAXLYRS;
309 opts->maxpkts = -1;
310
311 if (!(tvp = jas_tvparser_create(optstr ? optstr : ""))) {
312 return -1;
313 }
314
315 while (!jas_tvparser_next(tvp)) {
316 switch (jas_taginfo_nonull(jas_taginfos_lookup(decopts,
317 jas_tvparser_gettag(tvp)))->id) {
318 case OPT_MAXLYRS:
319 opts->maxlyrs = atoi(jas_tvparser_getval(tvp));
320 break;
321 case OPT_DEBUG:
322 opts->debug = atoi(jas_tvparser_getval(tvp));
323 break;
324 case OPT_MAXPKTS:
325 opts->maxpkts = atoi(jas_tvparser_getval(tvp));
326 break;
327 default:
328 jas_eprintf("warning: ignoring invalid option %s\n",
329 jas_tvparser_gettag(tvp));
330 break;
331 }
332 }
333
334 jas_tvparser_destroy(tvp);
335
336 return 0;
337 }
338
339 /******************************************************************************\
340 * Code for table-driven code stream decoder.
341 \******************************************************************************/
342
jpc_dec_mstab_lookup(uint_fast16_t id)343 static jpc_dec_mstabent_t *jpc_dec_mstab_lookup(uint_fast16_t id)
344 {
345 jpc_dec_mstabent_t *mstabent;
346 for (mstabent = jpc_dec_mstab; mstabent->id != 0; ++mstabent) {
347 if (mstabent->id == id) {
348 break;
349 }
350 }
351 return mstabent;
352 }
353
jpc_dec_decode(jpc_dec_t * dec)354 static int jpc_dec_decode(jpc_dec_t *dec)
355 {
356 jpc_ms_t *ms;
357 jpc_dec_mstabent_t *mstabent;
358 int ret;
359 jpc_cstate_t *cstate;
360
361 if (!(cstate = jpc_cstate_create())) {
362 return -1;
363 }
364 dec->cstate = cstate;
365
366 /* Initially, we should expect to encounter a SOC marker segment. */
367 dec->state = JPC_MHSOC;
368
369 for (;;) {
370
371 /* Get the next marker segment in the code stream. */
372 if (!(ms = jpc_getms(dec->in, cstate))) {
373 jas_eprintf("cannot get marker segment\n");
374 return -1;
375 }
376
377 mstabent = jpc_dec_mstab_lookup(ms->id);
378 assert(mstabent);
379
380 /* Ensure that this type of marker segment is permitted
381 at this point in the code stream. */
382 if (!(dec->state & mstabent->validstates)) {
383 jas_eprintf("unexpected marker segment type\n");
384 jpc_ms_destroy(ms);
385 return -1;
386 }
387
388 /* Process the marker segment. */
389 if (mstabent->action) {
390 ret = (*mstabent->action)(dec, ms);
391 } else {
392 /* No explicit action is required. */
393 ret = 0;
394 }
395
396 /* Destroy the marker segment. */
397 jpc_ms_destroy(ms);
398
399 if (ret < 0) {
400 return -1;
401 } else if (ret > 0) {
402 break;
403 }
404
405 }
406
407 return 0;
408 }
409
jpc_dec_process_crg(jpc_dec_t * dec,jpc_ms_t * ms)410 static int jpc_dec_process_crg(jpc_dec_t *dec, jpc_ms_t *ms)
411 {
412 int cmptno;
413 jpc_dec_cmpt_t *cmpt;
414 jpc_crg_t *crg;
415
416 crg = &ms->parms.crg;
417 for (cmptno = 0, cmpt = dec->cmpts; cmptno < dec->numcomps; ++cmptno,
418 ++cmpt) {
419 /* Ignore the information in the CRG marker segment for now.
420 This information serves no useful purpose for decoding anyhow.
421 Some other parts of the code need to be changed if these lines
422 are uncommented.
423 cmpt->hsubstep = crg->comps[cmptno].hoff;
424 cmpt->vsubstep = crg->comps[cmptno].voff;
425 */
426 }
427 return 0;
428 }
429
jpc_dec_process_soc(jpc_dec_t * dec,jpc_ms_t * ms)430 static int jpc_dec_process_soc(jpc_dec_t *dec, jpc_ms_t *ms)
431 {
432 /* Eliminate warnings about unused variables. */
433 ms = 0;
434
435 /* We should expect to encounter a SIZ marker segment next. */
436 dec->state = JPC_MHSIZ;
437
438 return 0;
439 }
440
jpc_dec_process_sot(jpc_dec_t * dec,jpc_ms_t * ms)441 static int jpc_dec_process_sot(jpc_dec_t *dec, jpc_ms_t *ms)
442 {
443 jpc_dec_tile_t *tile;
444 jpc_sot_t *sot = &ms->parms.sot;
445 jas_image_cmptparm_t *compinfos;
446 jas_image_cmptparm_t *compinfo;
447 jpc_dec_cmpt_t *cmpt;
448 int cmptno;
449
450 if (dec->state == JPC_MH) {
451
452 compinfos = jas_alloc2(dec->numcomps, sizeof(jas_image_cmptparm_t));
453 assert(compinfos);
454 for (cmptno = 0, cmpt = dec->cmpts, compinfo = compinfos;
455 cmptno < dec->numcomps; ++cmptno, ++cmpt, ++compinfo) {
456 compinfo->tlx = 0;
457 compinfo->tly = 0;
458 compinfo->prec = cmpt->prec;
459 compinfo->sgnd = cmpt->sgnd;
460 compinfo->width = cmpt->width;
461 compinfo->height = cmpt->height;
462 compinfo->hstep = cmpt->hstep;
463 compinfo->vstep = cmpt->vstep;
464 }
465
466 if (!(dec->image = jas_image_create(dec->numcomps, compinfos,
467 JAS_CLRSPC_UNKNOWN))) {
468 return -1;
469 }
470 jas_free(compinfos);
471
472 /* Is the packet header information stored in PPM marker segments in
473 the main header? */
474 if (dec->ppmstab) {
475 /* Convert the PPM marker segment data into a collection of streams
476 (one stream per tile-part). */
477 if (!(dec->pkthdrstreams = jpc_ppmstabtostreams(dec->ppmstab))) {
478 abort();
479 }
480 jpc_ppxstab_destroy(dec->ppmstab);
481 dec->ppmstab = 0;
482 }
483 }
484
485 if (sot->len > 0) {
486 dec->curtileendoff = jas_stream_getrwcount(dec->in) - ms->len -
487 4 + sot->len;
488 } else {
489 dec->curtileendoff = 0;
490 }
491
492 if (JAS_CAST(int, sot->tileno) > dec->numtiles) {
493 jas_eprintf("invalid tile number in SOT marker segment\n");
494 return -1;
495 }
496 /* Set the current tile. */
497 dec->curtile = &dec->tiles[sot->tileno];
498 tile = dec->curtile;
499 /* Ensure that this is the expected part number. */
500 if (sot->partno != tile->partno) {
501 return -1;
502 }
503 if (tile->numparts > 0 && sot->partno >= tile->numparts) {
504 return -1;
505 }
506 if (!tile->numparts && sot->numparts > 0) {
507 tile->numparts = sot->numparts;
508 }
509
510 tile->pptstab = 0;
511
512 switch (tile->state) {
513 case JPC_TILE_INIT:
514 /* This is the first tile-part for this tile. */
515 tile->state = JPC_TILE_ACTIVE;
516 assert(!tile->cp);
517 if (!(tile->cp = jpc_dec_cp_copy(dec->cp))) {
518 return -1;
519 }
520 jpc_dec_cp_resetflags(dec->cp);
521 break;
522 default:
523 if (sot->numparts == sot->partno - 1) {
524 tile->state = JPC_TILE_ACTIVELAST;
525 }
526 break;
527 }
528
529 /* Note: We do not increment the expected tile-part number until
530 all processing for this tile-part is complete. */
531
532 /* We should expect to encounter other tile-part header marker
533 segments next. */
534 dec->state = JPC_TPH;
535
536 return 0;
537 }
538
jpc_dec_process_sod(jpc_dec_t * dec,jpc_ms_t * ms)539 static int jpc_dec_process_sod(jpc_dec_t *dec, jpc_ms_t *ms)
540 {
541 jpc_dec_tile_t *tile;
542 int pos;
543
544 /* Eliminate compiler warnings about unused variables. */
545 ms = 0;
546
547 if (!(tile = dec->curtile)) {
548 return -1;
549 }
550
551 if (!tile->partno) {
552 if (!jpc_dec_cp_isvalid(tile->cp)) {
553 return -1;
554 }
555 jpc_dec_cp_prepare(tile->cp);
556 if (jpc_dec_tileinit(dec, tile)) {
557 return -1;
558 }
559 }
560
561 /* Are packet headers stored in the main header or tile-part header? */
562 if (dec->pkthdrstreams) {
563 /* Get the stream containing the packet header data for this
564 tile-part. */
565 if (!(tile->pkthdrstream = jpc_streamlist_remove(dec->pkthdrstreams, 0))) {
566 return -1;
567 }
568 }
569
570 if (tile->pptstab) {
571 if (!tile->pkthdrstream) {
572 if (!(tile->pkthdrstream = jas_stream_memopen(0, 0))) {
573 return -1;
574 }
575 }
576 pos = jas_stream_tell(tile->pkthdrstream);
577 jas_stream_seek(tile->pkthdrstream, 0, SEEK_END);
578 if (jpc_pptstabwrite(tile->pkthdrstream, tile->pptstab)) {
579 return -1;
580 }
581 jas_stream_seek(tile->pkthdrstream, pos, SEEK_SET);
582 jpc_ppxstab_destroy(tile->pptstab);
583 tile->pptstab = 0;
584 }
585
586 if (jas_getdbglevel() >= 10) {
587 jpc_dec_dump(dec, stderr);
588 }
589
590 if (jpc_dec_decodepkts(dec, (tile->pkthdrstream) ? tile->pkthdrstream :
591 dec->in, dec->in)) {
592 jas_eprintf("jpc_dec_decodepkts failed\n");
593 return -1;
594 }
595
596 /* Gobble any unconsumed tile data. */
597 if (dec->curtileendoff > 0) {
598 long curoff;
599 uint_fast32_t n;
600 curoff = jas_stream_getrwcount(dec->in);
601 if (curoff < dec->curtileendoff) {
602 n = dec->curtileendoff - curoff;
603 jas_eprintf("warning: ignoring trailing garbage (%lu bytes)\n",
604 (unsigned long) n);
605
606 while (n-- > 0) {
607 if (jas_stream_getc(dec->in) == EOF) {
608 jas_eprintf("read error\n");
609 return -1;
610 }
611 }
612 } else if (curoff > dec->curtileendoff) {
613 jas_eprintf("warning: not enough tile data (%lu bytes)\n",
614 (unsigned long) curoff - dec->curtileendoff);
615 }
616
617 }
618
619 if (tile->numparts > 0 && tile->partno == tile->numparts - 1) {
620 if (jpc_dec_tiledecode(dec, tile)) {
621 return -1;
622 }
623 jpc_dec_tilefini(dec, tile);
624 }
625
626 dec->curtile = 0;
627
628 /* Increment the expected tile-part number. */
629 ++tile->partno;
630
631 /* We should expect to encounter a SOT marker segment next. */
632 dec->state = JPC_TPHSOT;
633
634 return 0;
635 }
636
jpc_dec_tileinit(jpc_dec_t * dec,jpc_dec_tile_t * tile)637 static int jpc_dec_tileinit(jpc_dec_t *dec, jpc_dec_tile_t *tile)
638 {
639 jpc_dec_tcomp_t *tcomp;
640 int compno;
641 int rlvlno;
642 jpc_dec_rlvl_t *rlvl;
643 jpc_dec_band_t *band;
644 jpc_dec_prc_t *prc;
645 int bndno;
646 jpc_tsfb_band_t *bnd;
647 int bandno;
648 jpc_dec_ccp_t *ccp;
649 int prccnt;
650 jpc_dec_cblk_t *cblk;
651 int cblkcnt;
652 uint_fast32_t tlprcxstart;
653 uint_fast32_t tlprcystart;
654 uint_fast32_t brprcxend;
655 uint_fast32_t brprcyend;
656 uint_fast32_t tlcbgxstart;
657 uint_fast32_t tlcbgystart;
658 uint_fast32_t brcbgxend;
659 uint_fast32_t brcbgyend;
660 uint_fast32_t cbgxstart;
661 uint_fast32_t cbgystart;
662 uint_fast32_t cbgxend;
663 uint_fast32_t cbgyend;
664 uint_fast32_t tlcblkxstart;
665 uint_fast32_t tlcblkystart;
666 uint_fast32_t brcblkxend;
667 uint_fast32_t brcblkyend;
668 uint_fast32_t cblkxstart;
669 uint_fast32_t cblkystart;
670 uint_fast32_t cblkxend;
671 uint_fast32_t cblkyend;
672 uint_fast32_t tmpxstart;
673 uint_fast32_t tmpystart;
674 uint_fast32_t tmpxend;
675 uint_fast32_t tmpyend;
676 jpc_dec_cp_t *cp;
677 jpc_tsfb_band_t bnds[64];
678 jpc_pchg_t *pchg;
679 int pchgno;
680 jpc_dec_cmpt_t *cmpt;
681
682 cp = tile->cp;
683 tile->realmode = 0;
684 if (cp->mctid == JPC_MCT_ICT) {
685 tile->realmode = 1;
686 }
687
688 for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
689 dec->numcomps; ++compno, ++tcomp, ++cmpt) {
690 ccp = &tile->cp->ccps[compno];
691 if (ccp->qmfbid == JPC_COX_INS) {
692 tile->realmode = 1;
693 }
694 tcomp->numrlvls = ccp->numrlvls;
695 if (!(tcomp->rlvls = jas_alloc2(tcomp->numrlvls,
696 sizeof(jpc_dec_rlvl_t)))) {
697 return -1;
698 }
699 if (!(tcomp->data = jas_seq2d_create(JPC_CEILDIV(tile->xstart,
700 cmpt->hstep), JPC_CEILDIV(tile->ystart, cmpt->vstep),
701 JPC_CEILDIV(tile->xend, cmpt->hstep), JPC_CEILDIV(tile->yend,
702 cmpt->vstep)))) {
703 return -1;
704 }
705 if (!(tcomp->tsfb = jpc_cod_gettsfb(ccp->qmfbid,
706 tcomp->numrlvls - 1))) {
707 return -1;
708 }
709 {
710 jpc_tsfb_getbands(tcomp->tsfb, jas_seq2d_xstart(tcomp->data), jas_seq2d_ystart(tcomp->data), jas_seq2d_xend(tcomp->data), jas_seq2d_yend(tcomp->data), bnds);
711 }
712 for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;
713 ++rlvlno, ++rlvl) {
714 rlvl->bands = 0;
715 rlvl->xstart = JPC_CEILDIVPOW2(tcomp->xstart,
716 tcomp->numrlvls - 1 - rlvlno);
717 rlvl->ystart = JPC_CEILDIVPOW2(tcomp->ystart,
718 tcomp->numrlvls - 1 - rlvlno);
719 rlvl->xend = JPC_CEILDIVPOW2(tcomp->xend,
720 tcomp->numrlvls - 1 - rlvlno);
721 rlvl->yend = JPC_CEILDIVPOW2(tcomp->yend,
722 tcomp->numrlvls - 1 - rlvlno);
723 rlvl->prcwidthexpn = ccp->prcwidthexpns[rlvlno];
724 rlvl->prcheightexpn = ccp->prcheightexpns[rlvlno];
725 tlprcxstart = JPC_FLOORDIVPOW2(rlvl->xstart,
726 rlvl->prcwidthexpn) << rlvl->prcwidthexpn;
727 tlprcystart = JPC_FLOORDIVPOW2(rlvl->ystart,
728 rlvl->prcheightexpn) << rlvl->prcheightexpn;
729 brprcxend = JPC_CEILDIVPOW2(rlvl->xend,
730 rlvl->prcwidthexpn) << rlvl->prcwidthexpn;
731 brprcyend = JPC_CEILDIVPOW2(rlvl->yend,
732 rlvl->prcheightexpn) << rlvl->prcheightexpn;
733 rlvl->numhprcs = (brprcxend - tlprcxstart) >>
734 rlvl->prcwidthexpn;
735 rlvl->numvprcs = (brprcyend - tlprcystart) >>
736 rlvl->prcheightexpn;
737 rlvl->numprcs = rlvl->numhprcs * rlvl->numvprcs;
738
739 if (rlvl->xstart >= rlvl->xend || rlvl->ystart >= rlvl->yend) {
740 rlvl->bands = 0;
741 rlvl->numprcs = 0;
742 rlvl->numhprcs = 0;
743 rlvl->numvprcs = 0;
744 continue;
745 }
746 if (!rlvlno) {
747 tlcbgxstart = tlprcxstart;
748 tlcbgystart = tlprcystart;
749 brcbgxend = brprcxend;
750 brcbgyend = brprcyend;
751 rlvl->cbgwidthexpn = rlvl->prcwidthexpn;
752 rlvl->cbgheightexpn = rlvl->prcheightexpn;
753 } else {
754 tlcbgxstart = JPC_CEILDIVPOW2(tlprcxstart, 1);
755 tlcbgystart = JPC_CEILDIVPOW2(tlprcystart, 1);
756 brcbgxend = JPC_CEILDIVPOW2(brprcxend, 1);
757 brcbgyend = JPC_CEILDIVPOW2(brprcyend, 1);
758 rlvl->cbgwidthexpn = rlvl->prcwidthexpn - 1;
759 rlvl->cbgheightexpn = rlvl->prcheightexpn - 1;
760 }
761 rlvl->cblkwidthexpn = JAS_MIN(ccp->cblkwidthexpn,
762 rlvl->cbgwidthexpn);
763 rlvl->cblkheightexpn = JAS_MIN(ccp->cblkheightexpn,
764 rlvl->cbgheightexpn);
765
766 rlvl->numbands = (!rlvlno) ? 1 : 3;
767 if (!(rlvl->bands = jas_alloc2(rlvl->numbands,
768 sizeof(jpc_dec_band_t)))) {
769 return -1;
770 }
771 for (bandno = 0, band = rlvl->bands;
772 bandno < rlvl->numbands; ++bandno, ++band) {
773 bndno = (!rlvlno) ? 0 : (3 * (rlvlno - 1) +
774 bandno + 1);
775 bnd = &bnds[bndno];
776
777 band->orient = bnd->orient;
778 band->stepsize = ccp->stepsizes[bndno];
779 band->analgain = JPC_NOMINALGAIN(ccp->qmfbid,
780 tcomp->numrlvls - 1, rlvlno, band->orient);
781 band->absstepsize = jpc_calcabsstepsize(band->stepsize,
782 cmpt->prec + band->analgain);
783 band->numbps = ccp->numguardbits +
784 JPC_QCX_GETEXPN(band->stepsize) - 1;
785 band->roishift = (ccp->roishift + band->numbps >= JPC_PREC) ?
786 (JPC_PREC - 1 - band->numbps) : ccp->roishift;
787 band->data = 0;
788 band->prcs = 0;
789 if (bnd->xstart == bnd->xend || bnd->ystart == bnd->yend) {
790 continue;
791 }
792 if (!(band->data = jas_seq2d_create(0, 0, 0, 0))) {
793 return -1;
794 }
795 jas_seq2d_bindsub(band->data, tcomp->data, bnd->locxstart, bnd->locystart, bnd->locxend, bnd->locyend);
796 jas_seq2d_setshift(band->data, bnd->xstart, bnd->ystart);
797
798 assert(rlvl->numprcs);
799
800 if (!(band->prcs = jas_alloc2(rlvl->numprcs, sizeof(jpc_dec_prc_t)))) {
801 return -1;
802 }
803
804 /************************************************/
805 cbgxstart = tlcbgxstart;
806 cbgystart = tlcbgystart;
807 for (prccnt = rlvl->numprcs, prc = band->prcs;
808 prccnt > 0; --prccnt, ++prc) {
809 cbgxend = cbgxstart + (1 << rlvl->cbgwidthexpn);
810 cbgyend = cbgystart + (1 << rlvl->cbgheightexpn);
811 prc->xstart = JAS_MAX(cbgxstart, JAS_CAST(uint_fast32_t, jas_seq2d_xstart(band->data)));
812 prc->ystart = JAS_MAX(cbgystart, JAS_CAST(uint_fast32_t, jas_seq2d_ystart(band->data)));
813 prc->xend = JAS_MIN(cbgxend, JAS_CAST(uint_fast32_t, jas_seq2d_xend(band->data)));
814 prc->yend = JAS_MIN(cbgyend, JAS_CAST(uint_fast32_t, jas_seq2d_yend(band->data)));
815 if (prc->xend > prc->xstart && prc->yend > prc->ystart) {
816 tlcblkxstart = JPC_FLOORDIVPOW2(prc->xstart,
817 rlvl->cblkwidthexpn) << rlvl->cblkwidthexpn;
818 tlcblkystart = JPC_FLOORDIVPOW2(prc->ystart,
819 rlvl->cblkheightexpn) << rlvl->cblkheightexpn;
820 brcblkxend = JPC_CEILDIVPOW2(prc->xend,
821 rlvl->cblkwidthexpn) << rlvl->cblkwidthexpn;
822 brcblkyend = JPC_CEILDIVPOW2(prc->yend,
823 rlvl->cblkheightexpn) << rlvl->cblkheightexpn;
824 prc->numhcblks = (brcblkxend - tlcblkxstart) >>
825 rlvl->cblkwidthexpn;
826 prc->numvcblks = (brcblkyend - tlcblkystart) >>
827 rlvl->cblkheightexpn;
828 prc->numcblks = prc->numhcblks * prc->numvcblks;
829 assert(prc->numcblks > 0);
830
831 if (!(prc->incltagtree = jpc_tagtree_create(prc->numhcblks, prc->numvcblks))) {
832 return -1;
833 }
834 if (!(prc->numimsbstagtree = jpc_tagtree_create(prc->numhcblks, prc->numvcblks))) {
835 return -1;
836 }
837 if (!(prc->cblks = jas_alloc2(prc->numcblks, sizeof(jpc_dec_cblk_t)))) {
838 return -1;
839 }
840
841 cblkxstart = cbgxstart;
842 cblkystart = cbgystart;
843 for (cblkcnt = prc->numcblks, cblk = prc->cblks; cblkcnt > 0;) {
844 cblkxend = cblkxstart + (1 << rlvl->cblkwidthexpn);
845 cblkyend = cblkystart + (1 << rlvl->cblkheightexpn);
846 tmpxstart = JAS_MAX(cblkxstart, prc->xstart);
847 tmpystart = JAS_MAX(cblkystart, prc->ystart);
848 tmpxend = JAS_MIN(cblkxend, prc->xend);
849 tmpyend = JAS_MIN(cblkyend, prc->yend);
850 if (tmpxend > tmpxstart && tmpyend > tmpystart) {
851 cblk->firstpassno = -1;
852 cblk->mqdec = 0;
853 cblk->nulldec = 0;
854 cblk->flags = 0;
855 cblk->numpasses = 0;
856 cblk->segs.head = 0;
857 cblk->segs.tail = 0;
858 cblk->curseg = 0;
859 cblk->numimsbs = 0;
860 cblk->numlenbits = 3;
861 cblk->flags = 0;
862 if (!(cblk->data = jas_seq2d_create(0, 0, 0, 0))) {
863 return -1;
864 }
865 jas_seq2d_bindsub(cblk->data, band->data, tmpxstart, tmpystart, tmpxend, tmpyend);
866 ++cblk;
867 --cblkcnt;
868 }
869 cblkxstart += 1 << rlvl->cblkwidthexpn;
870 if (cblkxstart >= cbgxend) {
871 cblkxstart = cbgxstart;
872 cblkystart += 1 << rlvl->cblkheightexpn;
873 }
874 }
875
876 } else {
877 prc->cblks = 0;
878 prc->incltagtree = 0;
879 prc->numimsbstagtree = 0;
880 }
881 cbgxstart += 1 << rlvl->cbgwidthexpn;
882 if (cbgxstart >= brcbgxend) {
883 cbgxstart = tlcbgxstart;
884 cbgystart += 1 << rlvl->cbgheightexpn;
885 }
886
887 }
888 /********************************************/
889 }
890 }
891 }
892
893 if (!(tile->pi = jpc_dec_pi_create(dec, tile)))
894 {
895 return -1;
896 }
897
898 for (pchgno = 0; pchgno < jpc_pchglist_numpchgs(tile->cp->pchglist);
899 ++pchgno) {
900 pchg = jpc_pchg_copy(jpc_pchglist_get(tile->cp->pchglist, pchgno));
901 assert(pchg);
902 jpc_pi_addpchg(tile->pi, pchg);
903 }
904 jpc_pi_init(tile->pi);
905
906 return 0;
907 }
908
jpc_dec_tilefini(jpc_dec_t * dec,jpc_dec_tile_t * tile)909 static int jpc_dec_tilefini(jpc_dec_t *dec, jpc_dec_tile_t *tile)
910 {
911 jpc_dec_tcomp_t *tcomp;
912 int compno;
913 int bandno;
914 int rlvlno;
915 jpc_dec_band_t *band;
916 jpc_dec_rlvl_t *rlvl;
917 int prcno;
918 jpc_dec_prc_t *prc;
919 jpc_dec_seg_t *seg;
920 jpc_dec_cblk_t *cblk;
921 int cblkno;
922
923 if (tile->tcomps) {
924
925 for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
926 ++compno, ++tcomp) {
927 for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;
928 ++rlvlno, ++rlvl) {
929 if (!rlvl->bands) {
930 continue;
931 }
932 for (bandno = 0, band = rlvl->bands; bandno < rlvl->numbands; ++bandno, ++band) {
933 if (band->prcs) {
934 for (prcno = 0, prc = band->prcs; prcno <
935 rlvl->numprcs; ++prcno, ++prc) {
936 if (!prc->cblks) {
937 continue;
938 }
939 for (cblkno = 0, cblk = prc->cblks; cblkno < prc->numcblks; ++cblkno, ++cblk) {
940
941 while (cblk->segs.head) {
942 seg = cblk->segs.head;
943 jpc_seglist_remove(&cblk->segs, seg);
944 jpc_seg_destroy(seg);
945 }
946 jas_matrix_destroy(cblk->data);
947 if (cblk->mqdec) {
948 jpc_mqdec_destroy(cblk->mqdec);
949 }
950 if (cblk->nulldec) {
951 jpc_bitstream_close(cblk->nulldec);
952 }
953 if (cblk->flags) {
954 jas_matrix_destroy(cblk->flags);
955 }
956 }
957 if (prc->incltagtree) {
958 jpc_tagtree_destroy(prc->incltagtree);
959 }
960 if (prc->numimsbstagtree) {
961 jpc_tagtree_destroy(prc->numimsbstagtree);
962 }
963 if (prc->cblks) {
964 jas_free(prc->cblks);
965 }
966 }
967 }
968 if (band->data) {
969 jas_matrix_destroy(band->data);
970 }
971 if (band->prcs) {
972 jas_free(band->prcs);
973 }
974 }
975 if (rlvl->bands) {
976 jas_free(rlvl->bands);
977 }
978 }
979 if (tcomp->rlvls) {
980 jas_free(tcomp->rlvls);
981 }
982 if (tcomp->data) {
983 jas_matrix_destroy(tcomp->data);
984 }
985 if (tcomp->tsfb) {
986 jpc_tsfb_destroy(tcomp->tsfb);
987 }
988 }
989 }
990 if (tile->cp) {
991 jpc_dec_cp_destroy(tile->cp);
992 tile->cp = 0;
993 }
994 if (tile->tcomps) {
995 jas_free(tile->tcomps);
996 tile->tcomps = 0;
997 }
998 if (tile->pi) {
999 jpc_pi_destroy(tile->pi);
1000 tile->pi = 0;
1001 }
1002 if (tile->pkthdrstream) {
1003 jas_stream_close(tile->pkthdrstream);
1004 tile->pkthdrstream = 0;
1005 }
1006 if (tile->pptstab) {
1007 jpc_ppxstab_destroy(tile->pptstab);
1008 tile->pptstab = 0;
1009 }
1010
1011 tile->state = JPC_TILE_DONE;
1012
1013 return 0;
1014 }
1015
jpc_dec_tiledecode(jpc_dec_t * dec,jpc_dec_tile_t * tile)1016 static int jpc_dec_tiledecode(jpc_dec_t *dec, jpc_dec_tile_t *tile)
1017 {
1018 int i;
1019 int j;
1020 jpc_dec_tcomp_t *tcomp;
1021 jpc_dec_rlvl_t *rlvl;
1022 jpc_dec_band_t *band;
1023 int compno;
1024 int rlvlno;
1025 int bandno;
1026 int adjust;
1027 int v;
1028 jpc_dec_ccp_t *ccp;
1029 jpc_dec_cmpt_t *cmpt;
1030
1031 if (jpc_dec_decodecblks(dec, tile)) {
1032 jas_eprintf("jpc_dec_decodecblks failed\n");
1033 return -1;
1034 }
1035
1036 /* Perform dequantization. */
1037 for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
1038 ++compno, ++tcomp) {
1039 ccp = &tile->cp->ccps[compno];
1040 for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno < tcomp->numrlvls;
1041 ++rlvlno, ++rlvl) {
1042 if (!rlvl->bands) {
1043 continue;
1044 }
1045 for (bandno = 0, band = rlvl->bands;
1046 bandno < rlvl->numbands; ++bandno, ++band) {
1047 if (!band->data) {
1048 continue;
1049 }
1050 jpc_undo_roi(band->data, band->roishift, ccp->roishift -
1051 band->roishift, band->numbps);
1052 if (tile->realmode) {
1053 jas_matrix_asl(band->data, JPC_FIX_FRACBITS);
1054 jpc_dequantize(band->data, band->absstepsize);
1055 }
1056
1057 }
1058 }
1059 }
1060
1061 /* Apply an inverse wavelet transform if necessary. */
1062 for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
1063 ++compno, ++tcomp) {
1064 ccp = &tile->cp->ccps[compno];
1065 jpc_tsfb_synthesize(tcomp->tsfb, tcomp->data);
1066 }
1067
1068
1069 /* Apply an inverse intercomponent transform if necessary. */
1070 switch (tile->cp->mctid) {
1071 case JPC_MCT_RCT:
1072 assert(dec->numcomps == 3 || dec->numcomps == 4);
1073 jpc_irct(tile->tcomps[0].data, tile->tcomps[1].data,
1074 tile->tcomps[2].data);
1075 break;
1076 case JPC_MCT_ICT:
1077 assert(dec->numcomps == 3 || dec->numcomps == 4);
1078 jpc_iict(tile->tcomps[0].data, tile->tcomps[1].data,
1079 tile->tcomps[2].data);
1080 break;
1081 }
1082
1083 /* Perform rounding and convert to integer values. */
1084 if (tile->realmode) {
1085 for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
1086 ++compno, ++tcomp) {
1087 for (i = 0; i < jas_matrix_numrows(tcomp->data); ++i) {
1088 for (j = 0; j < jas_matrix_numcols(tcomp->data); ++j) {
1089 v = jas_matrix_get(tcomp->data, i, j);
1090 v = jpc_fix_round(v);
1091 jas_matrix_set(tcomp->data, i, j, jpc_fixtoint(v));
1092 }
1093 }
1094 }
1095 }
1096
1097 /* Perform level shift. */
1098 for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
1099 dec->numcomps; ++compno, ++tcomp, ++cmpt) {
1100 adjust = cmpt->sgnd ? 0 : (1 << (cmpt->prec - 1));
1101 for (i = 0; i < jas_matrix_numrows(tcomp->data); ++i) {
1102 for (j = 0; j < jas_matrix_numcols(tcomp->data); ++j) {
1103 *jas_matrix_getref(tcomp->data, i, j) += adjust;
1104 }
1105 }
1106 }
1107
1108 /* Perform clipping. */
1109 for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
1110 dec->numcomps; ++compno, ++tcomp, ++cmpt) {
1111 jpc_fix_t mn;
1112 jpc_fix_t mx;
1113 mn = cmpt->sgnd ? (-(1 << (cmpt->prec - 1))) : (0);
1114 mx = cmpt->sgnd ? ((1 << (cmpt->prec - 1)) - 1) : ((1 <<
1115 cmpt->prec) - 1);
1116 jas_matrix_clip(tcomp->data, mn, mx);
1117 }
1118
1119 /* XXX need to free tsfb struct */
1120
1121 /* Write the data for each component of the image. */
1122 for (compno = 0, tcomp = tile->tcomps, cmpt = dec->cmpts; compno <
1123 dec->numcomps; ++compno, ++tcomp, ++cmpt) {
1124 if (jas_image_writecmpt(dec->image, compno, tcomp->xstart -
1125 JPC_CEILDIV(dec->xstart, cmpt->hstep), tcomp->ystart -
1126 JPC_CEILDIV(dec->ystart, cmpt->vstep), jas_matrix_numcols(
1127 tcomp->data), jas_matrix_numrows(tcomp->data), tcomp->data)) {
1128 jas_eprintf("write component failed\n");
1129 return -4;
1130 }
1131 }
1132
1133 return 0;
1134 }
1135
jpc_dec_process_eoc(jpc_dec_t * dec,jpc_ms_t * ms)1136 static int jpc_dec_process_eoc(jpc_dec_t *dec, jpc_ms_t *ms)
1137 {
1138 int tileno;
1139 jpc_dec_tile_t *tile;
1140
1141 /* Eliminate compiler warnings about unused variables. */
1142 ms = 0;
1143
1144 for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; ++tileno,
1145 ++tile) {
1146 if (tile->state == JPC_TILE_ACTIVE) {
1147 if (jpc_dec_tiledecode(dec, tile)) {
1148 return -1;
1149 }
1150 }
1151 jpc_dec_tilefini(dec, tile);
1152 }
1153
1154 /* We are done processing the code stream. */
1155 dec->state = JPC_MT;
1156
1157 return 1;
1158 }
1159
jpc_dec_process_siz(jpc_dec_t * dec,jpc_ms_t * ms)1160 static int jpc_dec_process_siz(jpc_dec_t *dec, jpc_ms_t *ms)
1161 {
1162 jpc_siz_t *siz = &ms->parms.siz;
1163 int compno;
1164 int tileno;
1165 jpc_dec_tile_t *tile;
1166 jpc_dec_tcomp_t *tcomp;
1167 int htileno;
1168 int vtileno;
1169 jpc_dec_cmpt_t *cmpt;
1170
1171 dec->xstart = siz->xoff;
1172 dec->ystart = siz->yoff;
1173 dec->xend = siz->width;
1174 dec->yend = siz->height;
1175 dec->tilewidth = siz->tilewidth;
1176 dec->tileheight = siz->tileheight;
1177 dec->tilexoff = siz->tilexoff;
1178 dec->tileyoff = siz->tileyoff;
1179 dec->numcomps = siz->numcomps;
1180 if (!(dec->cp = jpc_dec_cp_create(dec->numcomps))) {
1181 return -1;
1182 }
1183
1184 if (!(dec->cmpts = jas_alloc2(dec->numcomps, sizeof(jpc_dec_cmpt_t)))) {
1185 return -1;
1186 }
1187
1188 for (compno = 0, cmpt = dec->cmpts; compno < dec->numcomps; ++compno,
1189 ++cmpt) {
1190 cmpt->prec = siz->comps[compno].prec;
1191 cmpt->sgnd = siz->comps[compno].sgnd;
1192 cmpt->hstep = siz->comps[compno].hsamp;
1193 cmpt->vstep = siz->comps[compno].vsamp;
1194 cmpt->width = JPC_CEILDIV(dec->xend, cmpt->hstep) -
1195 JPC_CEILDIV(dec->xstart, cmpt->hstep);
1196 cmpt->height = JPC_CEILDIV(dec->yend, cmpt->vstep) -
1197 JPC_CEILDIV(dec->ystart, cmpt->vstep);
1198 cmpt->hsubstep = 0;
1199 cmpt->vsubstep = 0;
1200 }
1201
1202 dec->image = 0;
1203
1204 dec->numhtiles = JPC_CEILDIV(dec->xend - dec->tilexoff, dec->tilewidth);
1205 dec->numvtiles = JPC_CEILDIV(dec->yend - dec->tileyoff, dec->tileheight);
1206 dec->numtiles = dec->numhtiles * dec->numvtiles;
1207 if (!(dec->tiles = jas_alloc2(dec->numtiles, sizeof(jpc_dec_tile_t)))) {
1208 return -1;
1209 }
1210
1211 for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles; ++tileno,
1212 ++tile) {
1213 htileno = tileno % dec->numhtiles;
1214 vtileno = tileno / dec->numhtiles;
1215 tile->realmode = 0;
1216 tile->state = JPC_TILE_INIT;
1217 tile->xstart = JAS_MAX(dec->tilexoff + htileno * dec->tilewidth,
1218 dec->xstart);
1219 tile->ystart = JAS_MAX(dec->tileyoff + vtileno * dec->tileheight,
1220 dec->ystart);
1221 tile->xend = JAS_MIN(dec->tilexoff + (htileno + 1) *
1222 dec->tilewidth, dec->xend);
1223 tile->yend = JAS_MIN(dec->tileyoff + (vtileno + 1) *
1224 dec->tileheight, dec->yend);
1225 tile->numparts = 0;
1226 tile->partno = 0;
1227 tile->pkthdrstream = 0;
1228 tile->pkthdrstreampos = 0;
1229 tile->pptstab = 0;
1230 tile->cp = 0;
1231 if (!(tile->tcomps = jas_alloc2(dec->numcomps,
1232 sizeof(jpc_dec_tcomp_t)))) {
1233 return -1;
1234 }
1235 for (compno = 0, cmpt = dec->cmpts, tcomp = tile->tcomps;
1236 compno < dec->numcomps; ++compno, ++cmpt, ++tcomp) {
1237 tcomp->rlvls = 0;
1238 tcomp->data = 0;
1239 tcomp->xstart = JPC_CEILDIV(tile->xstart, cmpt->hstep);
1240 tcomp->ystart = JPC_CEILDIV(tile->ystart, cmpt->vstep);
1241 tcomp->xend = JPC_CEILDIV(tile->xend, cmpt->hstep);
1242 tcomp->yend = JPC_CEILDIV(tile->yend, cmpt->vstep);
1243 tcomp->tsfb = 0;
1244 }
1245 }
1246
1247 dec->pkthdrstreams = 0;
1248
1249 /* We should expect to encounter other main header marker segments
1250 or an SOT marker segment next. */
1251 dec->state = JPC_MH;
1252
1253 return 0;
1254 }
1255
jpc_dec_process_cod(jpc_dec_t * dec,jpc_ms_t * ms)1256 static int jpc_dec_process_cod(jpc_dec_t *dec, jpc_ms_t *ms)
1257 {
1258 jpc_cod_t *cod = &ms->parms.cod;
1259 jpc_dec_tile_t *tile;
1260
1261 switch (dec->state) {
1262 case JPC_MH:
1263 jpc_dec_cp_setfromcod(dec->cp, cod);
1264 break;
1265 case JPC_TPH:
1266 if (!(tile = dec->curtile)) {
1267 return -1;
1268 }
1269 if (tile->partno != 0) {
1270 return -1;
1271 }
1272 jpc_dec_cp_setfromcod(tile->cp, cod);
1273 break;
1274 }
1275 return 0;
1276 }
1277
jpc_dec_process_coc(jpc_dec_t * dec,jpc_ms_t * ms)1278 static int jpc_dec_process_coc(jpc_dec_t *dec, jpc_ms_t *ms)
1279 {
1280 jpc_coc_t *coc = &ms->parms.coc;
1281 jpc_dec_tile_t *tile;
1282
1283 if (JAS_CAST(int, coc->compno) > dec->numcomps) {
1284 jas_eprintf("invalid component number in COC marker segment\n");
1285 return -1;
1286 }
1287 switch (dec->state) {
1288 case JPC_MH:
1289 jpc_dec_cp_setfromcoc(dec->cp, coc);
1290 break;
1291 case JPC_TPH:
1292 if (!(tile = dec->curtile)) {
1293 return -1;
1294 }
1295 if (tile->partno > 0) {
1296 return -1;
1297 }
1298 jpc_dec_cp_setfromcoc(tile->cp, coc);
1299 break;
1300 }
1301 return 0;
1302 }
1303
jpc_dec_process_rgn(jpc_dec_t * dec,jpc_ms_t * ms)1304 static int jpc_dec_process_rgn(jpc_dec_t *dec, jpc_ms_t *ms)
1305 {
1306 jpc_rgn_t *rgn = &ms->parms.rgn;
1307 jpc_dec_tile_t *tile;
1308
1309 if (JAS_CAST(int, rgn->compno) > dec->numcomps) {
1310 jas_eprintf("invalid component number in RGN marker segment\n");
1311 return -1;
1312 }
1313 switch (dec->state) {
1314 case JPC_MH:
1315 jpc_dec_cp_setfromrgn(dec->cp, rgn);
1316 break;
1317 case JPC_TPH:
1318 if (!(tile = dec->curtile)) {
1319 return -1;
1320 }
1321 if (tile->partno > 0) {
1322 return -1;
1323 }
1324 jpc_dec_cp_setfromrgn(tile->cp, rgn);
1325 break;
1326 }
1327
1328 return 0;
1329 }
1330
jpc_dec_process_qcd(jpc_dec_t * dec,jpc_ms_t * ms)1331 static int jpc_dec_process_qcd(jpc_dec_t *dec, jpc_ms_t *ms)
1332 {
1333 jpc_qcd_t *qcd = &ms->parms.qcd;
1334 jpc_dec_tile_t *tile;
1335
1336 switch (dec->state) {
1337 case JPC_MH:
1338 jpc_dec_cp_setfromqcd(dec->cp, qcd);
1339 break;
1340 case JPC_TPH:
1341 if (!(tile = dec->curtile)) {
1342 return -1;
1343 }
1344 if (tile->partno > 0) {
1345 return -1;
1346 }
1347 jpc_dec_cp_setfromqcd(tile->cp, qcd);
1348 break;
1349 }
1350 return 0;
1351 }
1352
jpc_dec_process_qcc(jpc_dec_t * dec,jpc_ms_t * ms)1353 static int jpc_dec_process_qcc(jpc_dec_t *dec, jpc_ms_t *ms)
1354 {
1355 jpc_qcc_t *qcc = &ms->parms.qcc;
1356 jpc_dec_tile_t *tile;
1357
1358 if (JAS_CAST(int, qcc->compno) > dec->numcomps) {
1359 jas_eprintf("invalid component number in QCC marker segment\n");
1360 return -1;
1361 }
1362 switch (dec->state) {
1363 case JPC_MH:
1364 jpc_dec_cp_setfromqcc(dec->cp, qcc);
1365 break;
1366 case JPC_TPH:
1367 if (!(tile = dec->curtile)) {
1368 return -1;
1369 }
1370 if (tile->partno > 0) {
1371 return -1;
1372 }
1373 jpc_dec_cp_setfromqcc(tile->cp, qcc);
1374 break;
1375 }
1376 return 0;
1377 }
1378
jpc_dec_process_poc(jpc_dec_t * dec,jpc_ms_t * ms)1379 static int jpc_dec_process_poc(jpc_dec_t *dec, jpc_ms_t *ms)
1380 {
1381 jpc_poc_t *poc = &ms->parms.poc;
1382 jpc_dec_tile_t *tile;
1383 switch (dec->state) {
1384 case JPC_MH:
1385 if (jpc_dec_cp_setfrompoc(dec->cp, poc, 1)) {
1386 return -1;
1387 }
1388 break;
1389 case JPC_TPH:
1390 if (!(tile = dec->curtile)) {
1391 return -1;
1392 }
1393 if (!tile->partno) {
1394 if (jpc_dec_cp_setfrompoc(tile->cp, poc, (!tile->partno))) {
1395 return -1;
1396 }
1397 } else {
1398 jpc_pi_addpchgfrompoc(tile->pi, poc);
1399 }
1400 break;
1401 }
1402 return 0;
1403 }
1404
jpc_dec_process_ppm(jpc_dec_t * dec,jpc_ms_t * ms)1405 static int jpc_dec_process_ppm(jpc_dec_t *dec, jpc_ms_t *ms)
1406 {
1407 jpc_ppm_t *ppm = &ms->parms.ppm;
1408 jpc_ppxstabent_t *ppmstabent;
1409
1410 if (!dec->ppmstab) {
1411 if (!(dec->ppmstab = jpc_ppxstab_create())) {
1412 return -1;
1413 }
1414 }
1415
1416 if (!(ppmstabent = jpc_ppxstabent_create())) {
1417 return -1;
1418 }
1419 ppmstabent->ind = ppm->ind;
1420 ppmstabent->data = ppm->data;
1421 ppm->data = 0;
1422 ppmstabent->len = ppm->len;
1423 if (jpc_ppxstab_insert(dec->ppmstab, ppmstabent)) {
1424 return -1;
1425 }
1426 return 0;
1427 }
1428
jpc_dec_process_ppt(jpc_dec_t * dec,jpc_ms_t * ms)1429 static int jpc_dec_process_ppt(jpc_dec_t *dec, jpc_ms_t *ms)
1430 {
1431 jpc_ppt_t *ppt = &ms->parms.ppt;
1432 jpc_dec_tile_t *tile;
1433 jpc_ppxstabent_t *pptstabent;
1434
1435 tile = dec->curtile;
1436 if (!tile->pptstab) {
1437 if (!(tile->pptstab = jpc_ppxstab_create())) {
1438 return -1;
1439 }
1440 }
1441 if (!(pptstabent = jpc_ppxstabent_create())) {
1442 return -1;
1443 }
1444 pptstabent->ind = ppt->ind;
1445 pptstabent->data = ppt->data;
1446 ppt->data = 0;
1447 pptstabent->len = ppt->len;
1448 if (jpc_ppxstab_insert(tile->pptstab, pptstabent)) {
1449 return -1;
1450 }
1451 return 0;
1452 }
1453
jpc_dec_process_com(jpc_dec_t * dec,jpc_ms_t * ms)1454 static int jpc_dec_process_com(jpc_dec_t *dec, jpc_ms_t *ms)
1455 {
1456 /* Eliminate compiler warnings about unused variables. */
1457 dec = 0;
1458 ms = 0;
1459
1460 return 0;
1461 }
1462
jpc_dec_process_unk(jpc_dec_t * dec,jpc_ms_t * ms)1463 static int jpc_dec_process_unk(jpc_dec_t *dec, jpc_ms_t *ms)
1464 {
1465 /* Eliminate compiler warnings about unused variables. */
1466 dec = 0;
1467
1468 jas_eprintf("warning: ignoring unknown marker segment\n");
1469 jpc_ms_dump(ms, stderr);
1470 return 0;
1471 }
1472
1473 /******************************************************************************\
1474 *
1475 \******************************************************************************/
1476
jpc_dec_cp_create(uint_fast16_t numcomps)1477 static jpc_dec_cp_t *jpc_dec_cp_create(uint_fast16_t numcomps)
1478 {
1479 jpc_dec_cp_t *cp;
1480 jpc_dec_ccp_t *ccp;
1481 int compno;
1482
1483 if (!(cp = jas_malloc(sizeof(jpc_dec_cp_t)))) {
1484 return 0;
1485 }
1486 cp->flags = 0;
1487 cp->numcomps = numcomps;
1488 cp->prgord = 0;
1489 cp->numlyrs = 0;
1490 cp->mctid = 0;
1491 cp->csty = 0;
1492 if (!(cp->ccps = jas_alloc2(cp->numcomps, sizeof(jpc_dec_ccp_t)))) {
1493 return 0;
1494 }
1495 if (!(cp->pchglist = jpc_pchglist_create())) {
1496 jas_free(cp->ccps);
1497 return 0;
1498 }
1499 for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
1500 ++compno, ++ccp) {
1501 ccp->flags = 0;
1502 ccp->numrlvls = 0;
1503 ccp->cblkwidthexpn = 0;
1504 ccp->cblkheightexpn = 0;
1505 ccp->qmfbid = 0;
1506 ccp->numstepsizes = 0;
1507 ccp->numguardbits = 0;
1508 ccp->roishift = 0;
1509 ccp->cblkctx = 0;
1510 }
1511 return cp;
1512 }
1513
jpc_dec_cp_copy(jpc_dec_cp_t * cp)1514 static jpc_dec_cp_t *jpc_dec_cp_copy(jpc_dec_cp_t *cp)
1515 {
1516 jpc_dec_cp_t *newcp;
1517 jpc_dec_ccp_t *newccp;
1518 jpc_dec_ccp_t *ccp;
1519 int compno;
1520
1521 if (!(newcp = jpc_dec_cp_create(cp->numcomps))) {
1522 return 0;
1523 }
1524 newcp->flags = cp->flags;
1525 newcp->prgord = cp->prgord;
1526 newcp->numlyrs = cp->numlyrs;
1527 newcp->mctid = cp->mctid;
1528 newcp->csty = cp->csty;
1529 jpc_pchglist_destroy(newcp->pchglist);
1530 newcp->pchglist = 0;
1531 if (!(newcp->pchglist = jpc_pchglist_copy(cp->pchglist))) {
1532 jas_free(newcp);
1533 return 0;
1534 }
1535 for (compno = 0, newccp = newcp->ccps, ccp = cp->ccps;
1536 compno < cp->numcomps;
1537 ++compno, ++newccp, ++ccp) {
1538 *newccp = *ccp;
1539 }
1540 return newcp;
1541 }
1542
jpc_dec_cp_resetflags(jpc_dec_cp_t * cp)1543 static void jpc_dec_cp_resetflags(jpc_dec_cp_t *cp)
1544 {
1545 int compno;
1546 jpc_dec_ccp_t *ccp;
1547 cp->flags &= (JPC_CSET | JPC_QSET);
1548 for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
1549 ++compno, ++ccp) {
1550 ccp->flags = 0;
1551 }
1552 }
1553
jpc_dec_cp_destroy(jpc_dec_cp_t * cp)1554 static void jpc_dec_cp_destroy(jpc_dec_cp_t *cp)
1555 {
1556 if (cp->ccps) {
1557 jas_free(cp->ccps);
1558 }
1559 if (cp->pchglist) {
1560 jpc_pchglist_destroy(cp->pchglist);
1561 }
1562 jas_free(cp);
1563 }
1564
jpc_dec_cp_isvalid(jpc_dec_cp_t * cp)1565 static int jpc_dec_cp_isvalid(jpc_dec_cp_t *cp)
1566 {
1567 uint_fast16_t compcnt;
1568 jpc_dec_ccp_t *ccp;
1569
1570 if (!(cp->flags & JPC_CSET) || !(cp->flags & JPC_QSET)) {
1571 return 0;
1572 }
1573 for (compcnt = cp->numcomps, ccp = cp->ccps; compcnt > 0; --compcnt,
1574 ++ccp) {
1575 /* Is there enough step sizes for the number of bands? */
1576 if ((ccp->qsty != JPC_QCX_SIQNT && JAS_CAST(int, ccp->numstepsizes) < 3 *
1577 ccp->numrlvls - 2) || (ccp->qsty == JPC_QCX_SIQNT &&
1578 ccp->numstepsizes != 1)) {
1579 return 0;
1580 }
1581 }
1582 return 1;
1583 }
1584
calcstepsizes(uint_fast16_t refstepsize,int numrlvls,uint_fast16_t * stepsizes)1585 static void calcstepsizes(uint_fast16_t refstepsize, int numrlvls,
1586 uint_fast16_t *stepsizes)
1587 {
1588 int bandno;
1589 int numbands;
1590 uint_fast16_t expn;
1591 uint_fast16_t mant;
1592 expn = JPC_QCX_GETEXPN(refstepsize);
1593 mant = JPC_QCX_GETMANT(refstepsize);
1594 numbands = 3 * numrlvls - 2;
1595 for (bandno = 0; bandno < numbands; ++bandno) {
1596 stepsizes[bandno] = JPC_QCX_MANT(mant) | JPC_QCX_EXPN(expn +
1597 (numrlvls - 1) - (numrlvls - 1 - ((bandno > 0) ? ((bandno + 2) / 3) : (0))));
1598 }
1599 }
1600
jpc_dec_cp_prepare(jpc_dec_cp_t * cp)1601 static int jpc_dec_cp_prepare(jpc_dec_cp_t *cp)
1602 {
1603 jpc_dec_ccp_t *ccp;
1604 int compno;
1605 int i;
1606 for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
1607 ++compno, ++ccp) {
1608 if (!(ccp->csty & JPC_COX_PRT)) {
1609 for (i = 0; i < JPC_MAXRLVLS; ++i) {
1610 ccp->prcwidthexpns[i] = 15;
1611 ccp->prcheightexpns[i] = 15;
1612 }
1613 }
1614 if (ccp->qsty == JPC_QCX_SIQNT) {
1615 calcstepsizes(ccp->stepsizes[0], ccp->numrlvls, ccp->stepsizes);
1616 }
1617 }
1618 return 0;
1619 }
1620
jpc_dec_cp_setfromcod(jpc_dec_cp_t * cp,jpc_cod_t * cod)1621 static int jpc_dec_cp_setfromcod(jpc_dec_cp_t *cp, jpc_cod_t *cod)
1622 {
1623 jpc_dec_ccp_t *ccp;
1624 int compno;
1625 cp->flags |= JPC_CSET;
1626 cp->prgord = cod->prg;
1627 if (cod->mctrans) {
1628 cp->mctid = (cod->compparms.qmfbid == JPC_COX_INS) ? (JPC_MCT_ICT) : (JPC_MCT_RCT);
1629 } else {
1630 cp->mctid = JPC_MCT_NONE;
1631 }
1632 cp->numlyrs = cod->numlyrs;
1633 cp->csty = cod->csty & (JPC_COD_SOP | JPC_COD_EPH);
1634 for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
1635 ++compno, ++ccp) {
1636 jpc_dec_cp_setfromcox(cp, ccp, &cod->compparms, 0);
1637 }
1638 cp->flags |= JPC_CSET;
1639 return 0;
1640 }
1641
jpc_dec_cp_setfromcoc(jpc_dec_cp_t * cp,jpc_coc_t * coc)1642 static int jpc_dec_cp_setfromcoc(jpc_dec_cp_t *cp, jpc_coc_t *coc)
1643 {
1644 jpc_dec_cp_setfromcox(cp, &cp->ccps[coc->compno], &coc->compparms, JPC_COC);
1645 return 0;
1646 }
1647
jpc_dec_cp_setfromcox(jpc_dec_cp_t * cp,jpc_dec_ccp_t * ccp,jpc_coxcp_t * compparms,int flags)1648 static int jpc_dec_cp_setfromcox(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp,
1649 jpc_coxcp_t *compparms, int flags)
1650 {
1651 int rlvlno;
1652
1653 /* Eliminate compiler warnings about unused variables. */
1654 cp = 0;
1655
1656 if ((flags & JPC_COC) || !(ccp->flags & JPC_COC)) {
1657 ccp->numrlvls = compparms->numdlvls + 1;
1658 ccp->cblkwidthexpn = JPC_COX_GETCBLKSIZEEXPN(
1659 compparms->cblkwidthval);
1660 ccp->cblkheightexpn = JPC_COX_GETCBLKSIZEEXPN(
1661 compparms->cblkheightval);
1662 ccp->qmfbid = compparms->qmfbid;
1663 ccp->cblkctx = compparms->cblksty;
1664 ccp->csty = compparms->csty & JPC_COX_PRT;
1665 for (rlvlno = 0; rlvlno < compparms->numrlvls; ++rlvlno) {
1666 ccp->prcwidthexpns[rlvlno] =
1667 compparms->rlvls[rlvlno].parwidthval;
1668 ccp->prcheightexpns[rlvlno] =
1669 compparms->rlvls[rlvlno].parheightval;
1670 }
1671 ccp->flags |= flags | JPC_CSET;
1672 }
1673 return 0;
1674 }
1675
jpc_dec_cp_setfromqcd(jpc_dec_cp_t * cp,jpc_qcd_t * qcd)1676 static int jpc_dec_cp_setfromqcd(jpc_dec_cp_t *cp, jpc_qcd_t *qcd)
1677 {
1678 int compno;
1679 jpc_dec_ccp_t *ccp;
1680 for (compno = 0, ccp = cp->ccps; compno < cp->numcomps;
1681 ++compno, ++ccp) {
1682 jpc_dec_cp_setfromqcx(cp, ccp, &qcd->compparms, 0);
1683 }
1684 cp->flags |= JPC_QSET;
1685 return 0;
1686 }
1687
jpc_dec_cp_setfromqcc(jpc_dec_cp_t * cp,jpc_qcc_t * qcc)1688 static int jpc_dec_cp_setfromqcc(jpc_dec_cp_t *cp, jpc_qcc_t *qcc)
1689 {
1690 return jpc_dec_cp_setfromqcx(cp, &cp->ccps[qcc->compno], &qcc->compparms, JPC_QCC);
1691 }
1692
jpc_dec_cp_setfromqcx(jpc_dec_cp_t * cp,jpc_dec_ccp_t * ccp,jpc_qcxcp_t * compparms,int flags)1693 static int jpc_dec_cp_setfromqcx(jpc_dec_cp_t *cp, jpc_dec_ccp_t *ccp,
1694 jpc_qcxcp_t *compparms, int flags)
1695 {
1696 int bandno;
1697
1698 /* Eliminate compiler warnings about unused variables. */
1699 cp = 0;
1700
1701 if ((flags & JPC_QCC) || !(ccp->flags & JPC_QCC)) {
1702 ccp->flags |= flags | JPC_QSET;
1703 for (bandno = 0; bandno < compparms->numstepsizes; ++bandno) {
1704 ccp->stepsizes[bandno] = compparms->stepsizes[bandno];
1705 }
1706 ccp->numstepsizes = compparms->numstepsizes;
1707 ccp->numguardbits = compparms->numguard;
1708 ccp->qsty = compparms->qntsty;
1709 }
1710 return 0;
1711 }
1712
jpc_dec_cp_setfromrgn(jpc_dec_cp_t * cp,jpc_rgn_t * rgn)1713 static int jpc_dec_cp_setfromrgn(jpc_dec_cp_t *cp, jpc_rgn_t *rgn)
1714 {
1715 jpc_dec_ccp_t *ccp;
1716 ccp = &cp->ccps[rgn->compno];
1717 ccp->roishift = rgn->roishift;
1718 return 0;
1719 }
1720
jpc_pi_addpchgfrompoc(jpc_pi_t * pi,jpc_poc_t * poc)1721 static int jpc_pi_addpchgfrompoc(jpc_pi_t *pi, jpc_poc_t *poc)
1722 {
1723 int pchgno;
1724 jpc_pchg_t *pchg;
1725 for (pchgno = 0; pchgno < poc->numpchgs; ++pchgno) {
1726 if (!(pchg = jpc_pchg_copy(&poc->pchgs[pchgno]))) {
1727 return -1;
1728 }
1729 if (jpc_pchglist_insert(pi->pchglist, -1, pchg)) {
1730 return -1;
1731 }
1732 }
1733 return 0;
1734 }
1735
jpc_dec_cp_setfrompoc(jpc_dec_cp_t * cp,jpc_poc_t * poc,int reset)1736 static int jpc_dec_cp_setfrompoc(jpc_dec_cp_t *cp, jpc_poc_t *poc, int reset)
1737 {
1738 int pchgno;
1739 jpc_pchg_t *pchg;
1740 if (reset) {
1741 while (jpc_pchglist_numpchgs(cp->pchglist) > 0) {
1742 pchg = jpc_pchglist_remove(cp->pchglist, 0);
1743 jpc_pchg_destroy(pchg);
1744 }
1745 }
1746 for (pchgno = 0; pchgno < poc->numpchgs; ++pchgno) {
1747 if (!(pchg = jpc_pchg_copy(&poc->pchgs[pchgno]))) {
1748 return -1;
1749 }
1750 if (jpc_pchglist_insert(cp->pchglist, -1, pchg)) {
1751 return -1;
1752 }
1753 }
1754 return 0;
1755 }
1756
jpc_calcabsstepsize(int stepsize,int numbits)1757 static jpc_fix_t jpc_calcabsstepsize(int stepsize, int numbits)
1758 {
1759 jpc_fix_t absstepsize;
1760 int n;
1761
1762 absstepsize = jpc_inttofix(1);
1763 n = JPC_FIX_FRACBITS - 11;
1764 absstepsize |= (n >= 0) ? (JPC_QCX_GETMANT(stepsize) << n) :
1765 (JPC_QCX_GETMANT(stepsize) >> (-n));
1766 n = numbits - JPC_QCX_GETEXPN(stepsize);
1767 absstepsize = (n >= 0) ? (absstepsize << n) : (absstepsize >> (-n));
1768 return absstepsize;
1769 }
1770
jpc_dequantize(jas_matrix_t * x,jpc_fix_t absstepsize)1771 static void jpc_dequantize(jas_matrix_t *x, jpc_fix_t absstepsize)
1772 {
1773 int i;
1774 int j;
1775 int t;
1776
1777 assert(absstepsize >= 0);
1778 if (absstepsize == jpc_inttofix(1)) {
1779 return;
1780 }
1781
1782 for (i = 0; i < jas_matrix_numrows(x); ++i) {
1783 for (j = 0; j < jas_matrix_numcols(x); ++j) {
1784 t = jas_matrix_get(x, i, j);
1785 if (t) {
1786 t = jpc_fix_mul(t, absstepsize);
1787 } else {
1788 t = 0;
1789 }
1790 jas_matrix_set(x, i, j, t);
1791 }
1792 }
1793
1794 }
1795
jpc_undo_roi(jas_matrix_t * x,int roishift,int bgshift,int numbps)1796 static void jpc_undo_roi(jas_matrix_t *x, int roishift, int bgshift, int numbps)
1797 {
1798 int i;
1799 int j;
1800 int thresh;
1801 jpc_fix_t val;
1802 jpc_fix_t mag;
1803 bool warn;
1804 uint_fast32_t mask;
1805
1806 if (roishift == 0 && bgshift == 0) {
1807 return;
1808 }
1809 thresh = 1 << roishift;
1810
1811 warn = false;
1812 for (i = 0; i < jas_matrix_numrows(x); ++i) {
1813 for (j = 0; j < jas_matrix_numcols(x); ++j) {
1814 val = jas_matrix_get(x, i, j);
1815 mag = JAS_ABS(val);
1816 if (mag >= thresh) {
1817 /* We are dealing with ROI data. */
1818 mag >>= roishift;
1819 val = (val < 0) ? (-mag) : mag;
1820 jas_matrix_set(x, i, j, val);
1821 } else {
1822 /* We are dealing with non-ROI (i.e., background) data. */
1823 mag <<= bgshift;
1824 mask = (1 << numbps) - 1;
1825 /* Perform a basic sanity check on the sample value. */
1826 /* Some implementations write garbage in the unused
1827 most-significant bit planes introduced by ROI shifting.
1828 Here we ensure that any such bits are masked off. */
1829 if (mag & (~mask)) {
1830 if (!warn) {
1831 jas_eprintf("warning: possibly corrupt code stream\n");
1832 warn = true;
1833 }
1834 mag &= mask;
1835 }
1836 val = (val < 0) ? (-mag) : mag;
1837 jas_matrix_set(x, i, j, val);
1838 }
1839 }
1840 }
1841 }
1842
jpc_dec_create(jpc_dec_importopts_t * impopts,jas_stream_t * in)1843 static jpc_dec_t *jpc_dec_create(jpc_dec_importopts_t *impopts, jas_stream_t *in)
1844 {
1845 jpc_dec_t *dec;
1846
1847 if (!(dec = jas_malloc(sizeof(jpc_dec_t)))) {
1848 return 0;
1849 }
1850
1851 dec->image = 0;
1852 dec->xstart = 0;
1853 dec->ystart = 0;
1854 dec->xend = 0;
1855 dec->yend = 0;
1856 dec->tilewidth = 0;
1857 dec->tileheight = 0;
1858 dec->tilexoff = 0;
1859 dec->tileyoff = 0;
1860 dec->numhtiles = 0;
1861 dec->numvtiles = 0;
1862 dec->numtiles = 0;
1863 dec->tiles = 0;
1864 dec->curtile = 0;
1865 dec->numcomps = 0;
1866 dec->in = in;
1867 dec->cp = 0;
1868 dec->maxlyrs = impopts->maxlyrs;
1869 dec->maxpkts = impopts->maxpkts;
1870 dec->numpkts = 0;
1871 dec->ppmseqno = 0;
1872 dec->state = 0;
1873 dec->cmpts = 0;
1874 dec->pkthdrstreams = 0;
1875 dec->ppmstab = 0;
1876 dec->curtileendoff = 0;
1877
1878 return dec;
1879 }
1880
jpc_dec_destroy(jpc_dec_t * dec)1881 static void jpc_dec_destroy(jpc_dec_t *dec)
1882 {
1883 if (dec->cstate) {
1884 jpc_cstate_destroy(dec->cstate);
1885 }
1886 if (dec->pkthdrstreams) {
1887 jpc_streamlist_destroy(dec->pkthdrstreams);
1888 }
1889 if (dec->image) {
1890 jas_image_destroy(dec->image);
1891 }
1892
1893 if (dec->cp) {
1894 jpc_dec_cp_destroy(dec->cp);
1895 }
1896
1897 if (dec->cmpts) {
1898 jas_free(dec->cmpts);
1899 }
1900
1901 if (dec->tiles) {
1902 jas_free(dec->tiles);
1903 }
1904
1905 jas_free(dec);
1906 }
1907
1908 /******************************************************************************\
1909 *
1910 \******************************************************************************/
1911
jpc_seglist_insert(jpc_dec_seglist_t * list,jpc_dec_seg_t * ins,jpc_dec_seg_t * node)1912 void jpc_seglist_insert(jpc_dec_seglist_t *list, jpc_dec_seg_t *ins, jpc_dec_seg_t *node)
1913 {
1914 jpc_dec_seg_t *prev;
1915 jpc_dec_seg_t *next;
1916
1917 prev = ins;
1918 node->prev = prev;
1919 next = prev ? (prev->next) : 0;
1920 node->prev = prev;
1921 node->next = next;
1922 if (prev) {
1923 prev->next = node;
1924 } else {
1925 list->head = node;
1926 }
1927 if (next) {
1928 next->prev = node;
1929 } else {
1930 list->tail = node;
1931 }
1932 }
1933
jpc_seglist_remove(jpc_dec_seglist_t * list,jpc_dec_seg_t * seg)1934 void jpc_seglist_remove(jpc_dec_seglist_t *list, jpc_dec_seg_t *seg)
1935 {
1936 jpc_dec_seg_t *prev;
1937 jpc_dec_seg_t *next;
1938
1939 prev = seg->prev;
1940 next = seg->next;
1941 if (prev) {
1942 prev->next = next;
1943 } else {
1944 list->head = next;
1945 }
1946 if (next) {
1947 next->prev = prev;
1948 } else {
1949 list->tail = prev;
1950 }
1951 seg->prev = 0;
1952 seg->next = 0;
1953 }
1954
jpc_seg_alloc()1955 jpc_dec_seg_t *jpc_seg_alloc()
1956 {
1957 jpc_dec_seg_t *seg;
1958
1959 if (!(seg = jas_malloc(sizeof(jpc_dec_seg_t)))) {
1960 return 0;
1961 }
1962 seg->prev = 0;
1963 seg->next = 0;
1964 seg->passno = -1;
1965 seg->numpasses = 0;
1966 seg->maxpasses = 0;
1967 seg->type = JPC_SEG_INVALID;
1968 seg->stream = 0;
1969 seg->cnt = 0;
1970 seg->complete = 0;
1971 seg->lyrno = -1;
1972 return seg;
1973 }
1974
jpc_seg_destroy(jpc_dec_seg_t * seg)1975 void jpc_seg_destroy(jpc_dec_seg_t *seg)
1976 {
1977 if (seg->stream) {
1978 jas_stream_close(seg->stream);
1979 }
1980 jas_free(seg);
1981 }
1982
jpc_dec_dump(jpc_dec_t * dec,FILE * out)1983 static int jpc_dec_dump(jpc_dec_t *dec, FILE *out)
1984 {
1985 jpc_dec_tile_t *tile;
1986 int tileno;
1987 jpc_dec_tcomp_t *tcomp;
1988 int compno;
1989 jpc_dec_rlvl_t *rlvl;
1990 int rlvlno;
1991 jpc_dec_band_t *band;
1992 int bandno;
1993 jpc_dec_prc_t *prc;
1994 int prcno;
1995 jpc_dec_cblk_t *cblk;
1996 int cblkno;
1997
1998 for (tileno = 0, tile = dec->tiles; tileno < dec->numtiles;
1999 ++tileno, ++tile) {
2000 for (compno = 0, tcomp = tile->tcomps; compno < dec->numcomps;
2001 ++compno, ++tcomp) {
2002 for (rlvlno = 0, rlvl = tcomp->rlvls; rlvlno <
2003 tcomp->numrlvls; ++rlvlno, ++rlvl) {
2004 fprintf(out, "RESOLUTION LEVEL %d\n", rlvlno);
2005 fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n",
2006 (int)rlvl->xstart, (int)rlvl->ystart, (int)rlvl->xend, (int)rlvl->yend, (int)(rlvl->xend -
2007 rlvl->xstart), (int)(rlvl->yend - rlvl->ystart));
2008 for (bandno = 0, band = rlvl->bands;
2009 bandno < rlvl->numbands; ++bandno, ++band) {
2010 fprintf(out, "BAND %d\n", bandno);
2011 fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n",
2012 (int)jas_seq2d_xstart(band->data), (int)jas_seq2d_ystart(band->data), (int)jas_seq2d_xend(band->data),
2013 (int)jas_seq2d_yend(band->data), (int)(jas_seq2d_xend(band->data) - jas_seq2d_xstart(band->data)),
2014 (int)(jas_seq2d_yend(band->data) - jas_seq2d_ystart(band->data)));
2015 for (prcno = 0, prc = band->prcs;
2016 prcno < rlvl->numprcs; ++prcno,
2017 ++prc) {
2018 fprintf(out, "CODE BLOCK GROUP %d\n", prcno);
2019 fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n",
2020 (int)prc->xstart, (int)prc->ystart, (int)prc->xend, (int)prc->yend, (int)(prc->xend -
2021 prc->xstart), (int)(prc->yend - prc->ystart));
2022 for (cblkno = 0, cblk =
2023 prc->cblks; cblkno <
2024 prc->numcblks; ++cblkno,
2025 ++cblk) {
2026 fprintf(out, "CODE BLOCK %d\n", cblkno);
2027 fprintf(out, "xs =%d, ys = %d, xe = %d, ye = %d, w = %d, h = %d\n",
2028 (int)jas_seq2d_xstart(cblk->data), (int)jas_seq2d_ystart(cblk->data), (int)jas_seq2d_xend(cblk->data),
2029 (int)jas_seq2d_yend(cblk->data), (int)(jas_seq2d_xend(cblk->data) - jas_seq2d_xstart(cblk->data)),
2030 (int)(jas_seq2d_yend(cblk->data) - jas_seq2d_ystart(cblk->data)));
2031 }
2032 }
2033 }
2034 }
2035 }
2036 }
2037
2038 return 0;
2039 }
2040
jpc_streamlist_create()2041 jpc_streamlist_t *jpc_streamlist_create()
2042 {
2043 jpc_streamlist_t *streamlist;
2044 int i;
2045
2046 if (!(streamlist = jas_malloc(sizeof(jpc_streamlist_t)))) {
2047 return 0;
2048 }
2049 streamlist->numstreams = 0;
2050 streamlist->maxstreams = 100;
2051 if (!(streamlist->streams = jas_alloc2(streamlist->maxstreams,
2052 sizeof(jas_stream_t *)))) {
2053 jas_free(streamlist);
2054 return 0;
2055 }
2056 for (i = 0; i < streamlist->maxstreams; ++i) {
2057 streamlist->streams[i] = 0;
2058 }
2059 return streamlist;
2060 }
2061
jpc_streamlist_insert(jpc_streamlist_t * streamlist,int streamno,jas_stream_t * stream)2062 int jpc_streamlist_insert(jpc_streamlist_t *streamlist, int streamno,
2063 jas_stream_t *stream)
2064 {
2065 jas_stream_t **newstreams;
2066 int newmaxstreams;
2067 int i;
2068 /* Grow the array of streams if necessary. */
2069 if (streamlist->numstreams >= streamlist->maxstreams) {
2070 newmaxstreams = streamlist->maxstreams + 1024;
2071 if (!(newstreams = jas_realloc2(streamlist->streams,
2072 (newmaxstreams + 1024), sizeof(jas_stream_t *)))) {
2073 return -1;
2074 }
2075 for (i = streamlist->numstreams; i < streamlist->maxstreams; ++i) {
2076 streamlist->streams[i] = 0;
2077 }
2078 streamlist->maxstreams = newmaxstreams;
2079 streamlist->streams = newstreams;
2080 }
2081 if (streamno != streamlist->numstreams) {
2082 /* Can only handle insertion at start of list. */
2083 return -1;
2084 }
2085 streamlist->streams[streamno] = stream;
2086 ++streamlist->numstreams;
2087 return 0;
2088 }
2089
jpc_streamlist_remove(jpc_streamlist_t * streamlist,int streamno)2090 jas_stream_t *jpc_streamlist_remove(jpc_streamlist_t *streamlist, int streamno)
2091 {
2092 jas_stream_t *stream;
2093 int i;
2094 if (streamno >= streamlist->numstreams) {
2095 abort();
2096 }
2097 stream = streamlist->streams[streamno];
2098 for (i = streamno + 1; i < streamlist->numstreams; ++i) {
2099 streamlist->streams[i - 1] = streamlist->streams[i];
2100 }
2101 --streamlist->numstreams;
2102 return stream;
2103 }
2104
jpc_streamlist_destroy(jpc_streamlist_t * streamlist)2105 void jpc_streamlist_destroy(jpc_streamlist_t *streamlist)
2106 {
2107 int streamno;
2108 if (streamlist->streams) {
2109 for (streamno = 0; streamno < streamlist->numstreams;
2110 ++streamno) {
2111 jas_stream_close(streamlist->streams[streamno]);
2112 }
2113 jas_free(streamlist->streams);
2114 }
2115 jas_free(streamlist);
2116 }
2117
jpc_streamlist_get(jpc_streamlist_t * streamlist,int streamno)2118 jas_stream_t *jpc_streamlist_get(jpc_streamlist_t *streamlist, int streamno)
2119 {
2120 assert(streamno < streamlist->numstreams);
2121 return streamlist->streams[streamno];
2122 }
2123
jpc_streamlist_numstreams(jpc_streamlist_t * streamlist)2124 int jpc_streamlist_numstreams(jpc_streamlist_t *streamlist)
2125 {
2126 return streamlist->numstreams;
2127 }
2128
jpc_ppxstab_create()2129 jpc_ppxstab_t *jpc_ppxstab_create()
2130 {
2131 jpc_ppxstab_t *tab;
2132
2133 if (!(tab = jas_malloc(sizeof(jpc_ppxstab_t)))) {
2134 return 0;
2135 }
2136 tab->numents = 0;
2137 tab->maxents = 0;
2138 tab->ents = 0;
2139 return tab;
2140 }
2141
jpc_ppxstab_destroy(jpc_ppxstab_t * tab)2142 void jpc_ppxstab_destroy(jpc_ppxstab_t *tab)
2143 {
2144 int i;
2145 for (i = 0; i < tab->numents; ++i) {
2146 jpc_ppxstabent_destroy(tab->ents[i]);
2147 }
2148 if (tab->ents) {
2149 jas_free(tab->ents);
2150 }
2151 jas_free(tab);
2152 }
2153
jpc_ppxstab_grow(jpc_ppxstab_t * tab,int maxents)2154 int jpc_ppxstab_grow(jpc_ppxstab_t *tab, int maxents)
2155 {
2156 jpc_ppxstabent_t **newents;
2157 if (tab->maxents < maxents) {
2158 newents = jas_realloc2(tab->ents, maxents, sizeof(jpc_ppxstabent_t *));
2159 if (!newents) {
2160 return -1;
2161 }
2162 tab->ents = newents;
2163 tab->maxents = maxents;
2164 }
2165 return 0;
2166 }
2167
jpc_ppxstab_insert(jpc_ppxstab_t * tab,jpc_ppxstabent_t * ent)2168 int jpc_ppxstab_insert(jpc_ppxstab_t *tab, jpc_ppxstabent_t *ent)
2169 {
2170 int inspt;
2171 int i;
2172
2173 for (i = 0; i < tab->numents; ++i) {
2174 if (tab->ents[i]->ind > ent->ind) {
2175 break;
2176 }
2177 }
2178 inspt = i;
2179
2180 if (tab->numents >= tab->maxents) {
2181 if (jpc_ppxstab_grow(tab, tab->maxents + 128)) {
2182 return -1;
2183 }
2184 }
2185
2186 for (i = tab->numents; i > inspt; --i) {
2187 tab->ents[i] = tab->ents[i - 1];
2188 }
2189 tab->ents[i] = ent;
2190 ++tab->numents;
2191
2192 return 0;
2193 }
2194
jpc_ppmstabtostreams(jpc_ppxstab_t * tab)2195 jpc_streamlist_t *jpc_ppmstabtostreams(jpc_ppxstab_t *tab)
2196 {
2197 jpc_streamlist_t *streams;
2198 uchar *dataptr;
2199 uint_fast32_t datacnt;
2200 uint_fast32_t tpcnt;
2201 jpc_ppxstabent_t *ent;
2202 int entno;
2203 jas_stream_t *stream;
2204 int n;
2205
2206 if (!(streams = jpc_streamlist_create())) {
2207 goto error;
2208 }
2209
2210 if (!tab->numents) {
2211 return streams;
2212 }
2213
2214 entno = 0;
2215 ent = tab->ents[entno];
2216 dataptr = ent->data;
2217 datacnt = ent->len;
2218 for (;;) {
2219
2220 /* Get the length of the packet header data for the current
2221 tile-part. */
2222 if (datacnt < 4) {
2223 goto error;
2224 }
2225 if (!(stream = jas_stream_memopen(0, 0))) {
2226 goto error;
2227 }
2228 if (jpc_streamlist_insert(streams, jpc_streamlist_numstreams(streams),
2229 stream)) {
2230 goto error;
2231 }
2232 tpcnt = (dataptr[0] << 24) | (dataptr[1] << 16) | (dataptr[2] << 8)
2233 | dataptr[3];
2234 datacnt -= 4;
2235 dataptr += 4;
2236
2237 /* Get the packet header data for the current tile-part. */
2238 while (tpcnt) {
2239 if (!datacnt) {
2240 if (++entno >= tab->numents) {
2241 goto error;
2242 }
2243 ent = tab->ents[entno];
2244 dataptr = ent->data;
2245 datacnt = ent->len;
2246 }
2247 n = JAS_MIN(tpcnt, datacnt);
2248 if (jas_stream_write(stream, dataptr, n) != n) {
2249 goto error;
2250 }
2251 tpcnt -= n;
2252 dataptr += n;
2253 datacnt -= n;
2254 }
2255 jas_stream_rewind(stream);
2256 if (!datacnt) {
2257 if (++entno >= tab->numents) {
2258 break;
2259 }
2260 ent = tab->ents[entno];
2261 dataptr = ent->data;
2262 datacnt = ent->len;
2263 }
2264 }
2265
2266 return streams;
2267
2268 error:
2269 jpc_streamlist_destroy(streams);
2270 return 0;
2271 }
2272
jpc_pptstabwrite(jas_stream_t * out,jpc_ppxstab_t * tab)2273 int jpc_pptstabwrite(jas_stream_t *out, jpc_ppxstab_t *tab)
2274 {
2275 int i;
2276 jpc_ppxstabent_t *ent;
2277 for (i = 0; i < tab->numents; ++i) {
2278 ent = tab->ents[i];
2279 if (jas_stream_write(out, ent->data, ent->len) != JAS_CAST(int, ent->len)) {
2280 return -1;
2281 }
2282 }
2283 return 0;
2284 }
2285
jpc_ppxstabent_create()2286 jpc_ppxstabent_t *jpc_ppxstabent_create()
2287 {
2288 jpc_ppxstabent_t *ent;
2289 if (!(ent = jas_malloc(sizeof(jpc_ppxstabent_t)))) {
2290 return 0;
2291 }
2292 ent->data = 0;
2293 ent->len = 0;
2294 ent->ind = 0;
2295 return ent;
2296 }
2297
jpc_ppxstabent_destroy(jpc_ppxstabent_t * ent)2298 void jpc_ppxstabent_destroy(jpc_ppxstabent_t *ent)
2299 {
2300 if (ent->data) {
2301 jas_free(ent->data);
2302 }
2303 jas_free(ent);
2304 }
2305