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