LCOV - code coverage report
Current view: directory - media/libjpeg - jdmarker.c (source / functions) Found Hit Coverage
Test: app.info Lines: 493 306 62.1 %
Date: 2012-06-02 Functions: 20 14 70.0 %

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

Generated by: LCOV version 1.7