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