Back to index

plt-scheme  4.2.1
jdmarker.c
Go to the documentation of this file.
00001 /*
00002  * jdmarker.c
00003  *
00004  * Copyright (C) 1991-1998, Thomas G. Lane.
00005  * This file is part of the Independent JPEG Group's software.
00006  * For conditions of distribution and use, see the accompanying README file.
00007  *
00008  * This file contains routines to decode JPEG datastream markers.
00009  * Most of the complexity arises from our desire to support input
00010  * suspension: if not all of the data for a marker is available,
00011  * we must exit back to the application.  On resumption, we reprocess
00012  * the marker.
00013  */
00014 
00015 #define JPEG_INTERNALS
00016 #include "jinclude.h"
00017 #include "jpeglib.h"
00018 
00019 
00020 typedef enum {                     /* JPEG marker codes */
00021   M_SOF0  = 0xc0,
00022   M_SOF1  = 0xc1,
00023   M_SOF2  = 0xc2,
00024   M_SOF3  = 0xc3,
00025   
00026   M_SOF5  = 0xc5,
00027   M_SOF6  = 0xc6,
00028   M_SOF7  = 0xc7,
00029   
00030   M_JPG   = 0xc8,
00031   M_SOF9  = 0xc9,
00032   M_SOF10 = 0xca,
00033   M_SOF11 = 0xcb,
00034   
00035   M_SOF13 = 0xcd,
00036   M_SOF14 = 0xce,
00037   M_SOF15 = 0xcf,
00038   
00039   M_DHT   = 0xc4,
00040   
00041   M_DAC   = 0xcc,
00042   
00043   M_RST0  = 0xd0,
00044   M_RST1  = 0xd1,
00045   M_RST2  = 0xd2,
00046   M_RST3  = 0xd3,
00047   M_RST4  = 0xd4,
00048   M_RST5  = 0xd5,
00049   M_RST6  = 0xd6,
00050   M_RST7  = 0xd7,
00051   
00052   M_SOI   = 0xd8,
00053   M_EOI   = 0xd9,
00054   M_SOS   = 0xda,
00055   M_DQT   = 0xdb,
00056   M_DNL   = 0xdc,
00057   M_DRI   = 0xdd,
00058   M_DHP   = 0xde,
00059   M_EXP   = 0xdf,
00060   
00061   M_APP0  = 0xe0,
00062   M_APP1  = 0xe1,
00063   M_APP2  = 0xe2,
00064   M_APP3  = 0xe3,
00065   M_APP4  = 0xe4,
00066   M_APP5  = 0xe5,
00067   M_APP6  = 0xe6,
00068   M_APP7  = 0xe7,
00069   M_APP8  = 0xe8,
00070   M_APP9  = 0xe9,
00071   M_APP10 = 0xea,
00072   M_APP11 = 0xeb,
00073   M_APP12 = 0xec,
00074   M_APP13 = 0xed,
00075   M_APP14 = 0xee,
00076   M_APP15 = 0xef,
00077   
00078   M_JPG0  = 0xf0,
00079   M_JPG13 = 0xfd,
00080   M_COM   = 0xfe,
00081   
00082   M_TEM   = 0x01,
00083   
00084   M_ERROR = 0x100
00085 } JPEG_MARKER;
00086 
00087 
00088 /* Private state */
00089 
00090 typedef struct {
00091   struct jpeg_marker_reader pub; /* public fields */
00092 
00093   /* Application-overridable marker processing methods */
00094   jpeg_marker_parser_method process_COM;
00095   jpeg_marker_parser_method process_APPn[16];
00096 
00097   /* Limit on marker data length to save for each marker type */
00098   unsigned int length_limit_COM;
00099   unsigned int length_limit_APPn[16];
00100 
00101   /* Status of COM/APPn marker saving */
00102   jpeg_saved_marker_ptr cur_marker;       /* NULL if not processing a marker */
00103   unsigned int bytes_read;         /* data bytes read so far in marker */
00104   /* Note: cur_marker is not linked into marker_list until it's all read. */
00105 } my_marker_reader;
00106 
00107 typedef my_marker_reader * my_marker_ptr;
00108 
00109 
00110 /*
00111  * Macros for fetching data from the data source module.
00112  *
00113  * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect
00114  * the current restart point; we update them only when we have reached a
00115  * suitable place to restart if a suspension occurs.
00116  */
00117 
00118 /* Declare and initialize local copies of input pointer/count */
00119 #define INPUT_VARS(cinfo)  \
00120        struct jpeg_source_mgr * datasrc = (cinfo)->src;  \
00121        const JOCTET * next_input_byte = datasrc->next_input_byte;  \
00122        size_t bytes_in_buffer = datasrc->bytes_in_buffer
00123 
00124 /* Unload the local copies --- do this only at a restart boundary */
00125 #define INPUT_SYNC(cinfo)  \
00126        ( datasrc->next_input_byte = next_input_byte,  \
00127          datasrc->bytes_in_buffer = bytes_in_buffer )
00128 
00129 /* Reload the local copies --- used only in MAKE_BYTE_AVAIL */
00130 #define INPUT_RELOAD(cinfo)  \
00131        ( next_input_byte = datasrc->next_input_byte,  \
00132          bytes_in_buffer = datasrc->bytes_in_buffer )
00133 
00134 /* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.
00135  * Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
00136  * but we must reload the local copies after a successful fill.
00137  */
00138 #define MAKE_BYTE_AVAIL(cinfo,action)  \
00139        if (bytes_in_buffer == 0) {  \
00140          if (! (*datasrc->fill_input_buffer) (cinfo))  \
00141            { action; }  \
00142          INPUT_RELOAD(cinfo);  \
00143        }
00144 
00145 /* Read a byte into variable V.
00146  * If must suspend, take the specified action (typically "return FALSE").
00147  */
00148 #define INPUT_BYTE(cinfo,V,action)  \
00149        MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
00150                 bytes_in_buffer--; \
00151                 V = GETJOCTET(*next_input_byte++); )
00152 
00153 /* As above, but read two bytes interpreted as an unsigned 16-bit integer.
00154  * V should be declared unsigned int or perhaps INT32.
00155  */
00156 #define INPUT_2BYTES(cinfo,V,action)  \
00157        MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
00158                 bytes_in_buffer--; \
00159                 V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
00160                 MAKE_BYTE_AVAIL(cinfo,action); \
00161                 bytes_in_buffer--; \
00162                 V += GETJOCTET(*next_input_byte++); )
00163 
00164 
00165 /*
00166  * Routines to process JPEG markers.
00167  *
00168  * Entry condition: JPEG marker itself has been read and its code saved
00169  *   in cinfo->unread_marker; input restart point is just after the marker.
00170  *
00171  * Exit: if return TRUE, have read and processed any parameters, and have
00172  *   updated the restart point to point after the parameters.
00173  *   If return FALSE, was forced to suspend before reaching end of
00174  *   marker parameters; restart point has not been moved.  Same routine
00175  *   will be called again after application supplies more input data.
00176  *
00177  * This approach to suspension assumes that all of a marker's parameters
00178  * can fit into a single input bufferload.  This should hold for "normal"
00179  * markers.  Some COM/APPn markers might have large parameter segments
00180  * that might not fit.  If we are simply dropping such a marker, we use
00181  * skip_input_data to get past it, and thereby put the problem on the
00182  * source manager's shoulders.  If we are saving the marker's contents
00183  * into memory, we use a slightly different convention: when forced to
00184  * suspend, the marker processor updates the restart point to the end of
00185  * what it's consumed (ie, the end of the buffer) before returning FALSE.
00186  * On resumption, cinfo->unread_marker still contains the marker code,
00187  * but the data source will point to the next chunk of marker data.
00188  * The marker processor must retain internal state to deal with this.
00189  *
00190  * Note that we don't bother to avoid duplicate trace messages if a
00191  * suspension occurs within marker parameters.  Other side effects
00192  * require more care.
00193  */
00194 
00195 
00196 LOCAL(boolean)
00197 get_soi (j_decompress_ptr cinfo)
00198 /* Process an SOI marker */
00199 {
00200   int i;
00201   
00202   TRACEMS(cinfo, 1, JTRC_SOI);
00203 
00204   if (cinfo->marker->saw_SOI)
00205     ERREXIT(cinfo, JERR_SOI_DUPLICATE);
00206 
00207   /* Reset all parameters that are defined to be reset by SOI */
00208 
00209   for (i = 0; i < NUM_ARITH_TBLS; i++) {
00210     cinfo->arith_dc_L[i] = 0;
00211     cinfo->arith_dc_U[i] = 1;
00212     cinfo->arith_ac_K[i] = 5;
00213   }
00214   cinfo->restart_interval = 0;
00215 
00216   /* Set initial assumptions for colorspace etc */
00217 
00218   cinfo->jpeg_color_space = JCS_UNKNOWN;
00219   cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
00220 
00221   cinfo->saw_JFIF_marker = FALSE;
00222   cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */
00223   cinfo->JFIF_minor_version = 1;
00224   cinfo->density_unit = 0;
00225   cinfo->X_density = 1;
00226   cinfo->Y_density = 1;
00227   cinfo->saw_Adobe_marker = FALSE;
00228   cinfo->Adobe_transform = 0;
00229 
00230   cinfo->marker->saw_SOI = TRUE;
00231 
00232   return TRUE;
00233 }
00234 
00235 
00236 LOCAL(boolean)
00237 get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
00238 /* Process a SOFn marker */
00239 {
00240   INT32 length;
00241   int c, ci;
00242   jpeg_component_info * compptr;
00243   INPUT_VARS(cinfo);
00244 
00245   cinfo->progressive_mode = is_prog;
00246   cinfo->arith_code = is_arith;
00247 
00248   INPUT_2BYTES(cinfo, length, return FALSE);
00249 
00250   INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);
00251   INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE);
00252   INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE);
00253   INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);
00254 
00255   length -= 8;
00256 
00257   TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,
00258           (int) cinfo->image_width, (int) cinfo->image_height,
00259           cinfo->num_components);
00260 
00261   if (cinfo->marker->saw_SOF)
00262     ERREXIT(cinfo, JERR_SOF_DUPLICATE);
00263 
00264   /* We don't support files in which the image height is initially specified */
00265   /* as 0 and is later redefined by DNL.  As long as we have to check that,  */
00266   /* might as well have a general sanity check. */
00267   if (cinfo->image_height <= 0 || cinfo->image_width <= 0
00268       || cinfo->num_components <= 0)
00269     ERREXIT(cinfo, JERR_EMPTY_IMAGE);
00270 
00271   if (length != (cinfo->num_components * 3))
00272     ERREXIT(cinfo, JERR_BAD_LENGTH);
00273 
00274   if (cinfo->comp_info == NULL)    /* do only once, even if suspend */
00275     cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)
00276                      ((j_common_ptr) cinfo, JPOOL_IMAGE,
00277                       cinfo->num_components * SIZEOF(jpeg_component_info));
00278   
00279   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00280        ci++, compptr++) {
00281     compptr->component_index = ci;
00282     INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
00283     INPUT_BYTE(cinfo, c, return FALSE);
00284     compptr->h_samp_factor = (c >> 4) & 15;
00285     compptr->v_samp_factor = (c     ) & 15;
00286     INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);
00287 
00288     TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,
00289             compptr->component_id, compptr->h_samp_factor,
00290             compptr->v_samp_factor, compptr->quant_tbl_no);
00291   }
00292 
00293   cinfo->marker->saw_SOF = TRUE;
00294 
00295   INPUT_SYNC(cinfo);
00296   return TRUE;
00297 }
00298 
00299 
00300 LOCAL(boolean)
00301 get_sos (j_decompress_ptr cinfo)
00302 /* Process a SOS marker */
00303 {
00304   INT32 length;
00305   int i, ci, n, c, cc;
00306   jpeg_component_info * compptr;
00307   INPUT_VARS(cinfo);
00308 
00309   if (! cinfo->marker->saw_SOF)
00310     ERREXIT(cinfo, JERR_SOS_NO_SOF);
00311 
00312   INPUT_2BYTES(cinfo, length, return FALSE);
00313 
00314   INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */
00315 
00316   TRACEMS1(cinfo, 1, JTRC_SOS, n);
00317 
00318   if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
00319     ERREXIT(cinfo, JERR_BAD_LENGTH);
00320 
00321   cinfo->comps_in_scan = n;
00322 
00323   /* Collect the component-spec parameters */
00324 
00325   for (i = 0; i < n; i++) {
00326     INPUT_BYTE(cinfo, cc, return FALSE);
00327     INPUT_BYTE(cinfo, c, return FALSE);
00328     
00329     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00330         ci++, compptr++) {
00331       if (cc == compptr->component_id)
00332        goto id_found;
00333     }
00334 
00335     ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
00336 
00337   id_found:
00338 
00339     cinfo->cur_comp_info[i] = compptr;
00340     compptr->dc_tbl_no = (c >> 4) & 15;
00341     compptr->ac_tbl_no = (c     ) & 15;
00342     
00343     TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,
00344             compptr->dc_tbl_no, compptr->ac_tbl_no);
00345   }
00346 
00347   /* Collect the additional scan parameters Ss, Se, Ah/Al. */
00348   INPUT_BYTE(cinfo, c, return FALSE);
00349   cinfo->Ss = c;
00350   INPUT_BYTE(cinfo, c, return FALSE);
00351   cinfo->Se = c;
00352   INPUT_BYTE(cinfo, c, return FALSE);
00353   cinfo->Ah = (c >> 4) & 15;
00354   cinfo->Al = (c     ) & 15;
00355 
00356   TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,
00357           cinfo->Ah, cinfo->Al);
00358 
00359   /* Prepare to scan data & restart markers */
00360   cinfo->marker->next_restart_num = 0;
00361 
00362   /* Count another SOS marker */
00363   cinfo->input_scan_number++;
00364 
00365   INPUT_SYNC(cinfo);
00366   return TRUE;
00367 }
00368 
00369 
00370 #ifdef D_ARITH_CODING_SUPPORTED
00371 
00372 LOCAL(boolean)
00373 get_dac (j_decompress_ptr cinfo)
00374 /* Process a DAC marker */
00375 {
00376   INT32 length;
00377   int index, val;
00378   INPUT_VARS(cinfo);
00379 
00380   INPUT_2BYTES(cinfo, length, return FALSE);
00381   length -= 2;
00382   
00383   while (length > 0) {
00384     INPUT_BYTE(cinfo, index, return FALSE);
00385     INPUT_BYTE(cinfo, val, return FALSE);
00386 
00387     length -= 2;
00388 
00389     TRACEMS2(cinfo, 1, JTRC_DAC, index, val);
00390 
00391     if (index < 0 || index >= (2*NUM_ARITH_TBLS))
00392       ERREXIT1(cinfo, JERR_DAC_INDEX, index);
00393 
00394     if (index >= NUM_ARITH_TBLS) { /* define AC table */
00395       cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
00396     } else {                /* define DC table */
00397       cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
00398       cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
00399       if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
00400        ERREXIT1(cinfo, JERR_DAC_VALUE, val);
00401     }
00402   }
00403 
00404   if (length != 0)
00405     ERREXIT(cinfo, JERR_BAD_LENGTH);
00406 
00407   INPUT_SYNC(cinfo);
00408   return TRUE;
00409 }
00410 
00411 #else /* ! D_ARITH_CODING_SUPPORTED */
00412 
00413 #define get_dac(cinfo)  skip_variable(cinfo)
00414 
00415 #endif /* D_ARITH_CODING_SUPPORTED */
00416 
00417 
00418 LOCAL(boolean)
00419 get_dht (j_decompress_ptr cinfo)
00420 /* Process a DHT marker */
00421 {
00422   INT32 length;
00423   UINT8 bits[17];
00424   UINT8 huffval[256];
00425   int i, index, count;
00426   JHUFF_TBL **htblptr;
00427   INPUT_VARS(cinfo);
00428 
00429   INPUT_2BYTES(cinfo, length, return FALSE);
00430   length -= 2;
00431   
00432   while (length > 16) {
00433     INPUT_BYTE(cinfo, index, return FALSE);
00434 
00435     TRACEMS1(cinfo, 1, JTRC_DHT, index);
00436       
00437     bits[0] = 0;
00438     count = 0;
00439     for (i = 1; i <= 16; i++) {
00440       INPUT_BYTE(cinfo, bits[i], return FALSE);
00441       count += bits[i];
00442     }
00443 
00444     length -= 1 + 16;
00445 
00446     TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
00447             bits[1], bits[2], bits[3], bits[4],
00448             bits[5], bits[6], bits[7], bits[8]);
00449     TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
00450             bits[9], bits[10], bits[11], bits[12],
00451             bits[13], bits[14], bits[15], bits[16]);
00452 
00453     /* Here we just do minimal validation of the counts to avoid walking
00454      * off the end of our table space.  jdhuff.c will check more carefully.
00455      */
00456     if (count > 256 || ((INT32) count) > length)
00457       ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
00458 
00459     for (i = 0; i < count; i++)
00460       INPUT_BYTE(cinfo, huffval[i], return FALSE);
00461 
00462     length -= count;
00463 
00464     if (index & 0x10) {            /* AC table definition */
00465       index -= 0x10;
00466       htblptr = &cinfo->ac_huff_tbl_ptrs[index];
00467     } else {                /* DC table definition */
00468       htblptr = &cinfo->dc_huff_tbl_ptrs[index];
00469     }
00470 
00471     if (index < 0 || index >= NUM_HUFF_TBLS)
00472       ERREXIT1(cinfo, JERR_DHT_INDEX, index);
00473 
00474     if (*htblptr == NULL)
00475       *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
00476   
00477     MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
00478     MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
00479   }
00480 
00481   if (length != 0)
00482     ERREXIT(cinfo, JERR_BAD_LENGTH);
00483 
00484   INPUT_SYNC(cinfo);
00485   return TRUE;
00486 }
00487 
00488 
00489 LOCAL(boolean)
00490 get_dqt (j_decompress_ptr cinfo)
00491 /* Process a DQT marker */
00492 {
00493   INT32 length;
00494   int n, i, prec;
00495   unsigned int tmp;
00496   JQUANT_TBL *quant_ptr;
00497   INPUT_VARS(cinfo);
00498 
00499   INPUT_2BYTES(cinfo, length, return FALSE);
00500   length -= 2;
00501 
00502   while (length > 0) {
00503     INPUT_BYTE(cinfo, n, return FALSE);
00504     prec = n >> 4;
00505     n &= 0x0F;
00506 
00507     TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);
00508 
00509     if (n >= NUM_QUANT_TBLS)
00510       ERREXIT1(cinfo, JERR_DQT_INDEX, n);
00511       
00512     if (cinfo->quant_tbl_ptrs[n] == NULL)
00513       cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);
00514     quant_ptr = cinfo->quant_tbl_ptrs[n];
00515 
00516     for (i = 0; i < DCTSIZE2; i++) {
00517       if (prec)
00518        INPUT_2BYTES(cinfo, tmp, return FALSE);
00519       else
00520        INPUT_BYTE(cinfo, tmp, return FALSE);
00521       /* We convert the zigzag-order table to natural array order. */
00522       quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp;
00523     }
00524 
00525     if (cinfo->err->trace_level >= 2) {
00526       for (i = 0; i < DCTSIZE2; i += 8) {
00527        TRACEMS8(cinfo, 2, JTRC_QUANTVALS,
00528                quant_ptr->quantval[i],   quant_ptr->quantval[i+1],
00529                quant_ptr->quantval[i+2], quant_ptr->quantval[i+3],
00530                quant_ptr->quantval[i+4], quant_ptr->quantval[i+5],
00531                quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]);
00532       }
00533     }
00534 
00535     length -= DCTSIZE2+1;
00536     if (prec) length -= DCTSIZE2;
00537   }
00538 
00539   if (length != 0)
00540     ERREXIT(cinfo, JERR_BAD_LENGTH);
00541 
00542   INPUT_SYNC(cinfo);
00543   return TRUE;
00544 }
00545 
00546 
00547 LOCAL(boolean)
00548 get_dri (j_decompress_ptr cinfo)
00549 /* Process a DRI marker */
00550 {
00551   INT32 length;
00552   unsigned int tmp;
00553   INPUT_VARS(cinfo);
00554 
00555   INPUT_2BYTES(cinfo, length, return FALSE);
00556   
00557   if (length != 4)
00558     ERREXIT(cinfo, JERR_BAD_LENGTH);
00559 
00560   INPUT_2BYTES(cinfo, tmp, return FALSE);
00561 
00562   TRACEMS1(cinfo, 1, JTRC_DRI, tmp);
00563 
00564   cinfo->restart_interval = tmp;
00565 
00566   INPUT_SYNC(cinfo);
00567   return TRUE;
00568 }
00569 
00570 
00571 /*
00572  * Routines for processing APPn and COM markers.
00573  * These are either saved in memory or discarded, per application request.
00574  * APP0 and APP14 are specially checked to see if they are
00575  * JFIF and Adobe markers, respectively.
00576  */
00577 
00578 #define APP0_DATA_LEN       14     /* Length of interesting data in APP0 */
00579 #define APP14_DATA_LEN      12     /* Length of interesting data in APP14 */
00580 #define APPN_DATA_LEN       14     /* Must be the largest of the above!! */
00581 
00582 
00583 LOCAL(void)
00584 examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
00585              unsigned int datalen, INT32 remaining)
00586 /* Examine first few bytes from an APP0.
00587  * Take appropriate action if it is a JFIF marker.
00588  * datalen is # of bytes at data[], remaining is length of rest of marker data.
00589  */
00590 {
00591   INT32 totallen = (INT32) datalen + remaining;
00592 
00593   if (datalen >= APP0_DATA_LEN &&
00594       GETJOCTET(data[0]) == 0x4A &&
00595       GETJOCTET(data[1]) == 0x46 &&
00596       GETJOCTET(data[2]) == 0x49 &&
00597       GETJOCTET(data[3]) == 0x46 &&
00598       GETJOCTET(data[4]) == 0) {
00599     /* Found JFIF APP0 marker: save info */
00600     cinfo->saw_JFIF_marker = TRUE;
00601     cinfo->JFIF_major_version = GETJOCTET(data[5]);
00602     cinfo->JFIF_minor_version = GETJOCTET(data[6]);
00603     cinfo->density_unit = GETJOCTET(data[7]);
00604     cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
00605     cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
00606     /* Check version.
00607      * Major version must be 1, anything else signals an incompatible change.
00608      * (We used to treat this as an error, but now it's a nonfatal warning,
00609      * because some bozo at Hijaak couldn't read the spec.)
00610      * Minor version should be 0..2, but process anyway if newer.
00611      */
00612     if (cinfo->JFIF_major_version != 1)
00613       WARNMS2(cinfo, JWRN_JFIF_MAJOR,
00614              cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
00615     /* Generate trace messages */
00616     TRACEMS5(cinfo, 1, JTRC_JFIF,
00617             cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
00618             cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
00619     /* Validate thumbnail dimensions and issue appropriate messages */
00620     if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
00621       TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
00622               GETJOCTET(data[12]), GETJOCTET(data[13]));
00623     totallen -= APP0_DATA_LEN;
00624     if (totallen !=
00625        ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3))
00626       TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);
00627   } else if (datalen >= 6 &&
00628       GETJOCTET(data[0]) == 0x4A &&
00629       GETJOCTET(data[1]) == 0x46 &&
00630       GETJOCTET(data[2]) == 0x58 &&
00631       GETJOCTET(data[3]) == 0x58 &&
00632       GETJOCTET(data[4]) == 0) {
00633     /* Found JFIF "JFXX" extension APP0 marker */
00634     /* The library doesn't actually do anything with these,
00635      * but we try to produce a helpful trace message.
00636      */
00637     switch (GETJOCTET(data[5])) {
00638     case 0x10:
00639       TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);
00640       break;
00641     case 0x11:
00642       TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);
00643       break;
00644     case 0x13:
00645       TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);
00646       break;
00647     default:
00648       TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
00649               GETJOCTET(data[5]), (int) totallen);
00650       break;
00651     }
00652   } else {
00653     /* Start of APP0 does not match "JFIF" or "JFXX", or too short */
00654     TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);
00655   }
00656 }
00657 
00658 
00659 LOCAL(void)
00660 examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data,
00661               unsigned int datalen, INT32 remaining)
00662 /* Examine first few bytes from an APP14.
00663  * Take appropriate action if it is an Adobe marker.
00664  * datalen is # of bytes at data[], remaining is length of rest of marker data.
00665  */
00666 {
00667   unsigned int version, flags0, flags1, transform;
00668 
00669   if (datalen >= APP14_DATA_LEN &&
00670       GETJOCTET(data[0]) == 0x41 &&
00671       GETJOCTET(data[1]) == 0x64 &&
00672       GETJOCTET(data[2]) == 0x6F &&
00673       GETJOCTET(data[3]) == 0x62 &&
00674       GETJOCTET(data[4]) == 0x65) {
00675     /* Found Adobe APP14 marker */
00676     version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
00677     flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
00678     flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
00679     transform = GETJOCTET(data[11]);
00680     TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
00681     cinfo->saw_Adobe_marker = TRUE;
00682     cinfo->Adobe_transform = (UINT8) transform;
00683   } else {
00684     /* Start of APP14 does not match "Adobe", or too short */
00685     TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));
00686   }
00687 }
00688 
00689 
00690 METHODDEF(boolean)
00691 get_interesting_appn (j_decompress_ptr cinfo)
00692 /* Process an APP0 or APP14 marker without saving it */
00693 {
00694   INT32 length;
00695   JOCTET b[APPN_DATA_LEN];
00696   unsigned int i, numtoread;
00697   INPUT_VARS(cinfo);
00698 
00699   INPUT_2BYTES(cinfo, length, return FALSE);
00700   length -= 2;
00701 
00702   /* get the interesting part of the marker data */
00703   if (length >= APPN_DATA_LEN)
00704     numtoread = APPN_DATA_LEN;
00705   else if (length > 0)
00706     numtoread = (unsigned int) length;
00707   else
00708     numtoread = 0;
00709   for (i = 0; i < numtoread; i++)
00710     INPUT_BYTE(cinfo, b[i], return FALSE);
00711   length -= numtoread;
00712 
00713   /* process it */
00714   switch (cinfo->unread_marker) {
00715   case M_APP0:
00716     examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length);
00717     break;
00718   case M_APP14:
00719     examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length);
00720     break;
00721   default:
00722     /* can't get here unless jpeg_save_markers chooses wrong processor */
00723     ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
00724     break;
00725   }
00726 
00727   /* skip any remaining data -- could be lots */
00728   INPUT_SYNC(cinfo);
00729   if (length > 0)
00730     (*cinfo->src->skip_input_data) (cinfo, (long) length);
00731 
00732   return TRUE;
00733 }
00734 
00735 
00736 #ifdef SAVE_MARKERS_SUPPORTED
00737 
00738 METHODDEF(boolean)
00739 save_marker (j_decompress_ptr cinfo)
00740 /* Save an APPn or COM marker into the marker list */
00741 {
00742   my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
00743   jpeg_saved_marker_ptr cur_marker = marker->cur_marker;
00744   unsigned int bytes_read, data_length;
00745   JOCTET FAR * data;
00746   INT32 length = 0;
00747   INPUT_VARS(cinfo);
00748 
00749   if (cur_marker == NULL) {
00750     /* begin reading a marker */
00751     INPUT_2BYTES(cinfo, length, return FALSE);
00752     length -= 2;
00753     if (length >= 0) {             /* watch out for bogus length word */
00754       /* figure out how much we want to save */
00755       unsigned int limit;
00756       if (cinfo->unread_marker == (int) M_COM)
00757        limit = marker->length_limit_COM;
00758       else
00759        limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];
00760       if ((unsigned int) length < limit)
00761        limit = (unsigned int) length;
00762       /* allocate and initialize the marker item */
00763       cur_marker = (jpeg_saved_marker_ptr)
00764        (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00765                                 SIZEOF(struct jpeg_marker_struct) + limit);
00766       cur_marker->next = NULL;
00767       cur_marker->marker = (UINT8) cinfo->unread_marker;
00768       cur_marker->original_length = (unsigned int) length;
00769       cur_marker->data_length = limit;
00770       /* data area is just beyond the jpeg_marker_struct */
00771       data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1);
00772       marker->cur_marker = cur_marker;
00773       marker->bytes_read = 0;
00774       bytes_read = 0;
00775       data_length = limit;
00776     } else {
00777       /* deal with bogus length word */
00778       bytes_read = data_length = 0;
00779       data = NULL;
00780     }
00781   } else {
00782     /* resume reading a marker */
00783     bytes_read = marker->bytes_read;
00784     data_length = cur_marker->data_length;
00785     data = cur_marker->data + bytes_read;
00786   }
00787 
00788   while (bytes_read < data_length) {
00789     INPUT_SYNC(cinfo);             /* move the restart point to here */
00790     marker->bytes_read = bytes_read;
00791     /* If there's not at least one byte in buffer, suspend */
00792     MAKE_BYTE_AVAIL(cinfo, return FALSE);
00793     /* Copy bytes with reasonable rapidity */
00794     while (bytes_read < data_length && bytes_in_buffer > 0) {
00795       *data++ = *next_input_byte++;
00796       bytes_in_buffer--;
00797       bytes_read++;
00798     }
00799   }
00800 
00801   /* Done reading what we want to read */
00802   if (cur_marker != NULL) { /* will be NULL if bogus length word */
00803     /* Add new marker to end of list */
00804     if (cinfo->marker_list == NULL) {
00805       cinfo->marker_list = cur_marker;
00806     } else {
00807       jpeg_saved_marker_ptr prev = cinfo->marker_list;
00808       while (prev->next != NULL)
00809        prev = prev->next;
00810       prev->next = cur_marker;
00811     }
00812     /* Reset pointer & calc remaining data length */
00813     data = cur_marker->data;
00814     length = cur_marker->original_length - data_length;
00815   }
00816   /* Reset to initial state for next marker */
00817   marker->cur_marker = NULL;
00818 
00819   /* Process the marker if interesting; else just make a generic trace msg */
00820   switch (cinfo->unread_marker) {
00821   case M_APP0:
00822     examine_app0(cinfo, data, data_length, length);
00823     break;
00824   case M_APP14:
00825     examine_app14(cinfo, data, data_length, length);
00826     break;
00827   default:
00828     TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
00829             (int) (data_length + length));
00830     break;
00831   }
00832 
00833   /* skip any remaining data -- could be lots */
00834   INPUT_SYNC(cinfo);        /* do before skip_input_data */
00835   if (length > 0)
00836     (*cinfo->src->skip_input_data) (cinfo, (long) length);
00837 
00838   return TRUE;
00839 }
00840 
00841 #endif /* SAVE_MARKERS_SUPPORTED */
00842 
00843 
00844 METHODDEF(boolean)
00845 skip_variable (j_decompress_ptr cinfo)
00846 /* Skip over an unknown or uninteresting variable-length marker */
00847 {
00848   INT32 length;
00849   INPUT_VARS(cinfo);
00850 
00851   INPUT_2BYTES(cinfo, length, return FALSE);
00852   length -= 2;
00853   
00854   TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);
00855 
00856   INPUT_SYNC(cinfo);        /* do before skip_input_data */
00857   if (length > 0)
00858     (*cinfo->src->skip_input_data) (cinfo, (long) length);
00859 
00860   return TRUE;
00861 }
00862 
00863 
00864 /*
00865  * Find the next JPEG marker, save it in cinfo->unread_marker.
00866  * Returns FALSE if had to suspend before reaching a marker;
00867  * in that case cinfo->unread_marker is unchanged.
00868  *
00869  * Note that the result might not be a valid marker code,
00870  * but it will never be 0 or FF.
00871  */
00872 
00873 LOCAL(boolean)
00874 next_marker (j_decompress_ptr cinfo)
00875 {
00876   int c;
00877   INPUT_VARS(cinfo);
00878 
00879   for (;;) {
00880     INPUT_BYTE(cinfo, c, return FALSE);
00881     /* Skip any non-FF bytes.
00882      * This may look a bit inefficient, but it will not occur in a valid file.
00883      * We sync after each discarded byte so that a suspending data source
00884      * can discard the byte from its buffer.
00885      */
00886     while (c != 0xFF) {
00887       cinfo->marker->discarded_bytes++;
00888       INPUT_SYNC(cinfo);
00889       INPUT_BYTE(cinfo, c, return FALSE);
00890     }
00891     /* This loop swallows any duplicate FF bytes.  Extra FFs are legal as
00892      * pad bytes, so don't count them in discarded_bytes.  We assume there
00893      * will not be so many consecutive FF bytes as to overflow a suspending
00894      * data source's input buffer.
00895      */
00896     do {
00897       INPUT_BYTE(cinfo, c, return FALSE);
00898     } while (c == 0xFF);
00899     if (c != 0)
00900       break;                /* found a valid marker, exit loop */
00901     /* Reach here if we found a stuffed-zero data sequence (FF/00).
00902      * Discard it and loop back to try again.
00903      */
00904     cinfo->marker->discarded_bytes += 2;
00905     INPUT_SYNC(cinfo);
00906   }
00907 
00908   if (cinfo->marker->discarded_bytes != 0) {
00909     WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);
00910     cinfo->marker->discarded_bytes = 0;
00911   }
00912 
00913   cinfo->unread_marker = c;
00914 
00915   INPUT_SYNC(cinfo);
00916   return TRUE;
00917 }
00918 
00919 
00920 LOCAL(boolean)
00921 first_marker (j_decompress_ptr cinfo)
00922 /* Like next_marker, but used to obtain the initial SOI marker. */
00923 /* For this marker, we do not allow preceding garbage or fill; otherwise,
00924  * we might well scan an entire input file before realizing it ain't JPEG.
00925  * If an application wants to process non-JFIF files, it must seek to the
00926  * SOI before calling the JPEG library.
00927  */
00928 {
00929   int c, c2;
00930   INPUT_VARS(cinfo);
00931 
00932   INPUT_BYTE(cinfo, c, return FALSE);
00933   INPUT_BYTE(cinfo, c2, return FALSE);
00934   if (c != 0xFF || c2 != (int) M_SOI)
00935     ERREXIT2(cinfo, JERR_NO_SOI, c, c2);
00936 
00937   cinfo->unread_marker = c2;
00938 
00939   INPUT_SYNC(cinfo);
00940   return TRUE;
00941 }
00942 
00943 
00944 /*
00945  * Read markers until SOS or EOI.
00946  *
00947  * Returns same codes as are defined for jpeg_consume_input:
00948  * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
00949  */
00950 
00951 METHODDEF(int)
00952 read_markers (j_decompress_ptr cinfo)
00953 {
00954   /* Outer loop repeats once for each marker. */
00955   for (;;) {
00956     /* Collect the marker proper, unless we already did. */
00957     /* NB: first_marker() enforces the requirement that SOI appear first. */
00958     if (cinfo->unread_marker == 0) {
00959       if (! cinfo->marker->saw_SOI) {
00960        if (! first_marker(cinfo))
00961          return JPEG_SUSPENDED;
00962       } else {
00963        if (! next_marker(cinfo))
00964          return JPEG_SUSPENDED;
00965       }
00966     }
00967     /* At this point cinfo->unread_marker contains the marker code and the
00968      * input point is just past the marker proper, but before any parameters.
00969      * A suspension will cause us to return with this state still true.
00970      */
00971     switch (cinfo->unread_marker) {
00972     case M_SOI:
00973       if (! get_soi(cinfo))
00974        return JPEG_SUSPENDED;
00975       break;
00976 
00977     case M_SOF0:            /* Baseline */
00978     case M_SOF1:            /* Extended sequential, Huffman */
00979       if (! get_sof(cinfo, FALSE, FALSE))
00980        return JPEG_SUSPENDED;
00981       break;
00982 
00983     case M_SOF2:            /* Progressive, Huffman */
00984       if (! get_sof(cinfo, TRUE, FALSE))
00985        return JPEG_SUSPENDED;
00986       break;
00987 
00988     case M_SOF9:            /* Extended sequential, arithmetic */
00989       if (! get_sof(cinfo, FALSE, TRUE))
00990        return JPEG_SUSPENDED;
00991       break;
00992 
00993     case M_SOF10:           /* Progressive, arithmetic */
00994       if (! get_sof(cinfo, TRUE, TRUE))
00995        return JPEG_SUSPENDED;
00996       break;
00997 
00998     /* Currently unsupported SOFn types */
00999     case M_SOF3:            /* Lossless, Huffman */
01000     case M_SOF5:            /* Differential sequential, Huffman */
01001     case M_SOF6:            /* Differential progressive, Huffman */
01002     case M_SOF7:            /* Differential lossless, Huffman */
01003     case M_JPG:                    /* Reserved for JPEG extensions */
01004     case M_SOF11:           /* Lossless, arithmetic */
01005     case M_SOF13:           /* Differential sequential, arithmetic */
01006     case M_SOF14:           /* Differential progressive, arithmetic */
01007     case M_SOF15:           /* Differential lossless, arithmetic */
01008       ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);
01009       break;
01010 
01011     case M_SOS:
01012       if (! get_sos(cinfo))
01013        return JPEG_SUSPENDED;
01014       cinfo->unread_marker = 0;    /* processed the marker */
01015       return JPEG_REACHED_SOS;
01016     
01017     case M_EOI:
01018       TRACEMS(cinfo, 1, JTRC_EOI);
01019       cinfo->unread_marker = 0;    /* processed the marker */
01020       return JPEG_REACHED_EOI;
01021       
01022     case M_DAC:
01023       if (! get_dac(cinfo))
01024        return JPEG_SUSPENDED;
01025       break;
01026       
01027     case M_DHT:
01028       if (! get_dht(cinfo))
01029        return JPEG_SUSPENDED;
01030       break;
01031       
01032     case M_DQT:
01033       if (! get_dqt(cinfo))
01034        return JPEG_SUSPENDED;
01035       break;
01036       
01037     case M_DRI:
01038       if (! get_dri(cinfo))
01039        return JPEG_SUSPENDED;
01040       break;
01041       
01042     case M_APP0:
01043     case M_APP1:
01044     case M_APP2:
01045     case M_APP3:
01046     case M_APP4:
01047     case M_APP5:
01048     case M_APP6:
01049     case M_APP7:
01050     case M_APP8:
01051     case M_APP9:
01052     case M_APP10:
01053     case M_APP11:
01054     case M_APP12:
01055     case M_APP13:
01056     case M_APP14:
01057     case M_APP15:
01058       if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[
01059               cinfo->unread_marker - (int) M_APP0]) (cinfo))
01060        return JPEG_SUSPENDED;
01061       break;
01062       
01063     case M_COM:
01064       if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
01065        return JPEG_SUSPENDED;
01066       break;
01067 
01068     case M_RST0:            /* these are all parameterless */
01069     case M_RST1:
01070     case M_RST2:
01071     case M_RST3:
01072     case M_RST4:
01073     case M_RST5:
01074     case M_RST6:
01075     case M_RST7:
01076     case M_TEM:
01077       TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);
01078       break;
01079 
01080     case M_DNL:                    /* Ignore DNL ... perhaps the wrong thing */
01081       if (! skip_variable(cinfo))
01082        return JPEG_SUSPENDED;
01083       break;
01084 
01085     default:                /* must be DHP, EXP, JPGn, or RESn */
01086       /* For now, we treat the reserved markers as fatal errors since they are
01087        * likely to be used to signal incompatible JPEG Part 3 extensions.
01088        * Once the JPEG 3 version-number marker is well defined, this code
01089        * ought to change!
01090        */
01091       ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
01092       break;
01093     }
01094     /* Successfully processed marker, so reset state variable */
01095     cinfo->unread_marker = 0;
01096   } /* end loop */
01097 }
01098 
01099 
01100 /*
01101  * Read a restart marker, which is expected to appear next in the datastream;
01102  * if the marker is not there, take appropriate recovery action.
01103  * Returns FALSE if suspension is required.
01104  *
01105  * This is called by the entropy decoder after it has read an appropriate
01106  * number of MCUs.  cinfo->unread_marker may be nonzero if the entropy decoder
01107  * has already read a marker from the data source.  Under normal conditions
01108  * cinfo->unread_marker will be reset to 0 before returning; if not reset,
01109  * it holds a marker which the decoder will be unable to read past.
01110  */
01111 
01112 METHODDEF(boolean)
01113 read_restart_marker (j_decompress_ptr cinfo)
01114 {
01115   /* Obtain a marker unless we already did. */
01116   /* Note that next_marker will complain if it skips any data. */
01117   if (cinfo->unread_marker == 0) {
01118     if (! next_marker(cinfo))
01119       return FALSE;
01120   }
01121 
01122   if (cinfo->unread_marker ==
01123       ((int) M_RST0 + cinfo->marker->next_restart_num)) {
01124     /* Normal case --- swallow the marker and let entropy decoder continue */
01125     TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);
01126     cinfo->unread_marker = 0;
01127   } else {
01128     /* Uh-oh, the restart markers have been messed up. */
01129     /* Let the data source manager determine how to resync. */
01130     if (! (*cinfo->src->resync_to_restart) (cinfo,
01131                                        cinfo->marker->next_restart_num))
01132       return FALSE;
01133   }
01134 
01135   /* Update next-restart state */
01136   cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;
01137 
01138   return TRUE;
01139 }
01140 
01141 
01142 /*
01143  * This is the default resync_to_restart method for data source managers
01144  * to use if they don't have any better approach.  Some data source managers
01145  * may be able to back up, or may have additional knowledge about the data
01146  * which permits a more intelligent recovery strategy; such managers would
01147  * presumably supply their own resync method.
01148  *
01149  * read_restart_marker calls resync_to_restart if it finds a marker other than
01150  * the restart marker it was expecting.  (This code is *not* used unless
01151  * a nonzero restart interval has been declared.)  cinfo->unread_marker is
01152  * the marker code actually found (might be anything, except 0 or FF).
01153  * The desired restart marker number (0..7) is passed as a parameter.
01154  * This routine is supposed to apply whatever error recovery strategy seems
01155  * appropriate in order to position the input stream to the next data segment.
01156  * Note that cinfo->unread_marker is treated as a marker appearing before
01157  * the current data-source input point; usually it should be reset to zero
01158  * before returning.
01159  * Returns FALSE if suspension is required.
01160  *
01161  * This implementation is substantially constrained by wanting to treat the
01162  * input as a data stream; this means we can't back up.  Therefore, we have
01163  * only the following actions to work with:
01164  *   1. Simply discard the marker and let the entropy decoder resume at next
01165  *      byte of file.
01166  *   2. Read forward until we find another marker, discarding intervening
01167  *      data.  (In theory we could look ahead within the current bufferload,
01168  *      without having to discard data if we don't find the desired marker.
01169  *      This idea is not implemented here, in part because it makes behavior
01170  *      dependent on buffer size and chance buffer-boundary positions.)
01171  *   3. Leave the marker unread (by failing to zero cinfo->unread_marker).
01172  *      This will cause the entropy decoder to process an empty data segment,
01173  *      inserting dummy zeroes, and then we will reprocess the marker.
01174  *
01175  * #2 is appropriate if we think the desired marker lies ahead, while #3 is
01176  * appropriate if the found marker is a future restart marker (indicating
01177  * that we have missed the desired restart marker, probably because it got
01178  * corrupted).
01179  * We apply #2 or #3 if the found marker is a restart marker no more than
01180  * two counts behind or ahead of the expected one.  We also apply #2 if the
01181  * found marker is not a legal JPEG marker code (it's certainly bogus data).
01182  * If the found marker is a restart marker more than 2 counts away, we do #1
01183  * (too much risk that the marker is erroneous; with luck we will be able to
01184  * resync at some future point).
01185  * For any valid non-restart JPEG marker, we apply #3.  This keeps us from
01186  * overrunning the end of a scan.  An implementation limited to single-scan
01187  * files might find it better to apply #2 for markers other than EOI, since
01188  * any other marker would have to be bogus data in that case.
01189  */
01190 
01191 GLOBAL(boolean)
01192 jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
01193 {
01194   int marker = cinfo->unread_marker;
01195   int action = 1;
01196   
01197   /* Always put up a warning. */
01198   WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);
01199   
01200   /* Outer loop handles repeated decision after scanning forward. */
01201   for (;;) {
01202     if (marker < (int) M_SOF0)
01203       action = 2;           /* invalid marker */
01204     else if (marker < (int) M_RST0 || marker > (int) M_RST7)
01205       action = 3;           /* valid non-restart marker */
01206     else {
01207       if (marker == ((int) M_RST0 + ((desired+1) & 7)) ||
01208          marker == ((int) M_RST0 + ((desired+2) & 7)))
01209        action = 3;          /* one of the next two expected restarts */
01210       else if (marker == ((int) M_RST0 + ((desired-1) & 7)) ||
01211               marker == ((int) M_RST0 + ((desired-2) & 7)))
01212        action = 2;          /* a prior restart, so advance */
01213       else
01214        action = 1;          /* desired restart or too far away */
01215     }
01216     TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);
01217     switch (action) {
01218     case 1:
01219       /* Discard marker and let entropy decoder resume processing. */
01220       cinfo->unread_marker = 0;
01221       return TRUE;
01222     case 2:
01223       /* Scan to the next marker, and repeat the decision loop. */
01224       if (! next_marker(cinfo))
01225        return FALSE;
01226       marker = cinfo->unread_marker;
01227       break;
01228     case 3:
01229       /* Return without advancing past this marker. */
01230       /* Entropy decoder will be forced to process an empty segment. */
01231       return TRUE;
01232     }
01233   } /* end loop */
01234 }
01235 
01236 
01237 /*
01238  * Reset marker processing state to begin a fresh datastream.
01239  */
01240 
01241 METHODDEF(void)
01242 reset_marker_reader (j_decompress_ptr cinfo)
01243 {
01244   my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
01245 
01246   cinfo->comp_info = NULL;         /* until allocated by get_sof */
01247   cinfo->input_scan_number = 0;           /* no SOS seen yet */
01248   cinfo->unread_marker = 0;        /* no pending marker */
01249   marker->pub.saw_SOI = FALSE;            /* set internal state too */
01250   marker->pub.saw_SOF = FALSE;
01251   marker->pub.discarded_bytes = 0;
01252   marker->cur_marker = NULL;
01253 }
01254 
01255 
01256 /*
01257  * Initialize the marker reader module.
01258  * This is called only once, when the decompression object is created.
01259  */
01260 
01261 GLOBAL(void)
01262 jinit_marker_reader (j_decompress_ptr cinfo)
01263 {
01264   my_marker_ptr marker;
01265   int i;
01266 
01267   /* Create subobject in permanent pool */
01268   marker = (my_marker_ptr)
01269     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
01270                             SIZEOF(my_marker_reader));
01271   cinfo->marker = (struct jpeg_marker_reader *) marker;
01272   /* Initialize public method pointers */
01273   marker->pub.reset_marker_reader = reset_marker_reader;
01274   marker->pub.read_markers = read_markers;
01275   marker->pub.read_restart_marker = read_restart_marker;
01276   /* Initialize COM/APPn processing.
01277    * By default, we examine and then discard APP0 and APP14,
01278    * but simply discard COM and all other APPn.
01279    */
01280   marker->process_COM = skip_variable;
01281   marker->length_limit_COM = 0;
01282   for (i = 0; i < 16; i++) {
01283     marker->process_APPn[i] = skip_variable;
01284     marker->length_limit_APPn[i] = 0;
01285   }
01286   marker->process_APPn[0] = get_interesting_appn;
01287   marker->process_APPn[14] = get_interesting_appn;
01288   /* Reset marker processing state */
01289   reset_marker_reader(cinfo);
01290 }
01291 
01292 
01293 /*
01294  * Control saving of COM and APPn markers into marker_list.
01295  */
01296 
01297 #ifdef SAVE_MARKERS_SUPPORTED
01298 
01299 GLOBAL(void)
01300 jpeg_save_markers (j_decompress_ptr cinfo, int marker_code,
01301                  unsigned int length_limit)
01302 {
01303   my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
01304   long maxlength;
01305   jpeg_marker_parser_method processor;
01306 
01307   /* Length limit mustn't be larger than what we can allocate
01308    * (should only be a concern in a 16-bit environment).
01309    */
01310   maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct);
01311   if (((long) length_limit) > maxlength)
01312     length_limit = (unsigned int) maxlength;
01313 
01314   /* Choose processor routine to use.
01315    * APP0/APP14 have special requirements.
01316    */
01317   if (length_limit) {
01318     processor = save_marker;
01319     /* If saving APP0/APP14, save at least enough for our internal use. */
01320     if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)
01321       length_limit = APP0_DATA_LEN;
01322     else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)
01323       length_limit = APP14_DATA_LEN;
01324   } else {
01325     processor = skip_variable;
01326     /* If discarding APP0/APP14, use our regular on-the-fly processor. */
01327     if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)
01328       processor = get_interesting_appn;
01329   }
01330 
01331   if (marker_code == (int) M_COM) {
01332     marker->process_COM = processor;
01333     marker->length_limit_COM = length_limit;
01334   } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {
01335     marker->process_APPn[marker_code - (int) M_APP0] = processor;
01336     marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;
01337   } else
01338     ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
01339 }
01340 
01341 #endif /* SAVE_MARKERS_SUPPORTED */
01342 
01343 
01344 /*
01345  * Install a special processing method for COM or APPn markers.
01346  */
01347 
01348 GLOBAL(void)
01349 jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
01350                         jpeg_marker_parser_method routine)
01351 {
01352   my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
01353 
01354   if (marker_code == (int) M_COM)
01355     marker->process_COM = routine;
01356   else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)
01357     marker->process_APPn[marker_code - (int) M_APP0] = routine;
01358   else
01359     ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
01360 }