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