Coverage Report

Created: 2025-12-03 07:28

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