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 License Version 2.0
11 *
12 * Copyright (c) 2001-2006 Michael David Adams
13 * Copyright (c) 1999-2000 Image Power, Inc.
14 * Copyright (c) 1999-2000 The University of British Columbia
15 *
16 * All rights reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person (the
19 * "User") obtaining a copy of this software and associated documentation
20 * files (the "Software"), to deal in the Software without restriction,
21 * including without limitation the rights to use, copy, modify, merge,
22 * publish, distribute, and/or sell copies of the Software, and to permit
23 * persons to whom the Software is furnished to do so, subject to the
24 * following conditions:
25 *
26 * 1. The above copyright notices and this permission notice (which
27 * includes the disclaimer below) shall be included in all copies or
28 * substantial portions of the Software.
29 *
30 * 2. The name of a copyright holder shall not be used to endorse or
31 * promote products derived from the Software without specific prior
32 * written permission.
33 *
34 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35 * LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36 * THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37 * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39 * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
40 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
45 * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46 * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47 * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48 * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49 * PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
50 * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51 * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
52 * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53 * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55 * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56 * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57 * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58 * RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59 * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60 *
61 * __END_OF_JASPER_LICENSE__
62 */
63
64 /*
65 * JPEG-2000 Code Stream Library
66 *
67 * $Id$
68 */
69
70 /******************************************************************************\
71 * Includes.
72 \******************************************************************************/
73
74 #include <stdlib.h>
75 #include <assert.h>
76 #include <ctype.h>
77 #ifndef PRIxFAST16
78 #include <inttypes.h>
79 #endif
80
81 #include "jasper/jas_malloc.h"
82 #include "jasper/jas_debug.h"
83
84 #include "jpc_cs.h"
85
86 /******************************************************************************\
87 * Types.
88 \******************************************************************************/
89
90 /* Marker segment table entry. */
91 typedef struct {
92 int id;
93 char *name;
94 jpc_msops_t ops;
95 } jpc_mstabent_t;
96
97 /******************************************************************************\
98 * Local prototypes.
99 \******************************************************************************/
100
101 static jpc_mstabent_t *jpc_mstab_lookup(int id);
102
103 static int jpc_poc_dumpparms(jpc_ms_t *ms, FILE *out);
104 static int jpc_poc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
105 static int jpc_poc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
106 static void jpc_poc_destroyparms(jpc_ms_t *ms);
107
108 static int jpc_unk_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
109 static int jpc_sot_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
110 static int jpc_siz_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
111 static int jpc_cod_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
112 static int jpc_coc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
113 static int jpc_qcd_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
114 static int jpc_qcc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
115 static int jpc_rgn_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
116 static int jpc_sop_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
117 static int jpc_ppm_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
118 static int jpc_ppt_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
119 static int jpc_crg_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
120 static int jpc_com_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in);
121
122 static int jpc_sot_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
123 static int jpc_siz_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
124 static int jpc_cod_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
125 static int jpc_coc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
126 static int jpc_qcd_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
127 static int jpc_qcc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
128 static int jpc_rgn_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
129 static int jpc_unk_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
130 static int jpc_sop_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
131 static int jpc_ppm_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
132 static int jpc_ppt_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
133 static int jpc_crg_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
134 static int jpc_com_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out);
135
136 static int jpc_sot_dumpparms(jpc_ms_t *ms, FILE *out);
137 static int jpc_siz_dumpparms(jpc_ms_t *ms, FILE *out);
138 static int jpc_cod_dumpparms(jpc_ms_t *ms, FILE *out);
139 static int jpc_coc_dumpparms(jpc_ms_t *ms, FILE *out);
140 static int jpc_qcd_dumpparms(jpc_ms_t *ms, FILE *out);
141 static int jpc_qcc_dumpparms(jpc_ms_t *ms, FILE *out);
142 static int jpc_rgn_dumpparms(jpc_ms_t *ms, FILE *out);
143 static int jpc_unk_dumpparms(jpc_ms_t *ms, FILE *out);
144 static int jpc_sop_dumpparms(jpc_ms_t *ms, FILE *out);
145 static int jpc_ppm_dumpparms(jpc_ms_t *ms, FILE *out);
146 static int jpc_ppt_dumpparms(jpc_ms_t *ms, FILE *out);
147 static int jpc_crg_dumpparms(jpc_ms_t *ms, FILE *out);
148 static int jpc_com_dumpparms(jpc_ms_t *ms, FILE *out);
149
150 static void jpc_siz_destroyparms(jpc_ms_t *ms);
151 static void jpc_qcd_destroyparms(jpc_ms_t *ms);
152 static void jpc_qcc_destroyparms(jpc_ms_t *ms);
153 static void jpc_cod_destroyparms(jpc_ms_t *ms);
154 static void jpc_coc_destroyparms(jpc_ms_t *ms);
155 static void jpc_unk_destroyparms(jpc_ms_t *ms);
156 static void jpc_ppm_destroyparms(jpc_ms_t *ms);
157 static void jpc_ppt_destroyparms(jpc_ms_t *ms);
158 static void jpc_crg_destroyparms(jpc_ms_t *ms);
159 static void jpc_com_destroyparms(jpc_ms_t *ms);
160
161 static void jpc_qcx_destroycompparms(jpc_qcxcp_t *compparms);
162 static int jpc_qcx_getcompparms(jpc_qcxcp_t *compparms, jpc_cstate_t *cstate,
163 jas_stream_t *in, uint_fast16_t len);
164 static int jpc_qcx_putcompparms(jpc_qcxcp_t *compparms, jpc_cstate_t *cstate,
165 jas_stream_t *out);
166 static void jpc_cox_destroycompparms(jpc_coxcp_t *compparms);
167 static int jpc_cox_getcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate,
168 jas_stream_t *in, int prtflag, jpc_coxcp_t *compparms);
169 static int jpc_cox_putcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate,
170 jas_stream_t *out, int prtflag, jpc_coxcp_t *compparms);
171
172 /******************************************************************************\
173 * Global data.
174 \******************************************************************************/
175
176 static jpc_mstabent_t jpc_mstab[] = {
177 {JPC_MS_SOC, "SOC", {0, 0, 0, 0}},
178 {JPC_MS_SOT, "SOT", {0, jpc_sot_getparms, jpc_sot_putparms,
179 jpc_sot_dumpparms}},
180 {JPC_MS_SOD, "SOD", {0, 0, 0, 0}},
181 {JPC_MS_EOC, "EOC", {0, 0, 0, 0}},
182 {JPC_MS_SIZ, "SIZ", {jpc_siz_destroyparms, jpc_siz_getparms,
183 jpc_siz_putparms, jpc_siz_dumpparms}},
184 {JPC_MS_COD, "COD", {jpc_cod_destroyparms, jpc_cod_getparms,
185 jpc_cod_putparms, jpc_cod_dumpparms}},
186 {JPC_MS_COC, "COC", {jpc_coc_destroyparms, jpc_coc_getparms,
187 jpc_coc_putparms, jpc_coc_dumpparms}},
188 {JPC_MS_RGN, "RGN", {0, jpc_rgn_getparms, jpc_rgn_putparms,
189 jpc_rgn_dumpparms}},
190 {JPC_MS_QCD, "QCD", {jpc_qcd_destroyparms, jpc_qcd_getparms,
191 jpc_qcd_putparms, jpc_qcd_dumpparms}},
192 {JPC_MS_QCC, "QCC", {jpc_qcc_destroyparms, jpc_qcc_getparms,
193 jpc_qcc_putparms, jpc_qcc_dumpparms}},
194 {JPC_MS_POC, "POC", {jpc_poc_destroyparms, jpc_poc_getparms,
195 jpc_poc_putparms, jpc_poc_dumpparms}},
196 {JPC_MS_TLM, "TLM", {0, jpc_unk_getparms, jpc_unk_putparms, 0}},
197 {JPC_MS_PLM, "PLM", {0, jpc_unk_getparms, jpc_unk_putparms, 0}},
198 {JPC_MS_PPM, "PPM", {jpc_ppm_destroyparms, jpc_ppm_getparms,
199 jpc_ppm_putparms, jpc_ppm_dumpparms}},
200 {JPC_MS_PPT, "PPT", {jpc_ppt_destroyparms, jpc_ppt_getparms,
201 jpc_ppt_putparms, jpc_ppt_dumpparms}},
202 {JPC_MS_SOP, "SOP", {0, jpc_sop_getparms, jpc_sop_putparms,
203 jpc_sop_dumpparms}},
204 {JPC_MS_EPH, "EPH", {0, 0, 0, 0}},
205 {JPC_MS_CRG, "CRG", {0, jpc_crg_getparms, jpc_crg_putparms,
206 jpc_crg_dumpparms}},
207 {JPC_MS_COM, "COM", {jpc_com_destroyparms, jpc_com_getparms,
208 jpc_com_putparms, jpc_com_dumpparms}},
209 {-1, "UNKNOWN", {jpc_unk_destroyparms, jpc_unk_getparms,
210 jpc_unk_putparms, jpc_unk_dumpparms}}
211 };
212
213 /******************************************************************************\
214 * Code stream manipulation functions.
215 \******************************************************************************/
216
217 /* Create a code stream state object. */
jpc_cstate_create()218 jpc_cstate_t *jpc_cstate_create()
219 {
220 jpc_cstate_t *cstate;
221 if (!(cstate = jas_malloc(sizeof(jpc_cstate_t)))) {
222 return 0;
223 }
224 cstate->numcomps = 0;
225 return cstate;
226 }
227
228 /* Destroy a code stream state object. */
jpc_cstate_destroy(jpc_cstate_t * cstate)229 void jpc_cstate_destroy(jpc_cstate_t *cstate)
230 {
231 jas_free(cstate);
232 }
233
234 /* Read a marker segment from a stream. */
jpc_getms(jas_stream_t * in,jpc_cstate_t * cstate)235 jpc_ms_t *jpc_getms(jas_stream_t *in, jpc_cstate_t *cstate)
236 {
237 jpc_ms_t *ms;
238 jpc_mstabent_t *mstabent;
239 jas_stream_t *tmpstream;
240
241 if (!(ms = jpc_ms_create(0))) {
242 return 0;
243 }
244
245 /* Get the marker type. */
246 if (jpc_getuint16(in, &ms->id) || ms->id < JPC_MS_MIN ||
247 ms->id > JPC_MS_MAX) {
248 jpc_ms_destroy(ms);
249 return 0;
250 }
251
252 mstabent = jpc_mstab_lookup(ms->id);
253 ms->ops = &mstabent->ops;
254
255 /* Get the marker segment length and parameters if present. */
256 /* Note: It is tacitly assumed that a marker segment cannot have
257 parameters unless it has a length field. That is, there cannot
258 be a parameters field without a length field and vice versa. */
259 if (JPC_MS_HASPARMS(ms->id)) {
260 /* Get the length of the marker segment. */
261 if (jpc_getuint16(in, &ms->len) || ms->len < 3) {
262 jpc_ms_destroy(ms);
263 return 0;
264 }
265 /* Calculate the length of the marker segment parameters. */
266 ms->len -= 2;
267 /* Create and prepare a temporary memory stream from which to
268 read the marker segment parameters. */
269 /* Note: This approach provides a simple way of ensuring that
270 we never read beyond the end of the marker segment (even if
271 the marker segment length is errantly set too small). */
272 if (!(tmpstream = jas_stream_memopen(0, 0))) {
273 jpc_ms_destroy(ms);
274 return 0;
275 }
276 if (jas_stream_copy(tmpstream, in, ms->len) ||
277 jas_stream_seek(tmpstream, 0, SEEK_SET) < 0) {
278 jas_stream_close(tmpstream);
279 jpc_ms_destroy(ms);
280 return 0;
281 }
282 /* Get the marker segment parameters. */
283 if ((*ms->ops->getparms)(ms, cstate, tmpstream)) {
284 ms->ops = 0;
285 jpc_ms_destroy(ms);
286 jas_stream_close(tmpstream);
287 return 0;
288 }
289
290 if (jas_getdbglevel() > 0) {
291 jpc_ms_dump(ms, stderr);
292 }
293
294 if (JAS_CAST(ulong, jas_stream_tell(tmpstream)) != ms->len) {
295 jas_eprintf("warning: trailing garbage in marker segment (%ld bytes)\n",
296 ms->len - jas_stream_tell(tmpstream));
297 }
298
299 /* Close the temporary stream. */
300 jas_stream_close(tmpstream);
301
302 } else {
303 /* There are no marker segment parameters. */
304 ms->len = 0;
305
306 if (jas_getdbglevel() > 0) {
307 jpc_ms_dump(ms, stderr);
308 }
309 }
310
311 /* Update the code stream state information based on the type of
312 marker segment read. */
313 /* Note: This is a bit of a hack, but I'm not going to define another
314 type of virtual function for this one special case. */
315 if (ms->id == JPC_MS_SIZ) {
316 cstate->numcomps = ms->parms.siz.numcomps;
317 }
318
319 return ms;
320 }
321
322 /* Write a marker segment to a stream. */
jpc_putms(jas_stream_t * out,jpc_cstate_t * cstate,jpc_ms_t * ms)323 int jpc_putms(jas_stream_t *out, jpc_cstate_t *cstate, jpc_ms_t *ms)
324 {
325 jas_stream_t *tmpstream;
326 int len;
327
328 /* Output the marker segment type. */
329 if (jpc_putuint16(out, ms->id)) {
330 return -1;
331 }
332
333 /* Output the marker segment length and parameters if necessary. */
334 if (ms->ops->putparms) {
335 /* Create a temporary stream in which to buffer the
336 parameter data. */
337 if (!(tmpstream = jas_stream_memopen(0, 0))) {
338 return -1;
339 }
340 if ((*ms->ops->putparms)(ms, cstate, tmpstream)) {
341 jas_stream_close(tmpstream);
342 return -1;
343 }
344 /* Get the number of bytes of parameter data written. */
345 if ((len = jas_stream_tell(tmpstream)) < 0) {
346 jas_stream_close(tmpstream);
347 return -1;
348 }
349 ms->len = len;
350 /* Write the marker segment length and parameter data to
351 the output stream. */
352 if (jas_stream_seek(tmpstream, 0, SEEK_SET) < 0 ||
353 jpc_putuint16(out, ms->len + 2) ||
354 jas_stream_copy(out, tmpstream, ms->len) < 0) {
355 jas_stream_close(tmpstream);
356 return -1;
357 }
358 /* Close the temporary stream. */
359 jas_stream_close(tmpstream);
360 }
361
362 /* This is a bit of a hack, but I'm not going to define another
363 type of virtual function for this one special case. */
364 if (ms->id == JPC_MS_SIZ) {
365 cstate->numcomps = ms->parms.siz.numcomps;
366 }
367
368 if (jas_getdbglevel() > 0) {
369 jpc_ms_dump(ms, stderr);
370 }
371
372 return 0;
373 }
374
375 /******************************************************************************\
376 * Marker segment operations.
377 \******************************************************************************/
378
379 /* Create a marker segment of the specified type. */
jpc_ms_create(int type)380 jpc_ms_t *jpc_ms_create(int type)
381 {
382 jpc_ms_t *ms;
383 jpc_mstabent_t *mstabent;
384
385 if (!(ms = jas_malloc(sizeof(jpc_ms_t)))) {
386 return 0;
387 }
388 ms->id = type;
389 ms->len = 0;
390 mstabent = jpc_mstab_lookup(ms->id);
391 ms->ops = &mstabent->ops;
392 memset(&ms->parms, 0, sizeof(jpc_msparms_t));
393 return ms;
394 }
395
396 /* Destroy a marker segment. */
jpc_ms_destroy(jpc_ms_t * ms)397 void jpc_ms_destroy(jpc_ms_t *ms)
398 {
399 if (ms->ops && ms->ops->destroyparms) {
400 (*ms->ops->destroyparms)(ms);
401 }
402 jas_free(ms);
403 }
404
405 /* Dump a marker segment to a stream for debugging. */
jpc_ms_dump(jpc_ms_t * ms,FILE * out)406 void jpc_ms_dump(jpc_ms_t *ms, FILE *out)
407 {
408 jpc_mstabent_t *mstabent;
409 mstabent = jpc_mstab_lookup(ms->id);
410 fprintf(out, "type = 0x%04" PRIxFAST16 " (%s);", ms->id, mstabent->name);
411 if (JPC_MS_HASPARMS(ms->id)) {
412 fprintf(out, " len = %" PRIuFAST16 ";", ms->len + 2);
413 if (ms->ops->dumpparms) {
414 (*ms->ops->dumpparms)(ms, out);
415 } else {
416 fprintf(out, "\n");
417 }
418 } else {
419 fprintf(out, "\n");
420 }
421 }
422
423 /******************************************************************************\
424 * SOT marker segment operations.
425 \******************************************************************************/
426
jpc_sot_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)427 static int jpc_sot_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
428 {
429 jpc_sot_t *sot = &ms->parms.sot;
430
431 /* Eliminate compiler warning about unused variables. */
432 cstate = 0;
433
434 if (jpc_getuint16(in, &sot->tileno) ||
435 jpc_getuint32(in, &sot->len) ||
436 jpc_getuint8(in, &sot->partno) ||
437 jpc_getuint8(in, &sot->numparts)) {
438 return -1;
439 }
440 if (jas_stream_eof(in)) {
441 return -1;
442 }
443 return 0;
444 }
445
jpc_sot_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)446 static int jpc_sot_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
447 {
448 jpc_sot_t *sot = &ms->parms.sot;
449
450 /* Eliminate compiler warning about unused variables. */
451 cstate = 0;
452
453 if (jpc_putuint16(out, sot->tileno) ||
454 jpc_putuint32(out, sot->len) ||
455 jpc_putuint8(out, sot->partno) ||
456 jpc_putuint8(out, sot->numparts)) {
457 return -1;
458 }
459 return 0;
460 }
461
jpc_sot_dumpparms(jpc_ms_t * ms,FILE * out)462 static int jpc_sot_dumpparms(jpc_ms_t *ms, FILE *out)
463 {
464 jpc_sot_t *sot = &ms->parms.sot;
465 fprintf(out, "tileno = %" PRIuFAST16 "; len = %" PRIuFAST32 "; partno = %" PRIuFAST8 "; "
466 "numparts = %" PRIuFAST8 "\n",
467 sot->tileno, sot->len, sot->partno, sot->numparts);
468 return 0;
469 }
470
471 /******************************************************************************\
472 * SIZ marker segment operations.
473 \******************************************************************************/
474
jpc_siz_destroyparms(jpc_ms_t * ms)475 static void jpc_siz_destroyparms(jpc_ms_t *ms)
476 {
477 jpc_siz_t *siz = &ms->parms.siz;
478 if (siz->comps) {
479 jas_free(siz->comps);
480 }
481 }
482
jpc_siz_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)483 static int jpc_siz_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate,
484 jas_stream_t *in)
485 {
486 jpc_siz_t *siz = &ms->parms.siz;
487 unsigned int i;
488 uint_fast8_t tmp;
489
490 /* Eliminate compiler warning about unused variables. */
491 cstate = 0;
492
493 if (jpc_getuint16(in, &siz->caps) ||
494 jpc_getuint32(in, &siz->width) ||
495 jpc_getuint32(in, &siz->height) ||
496 jpc_getuint32(in, &siz->xoff) ||
497 jpc_getuint32(in, &siz->yoff) ||
498 jpc_getuint32(in, &siz->tilewidth) ||
499 jpc_getuint32(in, &siz->tileheight) ||
500 jpc_getuint32(in, &siz->tilexoff) ||
501 jpc_getuint32(in, &siz->tileyoff) ||
502 jpc_getuint16(in, &siz->numcomps)) {
503 return -1;
504 }
505 if (!siz->width || !siz->height || !siz->tilewidth ||
506 !siz->tileheight || !siz->numcomps) {
507 return -1;
508 }
509 if (!(siz->comps = jas_alloc2(siz->numcomps, sizeof(jpc_sizcomp_t)))) {
510 return -1;
511 }
512 for (i = 0; i < siz->numcomps; ++i) {
513 if (jpc_getuint8(in, &tmp) ||
514 jpc_getuint8(in, &siz->comps[i].hsamp) ||
515 jpc_getuint8(in, &siz->comps[i].vsamp)) {
516 jas_free(siz->comps);
517 return -1;
518 }
519 if (siz->comps[i].hsamp == 0 || siz->comps[i].hsamp > 255) {
520 jas_eprintf("invalid XRsiz value %d\n", siz->comps[i].hsamp);
521 jas_free(siz->comps);
522 return -1;
523 }
524 if (siz->comps[i].vsamp == 0 || siz->comps[i].vsamp > 255) {
525 jas_eprintf("invalid YRsiz value %d\n", siz->comps[i].vsamp);
526 jas_free(siz->comps);
527 return -1;
528 }
529 siz->comps[i].sgnd = (tmp >> 7) & 1;
530 siz->comps[i].prec = (tmp & 0x7f) + 1;
531 }
532 if (jas_stream_eof(in)) {
533 jas_free(siz->comps);
534 return -1;
535 }
536 return 0;
537 }
538
jpc_siz_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)539 static int jpc_siz_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
540 {
541 jpc_siz_t *siz = &ms->parms.siz;
542 unsigned int i;
543
544 /* Eliminate compiler warning about unused variables. */
545 cstate = 0;
546
547 assert(siz->width && siz->height && siz->tilewidth &&
548 siz->tileheight && siz->numcomps);
549 if (jpc_putuint16(out, siz->caps) ||
550 jpc_putuint32(out, siz->width) ||
551 jpc_putuint32(out, siz->height) ||
552 jpc_putuint32(out, siz->xoff) ||
553 jpc_putuint32(out, siz->yoff) ||
554 jpc_putuint32(out, siz->tilewidth) ||
555 jpc_putuint32(out, siz->tileheight) ||
556 jpc_putuint32(out, siz->tilexoff) ||
557 jpc_putuint32(out, siz->tileyoff) ||
558 jpc_putuint16(out, siz->numcomps)) {
559 return -1;
560 }
561 for (i = 0; i < siz->numcomps; ++i) {
562 if (jpc_putuint8(out, ((siz->comps[i].sgnd & 1) << 7) |
563 ((siz->comps[i].prec - 1) & 0x7f)) ||
564 jpc_putuint8(out, siz->comps[i].hsamp) ||
565 jpc_putuint8(out, siz->comps[i].vsamp)) {
566 return -1;
567 }
568 }
569 return 0;
570 }
571
jpc_siz_dumpparms(jpc_ms_t * ms,FILE * out)572 static int jpc_siz_dumpparms(jpc_ms_t *ms, FILE *out)
573 {
574 jpc_siz_t *siz = &ms->parms.siz;
575 unsigned int i;
576 fprintf(out, "caps = 0x%02" PRIxFAST16 ";\n", siz->caps);
577 fprintf(out, "width = %" PRIuFAST32 "; height = %" PRIuFAST32 "; xoff = %" PRIuFAST32 "; yoff = %" PRIuFAST32 ";\n",
578 siz->width, siz->height, siz->xoff, siz->yoff);
579 fprintf(out, "tilewidth = %" PRIuFAST32 "; tileheight = %" PRIuFAST32 "; tilexoff = %" PRIuFAST32 "; "
580 "tileyoff = %" PRIuFAST32 ";\n", siz->tilewidth, siz->tileheight, siz->tilexoff,
581 siz->tileyoff);
582 for (i = 0; i < siz->numcomps; ++i) {
583 fprintf(out, "prec[%d] = %d; sgnd[%d] = %d; hsamp[%d] = %d; "
584 "vsamp[%d] = %d\n", i, siz->comps[i].prec, i,
585 siz->comps[i].sgnd, i, siz->comps[i].hsamp, i,
586 siz->comps[i].vsamp);
587 }
588 return 0;
589 }
590
591 /******************************************************************************\
592 * COD marker segment operations.
593 \******************************************************************************/
594
jpc_cod_destroyparms(jpc_ms_t * ms)595 static void jpc_cod_destroyparms(jpc_ms_t *ms)
596 {
597 jpc_cod_t *cod = &ms->parms.cod;
598 jpc_cox_destroycompparms(&cod->compparms);
599 }
600
jpc_cod_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)601 static int jpc_cod_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
602 {
603 jpc_cod_t *cod = &ms->parms.cod;
604 if (jpc_getuint8(in, &cod->csty)) {
605 return -1;
606 }
607 if (jpc_getuint8(in, &cod->prg) ||
608 jpc_getuint16(in, &cod->numlyrs) ||
609 jpc_getuint8(in, &cod->mctrans)) {
610 return -1;
611 }
612 if (jpc_cox_getcompparms(ms, cstate, in,
613 (cod->csty & JPC_COX_PRT) != 0, &cod->compparms)) {
614 return -1;
615 }
616 if (jas_stream_eof(in)) {
617 jpc_cod_destroyparms(ms);
618 return -1;
619 }
620 return 0;
621 }
622
jpc_cod_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)623 static int jpc_cod_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
624 {
625 jpc_cod_t *cod = &ms->parms.cod;
626 assert(cod->numlyrs > 0 && cod->compparms.numdlvls <= 32);
627 assert(cod->compparms.numdlvls == cod->compparms.numrlvls - 1);
628 if (jpc_putuint8(out, cod->compparms.csty) ||
629 jpc_putuint8(out, cod->prg) ||
630 jpc_putuint16(out, cod->numlyrs) ||
631 jpc_putuint8(out, cod->mctrans)) {
632 return -1;
633 }
634 if (jpc_cox_putcompparms(ms, cstate, out,
635 (cod->csty & JPC_COX_PRT) != 0, &cod->compparms)) {
636 return -1;
637 }
638 return 0;
639 }
640
jpc_cod_dumpparms(jpc_ms_t * ms,FILE * out)641 static int jpc_cod_dumpparms(jpc_ms_t *ms, FILE *out)
642 {
643 jpc_cod_t *cod = &ms->parms.cod;
644 int i;
645 fprintf(out, "csty = 0x%02x;\n", cod->compparms.csty);
646 fprintf(out, "numdlvls = %d; qmfbid = %d; mctrans = %d\n",
647 cod->compparms.numdlvls, cod->compparms.qmfbid, cod->mctrans);
648 fprintf(out, "prg = %" PRIuFAST8 "; numlyrs = %" PRIuFAST16 ";\n",
649 cod->prg, cod->numlyrs);
650 fprintf(out, "cblkwidthval = %d; cblkheightval = %d; "
651 "cblksty = 0x%02x;\n", cod->compparms.cblkwidthval, cod->compparms.cblkheightval,
652 cod->compparms.cblksty);
653 if (cod->csty & JPC_COX_PRT) {
654 for (i = 0; i < cod->compparms.numrlvls; ++i) {
655 jas_eprintf("prcwidth[%d] = %d, prcheight[%d] = %d\n",
656 i, cod->compparms.rlvls[i].parwidthval,
657 i, cod->compparms.rlvls[i].parheightval);
658 }
659 }
660 return 0;
661 }
662
663 /******************************************************************************\
664 * COC marker segment operations.
665 \******************************************************************************/
666
jpc_coc_destroyparms(jpc_ms_t * ms)667 static void jpc_coc_destroyparms(jpc_ms_t *ms)
668 {
669 jpc_coc_t *coc = &ms->parms.coc;
670 jpc_cox_destroycompparms(&coc->compparms);
671 }
672
jpc_coc_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)673 static int jpc_coc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
674 {
675 jpc_coc_t *coc = &ms->parms.coc;
676 uint_fast8_t tmp;
677 if (cstate->numcomps <= 256) {
678 if (jpc_getuint8(in, &tmp)) {
679 return -1;
680 }
681 coc->compno = tmp;
682 } else {
683 if (jpc_getuint16(in, &coc->compno)) {
684 return -1;
685 }
686 }
687 if (jpc_getuint8(in, &coc->compparms.csty)) {
688 return -1;
689 }
690 if (jpc_cox_getcompparms(ms, cstate, in,
691 (coc->compparms.csty & JPC_COX_PRT) != 0, &coc->compparms)) {
692 return -1;
693 }
694 if (jas_stream_eof(in)) {
695 return -1;
696 }
697 return 0;
698 }
699
jpc_coc_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)700 static int jpc_coc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
701 {
702 jpc_coc_t *coc = &ms->parms.coc;
703 assert(coc->compparms.numdlvls <= 32);
704 if (cstate->numcomps <= 256) {
705 if (jpc_putuint8(out, coc->compno)) {
706 return -1;
707 }
708 } else {
709 if (jpc_putuint16(out, coc->compno)) {
710 return -1;
711 }
712 }
713 if (jpc_putuint8(out, coc->compparms.csty)) {
714 return -1;
715 }
716 if (jpc_cox_putcompparms(ms, cstate, out,
717 (coc->compparms.csty & JPC_COX_PRT) != 0, &coc->compparms)) {
718 return -1;
719 }
720 return 0;
721 }
722
jpc_coc_dumpparms(jpc_ms_t * ms,FILE * out)723 static int jpc_coc_dumpparms(jpc_ms_t *ms, FILE *out)
724 {
725 jpc_coc_t *coc = &ms->parms.coc;
726 fprintf(out, "compno = %" PRIuFAST16 "; csty = 0x%02x; numdlvls = %d;\n",
727 coc->compno, coc->compparms.csty, coc->compparms.numdlvls);
728 fprintf(out, "cblkwidthval = %d; cblkheightval = %d; "
729 "cblksty = 0x%02x; qmfbid = %d;\n", coc->compparms.cblkwidthval,
730 coc->compparms.cblkheightval, coc->compparms.cblksty, coc->compparms.qmfbid);
731 return 0;
732 }
733 /******************************************************************************\
734 * COD/COC marker segment operation helper functions.
735 \******************************************************************************/
736
jpc_cox_destroycompparms(jpc_coxcp_t * compparms)737 static void jpc_cox_destroycompparms(jpc_coxcp_t *compparms)
738 {
739 /* Eliminate compiler warning about unused variables. */
740 compparms = 0;
741 }
742
jpc_cox_getcompparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in,int prtflag,jpc_coxcp_t * compparms)743 static int jpc_cox_getcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate,
744 jas_stream_t *in, int prtflag, jpc_coxcp_t *compparms)
745 {
746 uint_fast8_t tmp;
747 int i;
748
749 /* Eliminate compiler warning about unused variables. */
750 ms = 0;
751 cstate = 0;
752
753 if (jpc_getuint8(in, &compparms->numdlvls) ||
754 jpc_getuint8(in, &compparms->cblkwidthval) ||
755 jpc_getuint8(in, &compparms->cblkheightval) ||
756 jpc_getuint8(in, &compparms->cblksty) ||
757 jpc_getuint8(in, &compparms->qmfbid)) {
758 return -1;
759 }
760 compparms->numrlvls = compparms->numdlvls + 1;
761 if (compparms->numrlvls > JPC_MAXRLVLS) {
762 jpc_cox_destroycompparms(compparms);
763 return -1;
764 }
765 if (prtflag) {
766 for (i = 0; i < compparms->numrlvls; ++i) {
767 if (jpc_getuint8(in, &tmp)) {
768 jpc_cox_destroycompparms(compparms);
769 return -1;
770 }
771 compparms->rlvls[i].parwidthval = tmp & 0xf;
772 compparms->rlvls[i].parheightval = (tmp >> 4) & 0xf;
773 }
774 /* Sigh. This bit should be in the same field in both COC and COD mrk segs. */
775 compparms->csty |= JPC_COX_PRT;
776 } else {
777 }
778 if (jas_stream_eof(in)) {
779 jpc_cox_destroycompparms(compparms);
780 return -1;
781 }
782 return 0;
783 }
784
jpc_cox_putcompparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out,int prtflag,jpc_coxcp_t * compparms)785 static int jpc_cox_putcompparms(jpc_ms_t *ms, jpc_cstate_t *cstate,
786 jas_stream_t *out, int prtflag, jpc_coxcp_t *compparms)
787 {
788 int i;
789 assert(compparms->numdlvls <= 32);
790
791 /* Eliminate compiler warning about unused variables. */
792 ms = 0;
793 cstate = 0;
794
795 if (jpc_putuint8(out, compparms->numdlvls) ||
796 jpc_putuint8(out, compparms->cblkwidthval) ||
797 jpc_putuint8(out, compparms->cblkheightval) ||
798 jpc_putuint8(out, compparms->cblksty) ||
799 jpc_putuint8(out, compparms->qmfbid)) {
800 return -1;
801 }
802 if (prtflag) {
803 for (i = 0; i < compparms->numrlvls; ++i) {
804 if (jpc_putuint8(out,
805 ((compparms->rlvls[i].parheightval & 0xf) << 4) |
806 (compparms->rlvls[i].parwidthval & 0xf))) {
807 return -1;
808 }
809 }
810 }
811 return 0;
812 }
813
814 /******************************************************************************\
815 * RGN marker segment operations.
816 \******************************************************************************/
817
jpc_rgn_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)818 static int jpc_rgn_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
819 {
820 jpc_rgn_t *rgn = &ms->parms.rgn;
821 uint_fast8_t tmp;
822 if (cstate->numcomps <= 256) {
823 if (jpc_getuint8(in, &tmp)) {
824 return -1;
825 }
826 rgn->compno = tmp;
827 } else {
828 if (jpc_getuint16(in, &rgn->compno)) {
829 return -1;
830 }
831 }
832 if (jpc_getuint8(in, &rgn->roisty) ||
833 jpc_getuint8(in, &rgn->roishift)) {
834 return -1;
835 }
836 return 0;
837 }
838
jpc_rgn_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)839 static int jpc_rgn_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
840 {
841 jpc_rgn_t *rgn = &ms->parms.rgn;
842 if (cstate->numcomps <= 256) {
843 if (jpc_putuint8(out, rgn->compno)) {
844 return -1;
845 }
846 } else {
847 if (jpc_putuint16(out, rgn->compno)) {
848 return -1;
849 }
850 }
851 if (jpc_putuint8(out, rgn->roisty) ||
852 jpc_putuint8(out, rgn->roishift)) {
853 return -1;
854 }
855 return 0;
856 }
857
jpc_rgn_dumpparms(jpc_ms_t * ms,FILE * out)858 static int jpc_rgn_dumpparms(jpc_ms_t *ms, FILE *out)
859 {
860 jpc_rgn_t *rgn = &ms->parms.rgn;
861 fprintf(out, "compno = %" PRIuFAST16 "; roisty = %u; roishift = %u\n",
862 rgn->compno, rgn->roisty, rgn->roishift);
863 return 0;
864 }
865
866 /******************************************************************************\
867 * QCD marker segment operations.
868 \******************************************************************************/
869
jpc_qcd_destroyparms(jpc_ms_t * ms)870 static void jpc_qcd_destroyparms(jpc_ms_t *ms)
871 {
872 jpc_qcd_t *qcd = &ms->parms.qcd;
873 jpc_qcx_destroycompparms(&qcd->compparms);
874 }
875
jpc_qcd_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)876 static int jpc_qcd_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
877 {
878 jpc_qcxcp_t *compparms = &ms->parms.qcd.compparms;
879 return jpc_qcx_getcompparms(compparms, cstate, in, ms->len);
880 }
881
jpc_qcd_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)882 static int jpc_qcd_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
883 {
884 jpc_qcxcp_t *compparms = &ms->parms.qcd.compparms;
885 return jpc_qcx_putcompparms(compparms, cstate, out);
886 }
887
jpc_qcd_dumpparms(jpc_ms_t * ms,FILE * out)888 static int jpc_qcd_dumpparms(jpc_ms_t *ms, FILE *out)
889 {
890 jpc_qcd_t *qcd = &ms->parms.qcd;
891 int i;
892 fprintf(out, "qntsty = %d; numguard = %d; numstepsizes = %d\n",
893 (int) qcd->compparms.qntsty, qcd->compparms.numguard, qcd->compparms.numstepsizes);
894 for (i = 0; i < qcd->compparms.numstepsizes; ++i) {
895 fprintf(out, "expn[%d] = 0x%04x; mant[%d] = 0x%04x;\n",
896 i, (unsigned) JPC_QCX_GETEXPN(qcd->compparms.stepsizes[i]),
897 i, (unsigned) JPC_QCX_GETMANT(qcd->compparms.stepsizes[i]));
898 }
899 return 0;
900 }
901
902 /******************************************************************************\
903 * QCC marker segment operations.
904 \******************************************************************************/
905
jpc_qcc_destroyparms(jpc_ms_t * ms)906 static void jpc_qcc_destroyparms(jpc_ms_t *ms)
907 {
908 jpc_qcc_t *qcc = &ms->parms.qcc;
909 jpc_qcx_destroycompparms(&qcc->compparms);
910 }
911
jpc_qcc_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)912 static int jpc_qcc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
913 {
914 jpc_qcc_t *qcc = &ms->parms.qcc;
915 uint_fast8_t tmp;
916 int len;
917 len = ms->len;
918 tmp = 0;
919 if (cstate->numcomps <= 256) {
920 jpc_getuint8(in, &tmp);
921 qcc->compno = tmp;
922 --len;
923 } else {
924 jpc_getuint16(in, &qcc->compno);
925 len -= 2;
926 }
927 if (jpc_qcx_getcompparms(&qcc->compparms, cstate, in, len)) {
928 return -1;
929 }
930 if (jas_stream_eof(in)) {
931 jpc_qcc_destroyparms(ms);
932 return -1;
933 }
934 return 0;
935 }
936
jpc_qcc_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)937 static int jpc_qcc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
938 {
939 jpc_qcc_t *qcc = &ms->parms.qcc;
940 if (cstate->numcomps <= 256) {
941 jpc_putuint8(out, qcc->compno);
942 } else {
943 jpc_putuint16(out, qcc->compno);
944 }
945 if (jpc_qcx_putcompparms(&qcc->compparms, cstate, out)) {
946 return -1;
947 }
948 return 0;
949 }
950
jpc_qcc_dumpparms(jpc_ms_t * ms,FILE * out)951 static int jpc_qcc_dumpparms(jpc_ms_t *ms, FILE *out)
952 {
953 jpc_qcc_t *qcc = &ms->parms.qcc;
954 int i;
955 fprintf(out, "compno = %" PRIuFAST16 "; qntsty = %u; numguard = %u; "
956 "numstepsizes = %u\n", qcc->compno, qcc->compparms.qntsty, qcc->compparms.numguard,
957 qcc->compparms.numstepsizes);
958 for (i = 0; i < qcc->compparms.numstepsizes; ++i) {
959 fprintf(out, "expn[%d] = 0x%04x; mant[%d] = 0x%04x;\n",
960 i, (unsigned) JPC_QCX_GETEXPN(qcc->compparms.stepsizes[i]),
961 i, (unsigned) JPC_QCX_GETMANT(qcc->compparms.stepsizes[i]));
962 }
963 return 0;
964 }
965
966 /******************************************************************************\
967 * QCD/QCC marker segment helper functions.
968 \******************************************************************************/
969
jpc_qcx_destroycompparms(jpc_qcxcp_t * compparms)970 static void jpc_qcx_destroycompparms(jpc_qcxcp_t *compparms)
971 {
972 if (compparms->stepsizes) {
973 jas_free(compparms->stepsizes);
974 }
975 }
976
jpc_qcx_getcompparms(jpc_qcxcp_t * compparms,jpc_cstate_t * cstate,jas_stream_t * in,uint_fast16_t len)977 static int jpc_qcx_getcompparms(jpc_qcxcp_t *compparms, jpc_cstate_t *cstate,
978 jas_stream_t *in, uint_fast16_t len)
979 {
980 uint_fast8_t tmp;
981 int n;
982 int i;
983
984 /* Eliminate compiler warning about unused variables. */
985 cstate = 0;
986 tmp = 0;
987
988 n = 0;
989 jpc_getuint8(in, &tmp);
990 ++n;
991 compparms->qntsty = tmp & 0x1f;
992 compparms->numguard = (tmp >> 5) & 7;
993 switch (compparms->qntsty) {
994 case JPC_QCX_SIQNT:
995 compparms->numstepsizes = 1;
996 break;
997 case JPC_QCX_NOQNT:
998 compparms->numstepsizes = (len - n);
999 break;
1000 case JPC_QCX_SEQNT:
1001 /* XXX - this is a hack */
1002 compparms->numstepsizes = (len - n) / 2;
1003 break;
1004 }
1005 if (compparms->numstepsizes > 3 * JPC_MAXRLVLS + 1) {
1006 jpc_qcx_destroycompparms(compparms);
1007 return -1;
1008 } else if (compparms->numstepsizes > 0) {
1009 compparms->stepsizes = jas_malloc(compparms->numstepsizes *
1010 sizeof(uint_fast16_t));
1011 assert(compparms->stepsizes);
1012 for (i = 0; i < compparms->numstepsizes; ++i) {
1013 if (compparms->qntsty == JPC_QCX_NOQNT) {
1014 jpc_getuint8(in, &tmp);
1015 compparms->stepsizes[i] = JPC_QCX_EXPN(tmp >> 3);
1016 } else {
1017 jpc_getuint16(in, &compparms->stepsizes[i]);
1018 }
1019 }
1020 } else {
1021 compparms->stepsizes = 0;
1022 }
1023 if (jas_stream_error(in) || jas_stream_eof(in)) {
1024 jpc_qcx_destroycompparms(compparms);
1025 return -1;
1026 }
1027 return 0;
1028 }
1029
jpc_qcx_putcompparms(jpc_qcxcp_t * compparms,jpc_cstate_t * cstate,jas_stream_t * out)1030 static int jpc_qcx_putcompparms(jpc_qcxcp_t *compparms, jpc_cstate_t *cstate,
1031 jas_stream_t *out)
1032 {
1033 int i;
1034
1035 /* Eliminate compiler warning about unused variables. */
1036 cstate = 0;
1037
1038 jpc_putuint8(out, ((compparms->numguard & 7) << 5) | compparms->qntsty);
1039 for (i = 0; i < compparms->numstepsizes; ++i) {
1040 if (compparms->qntsty == JPC_QCX_NOQNT) {
1041 jpc_putuint8(out, JPC_QCX_GETEXPN(
1042 compparms->stepsizes[i]) << 3);
1043 } else {
1044 jpc_putuint16(out, compparms->stepsizes[i]);
1045 }
1046 }
1047 return 0;
1048 }
1049
1050 /******************************************************************************\
1051 * SOP marker segment operations.
1052 \******************************************************************************/
1053
jpc_sop_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)1054 static int jpc_sop_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
1055 {
1056 jpc_sop_t *sop = &ms->parms.sop;
1057
1058 /* Eliminate compiler warning about unused variable. */
1059 cstate = 0;
1060
1061 if (jpc_getuint16(in, &sop->seqno)) {
1062 return -1;
1063 }
1064 return 0;
1065 }
1066
jpc_sop_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)1067 static int jpc_sop_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
1068 {
1069 jpc_sop_t *sop = &ms->parms.sop;
1070
1071 /* Eliminate compiler warning about unused variable. */
1072 cstate = 0;
1073
1074 if (jpc_putuint16(out, sop->seqno)) {
1075 return -1;
1076 }
1077 return 0;
1078 }
1079
jpc_sop_dumpparms(jpc_ms_t * ms,FILE * out)1080 static int jpc_sop_dumpparms(jpc_ms_t *ms, FILE *out)
1081 {
1082 jpc_sop_t *sop = &ms->parms.sop;
1083 fprintf(out, "seqno = %" PRIuFAST16 ";\n", sop->seqno);
1084 return 0;
1085 }
1086
1087 /******************************************************************************\
1088 * PPM marker segment operations.
1089 \******************************************************************************/
1090
jpc_ppm_destroyparms(jpc_ms_t * ms)1091 static void jpc_ppm_destroyparms(jpc_ms_t *ms)
1092 {
1093 jpc_ppm_t *ppm = &ms->parms.ppm;
1094 if (ppm->data) {
1095 jas_free(ppm->data);
1096 }
1097 }
1098
jpc_ppm_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)1099 static int jpc_ppm_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
1100 {
1101 jpc_ppm_t *ppm = &ms->parms.ppm;
1102
1103 /* Eliminate compiler warning about unused variables. */
1104 cstate = 0;
1105
1106 ppm->data = 0;
1107
1108 if (ms->len < 1) {
1109 goto error;
1110 }
1111 if (jpc_getuint8(in, &ppm->ind)) {
1112 goto error;
1113 }
1114
1115 ppm->len = ms->len - 1;
1116 if (ppm->len > 0) {
1117 if (!(ppm->data = jas_malloc(ppm->len))) {
1118 goto error;
1119 }
1120 if (JAS_CAST(uint, jas_stream_read(in, ppm->data, ppm->len)) != ppm->len) {
1121 goto error;
1122 }
1123 } else {
1124 ppm->data = 0;
1125 }
1126 return 0;
1127
1128 error:
1129 jpc_ppm_destroyparms(ms);
1130 return -1;
1131 }
1132
jpc_ppm_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)1133 static int jpc_ppm_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
1134 {
1135 jpc_ppm_t *ppm = &ms->parms.ppm;
1136
1137 /* Eliminate compiler warning about unused variables. */
1138 cstate = 0;
1139
1140 if (JAS_CAST(uint, jas_stream_write(out, (char *) ppm->data, ppm->len)) != ppm->len) {
1141 return -1;
1142 }
1143 return 0;
1144 }
1145
jpc_ppm_dumpparms(jpc_ms_t * ms,FILE * out)1146 static int jpc_ppm_dumpparms(jpc_ms_t *ms, FILE *out)
1147 {
1148 jpc_ppm_t *ppm = &ms->parms.ppm;
1149 fprintf(out, "ind=%" PRIuFAST8 "; len = %" PRIuFAST16 ";\n",
1150 ppm->ind, ppm->len);
1151 if (ppm->len > 0) {
1152 fprintf(out, "data =\n");
1153 jas_memdump(out, ppm->data, ppm->len);
1154 }
1155 return 0;
1156 }
1157
1158 /******************************************************************************\
1159 * PPT marker segment operations.
1160 \******************************************************************************/
1161
jpc_ppt_destroyparms(jpc_ms_t * ms)1162 static void jpc_ppt_destroyparms(jpc_ms_t *ms)
1163 {
1164 jpc_ppt_t *ppt = &ms->parms.ppt;
1165 if (ppt->data) {
1166 jas_free(ppt->data);
1167 }
1168 }
1169
jpc_ppt_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)1170 static int jpc_ppt_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
1171 {
1172 jpc_ppt_t *ppt = &ms->parms.ppt;
1173
1174 /* Eliminate compiler warning about unused variables. */
1175 cstate = 0;
1176
1177 ppt->data = 0;
1178
1179 if (ms->len < 1) {
1180 goto error;
1181 }
1182 if (jpc_getuint8(in, &ppt->ind)) {
1183 goto error;
1184 }
1185 ppt->len = ms->len - 1;
1186 if (ppt->len > 0) {
1187 if (!(ppt->data = jas_malloc(ppt->len))) {
1188 goto error;
1189 }
1190 if (jas_stream_read(in, (char *) ppt->data, ppt->len) != JAS_CAST(int, ppt->len)) {
1191 goto error;
1192 }
1193 } else {
1194 ppt->data = 0;
1195 }
1196 return 0;
1197
1198 error:
1199 jpc_ppt_destroyparms(ms);
1200 return -1;
1201 }
1202
jpc_ppt_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)1203 static int jpc_ppt_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
1204 {
1205 jpc_ppt_t *ppt = &ms->parms.ppt;
1206
1207 /* Eliminate compiler warning about unused variable. */
1208 cstate = 0;
1209
1210 if (jpc_putuint8(out, ppt->ind)) {
1211 return -1;
1212 }
1213 if (jas_stream_write(out, (char *) ppt->data, ppt->len) != JAS_CAST(int, ppt->len)) {
1214 return -1;
1215 }
1216 return 0;
1217 }
1218
jpc_ppt_dumpparms(jpc_ms_t * ms,FILE * out)1219 static int jpc_ppt_dumpparms(jpc_ms_t *ms, FILE *out)
1220 {
1221 jpc_ppt_t *ppt = &ms->parms.ppt;
1222 fprintf(out, "ind=%d; len = %" PRIuFAST32 ";\n", ppt->ind, ppt->len);
1223 if (ppt->len > 0) {
1224 fprintf(out, "data =\n");
1225 jas_memdump(out, ppt->data, ppt->len);
1226 }
1227 return 0;
1228 }
1229
1230 /******************************************************************************\
1231 * POC marker segment operations.
1232 \******************************************************************************/
1233
jpc_poc_destroyparms(jpc_ms_t * ms)1234 static void jpc_poc_destroyparms(jpc_ms_t *ms)
1235 {
1236 jpc_poc_t *poc = &ms->parms.poc;
1237 if (poc->pchgs) {
1238 jas_free(poc->pchgs);
1239 }
1240 }
1241
jpc_poc_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)1242 static int jpc_poc_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
1243 {
1244 jpc_poc_t *poc = &ms->parms.poc;
1245 jpc_pocpchg_t *pchg;
1246 int pchgno;
1247 uint_fast8_t tmp;
1248 poc->numpchgs = (cstate->numcomps > 256) ? (ms->len / 9) :
1249 (ms->len / 7);
1250 if (!(poc->pchgs = jas_alloc2(poc->numpchgs, sizeof(jpc_pocpchg_t)))) {
1251 goto error;
1252 }
1253 for (pchgno = 0, pchg = poc->pchgs; pchgno < poc->numpchgs; ++pchgno,
1254 ++pchg) {
1255 if (jpc_getuint8(in, &pchg->rlvlnostart)) {
1256 goto error;
1257 }
1258 if (cstate->numcomps > 256) {
1259 if (jpc_getuint16(in, &pchg->compnostart)) {
1260 goto error;
1261 }
1262 } else {
1263 if (jpc_getuint8(in, &tmp)) {
1264 goto error;
1265 };
1266 pchg->compnostart = tmp;
1267 }
1268 if (jpc_getuint16(in, &pchg->lyrnoend) ||
1269 jpc_getuint8(in, &pchg->rlvlnoend)) {
1270 goto error;
1271 }
1272 if (cstate->numcomps > 256) {
1273 if (jpc_getuint16(in, &pchg->compnoend)) {
1274 goto error;
1275 }
1276 } else {
1277 if (jpc_getuint8(in, &tmp)) {
1278 goto error;
1279 }
1280 pchg->compnoend = tmp;
1281 }
1282 if (jpc_getuint8(in, &pchg->prgord)) {
1283 goto error;
1284 }
1285 if (pchg->rlvlnostart > pchg->rlvlnoend ||
1286 pchg->compnostart > pchg->compnoend) {
1287 goto error;
1288 }
1289 }
1290 return 0;
1291
1292 error:
1293 jpc_poc_destroyparms(ms);
1294 return -1;
1295 }
1296
jpc_poc_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)1297 static int jpc_poc_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
1298 {
1299 jpc_poc_t *poc = &ms->parms.poc;
1300 jpc_pocpchg_t *pchg;
1301 int pchgno;
1302 for (pchgno = 0, pchg = poc->pchgs; pchgno < poc->numpchgs; ++pchgno,
1303 ++pchg) {
1304 if (jpc_putuint8(out, pchg->rlvlnostart) ||
1305 ((cstate->numcomps > 256) ?
1306 jpc_putuint16(out, pchg->compnostart) :
1307 jpc_putuint8(out, pchg->compnostart)) ||
1308 jpc_putuint16(out, pchg->lyrnoend) ||
1309 jpc_putuint8(out, pchg->rlvlnoend) ||
1310 ((cstate->numcomps > 256) ?
1311 jpc_putuint16(out, pchg->compnoend) :
1312 jpc_putuint8(out, pchg->compnoend)) ||
1313 jpc_putuint8(out, pchg->prgord)) {
1314 return -1;
1315 }
1316 }
1317 return 0;
1318 }
1319
jpc_poc_dumpparms(jpc_ms_t * ms,FILE * out)1320 static int jpc_poc_dumpparms(jpc_ms_t *ms, FILE *out)
1321 {
1322 jpc_poc_t *poc = &ms->parms.poc;
1323 jpc_pocpchg_t *pchg;
1324 int pchgno;
1325 for (pchgno = 0, pchg = poc->pchgs; pchgno < poc->numpchgs;
1326 ++pchgno, ++pchg) {
1327 fprintf(out, "po[%d] = %d; ", pchgno, pchg->prgord);
1328 fprintf(out, "cs[%d] = %" PRIuFAST16 "; ce[%d] = %" PRIuFAST16 "; ",
1329 pchgno, pchg->compnostart, pchgno, pchg->compnoend);
1330 fprintf(out, "rs[%d] = %d; re[%d] = %d; ",
1331 pchgno, pchg->rlvlnostart, pchgno, pchg->rlvlnoend);
1332 fprintf(out, "le[%d] = %" PRIuFAST16 "\n", pchgno, pchg->lyrnoend);
1333 }
1334 return 0;
1335 }
1336
1337 /******************************************************************************\
1338 * CRG marker segment operations.
1339 \******************************************************************************/
1340
jpc_crg_destroyparms(jpc_ms_t * ms)1341 static void jpc_crg_destroyparms(jpc_ms_t *ms)
1342 {
1343 jpc_crg_t *crg = &ms->parms.crg;
1344 if (crg->comps) {
1345 jas_free(crg->comps);
1346 }
1347 }
1348
jpc_crg_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)1349 static int jpc_crg_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
1350 {
1351 jpc_crg_t *crg = &ms->parms.crg;
1352 jpc_crgcomp_t *comp;
1353 uint_fast16_t compno;
1354 crg->numcomps = cstate->numcomps;
1355 if (!(crg->comps = jas_alloc2(cstate->numcomps, sizeof(jpc_crgcomp_t)))) {
1356 return -1;
1357 }
1358 for (compno = 0, comp = crg->comps; compno < cstate->numcomps;
1359 ++compno, ++comp) {
1360 if (jpc_getuint16(in, &comp->hoff) ||
1361 jpc_getuint16(in, &comp->voff)) {
1362 jpc_crg_destroyparms(ms);
1363 return -1;
1364 }
1365 }
1366 return 0;
1367 }
1368
jpc_crg_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)1369 static int jpc_crg_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
1370 {
1371 jpc_crg_t *crg = &ms->parms.crg;
1372 int compno;
1373 jpc_crgcomp_t *comp;
1374
1375 /* Eliminate compiler warning about unused variables. */
1376 cstate = 0;
1377
1378 for (compno = 0, comp = crg->comps; compno < crg->numcomps; ++compno,
1379 ++comp) {
1380 if (jpc_putuint16(out, comp->hoff) ||
1381 jpc_putuint16(out, comp->voff)) {
1382 return -1;
1383 }
1384 }
1385 return 0;
1386 }
1387
jpc_crg_dumpparms(jpc_ms_t * ms,FILE * out)1388 static int jpc_crg_dumpparms(jpc_ms_t *ms, FILE *out)
1389 {
1390 jpc_crg_t *crg = &ms->parms.crg;
1391 int compno;
1392 jpc_crgcomp_t *comp;
1393 for (compno = 0, comp = crg->comps; compno < crg->numcomps; ++compno,
1394 ++comp) {
1395 fprintf(out, "hoff[%d] = %" PRIuFAST16 "; voff[%d] = %" PRIuFAST16 "\n",
1396 compno, comp->hoff, compno, comp->voff);
1397 }
1398 return 0;
1399 }
1400
1401 /******************************************************************************\
1402 * Operations for COM marker segment.
1403 \******************************************************************************/
1404
jpc_com_destroyparms(jpc_ms_t * ms)1405 static void jpc_com_destroyparms(jpc_ms_t *ms)
1406 {
1407 jpc_com_t *com = &ms->parms.com;
1408 if (com->data) {
1409 jas_free(com->data);
1410 }
1411 }
1412
jpc_com_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)1413 static int jpc_com_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
1414 {
1415 jpc_com_t *com = &ms->parms.com;
1416
1417 /* Eliminate compiler warning about unused variables. */
1418 cstate = 0;
1419
1420 if (jpc_getuint16(in, &com->regid)) {
1421 return -1;
1422 }
1423 com->len = ms->len - 2;
1424 if (com->len > 0) {
1425 if (!(com->data = jas_malloc(com->len))) {
1426 return -1;
1427 }
1428 if (jas_stream_read(in, com->data, com->len) != JAS_CAST(int, com->len)) {
1429 return -1;
1430 }
1431 } else {
1432 com->data = 0;
1433 }
1434 return 0;
1435 }
1436
jpc_com_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)1437 static int jpc_com_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
1438 {
1439 jpc_com_t *com = &ms->parms.com;
1440
1441 /* Eliminate compiler warning about unused variables. */
1442 cstate = 0;
1443
1444 if (jpc_putuint16(out, com->regid)) {
1445 return -1;
1446 }
1447 if (jas_stream_write(out, com->data, com->len) != JAS_CAST(int, com->len)) {
1448 return -1;
1449 }
1450 return 0;
1451 }
1452
jpc_com_dumpparms(jpc_ms_t * ms,FILE * out)1453 static int jpc_com_dumpparms(jpc_ms_t *ms, FILE *out)
1454 {
1455 jpc_com_t *com = &ms->parms.com;
1456 unsigned int i;
1457 int printable;
1458 fprintf(out, "regid = %" PRIuFAST16 ";\n", com->regid);
1459 printable = 1;
1460 for (i = 0; i < com->len; ++i) {
1461 if (!isprint(com->data[i])) {
1462 printable = 0;
1463 break;
1464 }
1465 }
1466 if (printable) {
1467 fprintf(out, "data = ");
1468 fwrite(com->data, sizeof(char), com->len, out);
1469 fprintf(out, "\n");
1470 }
1471 return 0;
1472 }
1473
1474 /******************************************************************************\
1475 * Operations for unknown types of marker segments.
1476 \******************************************************************************/
1477
jpc_unk_destroyparms(jpc_ms_t * ms)1478 static void jpc_unk_destroyparms(jpc_ms_t *ms)
1479 {
1480 jpc_unk_t *unk = &ms->parms.unk;
1481 if (unk->data) {
1482 jas_free(unk->data);
1483 }
1484 }
1485
jpc_unk_getparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * in)1486 static int jpc_unk_getparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *in)
1487 {
1488 jpc_unk_t *unk = &ms->parms.unk;
1489
1490 /* Eliminate compiler warning about unused variables. */
1491 cstate = 0;
1492
1493 if (ms->len > 0) {
1494 if (!(unk->data = jas_malloc(ms->len))) {
1495 return -1;
1496 }
1497 if (jas_stream_read(in, (char *) unk->data, ms->len) != JAS_CAST(int, ms->len)) {
1498 jas_free(unk->data);
1499 return -1;
1500 }
1501 unk->len = ms->len;
1502 } else {
1503 unk->data = 0;
1504 unk->len = 0;
1505 }
1506 return 0;
1507 }
1508
jpc_unk_putparms(jpc_ms_t * ms,jpc_cstate_t * cstate,jas_stream_t * out)1509 static int jpc_unk_putparms(jpc_ms_t *ms, jpc_cstate_t *cstate, jas_stream_t *out)
1510 {
1511 /* Eliminate compiler warning about unused variables. */
1512 cstate = 0;
1513 ms = 0;
1514 out = 0;
1515
1516 /* If this function is called, we are trying to write an unsupported
1517 type of marker segment. Return with an error indication. */
1518 return -1;
1519 }
1520
jpc_unk_dumpparms(jpc_ms_t * ms,FILE * out)1521 static int jpc_unk_dumpparms(jpc_ms_t *ms, FILE *out)
1522 {
1523 unsigned int i;
1524 jpc_unk_t *unk = &ms->parms.unk;
1525 for (i = 0; i < unk->len; ++i) {
1526 fprintf(out, "%02x ", unk->data[i]);
1527 }
1528 return 0;
1529 }
1530
1531 /******************************************************************************\
1532 * Primitive I/O operations.
1533 \******************************************************************************/
1534
jpc_getuint8(jas_stream_t * in,uint_fast8_t * val)1535 int jpc_getuint8(jas_stream_t *in, uint_fast8_t *val)
1536 {
1537 int c;
1538 if ((c = jas_stream_getc(in)) == EOF) {
1539 return -1;
1540 }
1541 if (val) {
1542 *val = c;
1543 }
1544 return 0;
1545 }
1546
jpc_putuint8(jas_stream_t * out,uint_fast8_t val)1547 int jpc_putuint8(jas_stream_t *out, uint_fast8_t val)
1548 {
1549 if (jas_stream_putc(out, val & 0xff) == EOF) {
1550 return -1;
1551 }
1552 return 0;
1553 }
1554
jpc_getuint16(jas_stream_t * in,uint_fast16_t * val)1555 int jpc_getuint16(jas_stream_t *in, uint_fast16_t *val)
1556 {
1557 uint_fast16_t v;
1558 int c;
1559 if ((c = jas_stream_getc(in)) == EOF) {
1560 return -1;
1561 }
1562 v = c;
1563 if ((c = jas_stream_getc(in)) == EOF) {
1564 return -1;
1565 }
1566 v = (v << 8) | c;
1567 if (val) {
1568 *val = v;
1569 }
1570 return 0;
1571 }
1572
jpc_putuint16(jas_stream_t * out,uint_fast16_t val)1573 int jpc_putuint16(jas_stream_t *out, uint_fast16_t val)
1574 {
1575 if (jas_stream_putc(out, (val >> 8) & 0xff) == EOF ||
1576 jas_stream_putc(out, val & 0xff) == EOF) {
1577 return -1;
1578 }
1579 return 0;
1580 }
1581
jpc_getuint32(jas_stream_t * in,uint_fast32_t * val)1582 int jpc_getuint32(jas_stream_t *in, uint_fast32_t *val)
1583 {
1584 uint_fast32_t v;
1585 int c;
1586 if ((c = jas_stream_getc(in)) == EOF) {
1587 return -1;
1588 }
1589 v = c;
1590 if ((c = jas_stream_getc(in)) == EOF) {
1591 return -1;
1592 }
1593 v = (v << 8) | c;
1594 if ((c = jas_stream_getc(in)) == EOF) {
1595 return -1;
1596 }
1597 v = (v << 8) | c;
1598 if ((c = jas_stream_getc(in)) == EOF) {
1599 return -1;
1600 }
1601 v = (v << 8) | c;
1602 if (val) {
1603 *val = v;
1604 }
1605 return 0;
1606 }
1607
jpc_putuint32(jas_stream_t * out,uint_fast32_t val)1608 int jpc_putuint32(jas_stream_t *out, uint_fast32_t val)
1609 {
1610 if (jas_stream_putc(out, (val >> 24) & 0xff) == EOF ||
1611 jas_stream_putc(out, (val >> 16) & 0xff) == EOF ||
1612 jas_stream_putc(out, (val >> 8) & 0xff) == EOF ||
1613 jas_stream_putc(out, val & 0xff) == EOF) {
1614 return -1;
1615 }
1616 return 0;
1617 }
1618
1619 /******************************************************************************\
1620 * Miscellany
1621 \******************************************************************************/
1622
jpc_mstab_lookup(int id)1623 static jpc_mstabent_t *jpc_mstab_lookup(int id)
1624 {
1625 jpc_mstabent_t *mstabent;
1626 for (mstabent = jpc_mstab;; ++mstabent) {
1627 if (mstabent->id == id || mstabent->id < 0) {
1628 return mstabent;
1629 }
1630 }
1631 assert(0);
1632 return 0;
1633 }
1634
jpc_validate(jas_stream_t * in)1635 int jpc_validate(jas_stream_t *in)
1636 {
1637 int n;
1638 int i;
1639 unsigned char buf[2];
1640
1641 assert(JAS_STREAM_MAXPUTBACK >= 2);
1642
1643 if ((n = jas_stream_read(in, (char *) buf, 2)) < 0) {
1644 return -1;
1645 }
1646 for (i = n - 1; i >= 0; --i) {
1647 if (jas_stream_ungetc(in, buf[i]) == EOF) {
1648 return -1;
1649 }
1650 }
1651 if (n < 2) {
1652 return -1;
1653 }
1654 if (buf[0] == (JPC_MS_SOC >> 8) && buf[1] == (JPC_MS_SOC & 0xff)) {
1655 return 0;
1656 }
1657 return -1;
1658 }
1659
jpc_getdata(jas_stream_t * in,jas_stream_t * out,long len)1660 int jpc_getdata(jas_stream_t *in, jas_stream_t *out, long len)
1661 {
1662 return jas_stream_copy(out, in, len);
1663 }
1664
jpc_putdata(jas_stream_t * out,jas_stream_t * in,long len)1665 int jpc_putdata(jas_stream_t *out, jas_stream_t *in, long len)
1666 {
1667 return jas_stream_copy(out, in, len);
1668 }
1669