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