jdmarker.c

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

Generated on Tue Jul 5 14:13:29 2011 for ROOT_528-00b_version by  doxygen 1.5.1