tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

jdmarker.c (42610B)


      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, 2024, 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  struct jpeg_source_mgr *datasrc = (cinfo)->src; \
    126  const JOCTET *next_input_byte = datasrc->next_input_byte; \
    127  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  ( datasrc->next_input_byte = next_input_byte, \
    132    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  ( next_input_byte = datasrc->next_input_byte, \
    137    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  if (bytes_in_buffer == 0) { \
    145    if (!(*datasrc->fill_input_buffer) (cinfo)) \
    146      { action; } \
    147    INPUT_RELOAD(cinfo); \
    148  }
    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  MAKESTMT( MAKE_BYTE_AVAIL(cinfo, action); \
    155            bytes_in_buffer--; \
    156            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  MAKESTMT( MAKE_BYTE_AVAIL(cinfo, action); \
    163            bytes_in_buffer--; \
    164            V = ((unsigned int)(*next_input_byte++)) << 8; \
    165            MAKE_BYTE_AVAIL(cinfo, action); \
    166            bytes_in_buffer--; \
    167            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 {
    205  int i;
    206 
    207  TRACEMS(cinfo, 1, JTRC_SOI);
    208 
    209  if (cinfo->marker->saw_SOI)
    210    ERREXIT(cinfo, JERR_SOI_DUPLICATE);
    211 
    212  /* Reset all parameters that are defined to be reset by SOI */
    213 
    214  for (i = 0; i < NUM_ARITH_TBLS; i++) {
    215    cinfo->arith_dc_L[i] = 0;
    216    cinfo->arith_dc_U[i] = 1;
    217    cinfo->arith_ac_K[i] = 5;
    218  }
    219  cinfo->restart_interval = 0;
    220 
    221  /* Set initial assumptions for colorspace etc */
    222 
    223  cinfo->jpeg_color_space = JCS_UNKNOWN;
    224  cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
    225 
    226  cinfo->saw_JFIF_marker = FALSE;
    227  cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */
    228  cinfo->JFIF_minor_version = 1;
    229  cinfo->density_unit = 0;
    230  cinfo->X_density = 1;
    231  cinfo->Y_density = 1;
    232  cinfo->saw_Adobe_marker = FALSE;
    233  cinfo->Adobe_transform = 0;
    234 
    235  cinfo->marker->saw_SOI = TRUE;
    236 
    237  return TRUE;
    238 }
    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 {
    246  JLONG length;
    247  int c, ci;
    248  jpeg_component_info *compptr;
    249  INPUT_VARS(cinfo);
    250 
    251  if (cinfo->marker->saw_SOF)
    252    ERREXIT(cinfo, JERR_SOF_DUPLICATE);
    253 
    254  cinfo->progressive_mode = is_prog;
    255  cinfo->master->lossless = is_lossless;
    256  cinfo->arith_code = is_arith;
    257 
    258  INPUT_2BYTES(cinfo, length, return FALSE);
    259 
    260  INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);
    261  INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE);
    262  INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE);
    263  INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);
    264 
    265  length -= 8;
    266 
    267  TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,
    268           (int)cinfo->image_width, (int)cinfo->image_height,
    269           cinfo->num_components);
    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  if (cinfo->image_height <= 0 || cinfo->image_width <= 0 ||
    275      cinfo->num_components <= 0)
    276    ERREXIT(cinfo, JERR_EMPTY_IMAGE);
    277 
    278  if (length != (cinfo->num_components * 3))
    279    ERREXIT(cinfo, JERR_BAD_LENGTH);
    280 
    281  if (cinfo->comp_info == NULL) /* do only once, even if suspend */
    282    cinfo->comp_info = (jpeg_component_info *)(*cinfo->mem->alloc_small)
    283                        ((j_common_ptr)cinfo, JPOOL_IMAGE,
    284                         cinfo->num_components * sizeof(jpeg_component_info));
    285 
    286  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    287       ci++, compptr++) {
    288    compptr->component_index = ci;
    289    INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
    290    INPUT_BYTE(cinfo, c, return FALSE);
    291    compptr->h_samp_factor = (c >> 4) & 15;
    292    compptr->v_samp_factor = (c     ) & 15;
    293    INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);
    294 
    295    TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,
    296             compptr->component_id, compptr->h_samp_factor,
    297             compptr->v_samp_factor, compptr->quant_tbl_no);
    298  }
    299 
    300  cinfo->marker->saw_SOF = TRUE;
    301 
    302  INPUT_SYNC(cinfo);
    303  return TRUE;
    304 }
    305 
    306 
    307 LOCAL(boolean)
    308 get_sos(j_decompress_ptr cinfo)
    309 /* Process a SOS marker */
    310 {
    311  JLONG length;
    312  int i, ci, n, c, cc, pi;
    313  jpeg_component_info *compptr;
    314  INPUT_VARS(cinfo);
    315 
    316  if (!cinfo->marker->saw_SOF)
    317    ERREXIT(cinfo, JERR_SOS_NO_SOF);
    318 
    319  INPUT_2BYTES(cinfo, length, return FALSE);
    320 
    321  INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */
    322 
    323  TRACEMS1(cinfo, 1, JTRC_SOS, n);
    324 
    325  if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
    326    ERREXIT(cinfo, JERR_BAD_LENGTH);
    327 
    328  cinfo->comps_in_scan = n;
    329 
    330  /* Collect the component-spec parameters */
    331 
    332  for (i = 0; i < MAX_COMPS_IN_SCAN; i++)
    333    cinfo->cur_comp_info[i] = NULL;
    334 
    335  for (i = 0; i < n; i++) {
    336    INPUT_BYTE(cinfo, cc, return FALSE);
    337    INPUT_BYTE(cinfo, c, return FALSE);
    338 
    339    for (ci = 0, compptr = cinfo->comp_info;
    340         ci < cinfo->num_components && ci < MAX_COMPS_IN_SCAN;
    341         ci++, compptr++) {
    342      if (cc == compptr->component_id && !cinfo->cur_comp_info[ci])
    343        goto id_found;
    344    }
    345 
    346    ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
    347 
    348 id_found:
    349 
    350    cinfo->cur_comp_info[i] = compptr;
    351    compptr->dc_tbl_no = (c >> 4) & 15;
    352    compptr->ac_tbl_no = (c     ) & 15;
    353 
    354    TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,
    355             compptr->dc_tbl_no, compptr->ac_tbl_no);
    356 
    357    /* This CSi (cc) should differ from the previous CSi */
    358    for (pi = 0; pi < i; pi++) {
    359      if (cinfo->cur_comp_info[pi] == compptr) {
    360        ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
    361      }
    362    }
    363  }
    364 
    365  /* Collect the additional scan parameters Ss, Se, Ah/Al. */
    366  INPUT_BYTE(cinfo, c, return FALSE);
    367  cinfo->Ss = c;
    368  INPUT_BYTE(cinfo, c, return FALSE);
    369  cinfo->Se = c;
    370  INPUT_BYTE(cinfo, c, return FALSE);
    371  cinfo->Ah = (c >> 4) & 15;
    372  cinfo->Al = (c     ) & 15;
    373 
    374  TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,
    375           cinfo->Ah, cinfo->Al);
    376 
    377  /* Prepare to scan data & restart markers */
    378  cinfo->marker->next_restart_num = 0;
    379 
    380  /* Count another SOS marker */
    381  cinfo->input_scan_number++;
    382 
    383  INPUT_SYNC(cinfo);
    384  return TRUE;
    385 }
    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 {
    394  JLONG length;
    395  int index, val;
    396  INPUT_VARS(cinfo);
    397 
    398  INPUT_2BYTES(cinfo, length, return FALSE);
    399  length -= 2;
    400 
    401  while (length > 0) {
    402    INPUT_BYTE(cinfo, index, return FALSE);
    403    INPUT_BYTE(cinfo, val, return FALSE);
    404 
    405    length -= 2;
    406 
    407    TRACEMS2(cinfo, 1, JTRC_DAC, index, val);
    408 
    409    if (index < 0 || index >= (2 * NUM_ARITH_TBLS))
    410      ERREXIT1(cinfo, JERR_DAC_INDEX, index);
    411 
    412    if (index >= NUM_ARITH_TBLS) { /* define AC table */
    413      cinfo->arith_ac_K[index - NUM_ARITH_TBLS] = (UINT8)val;
    414    } else {                    /* define DC table */
    415      cinfo->arith_dc_L[index] = (UINT8)(val & 0x0F);
    416      cinfo->arith_dc_U[index] = (UINT8)(val >> 4);
    417      if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
    418        ERREXIT1(cinfo, JERR_DAC_VALUE, val);
    419    }
    420  }
    421 
    422  if (length != 0)
    423    ERREXIT(cinfo, JERR_BAD_LENGTH);
    424 
    425  INPUT_SYNC(cinfo);
    426  return TRUE;
    427 }
    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 {
    440  JLONG length;
    441  UINT8 bits[17];
    442  UINT8 huffval[256];
    443  int i, index, count;
    444  JHUFF_TBL **htblptr;
    445  INPUT_VARS(cinfo);
    446 
    447  INPUT_2BYTES(cinfo, length, return FALSE);
    448  length -= 2;
    449 
    450  while (length > 16) {
    451    INPUT_BYTE(cinfo, index, return FALSE);
    452 
    453    TRACEMS1(cinfo, 1, JTRC_DHT, index);
    454 
    455    bits[0] = 0;
    456    count = 0;
    457    for (i = 1; i <= 16; i++) {
    458      INPUT_BYTE(cinfo, bits[i], return FALSE);
    459      count += bits[i];
    460    }
    461 
    462    length -= 1 + 16;
    463 
    464    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
    465             bits[1], bits[2], bits[3], bits[4],
    466             bits[5], bits[6], bits[7], bits[8]);
    467    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
    468             bits[9], bits[10], bits[11], bits[12],
    469             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    if (count > 256 || ((JLONG)count) > length)
    475      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
    476 
    477    for (i = 0; i < count; i++)
    478      INPUT_BYTE(cinfo, huffval[i], return FALSE);
    479 
    480    memset(&huffval[count], 0, (256 - count) * sizeof(UINT8));
    481 
    482    length -= count;
    483 
    484    if (index & 0x10) {         /* AC table definition */
    485      index -= 0x10;
    486      if (index < 0 || index >= NUM_HUFF_TBLS)
    487        ERREXIT1(cinfo, JERR_DHT_INDEX, index);
    488      htblptr = &cinfo->ac_huff_tbl_ptrs[index];
    489    } else {                    /* DC table definition */
    490      if (index < 0 || index >= NUM_HUFF_TBLS)
    491        ERREXIT1(cinfo, JERR_DHT_INDEX, index);
    492      htblptr = &cinfo->dc_huff_tbl_ptrs[index];
    493    }
    494 
    495    if (*htblptr == NULL)
    496      *htblptr = jpeg_alloc_huff_table((j_common_ptr)cinfo);
    497 
    498    memcpy((*htblptr)->bits, bits, sizeof((*htblptr)->bits));
    499    memcpy((*htblptr)->huffval, huffval, sizeof((*htblptr)->huffval));
    500  }
    501 
    502  if (length != 0)
    503    ERREXIT(cinfo, JERR_BAD_LENGTH);
    504 
    505  INPUT_SYNC(cinfo);
    506  return TRUE;
    507 }
    508 
    509 
    510 LOCAL(boolean)
    511 get_dqt(j_decompress_ptr cinfo)
    512 /* Process a DQT marker */
    513 {
    514  JLONG length;
    515  int n, i, prec;
    516  unsigned int tmp;
    517  JQUANT_TBL *quant_ptr;
    518  INPUT_VARS(cinfo);
    519 
    520  INPUT_2BYTES(cinfo, length, return FALSE);
    521  length -= 2;
    522 
    523  while (length > 0) {
    524    INPUT_BYTE(cinfo, n, return FALSE);
    525    prec = n >> 4;
    526    n &= 0x0F;
    527 
    528    TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);
    529 
    530    if (n >= NUM_QUANT_TBLS)
    531      ERREXIT1(cinfo, JERR_DQT_INDEX, n);
    532 
    533    if (cinfo->quant_tbl_ptrs[n] == NULL)
    534      cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr)cinfo);
    535    quant_ptr = cinfo->quant_tbl_ptrs[n];
    536 
    537    for (i = 0; i < DCTSIZE2; i++) {
    538      if (prec)
    539        INPUT_2BYTES(cinfo, tmp, return FALSE);
    540      else
    541        INPUT_BYTE(cinfo, tmp, return FALSE);
    542      /* We convert the zigzag-order table to natural array order. */
    543      quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16)tmp;
    544    }
    545 
    546    if (cinfo->err->trace_level >= 2) {
    547      for (i = 0; i < DCTSIZE2; i += 8) {
    548        TRACEMS8(cinfo, 2, JTRC_QUANTVALS,
    549                 quant_ptr->quantval[i],     quant_ptr->quantval[i + 1],
    550                 quant_ptr->quantval[i + 2], quant_ptr->quantval[i + 3],
    551                 quant_ptr->quantval[i + 4], quant_ptr->quantval[i + 5],
    552                 quant_ptr->quantval[i + 6], quant_ptr->quantval[i + 7]);
    553      }
    554    }
    555 
    556    length -= DCTSIZE2 + 1;
    557    if (prec) length -= DCTSIZE2;
    558  }
    559 
    560  if (length != 0)
    561    ERREXIT(cinfo, JERR_BAD_LENGTH);
    562 
    563  INPUT_SYNC(cinfo);
    564  return TRUE;
    565 }
    566 
    567 
    568 LOCAL(boolean)
    569 get_dri(j_decompress_ptr cinfo)
    570 /* Process a DRI marker */
    571 {
    572  JLONG length;
    573  unsigned int tmp;
    574  INPUT_VARS(cinfo);
    575 
    576  INPUT_2BYTES(cinfo, length, return FALSE);
    577 
    578  if (length != 4)
    579    ERREXIT(cinfo, JERR_BAD_LENGTH);
    580 
    581  INPUT_2BYTES(cinfo, tmp, return FALSE);
    582 
    583  TRACEMS1(cinfo, 1, JTRC_DRI, tmp);
    584 
    585  cinfo->restart_interval = tmp;
    586 
    587  INPUT_SYNC(cinfo);
    588  return TRUE;
    589 }
    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 #define APP0_DATA_LEN   14      /* Length of interesting data in APP0 */
    600 #define APP14_DATA_LEN  12      /* Length of interesting data in APP14 */
    601 #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 {
    612  JLONG totallen = (JLONG)datalen + remaining;
    613 
    614  if (datalen >= APP0_DATA_LEN &&
    615      data[0] == 0x4A &&
    616      data[1] == 0x46 &&
    617      data[2] == 0x49 &&
    618      data[3] == 0x46 &&
    619      data[4] == 0) {
    620    /* Found JFIF APP0 marker: save info */
    621    cinfo->saw_JFIF_marker = TRUE;
    622    cinfo->JFIF_major_version = data[5];
    623    cinfo->JFIF_minor_version = data[6];
    624    cinfo->density_unit = data[7];
    625    cinfo->X_density = (data[8] << 8) + data[9];
    626    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    if (cinfo->JFIF_major_version != 1)
    634      WARNMS2(cinfo, JWRN_JFIF_MAJOR,
    635              cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
    636    /* Generate trace messages */
    637    TRACEMS5(cinfo, 1, JTRC_JFIF,
    638             cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
    639             cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
    640    /* Validate thumbnail dimensions and issue appropriate messages */
    641    if (data[12] | data[13])
    642      TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, data[12], data[13]);
    643    totallen -= APP0_DATA_LEN;
    644    if (totallen != ((JLONG)data[12] * (JLONG)data[13] * (JLONG)3))
    645      TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int)totallen);
    646  } else if (datalen >= 6 &&
    647             data[0] == 0x4A &&
    648             data[1] == 0x46 &&
    649             data[2] == 0x58 &&
    650             data[3] == 0x58 &&
    651             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    switch (data[5]) {
    657    case 0x10:
    658      TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int)totallen);
    659      break;
    660    case 0x11:
    661      TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int)totallen);
    662      break;
    663    case 0x13:
    664      TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int)totallen);
    665      break;
    666    default:
    667      TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION, data[5], (int)totallen);
    668      break;
    669    }
    670  } else {
    671    /* Start of APP0 does not match "JFIF" or "JFXX", or too short */
    672    TRACEMS1(cinfo, 1, JTRC_APP0, (int)totallen);
    673  }
    674 }
    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 {
    685  unsigned int version, flags0, flags1, transform;
    686 
    687  if (datalen >= APP14_DATA_LEN &&
    688      data[0] == 0x41 &&
    689      data[1] == 0x64 &&
    690      data[2] == 0x6F &&
    691      data[3] == 0x62 &&
    692      data[4] == 0x65) {
    693    /* Found Adobe APP14 marker */
    694    version = (data[5] << 8) + data[6];
    695    flags0 = (data[7] << 8) + data[8];
    696    flags1 = (data[9] << 8) + data[10];
    697    transform = data[11];
    698    TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
    699    cinfo->saw_Adobe_marker = TRUE;
    700    cinfo->Adobe_transform = (UINT8)transform;
    701  } else {
    702    /* Start of APP14 does not match "Adobe", or too short */
    703    TRACEMS1(cinfo, 1, JTRC_APP14, (int)(datalen + remaining));
    704  }
    705 }
    706 
    707 
    708 METHODDEF(boolean)
    709 get_interesting_appn(j_decompress_ptr cinfo)
    710 /* Process an APP0 or APP14 marker without saving it */
    711 {
    712  JLONG length;
    713  JOCTET b[APPN_DATA_LEN];
    714  unsigned int i, numtoread;
    715  INPUT_VARS(cinfo);
    716 
    717  INPUT_2BYTES(cinfo, length, return FALSE);
    718  length -= 2;
    719 
    720  /* get the interesting part of the marker data */
    721  if (length >= APPN_DATA_LEN)
    722    numtoread = APPN_DATA_LEN;
    723  else if (length > 0)
    724    numtoread = (unsigned int)length;
    725  else
    726    numtoread = 0;
    727  for (i = 0; i < numtoread; i++)
    728    INPUT_BYTE(cinfo, b[i], return FALSE);
    729  length -= numtoread;
    730 
    731  /* process it */
    732  switch (cinfo->unread_marker) {
    733  case M_APP0:
    734    examine_app0(cinfo, (JOCTET *)b, numtoread, length);
    735    break;
    736  case M_APP14:
    737    examine_app14(cinfo, (JOCTET *)b, numtoread, length);
    738    break;
    739  default:
    740    /* can't get here unless jpeg_save_markers chooses wrong processor */
    741    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
    742    break;
    743  }
    744 
    745  /* skip any remaining data -- could be lots */
    746  INPUT_SYNC(cinfo);
    747  if (length > 0)
    748    (*cinfo->src->skip_input_data) (cinfo, (long)length);
    749 
    750  return TRUE;
    751 }
    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 {
    760  my_marker_ptr marker = (my_marker_ptr)cinfo->marker;
    761  jpeg_saved_marker_ptr cur_marker = marker->cur_marker;
    762  unsigned int bytes_read, data_length;
    763  JOCTET *data;
    764  JLONG length = 0;
    765  INPUT_VARS(cinfo);
    766 
    767  if (cur_marker == NULL) {
    768    /* begin reading a marker */
    769    INPUT_2BYTES(cinfo, length, return FALSE);
    770    length -= 2;
    771    if (length >= 0) {          /* watch out for bogus length word */
    772      /* figure out how much we want to save */
    773      unsigned int limit;
    774      if (cinfo->unread_marker == (int)M_COM)
    775        limit = marker->length_limit_COM;
    776      else
    777        limit = marker->length_limit_APPn[cinfo->unread_marker - (int)M_APP0];
    778      if ((unsigned int)length < limit)
    779        limit = (unsigned int)length;
    780      /* allocate and initialize the marker item */
    781      cur_marker = (jpeg_saved_marker_ptr)
    782        (*cinfo->mem->alloc_large) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    783                                    sizeof(struct jpeg_marker_struct) + limit);
    784      cur_marker->next = NULL;
    785      cur_marker->marker = (UINT8)cinfo->unread_marker;
    786      cur_marker->original_length = (unsigned int)length;
    787      cur_marker->data_length = limit;
    788      /* data area is just beyond the jpeg_marker_struct */
    789      data = cur_marker->data = (JOCTET *)(cur_marker + 1);
    790      marker->cur_marker = cur_marker;
    791      marker->bytes_read = 0;
    792      bytes_read = 0;
    793      data_length = limit;
    794    } else {
    795      /* deal with bogus length word */
    796      bytes_read = data_length = 0;
    797      data = NULL;
    798    }
    799  } else {
    800    /* resume reading a marker */
    801    bytes_read = marker->bytes_read;
    802    data_length = cur_marker->data_length;
    803    data = cur_marker->data + bytes_read;
    804  }
    805 
    806  while (bytes_read < data_length) {
    807    INPUT_SYNC(cinfo);          /* move the restart point to here */
    808    marker->bytes_read = bytes_read;
    809    /* If there's not at least one byte in buffer, suspend */
    810    MAKE_BYTE_AVAIL(cinfo, return FALSE);
    811    /* Copy bytes with reasonable rapidity */
    812    while (bytes_read < data_length && bytes_in_buffer > 0) {
    813      *data++ = *next_input_byte++;
    814      bytes_in_buffer--;
    815      bytes_read++;
    816    }
    817  }
    818 
    819  /* Done reading what we want to read */
    820  if (cur_marker != NULL) {     /* will be NULL if bogus length word */
    821    /* Add new marker to end of list */
    822    if (cinfo->marker_list == NULL || cinfo->master->marker_list_end == NULL) {
    823      cinfo->marker_list = cinfo->master->marker_list_end = cur_marker;
    824    } else {
    825      cinfo->master->marker_list_end->next = cur_marker;
    826      cinfo->master->marker_list_end = cur_marker;
    827    }
    828    /* Reset pointer & calc remaining data length */
    829    data = cur_marker->data;
    830    length = cur_marker->original_length - data_length;
    831  }
    832  /* Reset to initial state for next marker */
    833  marker->cur_marker = NULL;
    834 
    835  /* Process the marker if interesting; else just make a generic trace msg */
    836  switch (cinfo->unread_marker) {
    837  case M_APP0:
    838    examine_app0(cinfo, data, data_length, length);
    839    break;
    840  case M_APP14:
    841    examine_app14(cinfo, data, data_length, length);
    842    break;
    843  default:
    844    TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
    845             (int)(data_length + length));
    846    break;
    847  }
    848 
    849  /* skip any remaining data -- could be lots */
    850  INPUT_SYNC(cinfo);            /* do before skip_input_data */
    851  if (length > 0)
    852    (*cinfo->src->skip_input_data) (cinfo, (long)length);
    853 
    854  return TRUE;
    855 }
    856 
    857 #endif /* SAVE_MARKERS_SUPPORTED */
    858 
    859 
    860 METHODDEF(boolean)
    861 skip_variable(j_decompress_ptr cinfo)
    862 /* Skip over an unknown or uninteresting variable-length marker */
    863 {
    864  JLONG length;
    865  INPUT_VARS(cinfo);
    866 
    867  INPUT_2BYTES(cinfo, length, return FALSE);
    868  length -= 2;
    869 
    870  TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int)length);
    871 
    872  INPUT_SYNC(cinfo);            /* do before skip_input_data */
    873  if (length > 0)
    874    (*cinfo->src->skip_input_data) (cinfo, (long)length);
    875 
    876  return TRUE;
    877 }
    878 
    879 
    880 /*
    881 * Find the next JPEG marker, save it in cinfo->unread_marker.
    882 * Returns FALSE if had to suspend before reaching a marker;
    883 * in that case cinfo->unread_marker is unchanged.
    884 *
    885 * Note that the result might not be a valid marker code,
    886 * but it will never be 0 or FF.
    887 */
    888 
    889 LOCAL(boolean)
    890 next_marker(j_decompress_ptr cinfo)
    891 {
    892  int c;
    893  INPUT_VARS(cinfo);
    894 
    895  for (;;) {
    896    INPUT_BYTE(cinfo, c, return FALSE);
    897    /* Skip any non-FF bytes.
    898     * This may look a bit inefficient, but it will not occur in a valid file.
    899     * We sync after each discarded byte so that a suspending data source
    900     * can discard the byte from its buffer.
    901     */
    902    while (c != 0xFF) {
    903      cinfo->marker->discarded_bytes++;
    904      INPUT_SYNC(cinfo);
    905      INPUT_BYTE(cinfo, c, return FALSE);
    906    }
    907    /* This loop swallows any duplicate FF bytes.  Extra FFs are legal as
    908     * pad bytes, so don't count them in discarded_bytes.  We assume there
    909     * will not be so many consecutive FF bytes as to overflow a suspending
    910     * data source's input buffer.
    911     */
    912    do {
    913      INPUT_BYTE(cinfo, c, return FALSE);
    914    } while (c == 0xFF);
    915    if (c != 0)
    916      break;                    /* found a valid marker, exit loop */
    917    /* Reach here if we found a stuffed-zero data sequence (FF/00).
    918     * Discard it and loop back to try again.
    919     */
    920    cinfo->marker->discarded_bytes += 2;
    921    INPUT_SYNC(cinfo);
    922  }
    923 
    924  if (cinfo->marker->discarded_bytes != 0) {
    925    WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);
    926    cinfo->marker->discarded_bytes = 0;
    927  }
    928 
    929  cinfo->unread_marker = c;
    930 
    931  INPUT_SYNC(cinfo);
    932  return TRUE;
    933 }
    934 
    935 
    936 LOCAL(boolean)
    937 first_marker(j_decompress_ptr cinfo)
    938 /* Like next_marker, but used to obtain the initial SOI marker. */
    939 /* For this marker, we do not allow preceding garbage or fill; otherwise,
    940 * we might well scan an entire input file before realizing it ain't JPEG.
    941 * If an application wants to process non-JFIF files, it must seek to the
    942 * SOI before calling the JPEG library.
    943 */
    944 {
    945  int c, c2;
    946  INPUT_VARS(cinfo);
    947 
    948  INPUT_BYTE(cinfo, c, return FALSE);
    949  INPUT_BYTE(cinfo, c2, return FALSE);
    950  if (c != 0xFF || c2 != (int)M_SOI)
    951    ERREXIT2(cinfo, JERR_NO_SOI, c, c2);
    952 
    953  cinfo->unread_marker = c2;
    954 
    955  INPUT_SYNC(cinfo);
    956  return TRUE;
    957 }
    958 
    959 
    960 /*
    961 * Read markers until SOS or EOI.
    962 *
    963 * Returns same codes as are defined for jpeg_consume_input:
    964 * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
    965 */
    966 
    967 METHODDEF(int)
    968 read_markers(j_decompress_ptr cinfo)
    969 {
    970  /* Outer loop repeats once for each marker. */
    971  for (;;) {
    972    /* Collect the marker proper, unless we already did. */
    973    /* NB: first_marker() enforces the requirement that SOI appear first. */
    974    if (cinfo->unread_marker == 0) {
    975      if (!cinfo->marker->saw_SOI) {
    976        if (!first_marker(cinfo))
    977          return JPEG_SUSPENDED;
    978      } else {
    979        if (!next_marker(cinfo))
    980          return JPEG_SUSPENDED;
    981      }
    982    }
    983    /* At this point cinfo->unread_marker contains the marker code and the
    984     * input point is just past the marker proper, but before any parameters.
    985     * A suspension will cause us to return with this state still true.
    986     */
    987    switch (cinfo->unread_marker) {
    988    case M_SOI:
    989      if (!get_soi(cinfo))
    990        return JPEG_SUSPENDED;
    991      break;
    992 
    993    case M_SOF0:                /* Baseline */
    994    case M_SOF1:                /* Extended sequential, Huffman */
    995      if (!get_sof(cinfo, FALSE, FALSE, FALSE))
    996        return JPEG_SUSPENDED;
    997      break;
    998 
    999    case M_SOF2:                /* Progressive, Huffman */
   1000      if (!get_sof(cinfo, TRUE, FALSE, FALSE))
   1001        return JPEG_SUSPENDED;
   1002      break;
   1003 
   1004    case M_SOF3:                /* Lossless, Huffman */
   1005      if (!get_sof(cinfo, FALSE, TRUE, FALSE))
   1006        return JPEG_SUSPENDED;
   1007      break;
   1008 
   1009    case M_SOF9:                /* Extended sequential, arithmetic */
   1010      if (!get_sof(cinfo, FALSE, FALSE, TRUE))
   1011        return JPEG_SUSPENDED;
   1012      break;
   1013 
   1014    case M_SOF10:               /* Progressive, arithmetic */
   1015      if (!get_sof(cinfo, TRUE, FALSE, TRUE))
   1016        return JPEG_SUSPENDED;
   1017      break;
   1018 
   1019    case M_SOF11:               /* Lossless, arithmetic */
   1020      if (!get_sof(cinfo, FALSE, TRUE, TRUE))
   1021        return JPEG_SUSPENDED;
   1022      break;
   1023 
   1024    /* Currently unsupported SOFn types */
   1025    case M_SOF5:                /* Differential sequential, Huffman */
   1026    case M_SOF6:                /* Differential progressive, Huffman */
   1027    case M_SOF7:                /* Differential lossless, Huffman */
   1028    case M_JPG:                 /* Reserved for JPEG extensions */
   1029    case M_SOF13:               /* Differential sequential, arithmetic */
   1030    case M_SOF14:               /* Differential progressive, arithmetic */
   1031    case M_SOF15:               /* Differential lossless, arithmetic */
   1032      ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);
   1033      break;
   1034 
   1035    case M_SOS:
   1036      if (!get_sos(cinfo))
   1037        return JPEG_SUSPENDED;
   1038      cinfo->unread_marker = 0; /* processed the marker */
   1039      return JPEG_REACHED_SOS;
   1040 
   1041    case M_EOI:
   1042      TRACEMS(cinfo, 1, JTRC_EOI);
   1043      cinfo->unread_marker = 0; /* processed the marker */
   1044      return JPEG_REACHED_EOI;
   1045 
   1046    case M_DAC:
   1047      if (!get_dac(cinfo))
   1048        return JPEG_SUSPENDED;
   1049      break;
   1050 
   1051    case M_DHT:
   1052      if (!get_dht(cinfo))
   1053        return JPEG_SUSPENDED;
   1054      break;
   1055 
   1056    case M_DQT:
   1057      if (!get_dqt(cinfo))
   1058        return JPEG_SUSPENDED;
   1059      break;
   1060 
   1061    case M_DRI:
   1062      if (!get_dri(cinfo))
   1063        return JPEG_SUSPENDED;
   1064      break;
   1065 
   1066    case M_APP0:
   1067    case M_APP1:
   1068    case M_APP2:
   1069    case M_APP3:
   1070    case M_APP4:
   1071    case M_APP5:
   1072    case M_APP6:
   1073    case M_APP7:
   1074    case M_APP8:
   1075    case M_APP9:
   1076    case M_APP10:
   1077    case M_APP11:
   1078    case M_APP12:
   1079    case M_APP13:
   1080    case M_APP14:
   1081    case M_APP15:
   1082      if (!(*((my_marker_ptr)cinfo->marker)->process_APPn[
   1083               cinfo->unread_marker - (int)M_APP0]) (cinfo))
   1084        return JPEG_SUSPENDED;
   1085      break;
   1086 
   1087    case M_COM:
   1088      if (!(*((my_marker_ptr)cinfo->marker)->process_COM) (cinfo))
   1089        return JPEG_SUSPENDED;
   1090      break;
   1091 
   1092    case M_RST0:                /* these are all parameterless */
   1093    case M_RST1:
   1094    case M_RST2:
   1095    case M_RST3:
   1096    case M_RST4:
   1097    case M_RST5:
   1098    case M_RST6:
   1099    case M_RST7:
   1100    case M_TEM:
   1101      TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);
   1102      break;
   1103 
   1104    case M_DNL:                 /* Ignore DNL ... perhaps the wrong thing */
   1105      if (!skip_variable(cinfo))
   1106        return JPEG_SUSPENDED;
   1107      break;
   1108 
   1109    default:                    /* must be DHP, EXP, JPGn, or RESn */
   1110      /* For now, we treat the reserved markers as fatal errors since they are
   1111       * likely to be used to signal incompatible JPEG Part 3 extensions.
   1112       * Once the JPEG 3 version-number marker is well defined, this code
   1113       * ought to change!
   1114       */
   1115      ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
   1116      break;
   1117    }
   1118    /* Successfully processed marker, so reset state variable */
   1119    cinfo->unread_marker = 0;
   1120  } /* end loop */
   1121 }
   1122 
   1123 
   1124 /*
   1125 * Read a restart marker, which is expected to appear next in the datastream;
   1126 * if the marker is not there, take appropriate recovery action.
   1127 * Returns FALSE if suspension is required.
   1128 *
   1129 * This is called by the entropy decoder after it has read an appropriate
   1130 * number of MCUs.  cinfo->unread_marker may be nonzero if the entropy decoder
   1131 * has already read a marker from the data source.  Under normal conditions
   1132 * cinfo->unread_marker will be reset to 0 before returning; if not reset,
   1133 * it holds a marker which the decoder will be unable to read past.
   1134 */
   1135 
   1136 METHODDEF(boolean)
   1137 read_restart_marker(j_decompress_ptr cinfo)
   1138 {
   1139  /* Obtain a marker unless we already did. */
   1140  /* Note that next_marker will complain if it skips any data. */
   1141  if (cinfo->unread_marker == 0) {
   1142    if (!next_marker(cinfo))
   1143      return FALSE;
   1144  }
   1145 
   1146  if (cinfo->unread_marker ==
   1147      ((int)M_RST0 + cinfo->marker->next_restart_num)) {
   1148    /* Normal case --- swallow the marker and let entropy decoder continue */
   1149    TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);
   1150    cinfo->unread_marker = 0;
   1151  } else {
   1152    /* Uh-oh, the restart markers have been messed up. */
   1153    /* Let the data source manager determine how to resync. */
   1154    if (!(*cinfo->src->resync_to_restart) (cinfo,
   1155                                           cinfo->marker->next_restart_num))
   1156      return FALSE;
   1157  }
   1158 
   1159  /* Update next-restart state */
   1160  cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;
   1161 
   1162  return TRUE;
   1163 }
   1164 
   1165 
   1166 /*
   1167 * This is the default resync_to_restart method for data source managers
   1168 * to use if they don't have any better approach.  Some data source managers
   1169 * may be able to back up, or may have additional knowledge about the data
   1170 * which permits a more intelligent recovery strategy; such managers would
   1171 * presumably supply their own resync method.
   1172 *
   1173 * read_restart_marker calls resync_to_restart if it finds a marker other than
   1174 * the restart marker it was expecting.  (This code is *not* used unless
   1175 * a nonzero restart interval has been declared.)  cinfo->unread_marker is
   1176 * the marker code actually found (might be anything, except 0 or FF).
   1177 * The desired restart marker number (0..7) is passed as a parameter.
   1178 * This routine is supposed to apply whatever error recovery strategy seems
   1179 * appropriate in order to position the input stream to the next data segment.
   1180 * Note that cinfo->unread_marker is treated as a marker appearing before
   1181 * the current data-source input point; usually it should be reset to zero
   1182 * before returning.
   1183 * Returns FALSE if suspension is required.
   1184 *
   1185 * This implementation is substantially constrained by wanting to treat the
   1186 * input as a data stream; this means we can't back up.  Therefore, we have
   1187 * only the following actions to work with:
   1188 *   1. Simply discard the marker and let the entropy decoder resume at next
   1189 *      byte of file.
   1190 *   2. Read forward until we find another marker, discarding intervening
   1191 *      data.  (In theory we could look ahead within the current bufferload,
   1192 *      without having to discard data if we don't find the desired marker.
   1193 *      This idea is not implemented here, in part because it makes behavior
   1194 *      dependent on buffer size and chance buffer-boundary positions.)
   1195 *   3. Leave the marker unread (by failing to zero cinfo->unread_marker).
   1196 *      This will cause the entropy decoder to process an empty data segment,
   1197 *      inserting dummy zeroes, and then we will reprocess the marker.
   1198 *
   1199 * #2 is appropriate if we think the desired marker lies ahead, while #3 is
   1200 * appropriate if the found marker is a future restart marker (indicating
   1201 * that we have missed the desired restart marker, probably because it got
   1202 * corrupted).
   1203 * We apply #2 or #3 if the found marker is a restart marker no more than
   1204 * two counts behind or ahead of the expected one.  We also apply #2 if the
   1205 * found marker is not a legal JPEG marker code (it's certainly bogus data).
   1206 * If the found marker is a restart marker more than 2 counts away, we do #1
   1207 * (too much risk that the marker is erroneous; with luck we will be able to
   1208 * resync at some future point).
   1209 * For any valid non-restart JPEG marker, we apply #3.  This keeps us from
   1210 * overrunning the end of a scan.  An implementation limited to single-scan
   1211 * files might find it better to apply #2 for markers other than EOI, since
   1212 * any other marker would have to be bogus data in that case.
   1213 */
   1214 
   1215 GLOBAL(boolean)
   1216 jpeg_resync_to_restart(j_decompress_ptr cinfo, int desired)
   1217 {
   1218  int marker = cinfo->unread_marker;
   1219  int action = 1;
   1220 
   1221  /* Always put up a warning. */
   1222  WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);
   1223 
   1224  /* Outer loop handles repeated decision after scanning forward. */
   1225  for (;;) {
   1226    if (marker < (int)M_SOF0)
   1227      action = 2;               /* invalid marker */
   1228    else if (marker < (int)M_RST0 || marker > (int)M_RST7)
   1229      action = 3;               /* valid non-restart marker */
   1230    else {
   1231      if (marker == ((int)M_RST0 + ((desired + 1) & 7)) ||
   1232          marker == ((int)M_RST0 + ((desired + 2) & 7)))
   1233        action = 3;             /* one of the next two expected restarts */
   1234      else if (marker == ((int)M_RST0 + ((desired - 1) & 7)) ||
   1235               marker == ((int)M_RST0 + ((desired - 2) & 7)))
   1236        action = 2;             /* a prior restart, so advance */
   1237      else
   1238        action = 1;             /* desired restart or too far away */
   1239    }
   1240    TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);
   1241    switch (action) {
   1242    case 1:
   1243      /* Discard marker and let entropy decoder resume processing. */
   1244      cinfo->unread_marker = 0;
   1245      return TRUE;
   1246    case 2:
   1247      /* Scan to the next marker, and repeat the decision loop. */
   1248      if (!next_marker(cinfo))
   1249        return FALSE;
   1250      marker = cinfo->unread_marker;
   1251      break;
   1252    case 3:
   1253      /* Return without advancing past this marker. */
   1254      /* Entropy decoder will be forced to process an empty segment. */
   1255      return TRUE;
   1256    }
   1257  } /* end loop */
   1258 }
   1259 
   1260 
   1261 /*
   1262 * Reset marker processing state to begin a fresh datastream.
   1263 */
   1264 
   1265 METHODDEF(void)
   1266 reset_marker_reader(j_decompress_ptr cinfo)
   1267 {
   1268  my_marker_ptr marker = (my_marker_ptr)cinfo->marker;
   1269 
   1270  cinfo->comp_info = NULL;              /* until allocated by get_sof */
   1271  cinfo->input_scan_number = 0;         /* no SOS seen yet */
   1272  cinfo->unread_marker = 0;             /* no pending marker */
   1273  marker->pub.saw_SOI = FALSE;          /* set internal state too */
   1274  marker->pub.saw_SOF = FALSE;
   1275  marker->pub.discarded_bytes = 0;
   1276  marker->cur_marker = NULL;
   1277 }
   1278 
   1279 
   1280 /*
   1281 * Initialize the marker reader module.
   1282 * This is called only once, when the decompression object is created.
   1283 */
   1284 
   1285 GLOBAL(void)
   1286 jinit_marker_reader(j_decompress_ptr cinfo)
   1287 {
   1288  my_marker_ptr marker;
   1289  int i;
   1290 
   1291  /* Create subobject in permanent pool */
   1292  marker = (my_marker_ptr)
   1293    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_PERMANENT,
   1294                                sizeof(my_marker_reader));
   1295  cinfo->marker = (struct jpeg_marker_reader *)marker;
   1296  /* Initialize public method pointers */
   1297  marker->pub.reset_marker_reader = reset_marker_reader;
   1298  marker->pub.read_markers = read_markers;
   1299  marker->pub.read_restart_marker = read_restart_marker;
   1300  /* Initialize COM/APPn processing.
   1301   * By default, we examine and then discard APP0 and APP14,
   1302   * but simply discard COM and all other APPn.
   1303   */
   1304  marker->process_COM = skip_variable;
   1305  marker->length_limit_COM = 0;
   1306  for (i = 0; i < 16; i++) {
   1307    marker->process_APPn[i] = skip_variable;
   1308    marker->length_limit_APPn[i] = 0;
   1309  }
   1310  marker->process_APPn[0] = get_interesting_appn;
   1311  marker->process_APPn[14] = get_interesting_appn;
   1312  /* Reset marker processing state */
   1313  reset_marker_reader(cinfo);
   1314 }
   1315 
   1316 
   1317 /*
   1318 * Control saving of COM and APPn markers into marker_list.
   1319 */
   1320 
   1321 #ifdef SAVE_MARKERS_SUPPORTED
   1322 
   1323 GLOBAL(void)
   1324 jpeg_save_markers(j_decompress_ptr cinfo, int marker_code,
   1325                  unsigned int length_limit)
   1326 {
   1327  my_marker_ptr marker = (my_marker_ptr)cinfo->marker;
   1328  long maxlength;
   1329  jpeg_marker_parser_method processor;
   1330 
   1331  /* Length limit mustn't be larger than what we can allocate
   1332   * (should only be a concern in a 16-bit environment).
   1333   */
   1334  maxlength = cinfo->mem->max_alloc_chunk - sizeof(struct jpeg_marker_struct);
   1335  if (((long)length_limit) > maxlength)
   1336    length_limit = (unsigned int)maxlength;
   1337 
   1338  /* Choose processor routine to use.
   1339   * APP0/APP14 have special requirements.
   1340   */
   1341  if (length_limit) {
   1342    processor = save_marker;
   1343    /* If saving APP0/APP14, save at least enough for our internal use. */
   1344    if (marker_code == (int)M_APP0 && length_limit < APP0_DATA_LEN)
   1345      length_limit = APP0_DATA_LEN;
   1346    else if (marker_code == (int)M_APP14 && length_limit < APP14_DATA_LEN)
   1347      length_limit = APP14_DATA_LEN;
   1348  } else {
   1349    processor = skip_variable;
   1350    /* If discarding APP0/APP14, use our regular on-the-fly processor. */
   1351    if (marker_code == (int)M_APP0 || marker_code == (int)M_APP14)
   1352      processor = get_interesting_appn;
   1353  }
   1354 
   1355  if (marker_code == (int)M_COM) {
   1356    marker->process_COM = processor;
   1357    marker->length_limit_COM = length_limit;
   1358  } else if (marker_code >= (int)M_APP0 && marker_code <= (int)M_APP15) {
   1359    marker->process_APPn[marker_code - (int)M_APP0] = processor;
   1360    marker->length_limit_APPn[marker_code - (int)M_APP0] = length_limit;
   1361  } else
   1362    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
   1363 }
   1364 
   1365 #endif /* SAVE_MARKERS_SUPPORTED */
   1366 
   1367 
   1368 /*
   1369 * Install a special processing method for COM or APPn markers.
   1370 */
   1371 
   1372 GLOBAL(void)
   1373 jpeg_set_marker_processor(j_decompress_ptr cinfo, int marker_code,
   1374                          jpeg_marker_parser_method routine)
   1375 {
   1376  my_marker_ptr marker = (my_marker_ptr)cinfo->marker;
   1377 
   1378  if (marker_code == (int)M_COM)
   1379    marker->process_COM = routine;
   1380  else if (marker_code >= (int)M_APP0 && marker_code <= (int)M_APP15)
   1381    marker->process_APPn[marker_code - (int)M_APP0] = routine;
   1382  else
   1383    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
   1384 }