Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

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