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