/src/libjpeg-turbo.main/jdmarker.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * jdmarker.c | 
| 3 |  |  * | 
| 4 |  |  * This file was part of the Independent JPEG Group's software: | 
| 5 |  |  * Copyright (C) 1991-1998, Thomas G. Lane. | 
| 6 |  |  * Lossless JPEG Modifications: | 
| 7 |  |  * Copyright (C) 1999, Ken Murchison. | 
| 8 |  |  * libjpeg-turbo Modifications: | 
| 9 |  |  * Copyright (C) 2012, 2015, 2022, D. R. Commander. | 
| 10 |  |  * For conditions of distribution and use, see the accompanying README.ijg | 
| 11 |  |  * file. | 
| 12 |  |  * | 
| 13 |  |  * This file contains routines to decode JPEG datastream markers. | 
| 14 |  |  * Most of the complexity arises from our desire to support input | 
| 15 |  |  * suspension: if not all of the data for a marker is available, | 
| 16 |  |  * we must exit back to the application.  On resumption, we reprocess | 
| 17 |  |  * the marker. | 
| 18 |  |  */ | 
| 19 |  |  | 
| 20 |  | #define JPEG_INTERNALS | 
| 21 |  | #include "jinclude.h" | 
| 22 |  | #include "jpeglib.h" | 
| 23 |  |  | 
| 24 |  |  | 
| 25 |  | typedef enum {                  /* JPEG marker codes */ | 
| 26 |  |   M_SOF0  = 0xc0, | 
| 27 |  |   M_SOF1  = 0xc1, | 
| 28 |  |   M_SOF2  = 0xc2, | 
| 29 |  |   M_SOF3  = 0xc3, | 
| 30 |  |  | 
| 31 |  |   M_SOF5  = 0xc5, | 
| 32 |  |   M_SOF6  = 0xc6, | 
| 33 |  |   M_SOF7  = 0xc7, | 
| 34 |  |  | 
| 35 |  |   M_JPG   = 0xc8, | 
| 36 |  |   M_SOF9  = 0xc9, | 
| 37 |  |   M_SOF10 = 0xca, | 
| 38 |  |   M_SOF11 = 0xcb, | 
| 39 |  |  | 
| 40 |  |   M_SOF13 = 0xcd, | 
| 41 |  |   M_SOF14 = 0xce, | 
| 42 |  |   M_SOF15 = 0xcf, | 
| 43 |  |  | 
| 44 |  |   M_DHT   = 0xc4, | 
| 45 |  |  | 
| 46 |  |   M_DAC   = 0xcc, | 
| 47 |  |  | 
| 48 |  |   M_RST0  = 0xd0, | 
| 49 |  |   M_RST1  = 0xd1, | 
| 50 |  |   M_RST2  = 0xd2, | 
| 51 |  |   M_RST3  = 0xd3, | 
| 52 |  |   M_RST4  = 0xd4, | 
| 53 |  |   M_RST5  = 0xd5, | 
| 54 |  |   M_RST6  = 0xd6, | 
| 55 |  |   M_RST7  = 0xd7, | 
| 56 |  |  | 
| 57 |  |   M_SOI   = 0xd8, | 
| 58 |  |   M_EOI   = 0xd9, | 
| 59 |  |   M_SOS   = 0xda, | 
| 60 |  |   M_DQT   = 0xdb, | 
| 61 |  |   M_DNL   = 0xdc, | 
| 62 |  |   M_DRI   = 0xdd, | 
| 63 |  |   M_DHP   = 0xde, | 
| 64 |  |   M_EXP   = 0xdf, | 
| 65 |  |  | 
| 66 |  |   M_APP0  = 0xe0, | 
| 67 |  |   M_APP1  = 0xe1, | 
| 68 |  |   M_APP2  = 0xe2, | 
| 69 |  |   M_APP3  = 0xe3, | 
| 70 |  |   M_APP4  = 0xe4, | 
| 71 |  |   M_APP5  = 0xe5, | 
| 72 |  |   M_APP6  = 0xe6, | 
| 73 |  |   M_APP7  = 0xe7, | 
| 74 |  |   M_APP8  = 0xe8, | 
| 75 |  |   M_APP9  = 0xe9, | 
| 76 |  |   M_APP10 = 0xea, | 
| 77 |  |   M_APP11 = 0xeb, | 
| 78 |  |   M_APP12 = 0xec, | 
| 79 |  |   M_APP13 = 0xed, | 
| 80 |  |   M_APP14 = 0xee, | 
| 81 |  |   M_APP15 = 0xef, | 
| 82 |  |  | 
| 83 |  |   M_JPG0  = 0xf0, | 
| 84 |  |   M_JPG13 = 0xfd, | 
| 85 |  |   M_COM   = 0xfe, | 
| 86 |  |  | 
| 87 |  |   M_TEM   = 0x01, | 
| 88 |  |  | 
| 89 |  |   M_ERROR = 0x100 | 
| 90 |  | } JPEG_MARKER; | 
| 91 |  |  | 
| 92 |  |  | 
| 93 |  | /* Private state */ | 
| 94 |  |  | 
| 95 |  | typedef struct { | 
| 96 |  |   struct jpeg_marker_reader pub; /* public fields */ | 
| 97 |  |  | 
| 98 |  |   /* Application-overridable marker processing methods */ | 
| 99 |  |   jpeg_marker_parser_method process_COM; | 
| 100 |  |   jpeg_marker_parser_method process_APPn[16]; | 
| 101 |  |  | 
| 102 |  |   /* Limit on marker data length to save for each marker type */ | 
| 103 |  |   unsigned int length_limit_COM; | 
| 104 |  |   unsigned int length_limit_APPn[16]; | 
| 105 |  |  | 
| 106 |  |   /* Status of COM/APPn marker saving */ | 
| 107 |  |   jpeg_saved_marker_ptr cur_marker;     /* NULL if not processing a marker */ | 
| 108 |  |   unsigned int bytes_read;              /* data bytes read so far in marker */ | 
| 109 |  |   /* Note: cur_marker is not linked into marker_list until it's all read. */ | 
| 110 |  | } my_marker_reader; | 
| 111 |  |  | 
| 112 |  | typedef my_marker_reader *my_marker_ptr; | 
| 113 |  |  | 
| 114 |  |  | 
| 115 |  | /* | 
| 116 |  |  * Macros for fetching data from the data source module. | 
| 117 |  |  * | 
| 118 |  |  * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect | 
| 119 |  |  * the current restart point; we update them only when we have reached a | 
| 120 |  |  * suitable place to restart if a suspension occurs. | 
| 121 |  |  */ | 
| 122 |  |  | 
| 123 |  | /* Declare and initialize local copies of input pointer/count */ | 
| 124 |  | #define INPUT_VARS(cinfo) \ | 
| 125 | 140k |   struct jpeg_source_mgr *datasrc = (cinfo)->src; \ | 
| 126 | 140k |   const JOCTET *next_input_byte = datasrc->next_input_byte; \ | 
| 127 | 140k |   size_t bytes_in_buffer = datasrc->bytes_in_buffer | 
| 128 |  |  | 
| 129 |  | /* Unload the local copies --- do this only at a restart boundary */ | 
| 130 |  | #define INPUT_SYNC(cinfo) \ | 
| 131 | 4.11M |   ( datasrc->next_input_byte = next_input_byte, \ | 
| 132 | 4.11M |     datasrc->bytes_in_buffer = bytes_in_buffer ) | 
| 133 |  |  | 
| 134 |  | /* Reload the local copies --- used only in MAKE_BYTE_AVAIL */ | 
| 135 |  | #define INPUT_RELOAD(cinfo) \ | 
| 136 | 0 |   ( next_input_byte = datasrc->next_input_byte, \ | 
| 137 | 0 |     bytes_in_buffer = datasrc->bytes_in_buffer ) | 
| 138 |  |  | 
| 139 |  | /* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available. | 
| 140 |  |  * Note we do *not* do INPUT_SYNC before calling fill_input_buffer, | 
| 141 |  |  * but we must reload the local copies after a successful fill. | 
| 142 |  |  */ | 
| 143 |  | #define MAKE_BYTE_AVAIL(cinfo, action) \ | 
| 144 | 0 |   if (bytes_in_buffer == 0) { \ | 
| 145 | 0 |     if (!(*datasrc->fill_input_buffer) (cinfo)) \ | 
| 146 | 0 |       { action; } \ | 
| 147 | 0 |     INPUT_RELOAD(cinfo); \ | 
| 148 | 0 |   } | 
| 149 |  |  | 
| 150 |  | /* Read a byte into variable V. | 
| 151 |  |  * If must suspend, take the specified action (typically "return FALSE"). | 
| 152 |  |  */ | 
| 153 |  | #define INPUT_BYTE(cinfo, V, action) \ | 
| 154 | 5.27M |   MAKESTMT( MAKE_BYTE_AVAIL(cinfo, action); \ | 
| 155 | 5.13M |             bytes_in_buffer--; \ | 
| 156 | 5.13M |             V = *next_input_byte++; ) | 
| 157 |  |  | 
| 158 |  | /* As above, but read two bytes interpreted as an unsigned 16-bit integer. | 
| 159 |  |  * V should be declared unsigned int or perhaps JLONG. | 
| 160 |  |  */ | 
| 161 |  | #define INPUT_2BYTES(cinfo, V, action) \ | 
| 162 | 132k |   MAKESTMT( MAKE_BYTE_AVAIL(cinfo, action); \ | 
| 163 | 608k |             bytes_in_buffer--; \ | 
| 164 | 608k |             V = ((unsigned int)(*next_input_byte++)) << 8; \ | 
| 165 | 608k |             MAKE_BYTE_AVAIL(cinfo, action); \ | 
| 166 | 608k |             bytes_in_buffer--; \ | 
| 167 | 608k |             V += *next_input_byte++; ) | 
| 168 |  |  | 
| 169 |  |  | 
| 170 |  | /* | 
| 171 |  |  * Routines to process JPEG markers. | 
| 172 |  |  * | 
| 173 |  |  * Entry condition: JPEG marker itself has been read and its code saved | 
| 174 |  |  *   in cinfo->unread_marker; input restart point is just after the marker. | 
| 175 |  |  * | 
| 176 |  |  * Exit: if return TRUE, have read and processed any parameters, and have | 
| 177 |  |  *   updated the restart point to point after the parameters. | 
| 178 |  |  *   If return FALSE, was forced to suspend before reaching end of | 
| 179 |  |  *   marker parameters; restart point has not been moved.  Same routine | 
| 180 |  |  *   will be called again after application supplies more input data. | 
| 181 |  |  * | 
| 182 |  |  * This approach to suspension assumes that all of a marker's parameters | 
| 183 |  |  * can fit into a single input bufferload.  This should hold for "normal" | 
| 184 |  |  * markers.  Some COM/APPn markers might have large parameter segments | 
| 185 |  |  * that might not fit.  If we are simply dropping such a marker, we use | 
| 186 |  |  * skip_input_data to get past it, and thereby put the problem on the | 
| 187 |  |  * source manager's shoulders.  If we are saving the marker's contents | 
| 188 |  |  * into memory, we use a slightly different convention: when forced to | 
| 189 |  |  * suspend, the marker processor updates the restart point to the end of | 
| 190 |  |  * what it's consumed (ie, the end of the buffer) before returning FALSE. | 
| 191 |  |  * On resumption, cinfo->unread_marker still contains the marker code, | 
| 192 |  |  * but the data source will point to the next chunk of marker data. | 
| 193 |  |  * The marker processor must retain internal state to deal with this. | 
| 194 |  |  * | 
| 195 |  |  * Note that we don't bother to avoid duplicate trace messages if a | 
| 196 |  |  * suspension occurs within marker parameters.  Other side effects | 
| 197 |  |  * require more care. | 
| 198 |  |  */ | 
| 199 |  |  | 
| 200 |  |  | 
| 201 |  | LOCAL(boolean) | 
| 202 |  | get_soi(j_decompress_ptr cinfo) | 
| 203 |  | /* Process an SOI marker */ | 
| 204 | 10.3k | { | 
| 205 | 10.3k |   int i; | 
| 206 |  |  | 
| 207 | 10.3k |   TRACEMS(cinfo, 1, JTRC_SOI); | 
| 208 |  |  | 
| 209 | 10.3k |   if (cinfo->marker->saw_SOI) | 
| 210 | 109 |     ERREXIT(cinfo, JERR_SOI_DUPLICATE); | 
| 211 |  |  | 
| 212 |  |   /* Reset all parameters that are defined to be reset by SOI */ | 
| 213 |  |  | 
| 214 | 174k |   for (i = 0; i < NUM_ARITH_TBLS; i++) { | 
| 215 | 164k |     cinfo->arith_dc_L[i] = 0; | 
| 216 | 164k |     cinfo->arith_dc_U[i] = 1; | 
| 217 | 164k |     cinfo->arith_ac_K[i] = 5; | 
| 218 | 164k |   } | 
| 219 | 10.3k |   cinfo->restart_interval = 0; | 
| 220 |  |  | 
| 221 |  |   /* Set initial assumptions for colorspace etc */ | 
| 222 |  |  | 
| 223 | 10.3k |   cinfo->jpeg_color_space = JCS_UNKNOWN; | 
| 224 | 10.3k |   cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */ | 
| 225 |  |  | 
| 226 | 10.3k |   cinfo->saw_JFIF_marker = FALSE; | 
| 227 | 10.3k |   cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */ | 
| 228 | 10.3k |   cinfo->JFIF_minor_version = 1; | 
| 229 | 10.3k |   cinfo->density_unit = 0; | 
| 230 | 10.3k |   cinfo->X_density = 1; | 
| 231 | 10.3k |   cinfo->Y_density = 1; | 
| 232 | 10.3k |   cinfo->saw_Adobe_marker = FALSE; | 
| 233 | 10.3k |   cinfo->Adobe_transform = 0; | 
| 234 |  |  | 
| 235 | 10.3k |   cinfo->marker->saw_SOI = TRUE; | 
| 236 |  |  | 
| 237 | 10.3k |   return TRUE; | 
| 238 | 10.3k | } | 
| 239 |  |  | 
| 240 |  |  | 
| 241 |  | LOCAL(boolean) | 
| 242 |  | get_sof(j_decompress_ptr cinfo, boolean is_prog, boolean is_lossless, | 
| 243 |  |         boolean is_arith) | 
| 244 |  | /* Process a SOFn marker */ | 
| 245 | 9.15k | { | 
| 246 | 9.15k |   JLONG length; | 
| 247 | 9.15k |   int c, ci; | 
| 248 | 9.15k |   jpeg_component_info *compptr; | 
| 249 | 9.15k |   INPUT_VARS(cinfo); | 
| 250 |  |  | 
| 251 | 9.15k |   cinfo->progressive_mode = is_prog; | 
| 252 | 9.15k |   cinfo->master->lossless = is_lossless; | 
| 253 | 9.15k |   cinfo->arith_code = is_arith; | 
| 254 |  |  | 
| 255 | 9.15k |   INPUT_2BYTES(cinfo, length, return FALSE); | 
| 256 |  |  | 
| 257 | 9.15k |   INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE); | 
| 258 | 9.15k |   INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE); | 
| 259 | 9.15k |   INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE); | 
| 260 | 9.15k |   INPUT_BYTE(cinfo, cinfo->num_components, return FALSE); | 
| 261 |  |  | 
| 262 | 9.15k |   length -= 8; | 
| 263 |  |  | 
| 264 | 9.15k |   TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker, | 
| 265 | 9.15k |            (int)cinfo->image_width, (int)cinfo->image_height, | 
| 266 | 9.15k |            cinfo->num_components); | 
| 267 |  |  | 
| 268 | 9.15k |   if (cinfo->marker->saw_SOF) | 
| 269 | 51 |     ERREXIT(cinfo, JERR_SOF_DUPLICATE); | 
| 270 |  |  | 
| 271 |  |   /* We don't support files in which the image height is initially specified */ | 
| 272 |  |   /* as 0 and is later redefined by DNL.  As long as we have to check that,  */ | 
| 273 |  |   /* might as well have a general sanity check. */ | 
| 274 | 9.15k |   if (cinfo->image_height <= 0 || cinfo->image_width <= 0 || | 
| 275 | 9.15k |       cinfo->num_components <= 0) | 
| 276 | 5 |     ERREXIT(cinfo, JERR_EMPTY_IMAGE); | 
| 277 |  |  | 
| 278 | 9.15k |   if (length != (cinfo->num_components * 3)) | 
| 279 | 70 |     ERREXIT(cinfo, JERR_BAD_LENGTH); | 
| 280 |  |  | 
| 281 | 9.15k |   if (cinfo->comp_info == NULL) /* do only once, even if suspend */ | 
| 282 | 9.03k |     cinfo->comp_info = (jpeg_component_info *)(*cinfo->mem->alloc_small) | 
| 283 | 9.03k |                         ((j_common_ptr)cinfo, JPOOL_IMAGE, | 
| 284 | 9.03k |                          cinfo->num_components * sizeof(jpeg_component_info)); | 
| 285 |  |  | 
| 286 | 29.1k |   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; | 
| 287 | 20.0k |        ci++, compptr++) { | 
| 288 | 20.0k |     compptr->component_index = ci; | 
| 289 | 20.0k |     INPUT_BYTE(cinfo, compptr->component_id, return FALSE); | 
| 290 | 20.0k |     INPUT_BYTE(cinfo, c, return FALSE); | 
| 291 | 20.0k |     compptr->h_samp_factor = (c >> 4) & 15; | 
| 292 | 20.0k |     compptr->v_samp_factor = (c     ) & 15; | 
| 293 | 20.0k |     INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE); | 
| 294 |  |  | 
| 295 | 20.0k |     TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT, | 
| 296 | 20.0k |              compptr->component_id, compptr->h_samp_factor, | 
| 297 | 20.0k |              compptr->v_samp_factor, compptr->quant_tbl_no); | 
| 298 | 20.0k |   } | 
| 299 |  |  | 
| 300 | 9.15k |   cinfo->marker->saw_SOF = TRUE; | 
| 301 |  |  | 
| 302 | 9.15k |   INPUT_SYNC(cinfo); | 
| 303 | 9.15k |   return TRUE; | 
| 304 | 9.15k | } | 
| 305 |  |  | 
| 306 |  |  | 
| 307 |  | LOCAL(boolean) | 
| 308 |  | get_sos(j_decompress_ptr cinfo) | 
| 309 |  | /* Process a SOS marker */ | 
| 310 | 30.2k | { | 
| 311 | 30.2k |   JLONG length; | 
| 312 | 30.2k |   int i, ci, n, c, cc, pi; | 
| 313 | 30.2k |   jpeg_component_info *compptr; | 
| 314 | 30.2k |   INPUT_VARS(cinfo); | 
| 315 |  |  | 
| 316 | 30.2k |   if (!cinfo->marker->saw_SOF) | 
| 317 | 22 |     ERREXIT(cinfo, JERR_SOS_NO_SOF); | 
| 318 |  |  | 
| 319 | 30.2k |   INPUT_2BYTES(cinfo, length, return FALSE); | 
| 320 |  |  | 
| 321 | 30.2k |   INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */ | 
| 322 |  |  | 
| 323 | 30.2k |   TRACEMS1(cinfo, 1, JTRC_SOS, n); | 
| 324 |  |  | 
| 325 | 30.2k |   if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN) | 
| 326 | 108 |     ERREXIT(cinfo, JERR_BAD_LENGTH); | 
| 327 |  |  | 
| 328 | 30.2k |   cinfo->comps_in_scan = n; | 
| 329 |  |  | 
| 330 |  |   /* Collect the component-spec parameters */ | 
| 331 |  |  | 
| 332 | 150k |   for (i = 0; i < MAX_COMPS_IN_SCAN; i++) | 
| 333 | 120k |     cinfo->cur_comp_info[i] = NULL; | 
| 334 |  |  | 
| 335 | 77.2k |   for (i = 0; i < n; i++) { | 
| 336 | 47.1k |     INPUT_BYTE(cinfo, cc, return FALSE); | 
| 337 | 47.1k |     INPUT_BYTE(cinfo, c, return FALSE); | 
| 338 |  |  | 
| 339 | 47.1k |     for (ci = 0, compptr = cinfo->comp_info; | 
| 340 | 81.9k |          ci < cinfo->num_components && ci < MAX_COMPS_IN_SCAN; | 
| 341 | 81.8k |          ci++, compptr++) { | 
| 342 | 81.8k |       if (cc == compptr->component_id && !cinfo->cur_comp_info[ci]) | 
| 343 | 47.0k |         goto id_found; | 
| 344 | 81.8k |     } | 
| 345 |  |  | 
| 346 | 96 |     ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc); | 
| 347 |  |  | 
| 348 | 47.0k | id_found: | 
| 349 |  |  | 
| 350 | 47.0k |     cinfo->cur_comp_info[i] = compptr; | 
| 351 | 47.0k |     compptr->dc_tbl_no = (c >> 4) & 15; | 
| 352 | 47.0k |     compptr->ac_tbl_no = (c     ) & 15; | 
| 353 |  |  | 
| 354 | 47.0k |     TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc, | 
| 355 | 47.0k |              compptr->dc_tbl_no, compptr->ac_tbl_no); | 
| 356 |  |  | 
| 357 |  |     /* This CSi (cc) should differ from the previous CSi */ | 
| 358 | 70.8k |     for (pi = 0; pi < i; pi++) { | 
| 359 | 23.7k |       if (cinfo->cur_comp_info[pi] == compptr) { | 
| 360 | 3 |         ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc); | 
| 361 | 3 |       } | 
| 362 | 23.7k |     } | 
| 363 | 47.0k |   } | 
| 364 |  |  | 
| 365 |  |   /* Collect the additional scan parameters Ss, Se, Ah/Al. */ | 
| 366 | 30.1k |   INPUT_BYTE(cinfo, c, return FALSE); | 
| 367 | 30.1k |   cinfo->Ss = c; | 
| 368 | 30.1k |   INPUT_BYTE(cinfo, c, return FALSE); | 
| 369 | 30.1k |   cinfo->Se = c; | 
| 370 | 30.1k |   INPUT_BYTE(cinfo, c, return FALSE); | 
| 371 | 30.1k |   cinfo->Ah = (c >> 4) & 15; | 
| 372 | 30.1k |   cinfo->Al = (c     ) & 15; | 
| 373 |  |  | 
| 374 | 30.1k |   TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se, | 
| 375 | 30.1k |            cinfo->Ah, cinfo->Al); | 
| 376 |  |  | 
| 377 |  |   /* Prepare to scan data & restart markers */ | 
| 378 | 30.1k |   cinfo->marker->next_restart_num = 0; | 
| 379 |  |  | 
| 380 |  |   /* Count another SOS marker */ | 
| 381 | 30.1k |   cinfo->input_scan_number++; | 
| 382 |  |  | 
| 383 | 30.1k |   INPUT_SYNC(cinfo); | 
| 384 | 30.1k |   return TRUE; | 
| 385 | 30.1k | } | 
| 386 |  |  | 
| 387 |  |  | 
| 388 |  | #ifdef D_ARITH_CODING_SUPPORTED | 
| 389 |  |  | 
| 390 |  | LOCAL(boolean) | 
| 391 |  | get_dac(j_decompress_ptr cinfo) | 
| 392 |  | /* Process a DAC marker */ | 
| 393 | 664 | { | 
| 394 | 664 |   JLONG length; | 
| 395 | 664 |   int index, val; | 
| 396 | 664 |   INPUT_VARS(cinfo); | 
| 397 |  |  | 
| 398 | 664 |   INPUT_2BYTES(cinfo, length, return FALSE); | 
| 399 | 664 |   length -= 2; | 
| 400 |  |  | 
| 401 | 5.02k |   while (length > 0) { | 
| 402 | 4.35k |     INPUT_BYTE(cinfo, index, return FALSE); | 
| 403 | 4.35k |     INPUT_BYTE(cinfo, val, return FALSE); | 
| 404 |  |  | 
| 405 | 4.35k |     length -= 2; | 
| 406 |  |  | 
| 407 | 4.35k |     TRACEMS2(cinfo, 1, JTRC_DAC, index, val); | 
| 408 |  |  | 
| 409 | 4.35k |     if (index < 0 || index >= (2 * NUM_ARITH_TBLS)) | 
| 410 | 84 |       ERREXIT1(cinfo, JERR_DAC_INDEX, index); | 
| 411 |  |  | 
| 412 | 4.35k |     if (index >= NUM_ARITH_TBLS) { /* define AC table */ | 
| 413 | 666 |       cinfo->arith_ac_K[index - NUM_ARITH_TBLS] = (UINT8)val; | 
| 414 | 3.69k |     } else {                    /* define DC table */ | 
| 415 | 3.69k |       cinfo->arith_dc_L[index] = (UINT8)(val & 0x0F); | 
| 416 | 3.69k |       cinfo->arith_dc_U[index] = (UINT8)(val >> 4); | 
| 417 | 3.69k |       if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index]) | 
| 418 | 16 |         ERREXIT1(cinfo, JERR_DAC_VALUE, val); | 
| 419 | 3.69k |     } | 
| 420 | 4.35k |   } | 
| 421 |  |  | 
| 422 | 664 |   if (length != 0) | 
| 423 | 5 |     ERREXIT(cinfo, JERR_BAD_LENGTH); | 
| 424 |  |  | 
| 425 | 664 |   INPUT_SYNC(cinfo); | 
| 426 | 664 |   return TRUE; | 
| 427 | 664 | } | 
| 428 |  |  | 
| 429 |  | #else /* !D_ARITH_CODING_SUPPORTED */ | 
| 430 |  |  | 
| 431 |  | #define get_dac(cinfo)  skip_variable(cinfo) | 
| 432 |  |  | 
| 433 |  | #endif /* D_ARITH_CODING_SUPPORTED */ | 
| 434 |  |  | 
| 435 |  |  | 
| 436 |  | LOCAL(boolean) | 
| 437 |  | get_dht(j_decompress_ptr cinfo) | 
| 438 |  | /* Process a DHT marker */ | 
| 439 | 8.04k | { | 
| 440 | 8.04k |   JLONG length; | 
| 441 | 8.04k |   UINT8 bits[17]; | 
| 442 | 8.04k |   UINT8 huffval[256]; | 
| 443 | 8.04k |   int i, index, count; | 
| 444 | 8.04k |   JHUFF_TBL **htblptr; | 
| 445 | 8.04k |   INPUT_VARS(cinfo); | 
| 446 |  |  | 
| 447 | 8.04k |   INPUT_2BYTES(cinfo, length, return FALSE); | 
| 448 | 8.04k |   length -= 2; | 
| 449 |  |  | 
| 450 | 17.3k |   while (length > 16) { | 
| 451 | 9.26k |     INPUT_BYTE(cinfo, index, return FALSE); | 
| 452 |  |  | 
| 453 | 9.26k |     TRACEMS1(cinfo, 1, JTRC_DHT, index); | 
| 454 |  |  | 
| 455 | 9.26k |     bits[0] = 0; | 
| 456 | 9.26k |     count = 0; | 
| 457 | 157k |     for (i = 1; i <= 16; i++) { | 
| 458 | 148k |       INPUT_BYTE(cinfo, bits[i], return FALSE); | 
| 459 | 148k |       count += bits[i]; | 
| 460 | 148k |     } | 
| 461 |  |  | 
| 462 | 9.26k |     length -= 1 + 16; | 
| 463 |  |  | 
| 464 | 9.26k |     TRACEMS8(cinfo, 2, JTRC_HUFFBITS, | 
| 465 | 9.26k |              bits[1], bits[2], bits[3], bits[4], | 
| 466 | 9.26k |              bits[5], bits[6], bits[7], bits[8]); | 
| 467 | 9.26k |     TRACEMS8(cinfo, 2, JTRC_HUFFBITS, | 
| 468 | 9.26k |              bits[9], bits[10], bits[11], bits[12], | 
| 469 | 9.26k |              bits[13], bits[14], bits[15], bits[16]); | 
| 470 |  |  | 
| 471 |  |     /* Here we just do minimal validation of the counts to avoid walking | 
| 472 |  |      * off the end of our table space.  jdhuff.c will check more carefully. | 
| 473 |  |      */ | 
| 474 | 9.26k |     if (count > 256 || ((JLONG)count) > length) | 
| 475 | 164 |       ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); | 
| 476 |  |  | 
| 477 | 128k |     for (i = 0; i < count; i++) | 
| 478 | 119k |       INPUT_BYTE(cinfo, huffval[i], return FALSE); | 
| 479 |  |  | 
| 480 | 9.26k |     memset(&huffval[count], 0, (256 - count) * sizeof(UINT8)); | 
| 481 |  |  | 
| 482 | 9.26k |     length -= count; | 
| 483 |  |  | 
| 484 | 9.26k |     if (index & 0x10) {         /* AC table definition */ | 
| 485 | 4.27k |       index -= 0x10; | 
| 486 | 4.27k |       if (index < 0 || index >= NUM_HUFF_TBLS) | 
| 487 | 13 |         ERREXIT1(cinfo, JERR_DHT_INDEX, index); | 
| 488 | 4.27k |       htblptr = &cinfo->ac_huff_tbl_ptrs[index]; | 
| 489 | 4.99k |     } else {                    /* DC table definition */ | 
| 490 | 4.99k |       if (index < 0 || index >= NUM_HUFF_TBLS) | 
| 491 | 13 |         ERREXIT1(cinfo, JERR_DHT_INDEX, index); | 
| 492 | 4.99k |       htblptr = &cinfo->dc_huff_tbl_ptrs[index]; | 
| 493 | 4.99k |     } | 
| 494 |  |  | 
| 495 | 9.26k |     if (*htblptr == NULL) | 
| 496 | 2.19k |       *htblptr = jpeg_alloc_huff_table((j_common_ptr)cinfo); | 
| 497 |  |  | 
| 498 | 9.26k |     memcpy((*htblptr)->bits, bits, sizeof((*htblptr)->bits)); | 
| 499 | 9.26k |     memcpy((*htblptr)->huffval, huffval, sizeof((*htblptr)->huffval)); | 
| 500 | 9.26k |   } | 
| 501 |  |  | 
| 502 | 8.04k |   if (length != 0) | 
| 503 | 15 |     ERREXIT(cinfo, JERR_BAD_LENGTH); | 
| 504 |  |  | 
| 505 | 8.04k |   INPUT_SYNC(cinfo); | 
| 506 | 8.04k |   return TRUE; | 
| 507 | 8.04k | } | 
| 508 |  |  | 
| 509 |  |  | 
| 510 |  | LOCAL(boolean) | 
| 511 |  | get_dqt(j_decompress_ptr cinfo) | 
| 512 |  | /* Process a DQT marker */ | 
| 513 | 7.02k | { | 
| 514 | 7.02k |   JLONG length; | 
| 515 | 7.02k |   int n, i, prec; | 
| 516 | 7.02k |   unsigned int tmp; | 
| 517 | 7.02k |   JQUANT_TBL *quant_ptr; | 
| 518 | 7.02k |   INPUT_VARS(cinfo); | 
| 519 |  |  | 
| 520 | 7.02k |   INPUT_2BYTES(cinfo, length, return FALSE); | 
| 521 | 7.02k |   length -= 2; | 
| 522 |  |  | 
| 523 | 15.1k |   while (length > 0) { | 
| 524 | 8.14k |     INPUT_BYTE(cinfo, n, return FALSE); | 
| 525 | 8.14k |     prec = n >> 4; | 
| 526 | 8.14k |     n &= 0x0F; | 
| 527 |  |  | 
| 528 | 8.14k |     TRACEMS2(cinfo, 1, JTRC_DQT, n, prec); | 
| 529 |  |  | 
| 530 | 8.14k |     if (n >= NUM_QUANT_TBLS) | 
| 531 | 89 |       ERREXIT1(cinfo, JERR_DQT_INDEX, n); | 
| 532 |  |  | 
| 533 | 8.14k |     if (cinfo->quant_tbl_ptrs[n] == NULL) | 
| 534 | 3.13k |       cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr)cinfo); | 
| 535 | 8.14k |     quant_ptr = cinfo->quant_tbl_ptrs[n]; | 
| 536 |  |  | 
| 537 | 523k |     for (i = 0; i < DCTSIZE2; i++) { | 
| 538 | 515k |       if (prec) | 
| 539 | 515k |         INPUT_2BYTES(cinfo, tmp, return FALSE); | 
| 540 | 475k |       else | 
| 541 | 515k |         INPUT_BYTE(cinfo, tmp, return FALSE); | 
| 542 |  |       /* We convert the zigzag-order table to natural array order. */ | 
| 543 | 515k |       quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16)tmp; | 
| 544 | 515k |     } | 
| 545 |  |  | 
| 546 | 8.14k |     if (cinfo->err->trace_level >= 2) { | 
| 547 | 0 |       for (i = 0; i < DCTSIZE2; i += 8) { | 
| 548 | 0 |         TRACEMS8(cinfo, 2, JTRC_QUANTVALS, | 
| 549 | 0 |                  quant_ptr->quantval[i],     quant_ptr->quantval[i + 1], | 
| 550 | 0 |                  quant_ptr->quantval[i + 2], quant_ptr->quantval[i + 3], | 
| 551 | 0 |                  quant_ptr->quantval[i + 4], quant_ptr->quantval[i + 5], | 
| 552 | 0 |                  quant_ptr->quantval[i + 6], quant_ptr->quantval[i + 7]); | 
| 553 | 0 |       } | 
| 554 | 0 |     } | 
| 555 |  |  | 
| 556 | 8.14k |     length -= DCTSIZE2 + 1; | 
| 557 | 8.14k |     if (prec) length -= DCTSIZE2; | 
| 558 | 8.14k |   } | 
| 559 |  |  | 
| 560 | 7.02k |   if (length != 0) | 
| 561 | 46 |     ERREXIT(cinfo, JERR_BAD_LENGTH); | 
| 562 |  |  | 
| 563 | 7.02k |   INPUT_SYNC(cinfo); | 
| 564 | 7.02k |   return TRUE; | 
| 565 | 7.02k | } | 
| 566 |  |  | 
| 567 |  |  | 
| 568 |  | LOCAL(boolean) | 
| 569 |  | get_dri(j_decompress_ptr cinfo) | 
| 570 |  | /* Process a DRI marker */ | 
| 571 | 1.71k | { | 
| 572 | 1.71k |   JLONG length; | 
| 573 | 1.71k |   unsigned int tmp; | 
| 574 | 1.71k |   INPUT_VARS(cinfo); | 
| 575 |  |  | 
| 576 | 1.71k |   INPUT_2BYTES(cinfo, length, return FALSE); | 
| 577 |  |  | 
| 578 | 1.71k |   if (length != 4) | 
| 579 | 28 |     ERREXIT(cinfo, JERR_BAD_LENGTH); | 
| 580 |  |  | 
| 581 | 1.71k |   INPUT_2BYTES(cinfo, tmp, return FALSE); | 
| 582 |  |  | 
| 583 | 1.71k |   TRACEMS1(cinfo, 1, JTRC_DRI, tmp); | 
| 584 |  |  | 
| 585 | 1.71k |   cinfo->restart_interval = tmp; | 
| 586 |  |  | 
| 587 | 1.71k |   INPUT_SYNC(cinfo); | 
| 588 | 1.71k |   return TRUE; | 
| 589 | 1.71k | } | 
| 590 |  |  | 
| 591 |  |  | 
| 592 |  | /* | 
| 593 |  |  * Routines for processing APPn and COM markers. | 
| 594 |  |  * These are either saved in memory or discarded, per application request. | 
| 595 |  |  * APP0 and APP14 are specially checked to see if they are | 
| 596 |  |  * JFIF and Adobe markers, respectively. | 
| 597 |  |  */ | 
| 598 |  |  | 
| 599 | 10.2k | #define APP0_DATA_LEN   14      /* Length of interesting data in APP0 */ | 
| 600 | 3.81k | #define APP14_DATA_LEN  12      /* Length of interesting data in APP14 */ | 
| 601 | 10.7k | #define APPN_DATA_LEN   14      /* Must be the largest of the above!! */ | 
| 602 |  |  | 
| 603 |  |  | 
| 604 |  | LOCAL(void) | 
| 605 |  | examine_app0(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen, | 
| 606 |  |              JLONG remaining) | 
| 607 |  | /* Examine first few bytes from an APP0. | 
| 608 |  |  * Take appropriate action if it is a JFIF marker. | 
| 609 |  |  * datalen is # of bytes at data[], remaining is length of rest of marker data. | 
| 610 |  |  */ | 
| 611 | 4.64k | { | 
| 612 | 4.64k |   JLONG totallen = (JLONG)datalen + remaining; | 
| 613 |  |  | 
| 614 | 4.64k |   if (datalen >= APP0_DATA_LEN && | 
| 615 | 4.64k |       data[0] == 0x4A && | 
| 616 | 4.64k |       data[1] == 0x46 && | 
| 617 | 4.64k |       data[2] == 0x49 && | 
| 618 | 4.64k |       data[3] == 0x46 && | 
| 619 | 4.64k |       data[4] == 0) { | 
| 620 |  |     /* Found JFIF APP0 marker: save info */ | 
| 621 | 972 |     cinfo->saw_JFIF_marker = TRUE; | 
| 622 | 972 |     cinfo->JFIF_major_version = data[5]; | 
| 623 | 972 |     cinfo->JFIF_minor_version = data[6]; | 
| 624 | 972 |     cinfo->density_unit = data[7]; | 
| 625 | 972 |     cinfo->X_density = (data[8] << 8) + data[9]; | 
| 626 | 972 |     cinfo->Y_density = (data[10] << 8) + data[11]; | 
| 627 |  |     /* Check version. | 
| 628 |  |      * Major version must be 1, anything else signals an incompatible change. | 
| 629 |  |      * (We used to treat this as an error, but now it's a nonfatal warning, | 
| 630 |  |      * because some bozo at Hijaak couldn't read the spec.) | 
| 631 |  |      * Minor version should be 0..2, but process anyway if newer. | 
| 632 |  |      */ | 
| 633 | 972 |     if (cinfo->JFIF_major_version != 1) | 
| 634 | 347 |       WARNMS2(cinfo, JWRN_JFIF_MAJOR, | 
| 635 | 972 |               cinfo->JFIF_major_version, cinfo->JFIF_minor_version); | 
| 636 |  |     /* Generate trace messages */ | 
| 637 | 972 |     TRACEMS5(cinfo, 1, JTRC_JFIF, | 
| 638 | 972 |              cinfo->JFIF_major_version, cinfo->JFIF_minor_version, | 
| 639 | 972 |              cinfo->X_density, cinfo->Y_density, cinfo->density_unit); | 
| 640 |  |     /* Validate thumbnail dimensions and issue appropriate messages */ | 
| 641 | 972 |     if (data[12] | data[13]) | 
| 642 | 446 |       TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, data[12], data[13]); | 
| 643 | 972 |     totallen -= APP0_DATA_LEN; | 
| 644 | 972 |     if (totallen != ((JLONG)data[12] * (JLONG)data[13] * (JLONG)3)) | 
| 645 | 317 |       TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int)totallen); | 
| 646 | 3.66k |   } else if (datalen >= 6 && | 
| 647 | 3.66k |              data[0] == 0x4A && | 
| 648 | 3.66k |              data[1] == 0x46 && | 
| 649 | 3.66k |              data[2] == 0x58 && | 
| 650 | 3.66k |              data[3] == 0x58 && | 
| 651 | 3.66k |              data[4] == 0) { | 
| 652 |  |     /* Found JFIF "JFXX" extension APP0 marker */ | 
| 653 |  |     /* The library doesn't actually do anything with these, | 
| 654 |  |      * but we try to produce a helpful trace message. | 
| 655 |  |      */ | 
| 656 | 840 |     switch (data[5]) { | 
| 657 | 194 |     case 0x10: | 
| 658 | 194 |       TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int)totallen); | 
| 659 | 194 |       break; | 
| 660 | 248 |     case 0x11: | 
| 661 | 248 |       TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int)totallen); | 
| 662 | 248 |       break; | 
| 663 | 198 |     case 0x13: | 
| 664 | 198 |       TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int)totallen); | 
| 665 | 198 |       break; | 
| 666 | 200 |     default: | 
| 667 | 200 |       TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION, data[5], (int)totallen); | 
| 668 | 200 |       break; | 
| 669 | 840 |     } | 
| 670 | 2.82k |   } else { | 
| 671 |  |     /* Start of APP0 does not match "JFIF" or "JFXX", or too short */ | 
| 672 | 2.82k |     TRACEMS1(cinfo, 1, JTRC_APP0, (int)totallen); | 
| 673 | 2.82k |   } | 
| 674 | 4.64k | } | 
| 675 |  |  | 
| 676 |  |  | 
| 677 |  | LOCAL(void) | 
| 678 |  | examine_app14(j_decompress_ptr cinfo, JOCTET *data, unsigned int datalen, | 
| 679 |  |               JLONG remaining) | 
| 680 |  | /* Examine first few bytes from an APP14. | 
| 681 |  |  * Take appropriate action if it is an Adobe marker. | 
| 682 |  |  * datalen is # of bytes at data[], remaining is length of rest of marker data. | 
| 683 |  |  */ | 
| 684 | 1.90k | { | 
| 685 | 1.90k |   unsigned int version, flags0, flags1, transform; | 
| 686 |  |  | 
| 687 | 1.90k |   if (datalen >= APP14_DATA_LEN && | 
| 688 | 1.90k |       data[0] == 0x41 && | 
| 689 | 1.90k |       data[1] == 0x64 && | 
| 690 | 1.90k |       data[2] == 0x6F && | 
| 691 | 1.90k |       data[3] == 0x62 && | 
| 692 | 1.90k |       data[4] == 0x65) { | 
| 693 |  |     /* Found Adobe APP14 marker */ | 
| 694 | 352 |     version = (data[5] << 8) + data[6]; | 
| 695 | 352 |     flags0 = (data[7] << 8) + data[8]; | 
| 696 | 352 |     flags1 = (data[9] << 8) + data[10]; | 
| 697 | 352 |     transform = data[11]; | 
| 698 | 352 |     TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform); | 
| 699 | 352 |     cinfo->saw_Adobe_marker = TRUE; | 
| 700 | 352 |     cinfo->Adobe_transform = (UINT8)transform; | 
| 701 | 1.55k |   } else { | 
| 702 |  |     /* Start of APP14 does not match "Adobe", or too short */ | 
| 703 | 1.55k |     TRACEMS1(cinfo, 1, JTRC_APP14, (int)(datalen + remaining)); | 
| 704 | 1.55k |   } | 
| 705 | 1.90k | } | 
| 706 |  |  | 
| 707 |  |  | 
| 708 |  | METHODDEF(boolean) | 
| 709 |  | get_interesting_appn(j_decompress_ptr cinfo) | 
| 710 |  | /* Process an APP0 or APP14 marker without saving it */ | 
| 711 | 6.54k | { | 
| 712 | 6.54k |   JLONG length; | 
| 713 | 6.54k |   JOCTET b[APPN_DATA_LEN]; | 
| 714 | 6.54k |   unsigned int i, numtoread; | 
| 715 | 6.54k |   INPUT_VARS(cinfo); | 
| 716 |  |  | 
| 717 | 6.54k |   INPUT_2BYTES(cinfo, length, return FALSE); | 
| 718 | 6.54k |   length -= 2; | 
| 719 |  |  | 
| 720 |  |   /* get the interesting part of the marker data */ | 
| 721 | 6.54k |   if (length >= APPN_DATA_LEN) | 
| 722 | 4.23k |     numtoread = APPN_DATA_LEN; | 
| 723 | 2.31k |   else if (length > 0) | 
| 724 | 1.54k |     numtoread = (unsigned int)length; | 
| 725 | 770 |   else | 
| 726 | 770 |     numtoread = 0; | 
| 727 | 78.4k |   for (i = 0; i < numtoread; i++) | 
| 728 | 71.9k |     INPUT_BYTE(cinfo, b[i], return FALSE); | 
| 729 | 6.54k |   length -= numtoread; | 
| 730 |  |  | 
| 731 |  |   /* process it */ | 
| 732 | 6.54k |   switch (cinfo->unread_marker) { | 
| 733 | 4.64k |   case M_APP0: | 
| 734 | 4.64k |     examine_app0(cinfo, (JOCTET *)b, numtoread, length); | 
| 735 | 4.64k |     break; | 
| 736 | 1.90k |   case M_APP14: | 
| 737 | 1.90k |     examine_app14(cinfo, (JOCTET *)b, numtoread, length); | 
| 738 | 1.90k |     break; | 
| 739 | 0 |   default: | 
| 740 |  |     /* can't get here unless jpeg_save_markers chooses wrong processor */ | 
| 741 | 0 |     ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); | 
| 742 | 0 |     break; | 
| 743 | 6.54k |   } | 
| 744 |  |  | 
| 745 |  |   /* skip any remaining data -- could be lots */ | 
| 746 | 6.54k |   INPUT_SYNC(cinfo); | 
| 747 | 6.54k |   if (length > 0) | 
| 748 | 580 |     (*cinfo->src->skip_input_data) (cinfo, (long)length); | 
| 749 |  |  | 
| 750 | 6.54k |   return TRUE; | 
| 751 | 6.54k | } | 
| 752 |  |  | 
| 753 |  |  | 
| 754 |  | #ifdef SAVE_MARKERS_SUPPORTED | 
| 755 |  |  | 
| 756 |  | METHODDEF(boolean) | 
| 757 |  | save_marker(j_decompress_ptr cinfo) | 
| 758 |  | /* Save an APPn or COM marker into the marker list */ | 
| 759 | 0 | { | 
| 760 | 0 |   my_marker_ptr marker = (my_marker_ptr)cinfo->marker; | 
| 761 | 0 |   jpeg_saved_marker_ptr cur_marker = marker->cur_marker; | 
| 762 | 0 |   unsigned int bytes_read, data_length; | 
| 763 | 0 |   JOCTET *data; | 
| 764 | 0 |   JLONG length = 0; | 
| 765 | 0 |   INPUT_VARS(cinfo); | 
| 766 |  | 
 | 
| 767 | 0 |   if (cur_marker == NULL) { | 
| 768 |  |     /* begin reading a marker */ | 
| 769 | 0 |     INPUT_2BYTES(cinfo, length, return FALSE); | 
| 770 | 0 |     length -= 2; | 
| 771 | 0 |     if (length >= 0) {          /* watch out for bogus length word */ | 
| 772 |  |       /* figure out how much we want to save */ | 
| 773 | 0 |       unsigned int limit; | 
| 774 | 0 |       if (cinfo->unread_marker == (int)M_COM) | 
| 775 | 0 |         limit = marker->length_limit_COM; | 
| 776 | 0 |       else | 
| 777 | 0 |         limit = marker->length_limit_APPn[cinfo->unread_marker - (int)M_APP0]; | 
| 778 | 0 |       if ((unsigned int)length < limit) | 
| 779 | 0 |         limit = (unsigned int)length; | 
| 780 |  |       /* allocate and initialize the marker item */ | 
| 781 | 0 |       cur_marker = (jpeg_saved_marker_ptr) | 
| 782 | 0 |         (*cinfo->mem->alloc_large) ((j_common_ptr)cinfo, JPOOL_IMAGE, | 
| 783 | 0 |                                     sizeof(struct jpeg_marker_struct) + limit); | 
| 784 | 0 |       cur_marker->next = NULL; | 
| 785 | 0 |       cur_marker->marker = (UINT8)cinfo->unread_marker; | 
| 786 | 0 |       cur_marker->original_length = (unsigned int)length; | 
| 787 | 0 |       cur_marker->data_length = limit; | 
| 788 |  |       /* data area is just beyond the jpeg_marker_struct */ | 
| 789 | 0 |       data = cur_marker->data = (JOCTET *)(cur_marker + 1); | 
| 790 | 0 |       marker->cur_marker = cur_marker; | 
| 791 | 0 |       marker->bytes_read = 0; | 
| 792 | 0 |       bytes_read = 0; | 
| 793 | 0 |       data_length = limit; | 
| 794 | 0 |     } else { | 
| 795 |  |       /* deal with bogus length word */ | 
| 796 | 0 |       bytes_read = data_length = 0; | 
| 797 | 0 |       data = NULL; | 
| 798 | 0 |     } | 
| 799 | 0 |   } else { | 
| 800 |  |     /* resume reading a marker */ | 
| 801 | 0 |     bytes_read = marker->bytes_read; | 
| 802 | 0 |     data_length = cur_marker->data_length; | 
| 803 | 0 |     data = cur_marker->data + bytes_read; | 
| 804 | 0 |   } | 
| 805 |  |  | 
| 806 | 0 |   while (bytes_read < data_length) { | 
| 807 | 0 |     INPUT_SYNC(cinfo);          /* move the restart point to here */ | 
| 808 | 0 |     marker->bytes_read = bytes_read; | 
| 809 |  |     /* If there's not at least one byte in buffer, suspend */ | 
| 810 | 0 |     MAKE_BYTE_AVAIL(cinfo, return FALSE); | 
| 811 |  |     /* Copy bytes with reasonable rapidity */ | 
| 812 | 0 |     while (bytes_read < data_length && bytes_in_buffer > 0) { | 
| 813 | 0 |       *data++ = *next_input_byte++; | 
| 814 | 0 |       bytes_in_buffer--; | 
| 815 | 0 |       bytes_read++; | 
| 816 | 0 |     } | 
| 817 | 0 |   } | 
| 818 |  |  | 
| 819 |  |   /* Done reading what we want to read */ | 
| 820 | 0 |   if (cur_marker != NULL) {     /* will be NULL if bogus length word */ | 
| 821 |  |     /* Add new marker to end of list */ | 
| 822 | 0 |     if (cinfo->marker_list == NULL) { | 
| 823 | 0 |       cinfo->marker_list = cur_marker; | 
| 824 | 0 |     } else { | 
| 825 | 0 |       jpeg_saved_marker_ptr prev = cinfo->marker_list; | 
| 826 | 0 |       while (prev->next != NULL) | 
| 827 | 0 |         prev = prev->next; | 
| 828 | 0 |       prev->next = cur_marker; | 
| 829 | 0 |     } | 
| 830 |  |     /* Reset pointer & calc remaining data length */ | 
| 831 | 0 |     data = cur_marker->data; | 
| 832 | 0 |     length = cur_marker->original_length - data_length; | 
| 833 | 0 |   } | 
| 834 |  |   /* Reset to initial state for next marker */ | 
| 835 | 0 |   marker->cur_marker = NULL; | 
| 836 |  |  | 
| 837 |  |   /* Process the marker if interesting; else just make a generic trace msg */ | 
| 838 | 0 |   switch (cinfo->unread_marker) { | 
| 839 | 0 |   case M_APP0: | 
| 840 | 0 |     examine_app0(cinfo, data, data_length, length); | 
| 841 | 0 |     break; | 
| 842 | 0 |   case M_APP14: | 
| 843 | 0 |     examine_app14(cinfo, data, data_length, length); | 
| 844 | 0 |     break; | 
| 845 | 0 |   default: | 
| 846 | 0 |     TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, | 
| 847 | 0 |              (int)(data_length + length)); | 
| 848 | 0 |     break; | 
| 849 | 0 |   } | 
| 850 |  |  | 
| 851 |  |   /* skip any remaining data -- could be lots */ | 
| 852 | 0 |   INPUT_SYNC(cinfo);            /* do before skip_input_data */ | 
| 853 | 0 |   if (length > 0) | 
| 854 | 0 |     (*cinfo->src->skip_input_data) (cinfo, (long)length); | 
| 855 |  | 
 | 
| 856 | 0 |   return TRUE; | 
| 857 | 0 | } | 
| 858 |  |  | 
| 859 |  | #endif /* SAVE_MARKERS_SUPPORTED */ | 
| 860 |  |  | 
| 861 |  |  | 
| 862 |  | METHODDEF(boolean) | 
| 863 |  | skip_variable(j_decompress_ptr cinfo) | 
| 864 |  | /* Skip over an unknown or uninteresting variable-length marker */ | 
| 865 | 9.04k | { | 
| 866 | 9.04k |   JLONG length; | 
| 867 | 9.04k |   INPUT_VARS(cinfo); | 
| 868 |  |  | 
| 869 | 9.04k |   INPUT_2BYTES(cinfo, length, return FALSE); | 
| 870 | 9.04k |   length -= 2; | 
| 871 |  |  | 
| 872 | 9.04k |   TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int)length); | 
| 873 |  |  | 
| 874 | 9.04k |   INPUT_SYNC(cinfo);            /* do before skip_input_data */ | 
| 875 | 9.04k |   if (length > 0) | 
| 876 | 1.55k |     (*cinfo->src->skip_input_data) (cinfo, (long)length); | 
| 877 |  |  | 
| 878 | 9.04k |   return TRUE; | 
| 879 | 9.04k | } | 
| 880 |  |  | 
| 881 |  |  | 
| 882 |  | /* | 
| 883 |  |  * Find the next JPEG marker, save it in cinfo->unread_marker. | 
| 884 |  |  * Returns FALSE if had to suspend before reaching a marker; | 
| 885 |  |  * in that case cinfo->unread_marker is unchanged. | 
| 886 |  |  * | 
| 887 |  |  * Note that the result might not be a valid marker code, | 
| 888 |  |  * but it will never be 0 or FF. | 
| 889 |  |  */ | 
| 890 |  |  | 
| 891 |  | LOCAL(boolean) | 
| 892 |  | next_marker(j_decompress_ptr cinfo) | 
| 893 | 57.4k | { | 
| 894 | 57.4k |   int c; | 
| 895 | 57.4k |   INPUT_VARS(cinfo); | 
| 896 |  |  | 
| 897 | 72.9k |   for (;;) { | 
| 898 | 72.9k |     INPUT_BYTE(cinfo, c, return FALSE); | 
| 899 |  |     /* Skip any non-FF bytes. | 
| 900 |  |      * This may look a bit inefficient, but it will not occur in a valid file. | 
| 901 |  |      * We sync after each discarded byte so that a suspending data source | 
| 902 |  |      * can discard the byte from its buffer. | 
| 903 |  |      */ | 
| 904 | 4.03M |     while (c != 0xFF) { | 
| 905 | 3.95M |       cinfo->marker->discarded_bytes++; | 
| 906 | 3.95M |       INPUT_SYNC(cinfo); | 
| 907 | 3.95M |       INPUT_BYTE(cinfo, c, return FALSE); | 
| 908 | 3.95M |     } | 
| 909 |  |     /* This loop swallows any duplicate FF bytes.  Extra FFs are legal as | 
| 910 |  |      * pad bytes, so don't count them in discarded_bytes.  We assume there | 
| 911 |  |      * will not be so many consecutive FF bytes as to overflow a suspending | 
| 912 |  |      * data source's input buffer. | 
| 913 |  |      */ | 
| 914 | 83.3k |     do { | 
| 915 | 83.3k |       INPUT_BYTE(cinfo, c, return FALSE); | 
| 916 | 83.3k |     } while (c == 0xFF); | 
| 917 | 72.9k |     if (c != 0) | 
| 918 | 57.4k |       break;                    /* found a valid marker, exit loop */ | 
| 919 |  |     /* Reach here if we found a stuffed-zero data sequence (FF/00). | 
| 920 |  |      * Discard it and loop back to try again. | 
| 921 |  |      */ | 
| 922 | 15.4k |     cinfo->marker->discarded_bytes += 2; | 
| 923 | 15.4k |     INPUT_SYNC(cinfo); | 
| 924 | 15.4k |   } | 
| 925 |  |  | 
| 926 | 57.4k |   if (cinfo->marker->discarded_bytes != 0) { | 
| 927 | 12.2k |     WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c); | 
| 928 | 12.2k |     cinfo->marker->discarded_bytes = 0; | 
| 929 | 12.2k |   } | 
| 930 |  |  | 
| 931 | 57.4k |   cinfo->unread_marker = c; | 
| 932 |  |  | 
| 933 | 57.4k |   INPUT_SYNC(cinfo); | 
| 934 | 57.4k |   return TRUE; | 
| 935 | 57.4k | } | 
| 936 |  |  | 
| 937 |  |  | 
| 938 |  | LOCAL(boolean) | 
| 939 |  | first_marker(j_decompress_ptr cinfo) | 
| 940 |  | /* Like next_marker, but used to obtain the initial SOI marker. */ | 
| 941 |  | /* For this marker, we do not allow preceding garbage or fill; otherwise, | 
| 942 |  |  * we might well scan an entire input file before realizing it ain't JPEG. | 
| 943 |  |  * If an application wants to process non-JFIF files, it must seek to the | 
| 944 |  |  * SOI before calling the JPEG library. | 
| 945 |  |  */ | 
| 946 | 10.2k | { | 
| 947 | 10.2k |   int c, c2; | 
| 948 | 10.2k |   INPUT_VARS(cinfo); | 
| 949 |  |  | 
| 950 | 10.2k |   INPUT_BYTE(cinfo, c, return FALSE); | 
| 951 | 10.2k |   INPUT_BYTE(cinfo, c2, return FALSE); | 
| 952 | 10.2k |   if (c != 0xFF || c2 != (int)M_SOI) | 
| 953 | 26 |     ERREXIT2(cinfo, JERR_NO_SOI, c, c2); | 
| 954 |  |  | 
| 955 | 10.2k |   cinfo->unread_marker = c2; | 
| 956 |  |  | 
| 957 | 10.2k |   INPUT_SYNC(cinfo); | 
| 958 | 10.2k |   return TRUE; | 
| 959 | 10.2k | } | 
| 960 |  |  | 
| 961 |  |  | 
| 962 |  | /* | 
| 963 |  |  * Read markers until SOS or EOI. | 
| 964 |  |  * | 
| 965 |  |  * Returns same codes as are defined for jpeg_consume_input: | 
| 966 |  |  * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. | 
| 967 |  |  */ | 
| 968 |  |  | 
| 969 |  | METHODDEF(int) | 
| 970 |  | read_markers(j_decompress_ptr cinfo) | 
| 971 | 35.3k | { | 
| 972 |  |   /* Outer loop repeats once for each marker. */ | 
| 973 | 89.9k |   for (;;) { | 
| 974 |  |     /* Collect the marker proper, unless we already did. */ | 
| 975 |  |     /* NB: first_marker() enforces the requirement that SOI appear first. */ | 
| 976 | 89.9k |     if (cinfo->unread_marker == 0) { | 
| 977 | 65.0k |       if (!cinfo->marker->saw_SOI) { | 
| 978 | 10.2k |         if (!first_marker(cinfo)) | 
| 979 | 0 |           return JPEG_SUSPENDED; | 
| 980 | 54.8k |       } else { | 
| 981 | 54.8k |         if (!next_marker(cinfo)) | 
| 982 | 0 |           return JPEG_SUSPENDED; | 
| 983 | 54.8k |       } | 
| 984 | 65.0k |     } | 
| 985 |  |     /* At this point cinfo->unread_marker contains the marker code and the | 
| 986 |  |      * input point is just past the marker proper, but before any parameters. | 
| 987 |  |      * A suspension will cause us to return with this state still true. | 
| 988 |  |      */ | 
| 989 | 89.9k |     switch (cinfo->unread_marker) { | 
| 990 | 10.3k |     case M_SOI: | 
| 991 | 10.3k |       if (!get_soi(cinfo)) | 
| 992 | 0 |         return JPEG_SUSPENDED; | 
| 993 | 10.3k |       break; | 
| 994 |  |  | 
| 995 | 10.3k |     case M_SOF0:                /* Baseline */ | 
| 996 | 1.91k |     case M_SOF1:                /* Extended sequential, Huffman */ | 
| 997 | 1.91k |       if (!get_sof(cinfo, FALSE, FALSE, FALSE)) | 
| 998 | 0 |         return JPEG_SUSPENDED; | 
| 999 | 1.91k |       break; | 
| 1000 |  |  | 
| 1001 | 1.91k |     case M_SOF2:                /* Progressive, Huffman */ | 
| 1002 | 1.70k |       if (!get_sof(cinfo, TRUE, FALSE, FALSE)) | 
| 1003 | 0 |         return JPEG_SUSPENDED; | 
| 1004 | 1.70k |       break; | 
| 1005 |  |  | 
| 1006 | 2.36k |     case M_SOF3:                /* Lossless, Huffman */ | 
| 1007 | 2.36k |       if (!get_sof(cinfo, FALSE, TRUE, FALSE)) | 
| 1008 | 0 |         return JPEG_SUSPENDED; | 
| 1009 | 2.36k |       break; | 
| 1010 |  |  | 
| 1011 | 2.36k |     case M_SOF9:                /* Extended sequential, arithmetic */ | 
| 1012 | 566 |       if (!get_sof(cinfo, FALSE, FALSE, TRUE)) | 
| 1013 | 0 |         return JPEG_SUSPENDED; | 
| 1014 | 566 |       break; | 
| 1015 |  |  | 
| 1016 | 2.58k |     case M_SOF10:               /* Progressive, arithmetic */ | 
| 1017 | 2.58k |       if (!get_sof(cinfo, TRUE, FALSE, TRUE)) | 
| 1018 | 0 |         return JPEG_SUSPENDED; | 
| 1019 | 2.58k |       break; | 
| 1020 |  |  | 
| 1021 | 2.58k |     case M_SOF11:               /* Lossless, arithmetic */ | 
| 1022 | 27 |       if (!get_sof(cinfo, FALSE, TRUE, TRUE)) | 
| 1023 | 0 |         return JPEG_SUSPENDED; | 
| 1024 | 27 |       break; | 
| 1025 |  |  | 
| 1026 |  |     /* Currently unsupported SOFn types */ | 
| 1027 | 27 |     case M_SOF5:                /* Differential sequential, Huffman */ | 
| 1028 | 5 |     case M_SOF6:                /* Differential progressive, Huffman */ | 
| 1029 | 7 |     case M_SOF7:                /* Differential lossless, Huffman */ | 
| 1030 | 8 |     case M_JPG:                 /* Reserved for JPEG extensions */ | 
| 1031 | 10 |     case M_SOF13:               /* Differential sequential, arithmetic */ | 
| 1032 | 12 |     case M_SOF14:               /* Differential progressive, arithmetic */ | 
| 1033 | 14 |     case M_SOF15:               /* Differential lossless, arithmetic */ | 
| 1034 | 14 |       ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker); | 
| 1035 | 14 |       break; | 
| 1036 |  |  | 
| 1037 | 30.2k |     case M_SOS: | 
| 1038 | 30.2k |       if (!get_sos(cinfo)) | 
| 1039 | 0 |         return JPEG_SUSPENDED; | 
| 1040 | 30.2k |       cinfo->unread_marker = 0; /* processed the marker */ | 
| 1041 | 30.2k |       return JPEG_REACHED_SOS; | 
| 1042 |  |  | 
| 1043 | 4.15k |     case M_EOI: | 
| 1044 | 4.15k |       TRACEMS(cinfo, 1, JTRC_EOI); | 
| 1045 | 4.15k |       cinfo->unread_marker = 0; /* processed the marker */ | 
| 1046 | 4.15k |       return JPEG_REACHED_EOI; | 
| 1047 |  |  | 
| 1048 | 664 |     case M_DAC: | 
| 1049 | 664 |       if (!get_dac(cinfo)) | 
| 1050 | 0 |         return JPEG_SUSPENDED; | 
| 1051 | 664 |       break; | 
| 1052 |  |  | 
| 1053 | 8.04k |     case M_DHT: | 
| 1054 | 8.04k |       if (!get_dht(cinfo)) | 
| 1055 | 0 |         return JPEG_SUSPENDED; | 
| 1056 | 8.04k |       break; | 
| 1057 |  |  | 
| 1058 | 8.04k |     case M_DQT: | 
| 1059 | 7.02k |       if (!get_dqt(cinfo)) | 
| 1060 | 0 |         return JPEG_SUSPENDED; | 
| 1061 | 7.02k |       break; | 
| 1062 |  |  | 
| 1063 | 7.02k |     case M_DRI: | 
| 1064 | 1.71k |       if (!get_dri(cinfo)) | 
| 1065 | 0 |         return JPEG_SUSPENDED; | 
| 1066 | 1.71k |       break; | 
| 1067 |  |  | 
| 1068 | 4.64k |     case M_APP0: | 
| 1069 | 6.91k |     case M_APP1: | 
| 1070 | 7.15k |     case M_APP2: | 
| 1071 | 7.71k |     case M_APP3: | 
| 1072 | 7.92k |     case M_APP4: | 
| 1073 | 8.14k |     case M_APP5: | 
| 1074 | 8.37k |     case M_APP6: | 
| 1075 | 8.56k |     case M_APP7: | 
| 1076 | 8.81k |     case M_APP8: | 
| 1077 | 9.05k |     case M_APP9: | 
| 1078 | 9.30k |     case M_APP10: | 
| 1079 | 9.50k |     case M_APP11: | 
| 1080 | 9.84k |     case M_APP12: | 
| 1081 | 12.6k |     case M_APP13: | 
| 1082 | 14.5k |     case M_APP14: | 
| 1083 | 14.8k |     case M_APP15: | 
| 1084 | 14.8k |       if (!(*((my_marker_ptr)cinfo->marker)->process_APPn[ | 
| 1085 | 14.8k |                cinfo->unread_marker - (int)M_APP0]) (cinfo)) | 
| 1086 | 0 |         return JPEG_SUSPENDED; | 
| 1087 | 14.8k |       break; | 
| 1088 |  |  | 
| 1089 | 14.8k |     case M_COM: | 
| 1090 | 244 |       if (!(*((my_marker_ptr)cinfo->marker)->process_COM) (cinfo)) | 
| 1091 | 0 |         return JPEG_SUSPENDED; | 
| 1092 | 244 |       break; | 
| 1093 |  |  | 
| 1094 | 244 |     case M_RST0:                /* these are all parameterless */ | 
| 1095 | 473 |     case M_RST1: | 
| 1096 | 829 |     case M_RST2: | 
| 1097 | 1.05k |     case M_RST3: | 
| 1098 | 1.45k |     case M_RST4: | 
| 1099 | 1.82k |     case M_RST5: | 
| 1100 | 2.04k |     case M_RST6: | 
| 1101 | 2.24k |     case M_RST7: | 
| 1102 | 2.71k |     case M_TEM: | 
| 1103 | 2.71k |       TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker); | 
| 1104 | 2.71k |       break; | 
| 1105 |  |  | 
| 1106 | 532 |     case M_DNL:                 /* Ignore DNL ... perhaps the wrong thing */ | 
| 1107 | 532 |       if (!skip_variable(cinfo)) | 
| 1108 | 0 |         return JPEG_SUSPENDED; | 
| 1109 | 532 |       break; | 
| 1110 |  |  | 
| 1111 | 532 |     default:                    /* must be DHP, EXP, JPGn, or RESn */ | 
| 1112 |  |       /* For now, we treat the reserved markers as fatal errors since they are | 
| 1113 |  |        * likely to be used to signal incompatible JPEG Part 3 extensions. | 
| 1114 |  |        * Once the JPEG 3 version-number marker is well defined, this code | 
| 1115 |  |        * ought to change! | 
| 1116 |  |        */ | 
| 1117 | 269 |       ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); | 
| 1118 | 269 |       break; | 
| 1119 | 89.9k |     } | 
| 1120 |  |     /* Successfully processed marker, so reset state variable */ | 
| 1121 | 54.5k |     cinfo->unread_marker = 0; | 
| 1122 | 54.5k |   } /* end loop */ | 
| 1123 | 35.3k | } | 
| 1124 |  |  | 
| 1125 |  |  | 
| 1126 |  | /* | 
| 1127 |  |  * Read a restart marker, which is expected to appear next in the datastream; | 
| 1128 |  |  * if the marker is not there, take appropriate recovery action. | 
| 1129 |  |  * Returns FALSE if suspension is required. | 
| 1130 |  |  * | 
| 1131 |  |  * This is called by the entropy decoder after it has read an appropriate | 
| 1132 |  |  * number of MCUs.  cinfo->unread_marker may be nonzero if the entropy decoder | 
| 1133 |  |  * has already read a marker from the data source.  Under normal conditions | 
| 1134 |  |  * cinfo->unread_marker will be reset to 0 before returning; if not reset, | 
| 1135 |  |  * it holds a marker which the decoder will be unable to read past. | 
| 1136 |  |  */ | 
| 1137 |  |  | 
| 1138 |  | METHODDEF(boolean) | 
| 1139 |  | read_restart_marker(j_decompress_ptr cinfo) | 
| 1140 | 7.41M | { | 
| 1141 |  |   /* Obtain a marker unless we already did. */ | 
| 1142 |  |   /* Note that next_marker will complain if it skips any data. */ | 
| 1143 | 7.41M |   if (cinfo->unread_marker == 0) { | 
| 1144 | 955 |     if (!next_marker(cinfo)) | 
| 1145 | 0 |       return FALSE; | 
| 1146 | 955 |   } | 
| 1147 |  |  | 
| 1148 | 7.41M |   if (cinfo->unread_marker == | 
| 1149 | 7.41M |       ((int)M_RST0 + cinfo->marker->next_restart_num)) { | 
| 1150 |  |     /* Normal case --- swallow the marker and let entropy decoder continue */ | 
| 1151 | 2.84k |     TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num); | 
| 1152 | 2.84k |     cinfo->unread_marker = 0; | 
| 1153 | 7.41M |   } else { | 
| 1154 |  |     /* Uh-oh, the restart markers have been messed up. */ | 
| 1155 |  |     /* Let the data source manager determine how to resync. */ | 
| 1156 | 7.41M |     if (!(*cinfo->src->resync_to_restart) (cinfo, | 
| 1157 | 7.41M |                                            cinfo->marker->next_restart_num)) | 
| 1158 | 0 |       return FALSE; | 
| 1159 | 7.41M |   } | 
| 1160 |  |  | 
| 1161 |  |   /* Update next-restart state */ | 
| 1162 | 7.41M |   cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7; | 
| 1163 |  |  | 
| 1164 | 7.41M |   return TRUE; | 
| 1165 | 7.41M | } | 
| 1166 |  |  | 
| 1167 |  |  | 
| 1168 |  | /* | 
| 1169 |  |  * This is the default resync_to_restart method for data source managers | 
| 1170 |  |  * to use if they don't have any better approach.  Some data source managers | 
| 1171 |  |  * may be able to back up, or may have additional knowledge about the data | 
| 1172 |  |  * which permits a more intelligent recovery strategy; such managers would | 
| 1173 |  |  * presumably supply their own resync method. | 
| 1174 |  |  * | 
| 1175 |  |  * read_restart_marker calls resync_to_restart if it finds a marker other than | 
| 1176 |  |  * the restart marker it was expecting.  (This code is *not* used unless | 
| 1177 |  |  * a nonzero restart interval has been declared.)  cinfo->unread_marker is | 
| 1178 |  |  * the marker code actually found (might be anything, except 0 or FF). | 
| 1179 |  |  * The desired restart marker number (0..7) is passed as a parameter. | 
| 1180 |  |  * This routine is supposed to apply whatever error recovery strategy seems | 
| 1181 |  |  * appropriate in order to position the input stream to the next data segment. | 
| 1182 |  |  * Note that cinfo->unread_marker is treated as a marker appearing before | 
| 1183 |  |  * the current data-source input point; usually it should be reset to zero | 
| 1184 |  |  * before returning. | 
| 1185 |  |  * Returns FALSE if suspension is required. | 
| 1186 |  |  * | 
| 1187 |  |  * This implementation is substantially constrained by wanting to treat the | 
| 1188 |  |  * input as a data stream; this means we can't back up.  Therefore, we have | 
| 1189 |  |  * only the following actions to work with: | 
| 1190 |  |  *   1. Simply discard the marker and let the entropy decoder resume at next | 
| 1191 |  |  *      byte of file. | 
| 1192 |  |  *   2. Read forward until we find another marker, discarding intervening | 
| 1193 |  |  *      data.  (In theory we could look ahead within the current bufferload, | 
| 1194 |  |  *      without having to discard data if we don't find the desired marker. | 
| 1195 |  |  *      This idea is not implemented here, in part because it makes behavior | 
| 1196 |  |  *      dependent on buffer size and chance buffer-boundary positions.) | 
| 1197 |  |  *   3. Leave the marker unread (by failing to zero cinfo->unread_marker). | 
| 1198 |  |  *      This will cause the entropy decoder to process an empty data segment, | 
| 1199 |  |  *      inserting dummy zeroes, and then we will reprocess the marker. | 
| 1200 |  |  * | 
| 1201 |  |  * #2 is appropriate if we think the desired marker lies ahead, while #3 is | 
| 1202 |  |  * appropriate if the found marker is a future restart marker (indicating | 
| 1203 |  |  * that we have missed the desired restart marker, probably because it got | 
| 1204 |  |  * corrupted). | 
| 1205 |  |  * We apply #2 or #3 if the found marker is a restart marker no more than | 
| 1206 |  |  * two counts behind or ahead of the expected one.  We also apply #2 if the | 
| 1207 |  |  * found marker is not a legal JPEG marker code (it's certainly bogus data). | 
| 1208 |  |  * If the found marker is a restart marker more than 2 counts away, we do #1 | 
| 1209 |  |  * (too much risk that the marker is erroneous; with luck we will be able to | 
| 1210 |  |  * resync at some future point). | 
| 1211 |  |  * For any valid non-restart JPEG marker, we apply #3.  This keeps us from | 
| 1212 |  |  * overrunning the end of a scan.  An implementation limited to single-scan | 
| 1213 |  |  * files might find it better to apply #2 for markers other than EOI, since | 
| 1214 |  |  * any other marker would have to be bogus data in that case. | 
| 1215 |  |  */ | 
| 1216 |  |  | 
| 1217 |  | GLOBAL(boolean) | 
| 1218 |  | jpeg_resync_to_restart(j_decompress_ptr cinfo, int desired) | 
| 1219 | 7.41M | { | 
| 1220 | 7.41M |   int marker = cinfo->unread_marker; | 
| 1221 | 7.41M |   int action = 1; | 
| 1222 |  |  | 
| 1223 |  |   /* Always put up a warning. */ | 
| 1224 | 7.41M |   WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired); | 
| 1225 |  |  | 
| 1226 |  |   /* Outer loop handles repeated decision after scanning forward. */ | 
| 1227 | 7.41M |   for (;;) { | 
| 1228 | 7.41M |     if (marker < (int)M_SOF0) | 
| 1229 | 895 |       action = 2;               /* invalid marker */ | 
| 1230 | 7.41M |     else if (marker < (int)M_RST0 || marker > (int)M_RST7) | 
| 1231 | 7.40M |       action = 3;               /* valid non-restart marker */ | 
| 1232 | 6.83k |     else { | 
| 1233 | 6.83k |       if (marker == ((int)M_RST0 + ((desired + 1) & 7)) || | 
| 1234 | 6.83k |           marker == ((int)M_RST0 + ((desired + 2) & 7))) | 
| 1235 | 3.59k |         action = 3;             /* one of the next two expected restarts */ | 
| 1236 | 3.23k |       else if (marker == ((int)M_RST0 + ((desired - 1) & 7)) || | 
| 1237 | 3.23k |                marker == ((int)M_RST0 + ((desired - 2) & 7))) | 
| 1238 | 793 |         action = 2;             /* a prior restart, so advance */ | 
| 1239 | 2.44k |       else | 
| 1240 | 2.44k |         action = 1;             /* desired restart or too far away */ | 
| 1241 | 6.83k |     } | 
| 1242 | 7.41M |     TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action); | 
| 1243 | 7.41M |     switch (action) { | 
| 1244 | 2.44k |     case 1: | 
| 1245 |  |       /* Discard marker and let entropy decoder resume processing. */ | 
| 1246 | 2.44k |       cinfo->unread_marker = 0; | 
| 1247 | 2.44k |       return TRUE; | 
| 1248 | 1.68k |     case 2: | 
| 1249 |  |       /* Scan to the next marker, and repeat the decision loop. */ | 
| 1250 | 1.68k |       if (!next_marker(cinfo)) | 
| 1251 | 0 |         return FALSE; | 
| 1252 | 1.68k |       marker = cinfo->unread_marker; | 
| 1253 | 1.68k |       break; | 
| 1254 | 7.40M |     case 3: | 
| 1255 |  |       /* Return without advancing past this marker. */ | 
| 1256 |  |       /* Entropy decoder will be forced to process an empty segment. */ | 
| 1257 | 7.40M |       return TRUE; | 
| 1258 | 7.41M |     } | 
| 1259 | 7.41M |   } /* end loop */ | 
| 1260 | 7.41M | } | 
| 1261 |  |  | 
| 1262 |  |  | 
| 1263 |  | /* | 
| 1264 |  |  * Reset marker processing state to begin a fresh datastream. | 
| 1265 |  |  */ | 
| 1266 |  |  | 
| 1267 |  | METHODDEF(void) | 
| 1268 |  | reset_marker_reader(j_decompress_ptr cinfo) | 
| 1269 | 15.9k | { | 
| 1270 | 15.9k |   my_marker_ptr marker = (my_marker_ptr)cinfo->marker; | 
| 1271 |  |  | 
| 1272 | 15.9k |   cinfo->comp_info = NULL;              /* until allocated by get_sof */ | 
| 1273 | 15.9k |   cinfo->input_scan_number = 0;         /* no SOS seen yet */ | 
| 1274 | 15.9k |   cinfo->unread_marker = 0;             /* no pending marker */ | 
| 1275 | 15.9k |   marker->pub.saw_SOI = FALSE;          /* set internal state too */ | 
| 1276 | 15.9k |   marker->pub.saw_SOF = FALSE; | 
| 1277 | 15.9k |   marker->pub.discarded_bytes = 0; | 
| 1278 | 15.9k |   marker->cur_marker = NULL; | 
| 1279 | 15.9k | } | 
| 1280 |  |  | 
| 1281 |  |  | 
| 1282 |  | /* | 
| 1283 |  |  * Initialize the marker reader module. | 
| 1284 |  |  * This is called only once, when the decompression object is created. | 
| 1285 |  |  */ | 
| 1286 |  |  | 
| 1287 |  | GLOBAL(void) | 
| 1288 |  | jinit_marker_reader(j_decompress_ptr cinfo) | 
| 1289 | 5.67k | { | 
| 1290 | 5.67k |   my_marker_ptr marker; | 
| 1291 | 5.67k |   int i; | 
| 1292 |  |  | 
| 1293 |  |   /* Create subobject in permanent pool */ | 
| 1294 | 5.67k |   marker = (my_marker_ptr) | 
| 1295 | 5.67k |     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT, | 
| 1296 | 5.67k |                                 sizeof(my_marker_reader)); | 
| 1297 | 5.67k |   cinfo->marker = (struct jpeg_marker_reader *)marker; | 
| 1298 |  |   /* Initialize public method pointers */ | 
| 1299 | 5.67k |   marker->pub.reset_marker_reader = reset_marker_reader; | 
| 1300 | 5.67k |   marker->pub.read_markers = read_markers; | 
| 1301 | 5.67k |   marker->pub.read_restart_marker = read_restart_marker; | 
| 1302 |  |   /* Initialize COM/APPn processing. | 
| 1303 |  |    * By default, we examine and then discard APP0 and APP14, | 
| 1304 |  |    * but simply discard COM and all other APPn. | 
| 1305 |  |    */ | 
| 1306 | 5.67k |   marker->process_COM = skip_variable; | 
| 1307 | 5.67k |   marker->length_limit_COM = 0; | 
| 1308 | 96.4k |   for (i = 0; i < 16; i++) { | 
| 1309 | 90.7k |     marker->process_APPn[i] = skip_variable; | 
| 1310 | 90.7k |     marker->length_limit_APPn[i] = 0; | 
| 1311 | 90.7k |   } | 
| 1312 | 5.67k |   marker->process_APPn[0] = get_interesting_appn; | 
| 1313 | 5.67k |   marker->process_APPn[14] = get_interesting_appn; | 
| 1314 |  |   /* Reset marker processing state */ | 
| 1315 | 5.67k |   reset_marker_reader(cinfo); | 
| 1316 | 5.67k | } | 
| 1317 |  |  | 
| 1318 |  |  | 
| 1319 |  | /* | 
| 1320 |  |  * Control saving of COM and APPn markers into marker_list. | 
| 1321 |  |  */ | 
| 1322 |  |  | 
| 1323 |  | #ifdef SAVE_MARKERS_SUPPORTED | 
| 1324 |  |  | 
| 1325 |  | GLOBAL(void) | 
| 1326 |  | jpeg_save_markers(j_decompress_ptr cinfo, int marker_code, | 
| 1327 |  |                   unsigned int length_limit) | 
| 1328 | 0 | { | 
| 1329 | 0 |   my_marker_ptr marker = (my_marker_ptr)cinfo->marker; | 
| 1330 | 0 |   long maxlength; | 
| 1331 | 0 |   jpeg_marker_parser_method processor; | 
| 1332 |  |  | 
| 1333 |  |   /* Length limit mustn't be larger than what we can allocate | 
| 1334 |  |    * (should only be a concern in a 16-bit environment). | 
| 1335 |  |    */ | 
| 1336 | 0 |   maxlength = cinfo->mem->max_alloc_chunk - sizeof(struct jpeg_marker_struct); | 
| 1337 | 0 |   if (((long)length_limit) > maxlength) | 
| 1338 | 0 |     length_limit = (unsigned int)maxlength; | 
| 1339 |  |  | 
| 1340 |  |   /* Choose processor routine to use. | 
| 1341 |  |    * APP0/APP14 have special requirements. | 
| 1342 |  |    */ | 
| 1343 | 0 |   if (length_limit) { | 
| 1344 | 0 |     processor = save_marker; | 
| 1345 |  |     /* If saving APP0/APP14, save at least enough for our internal use. */ | 
| 1346 | 0 |     if (marker_code == (int)M_APP0 && length_limit < APP0_DATA_LEN) | 
| 1347 | 0 |       length_limit = APP0_DATA_LEN; | 
| 1348 | 0 |     else if (marker_code == (int)M_APP14 && length_limit < APP14_DATA_LEN) | 
| 1349 | 0 |       length_limit = APP14_DATA_LEN; | 
| 1350 | 0 |   } else { | 
| 1351 | 0 |     processor = skip_variable; | 
| 1352 |  |     /* If discarding APP0/APP14, use our regular on-the-fly processor. */ | 
| 1353 | 0 |     if (marker_code == (int)M_APP0 || marker_code == (int)M_APP14) | 
| 1354 | 0 |       processor = get_interesting_appn; | 
| 1355 | 0 |   } | 
| 1356 |  | 
 | 
| 1357 | 0 |   if (marker_code == (int)M_COM) { | 
| 1358 | 0 |     marker->process_COM = processor; | 
| 1359 | 0 |     marker->length_limit_COM = length_limit; | 
| 1360 | 0 |   } else if (marker_code >= (int)M_APP0 && marker_code <= (int)M_APP15) { | 
| 1361 | 0 |     marker->process_APPn[marker_code - (int)M_APP0] = processor; | 
| 1362 | 0 |     marker->length_limit_APPn[marker_code - (int)M_APP0] = length_limit; | 
| 1363 | 0 |   } else | 
| 1364 | 0 |     ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); | 
| 1365 | 0 | } | 
| 1366 |  |  | 
| 1367 |  | #endif /* SAVE_MARKERS_SUPPORTED */ | 
| 1368 |  |  | 
| 1369 |  |  | 
| 1370 |  | /* | 
| 1371 |  |  * Install a special processing method for COM or APPn markers. | 
| 1372 |  |  */ | 
| 1373 |  |  | 
| 1374 |  | GLOBAL(void) | 
| 1375 |  | jpeg_set_marker_processor(j_decompress_ptr cinfo, int marker_code, | 
| 1376 |  |                           jpeg_marker_parser_method routine) | 
| 1377 | 0 | { | 
| 1378 | 0 |   my_marker_ptr marker = (my_marker_ptr)cinfo->marker; | 
| 1379 |  | 
 | 
| 1380 | 0 |   if (marker_code == (int)M_COM) | 
| 1381 | 0 |     marker->process_COM = routine; | 
| 1382 | 0 |   else if (marker_code >= (int)M_APP0 && marker_code <= (int)M_APP15) | 
| 1383 | 0 |     marker->process_APPn[marker_code - (int)M_APP0] = routine; | 
| 1384 | 0 |   else | 
| 1385 | 0 |     ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); | 
| 1386 | 0 | } |