vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

jpc_cs.c (46440B)


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