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