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