jdmarker.c revision 0
0N/A * reserved comment block 0N/A * DO NOT REMOVE OR ALTER! 0N/A * Copyright (C) 1991-1998, Thomas G. Lane. 0N/A * This file is part of the Independent JPEG Group's software. 0N/A * For conditions of distribution and use, see the accompanying README file. 0N/A * This file contains routines to decode JPEG datastream markers. 0N/A * Most of the complexity arises from our desire to support input 0N/A * suspension: if not all of the data for a marker is available, 0N/A * we must exit back to the application. On resumption, we reprocess 0N/Atypedef enum {
/* JPEG marker codes */ 0N/A /* Application-overridable marker processing methods */ 0N/A /* Limit on marker data length to save for each marker type */ 0N/A /* Note: cur_marker is not linked into marker_list until it's all read. */ 0N/A * Macros for fetching data from the data source module. 0N/A * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect 0N/A * the current restart point; we update them only when we have reached a 0N/A * suitable place to restart if a suspension occurs. 0N/A/* Unload the local copies --- do this only at a restart boundary */ 0N/A/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */ 0N/A/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available. 0N/A * Note we do *not* do INPUT_SYNC before calling fill_input_buffer, 0N/A * but we must reload the local copies after a successful fill. 0N/A/* Read a byte into variable V. 0N/A * If must suspend, take the specified action (typically "return FALSE"). 0N/A/* As above, but read two bytes interpreted as an unsigned 16-bit integer. 0N/A * V should be declared unsigned int or perhaps INT32. 0N/A * Routines to process JPEG markers. 0N/A * Entry condition: JPEG marker itself has been read and its code saved 0N/A * in cinfo->unread_marker; input restart point is just after the marker. 0N/A * Exit: if return TRUE, have read and processed any parameters, and have 0N/A * updated the restart point to point after the parameters. 0N/A * If return FALSE, was forced to suspend before reaching end of 0N/A * marker parameters; restart point has not been moved. Same routine 0N/A * will be called again after application supplies more input data. 0N/A * This approach to suspension assumes that all of a marker's parameters 0N/A * can fit into a single input bufferload. This should hold for "normal" 0N/A * markers. Some COM/APPn markers might have large parameter segments 0N/A * that might not fit. If we are simply dropping such a marker, we use 0N/A * skip_input_data to get past it, and thereby put the problem on the 0N/A * source manager's shoulders. If we are saving the marker's contents 0N/A * into memory, we use a slightly different convention: when forced to 0N/A * suspend, the marker processor updates the restart point to the end of 0N/A * what it's consumed (ie, the end of the buffer) before returning FALSE. 0N/A * On resumption, cinfo->unread_marker still contains the marker code, 0N/A * but the data source will point to the next chunk of marker data. 0N/A * The marker processor must retain internal state to deal with this. 0N/A * Note that we don't bother to avoid duplicate trace messages if a 0N/A * suspension occurs within marker parameters. Other side effects 0N/A * require more care. 0N/A/* Process an SOI marker */ 0N/A /* Reset all parameters that are defined to be reset by SOI */ 0N/A /* Set initial assumptions for colorspace etc */ 0N/A/* Process a SOFn marker */ 0N/A /* We don't support files in which the image height is initially specified */ 0N/A /* as 0 and is later redefined by DNL. As long as we have to check that, */ 0N/A /* might as well have a general sanity check. */ 0N/A/* Process a SOS marker */ 0N/A /* Collect the component-spec parameters */ 0N/A for (i = 0; i < n; i++) {
0N/A /* Collect the additional scan parameters Ss, Se, Ah/Al. */ 0N/A /* Prepare to scan data & restart markers */ 0N/A /* Count another SOS marker */ 0N/A/* Process a DAC marker */ 0N/A }
else {
/* define DC table */ 0N/A#
else /* ! D_ARITH_CODING_SUPPORTED */ 0N/A#
endif /* D_ARITH_CODING_SUPPORTED */ 0N/A/* Process a DHT marker */ 0N/A for (i =
1; i <=
16; i++) {
0N/A /* Here we just do minimal validation of the counts to avoid walking 0N/A * off the end of our table space. jdhuff.c will check more carefully. 0N/A if (
index &
0x10) {
/* AC table definition */ 0N/A }
else {
/* DC table definition */ 0N/A/* Process a DQT marker */ 0N/A /* We convert the zigzag-order table to natural array order. */ 0N/A/* Process a DRI marker */ 0N/A * Routines for processing APPn and COM markers. 0N/A * These are either saved in memory or discarded, per application request. 0N/A * APP0 and APP14 are specially checked to see if they are 0N/A * JFIF and Adobe markers, respectively. 0N/A/* Examine first few bytes from an APP0. 0N/A * Take appropriate action if it is a JFIF marker. 0N/A * datalen is # of bytes at data[], remaining is length of rest of marker data. 0N/A /* Found JFIF APP0 marker: save info */ 0N/A * Major version must be 1, anything else signals an incompatible change. 0N/A * (We used to treat this as an error, but now it's a nonfatal warning, 0N/A * because some bozo at Hijaak couldn't read the spec.) 0N/A * Minor version should be 0..2, but process anyway if newer. 0N/A /* Generate trace messages */ 0N/A /* Validate thumbnail dimensions and issue appropriate messages */ 0N/A /* Found JFIF "JFXX" extension APP0 marker */ 0N/A /* The library doesn't actually do anything with these, 0N/A * but we try to produce a helpful trace message. 0N/A /* Start of APP0 does not match "JFIF" or "JFXX", or too short */ 0N/A * In this case we have seen the APP0 marker but the remaining 0N/A * APP0 section may be corrupt. Regardless, we will set the 0N/A * saw_JFIF_marker flag as it is important for making the 0N/A * correct choice of JPEG color space later (we will assume 0N/A * YCbCr in this case). The version and density fields will 0N/A * contain default values, which should be sufficient for our needs. 0N/A/* Examine first few bytes from an APP14. 0N/A * Take appropriate action if it is an Adobe marker. 0N/A * datalen is # of bytes at data[], remaining is length of rest of marker data. 0N/A /* Found Adobe APP14 marker */ 0N/A /* Start of APP14 does not match "Adobe", or too short */ 0N/A/* Process an APP0 or APP14 marker without saving it */ 0N/A /* get the interesting part of the marker data */ 0N/A /* can't get here unless jpeg_save_markers chooses wrong processor */ 0N/A /* skip any remaining data -- could be lots */ 0N/A/* Save an APPn or COM marker into the marker list */ 0N/A /* begin reading a marker */ 0N/A if (
length >= 0) {
/* watch out for bogus length word */ 0N/A /* figure out how much we want to save */ 0N/A /* allocate and initialize the marker item */ 0N/A /* data area is just beyond the jpeg_marker_struct */ 0N/A /* deal with bogus length word */ 0N/A /* resume reading a marker */ 0N/A /* If there's not at least one byte in buffer, suspend */ 0N/A /* Copy bytes with reasonable rapidity */ 0N/A /* Done reading what we want to read */ 0N/A /* Add new marker to end of list */ 0N/A /* Reset pointer & calc remaining data length */ 0N/A /* Reset to initial state for next marker */ 0N/A /* Process the marker if interesting; else just make a generic trace msg */ 0N/A /* skip any remaining data -- could be lots */ 0N/A#
endif /* SAVE_MARKERS_SUPPORTED */ 0N/A/* Skip over an unknown or uninteresting variable-length marker */ 0N/A * Find the next JPEG marker, save it in cinfo->unread_marker. 0N/A * Returns FALSE if had to suspend before reaching a marker; 0N/A * in that case cinfo->unread_marker is unchanged. 0N/A * Note that the result might not be a valid marker code, 0N/A * but it will never be 0 or FF. 0N/A /* Skip any non-FF bytes. 0N/A * This may look a bit inefficient, but it will not occur in a valid file. 0N/A * We sync after each discarded byte so that a suspending data source 0N/A * can discard the byte from its buffer. 0N/A /* This loop swallows any duplicate FF bytes. Extra FFs are legal as 0N/A * pad bytes, so don't count them in discarded_bytes. We assume there 0N/A * will not be so many consecutive FF bytes as to overflow a suspending 0N/A * data source's input buffer. 0N/A }
while (c ==
0xFF);
0N/A break;
/* found a valid marker, exit loop */ 0N/A /* Reach here if we found a stuffed-zero data sequence (FF/00). 0N/A * Discard it and loop back to try again. 0N/A/* Like next_marker, but used to obtain the initial SOI marker. */ 0N/A/* For this marker, we do not allow preceding garbage or fill; otherwise, 0N/A * we might well scan an entire input file before realizing it ain't JPEG. 0N/A * If an application wants to process non-JFIF files, it must seek to the 0N/A * SOI before calling the JPEG library. 0N/A * Read markers until SOS or EOI. 0N/A * Returns same codes as are defined for jpeg_consume_input: 0N/A * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. 0N/A /* Outer loop repeats once for each marker. */ 0N/A /* Collect the marker proper, unless we already did. */ 0N/A /* NB: first_marker() enforces the requirement that SOI appear first. */ 0N/A /* At this point cinfo->unread_marker contains the marker code and the 0N/A * input point is just past the marker proper, but before any parameters. 0N/A * A suspension will cause us to return with this state still true. 0N/A case M_SOF1:
/* Extended sequential, Huffman */ 0N/A case M_SOF9:
/* Extended sequential, arithmetic */ 0N/A /* Currently unsupported SOFn types */ 0N/A case M_SOF5:
/* Differential sequential, Huffman */ 0N/A case M_SOF6:
/* Differential progressive, Huffman */ 0N/A case M_SOF7:
/* Differential lossless, Huffman */ 0N/A case M_JPG:
/* Reserved for JPEG extensions */ 0N/A case M_SOF13:
/* Differential sequential, arithmetic */ 0N/A case M_SOF14:
/* Differential progressive, arithmetic */ 0N/A case M_SOF15:
/* Differential lossless, arithmetic */ 0N/A case M_RST0:
/* these are all parameterless */ 0N/A case M_DNL:
/* Ignore DNL ... perhaps the wrong thing */ 0N/A default:
/* must be DHP, EXP, JPGn, or RESn */ 0N/A /* For now, we treat the reserved markers as fatal errors since they are 0N/A * likely to be used to signal incompatible JPEG Part 3 extensions. 0N/A * Once the JPEG 3 version-number marker is well defined, this code 0N/A * [To be behaviorally compatible with other popular image display 0N/A * applications, we are now treating these unknown markers as warnings, 0N/A * rather than errors. This allows processing to continue, although 0N/A * any portions of the image after the bad marker may be corrupted 0N/A /* Successfully processed marker, so reset state variable */ 0N/A * Read a restart marker, which is expected to appear next in the datastream; 0N/A * if the marker is not there, take appropriate recovery action. 0N/A * Returns FALSE if suspension is required. 0N/A * This is called by the entropy decoder after it has read an appropriate 0N/A * number of MCUs. cinfo->unread_marker may be nonzero if the entropy decoder 0N/A * has already read a marker from the data source. Under normal conditions 0N/A * cinfo->unread_marker will be reset to 0 before returning; if not reset, 0N/A * it holds a marker which the decoder will be unable to read past. 0N/A /* Obtain a marker unless we already did. */ 0N/A /* Note that next_marker will complain if it skips any data. */ 0N/A /* Normal case --- swallow the marker and let entropy decoder continue */ 0N/A /* Uh-oh, the restart markers have been messed up. */ 0N/A /* Let the data source manager determine how to resync. */ 0N/A /* Update next-restart state */ 0N/A * This is the default resync_to_restart method for data source managers 0N/A * to use if they don't have any better approach. Some data source managers 0N/A * may be able to back up, or may have additional knowledge about the data 0N/A * which permits a more intelligent recovery strategy; such managers would 0N/A * presumably supply their own resync method. 0N/A * read_restart_marker calls resync_to_restart if it finds a marker other than 0N/A * the restart marker it was expecting. (This code is *not* used unless 0N/A * a nonzero restart interval has been declared.) cinfo->unread_marker is 0N/A * the marker code actually found (might be anything, except 0 or FF). 0N/A * The desired restart marker number (0..7) is passed as a parameter. 0N/A * This routine is supposed to apply whatever error recovery strategy seems 0N/A * appropriate in order to position the input stream to the next data segment. 0N/A * Note that cinfo->unread_marker is treated as a marker appearing before 0N/A * the current data-source input point; usually it should be reset to zero 0N/A * Returns FALSE if suspension is required. 0N/A * This implementation is substantially constrained by wanting to treat the 0N/A * input as a data stream; this means we can't back up. Therefore, we have 0N/A * only the following actions to work with: 0N/A * 1. Simply discard the marker and let the entropy decoder resume at next 0N/A * 2. Read forward until we find another marker, discarding intervening 0N/A * data. (In theory we could look ahead within the current bufferload, 0N/A * without having to discard data if we don't find the desired marker. 0N/A * This idea is not implemented here, in part because it makes behavior 0N/A * dependent on buffer size and chance buffer-boundary positions.) 0N/A * 3. Leave the marker unread (by failing to zero cinfo->unread_marker). 0N/A * This will cause the entropy decoder to process an empty data segment, 0N/A * inserting dummy zeroes, and then we will reprocess the marker. 0N/A * #2 is appropriate if we think the desired marker lies ahead, while #3 is 0N/A * appropriate if the found marker is a future restart marker (indicating 0N/A * that we have missed the desired restart marker, probably because it got 0N/A * We apply #2 or #3 if the found marker is a restart marker no more than 0N/A * two counts behind or ahead of the expected one. We also apply #2 if the 0N/A * found marker is not a legal JPEG marker code (it's certainly bogus data). 0N/A * If the found marker is a restart marker more than 2 counts away, we do #1 0N/A * (too much risk that the marker is erroneous; with luck we will be able to 0N/A * resync at some future point). 0N/A * For any valid non-restart JPEG marker, we apply #3. This keeps us from 0N/A * overrunning the end of a scan. An implementation limited to single-scan 0N/A * files might find it better to apply #2 for markers other than EOI, since 0N/A * any other marker would have to be bogus data in that case. 0N/A /* Always put up a warning. */ 0N/A /* Outer loop handles repeated decision after scanning forward. */ 0N/A action =
3;
/* one of the next two expected restarts */ 0N/A action =
2;
/* a prior restart, so advance */ 0N/A action =
1;
/* desired restart or too far away */ 0N/A /* Discard marker and let entropy decoder resume processing. */ 0N/A /* Scan to the next marker, and repeat the decision loop. */ 0N/A /* Return without advancing past this marker. */ 0N/A /* Entropy decoder will be forced to process an empty segment. */ 0N/A * Reset marker processing state to begin a fresh datastream. 0N/A * Initialize the marker reader module. 0N/A * This is called only once, when the decompression object is created. 0N/A /* Create subobject in permanent pool */ 0N/A /* Initialize public method pointers */ 0N/A * By default, we examine and then discard APP0 and APP14. 0N/A * We also may need to save APP1 to detect the case of EXIF images (see 4881314). 0N/A * COM and all other APPn are simply discarded. 0N/A for (i = 0; i <
16; i++) {
0N/A /* Reset marker processing state */ 0N/A * Control saving of COM and APPn markers into marker_list. 0N/A /* Length limit mustn't be larger than what we can allocate 0N/A * (should only be a concern in a 16-bit environment). 0N/A /* Choose processor routine to use. 0N/A /* If saving APP0/APP14, save at least enough for our internal use. */ 0N/A /* If discarding APP0/APP14, use our regular on-the-fly processor. */ 0N/A#
endif /* SAVE_MARKERS_SUPPORTED */ 0N/A * Install a special processing method for COM or APPn markers.