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