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