Path: blob/master/src/java.desktop/share/native/libjavajpeg/jdmarker.c
41149 views
/*1* reserved comment block2* DO NOT REMOVE OR ALTER!3*/4/*5* jdmarker.c6*7* Copyright (C) 1991-1998, Thomas G. Lane.8* This file is part of the Independent JPEG Group's software.9* For conditions of distribution and use, see the accompanying README file.10*11* This file contains routines to decode JPEG datastream markers.12* Most of the complexity arises from our desire to support input13* suspension: if not all of the data for a marker is available,14* we must exit back to the application. On resumption, we reprocess15* the marker.16*/1718#define JPEG_INTERNALS19#include "jinclude.h"20#include "jpeglib.h"212223typedef enum { /* JPEG marker codes */24M_SOF0 = 0xc0,25M_SOF1 = 0xc1,26M_SOF2 = 0xc2,27M_SOF3 = 0xc3,2829M_SOF5 = 0xc5,30M_SOF6 = 0xc6,31M_SOF7 = 0xc7,3233M_JPG = 0xc8,34M_SOF9 = 0xc9,35M_SOF10 = 0xca,36M_SOF11 = 0xcb,3738M_SOF13 = 0xcd,39M_SOF14 = 0xce,40M_SOF15 = 0xcf,4142M_DHT = 0xc4,4344M_DAC = 0xcc,4546M_RST0 = 0xd0,47M_RST1 = 0xd1,48M_RST2 = 0xd2,49M_RST3 = 0xd3,50M_RST4 = 0xd4,51M_RST5 = 0xd5,52M_RST6 = 0xd6,53M_RST7 = 0xd7,5455M_SOI = 0xd8,56M_EOI = 0xd9,57M_SOS = 0xda,58M_DQT = 0xdb,59M_DNL = 0xdc,60M_DRI = 0xdd,61M_DHP = 0xde,62M_EXP = 0xdf,6364M_APP0 = 0xe0,65M_APP1 = 0xe1,66M_APP2 = 0xe2,67M_APP3 = 0xe3,68M_APP4 = 0xe4,69M_APP5 = 0xe5,70M_APP6 = 0xe6,71M_APP7 = 0xe7,72M_APP8 = 0xe8,73M_APP9 = 0xe9,74M_APP10 = 0xea,75M_APP11 = 0xeb,76M_APP12 = 0xec,77M_APP13 = 0xed,78M_APP14 = 0xee,79M_APP15 = 0xef,8081M_JPG0 = 0xf0,82M_JPG13 = 0xfd,83M_COM = 0xfe,8485M_TEM = 0x01,8687M_ERROR = 0x10088} JPEG_MARKER;899091/* Private state */9293typedef struct {94struct jpeg_marker_reader pub; /* public fields */9596/* Application-overridable marker processing methods */97jpeg_marker_parser_method process_COM;98jpeg_marker_parser_method process_APPn[16];99100/* Limit on marker data length to save for each marker type */101unsigned int length_limit_COM;102unsigned int length_limit_APPn[16];103104/* Status of COM/APPn marker saving */105jpeg_saved_marker_ptr cur_marker; /* NULL if not processing a marker */106unsigned int bytes_read; /* data bytes read so far in marker */107/* Note: cur_marker is not linked into marker_list until it's all read. */108} my_marker_reader;109110typedef my_marker_reader * my_marker_ptr;111112113/*114* Macros for fetching data from the data source module.115*116* At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect117* the current restart point; we update them only when we have reached a118* suitable place to restart if a suspension occurs.119*/120121/* Declare and initialize local copies of input pointer/count */122#define INPUT_VARS(cinfo) \123struct jpeg_source_mgr * datasrc = (cinfo)->src; \124const JOCTET * next_input_byte = datasrc->next_input_byte; \125size_t bytes_in_buffer = datasrc->bytes_in_buffer126127/* Unload the local copies --- do this only at a restart boundary */128#define INPUT_SYNC(cinfo) \129( datasrc->next_input_byte = next_input_byte, \130datasrc->bytes_in_buffer = bytes_in_buffer )131132/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */133#define INPUT_RELOAD(cinfo) \134( next_input_byte = datasrc->next_input_byte, \135bytes_in_buffer = datasrc->bytes_in_buffer )136137/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.138* Note we do *not* do INPUT_SYNC before calling fill_input_buffer,139* but we must reload the local copies after a successful fill.140*/141#define MAKE_BYTE_AVAIL(cinfo,action) \142if (bytes_in_buffer == 0) { \143if (! (*datasrc->fill_input_buffer) (cinfo)) \144{ action; } \145INPUT_RELOAD(cinfo); \146}147148/* Read a byte into variable V.149* If must suspend, take the specified action (typically "return FALSE").150*/151#define INPUT_BYTE(cinfo,V,action) \152MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \153bytes_in_buffer--; \154V = GETJOCTET(*next_input_byte++); )155156/* As above, but read two bytes interpreted as an unsigned 16-bit integer.157* V should be declared unsigned int or perhaps INT32.158*/159#define INPUT_2BYTES(cinfo,V,action) \160MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \161bytes_in_buffer--; \162V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \163MAKE_BYTE_AVAIL(cinfo,action); \164bytes_in_buffer--; \165V += GETJOCTET(*next_input_byte++); )166167168/*169* Routines to process JPEG markers.170*171* Entry condition: JPEG marker itself has been read and its code saved172* in cinfo->unread_marker; input restart point is just after the marker.173*174* Exit: if return TRUE, have read and processed any parameters, and have175* updated the restart point to point after the parameters.176* If return FALSE, was forced to suspend before reaching end of177* marker parameters; restart point has not been moved. Same routine178* will be called again after application supplies more input data.179*180* This approach to suspension assumes that all of a marker's parameters181* can fit into a single input bufferload. This should hold for "normal"182* markers. Some COM/APPn markers might have large parameter segments183* that might not fit. If we are simply dropping such a marker, we use184* skip_input_data to get past it, and thereby put the problem on the185* source manager's shoulders. If we are saving the marker's contents186* into memory, we use a slightly different convention: when forced to187* suspend, the marker processor updates the restart point to the end of188* what it's consumed (ie, the end of the buffer) before returning FALSE.189* On resumption, cinfo->unread_marker still contains the marker code,190* but the data source will point to the next chunk of marker data.191* The marker processor must retain internal state to deal with this.192*193* Note that we don't bother to avoid duplicate trace messages if a194* suspension occurs within marker parameters. Other side effects195* require more care.196*/197198199LOCAL(boolean)200get_soi (j_decompress_ptr cinfo)201/* Process an SOI marker */202{203int i;204205TRACEMS(cinfo, 1, JTRC_SOI);206207if (cinfo->marker->saw_SOI)208ERREXIT(cinfo, JERR_SOI_DUPLICATE);209210/* Reset all parameters that are defined to be reset by SOI */211212for (i = 0; i < NUM_ARITH_TBLS; i++) {213cinfo->arith_dc_L[i] = 0;214cinfo->arith_dc_U[i] = 1;215cinfo->arith_ac_K[i] = 5;216}217cinfo->restart_interval = 0;218219/* Set initial assumptions for colorspace etc */220221cinfo->jpeg_color_space = JCS_UNKNOWN;222cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */223224cinfo->saw_JFIF_marker = FALSE;225cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */226cinfo->JFIF_minor_version = 1;227cinfo->density_unit = 0;228cinfo->X_density = 1;229cinfo->Y_density = 1;230cinfo->saw_Adobe_marker = FALSE;231cinfo->Adobe_transform = 0;232233cinfo->marker->saw_SOI = TRUE;234235return TRUE;236}237238239LOCAL(boolean)240get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)241/* Process a SOFn marker */242{243INT32 length;244int c, ci;245jpeg_component_info * compptr;246INPUT_VARS(cinfo);247248cinfo->progressive_mode = is_prog;249cinfo->arith_code = is_arith;250251INPUT_2BYTES(cinfo, length, return FALSE);252253INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);254INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE);255INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE);256INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);257258length -= 8;259260TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,261(int) cinfo->image_width, (int) cinfo->image_height,262cinfo->num_components);263264if (cinfo->marker->saw_SOF)265ERREXIT(cinfo, JERR_SOF_DUPLICATE);266267/* We don't support files in which the image height is initially specified */268/* as 0 and is later redefined by DNL. As long as we have to check that, */269/* might as well have a general sanity check. */270if (cinfo->image_height <= 0 || cinfo->image_width <= 0271|| cinfo->num_components <= 0)272ERREXIT(cinfo, JERR_EMPTY_IMAGE);273274if (length != (cinfo->num_components * 3))275ERREXIT(cinfo, JERR_BAD_LENGTH);276277if (cinfo->comp_info == NULL) { /* do only once, even if suspend */278cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)279((j_common_ptr) cinfo, JPOOL_IMAGE,280cinfo->num_components * SIZEOF(jpeg_component_info));281MEMZERO(cinfo->comp_info,282cinfo->num_components * SIZEOF(jpeg_component_info));283}284285for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;286ci++, compptr++) {287compptr->component_index = ci;288INPUT_BYTE(cinfo, compptr->component_id, return FALSE);289INPUT_BYTE(cinfo, c, return FALSE);290compptr->h_samp_factor = (c >> 4) & 15;291compptr->v_samp_factor = (c ) & 15;292INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);293294TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,295compptr->component_id, compptr->h_samp_factor,296compptr->v_samp_factor, compptr->quant_tbl_no);297}298299cinfo->marker->saw_SOF = TRUE;300301INPUT_SYNC(cinfo);302return TRUE;303}304305306LOCAL(boolean)307get_sos (j_decompress_ptr cinfo)308/* Process a SOS marker */309{310INT32 length;311int i, ci, n, c, cc;312jpeg_component_info * compptr;313INPUT_VARS(cinfo);314315if (! cinfo->marker->saw_SOF)316ERREXIT(cinfo, JERR_SOS_NO_SOF);317318INPUT_2BYTES(cinfo, length, return FALSE);319320INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */321322TRACEMS1(cinfo, 1, JTRC_SOS, n);323324if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)325ERREXIT(cinfo, JERR_BAD_LENGTH);326327cinfo->comps_in_scan = n;328329/* Collect the component-spec parameters */330331for (i = 0; i < n; i++) {332INPUT_BYTE(cinfo, cc, return FALSE);333INPUT_BYTE(cinfo, c, return FALSE);334335for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;336ci++, compptr++) {337if (cc == compptr->component_id)338goto id_found;339}340341ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);342343id_found:344345cinfo->cur_comp_info[i] = compptr;346compptr->dc_tbl_no = (c >> 4) & 15;347compptr->ac_tbl_no = (c ) & 15;348349TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,350compptr->dc_tbl_no, compptr->ac_tbl_no);351352/* This CSi (cc) should differ from the previous CSi */353for (ci = 0; ci < i; ci++) {354if (cinfo->cur_comp_info[ci] == compptr)355ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);356}357}358359/* Collect the additional scan parameters Ss, Se, Ah/Al. */360INPUT_BYTE(cinfo, c, return FALSE);361cinfo->Ss = c;362INPUT_BYTE(cinfo, c, return FALSE);363cinfo->Se = c;364INPUT_BYTE(cinfo, c, return FALSE);365cinfo->Ah = (c >> 4) & 15;366cinfo->Al = (c ) & 15;367368TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,369cinfo->Ah, cinfo->Al);370371/* Prepare to scan data & restart markers */372cinfo->marker->next_restart_num = 0;373374/* Count another SOS marker */375cinfo->input_scan_number++;376377INPUT_SYNC(cinfo);378return TRUE;379}380381382#ifdef D_ARITH_CODING_SUPPORTED383384LOCAL(boolean)385get_dac (j_decompress_ptr cinfo)386/* Process a DAC marker */387{388INT32 length;389int index, val;390INPUT_VARS(cinfo);391392INPUT_2BYTES(cinfo, length, return FALSE);393length -= 2;394395while (length > 0) {396INPUT_BYTE(cinfo, index, return FALSE);397INPUT_BYTE(cinfo, val, return FALSE);398399length -= 2;400401TRACEMS2(cinfo, 1, JTRC_DAC, index, val);402403if (index < 0 || index >= (2*NUM_ARITH_TBLS))404ERREXIT1(cinfo, JERR_DAC_INDEX, index);405406if (index >= NUM_ARITH_TBLS) { /* define AC table */407cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;408} else { /* define DC table */409cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);410cinfo->arith_dc_U[index] = (UINT8) (val >> 4);411if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])412ERREXIT1(cinfo, JERR_DAC_VALUE, val);413}414}415416if (length != 0)417ERREXIT(cinfo, JERR_BAD_LENGTH);418419INPUT_SYNC(cinfo);420return TRUE;421}422423#else /* ! D_ARITH_CODING_SUPPORTED */424425#define get_dac(cinfo) skip_variable(cinfo)426427#endif /* D_ARITH_CODING_SUPPORTED */428429430LOCAL(boolean)431get_dht (j_decompress_ptr cinfo)432/* Process a DHT marker */433{434INT32 length;435UINT8 bits[17];436UINT8 huffval[256];437int i, index, count;438JHUFF_TBL **htblptr;439INPUT_VARS(cinfo);440441INPUT_2BYTES(cinfo, length, return FALSE);442length -= 2;443444while (length > 16) {445INPUT_BYTE(cinfo, index, return FALSE);446447TRACEMS1(cinfo, 1, JTRC_DHT, index);448449bits[0] = 0;450count = 0;451for (i = 1; i <= 16; i++) {452INPUT_BYTE(cinfo, bits[i], return FALSE);453count += bits[i];454}455456length -= 1 + 16;457458TRACEMS8(cinfo, 2, JTRC_HUFFBITS,459bits[1], bits[2], bits[3], bits[4],460bits[5], bits[6], bits[7], bits[8]);461TRACEMS8(cinfo, 2, JTRC_HUFFBITS,462bits[9], bits[10], bits[11], bits[12],463bits[13], bits[14], bits[15], bits[16]);464465/* Here we just do minimal validation of the counts to avoid walking466* off the end of our table space. jdhuff.c will check more carefully.467*/468if (count > 256 || ((INT32) count) > length)469ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);470471for (i = 0; i < count; i++)472INPUT_BYTE(cinfo, huffval[i], return FALSE);473474length -= count;475476if (index & 0x10) { /* AC table definition */477index -= 0x10;478htblptr = &cinfo->ac_huff_tbl_ptrs[index];479} else { /* DC table definition */480htblptr = &cinfo->dc_huff_tbl_ptrs[index];481}482483if (index < 0 || index >= NUM_HUFF_TBLS)484ERREXIT1(cinfo, JERR_DHT_INDEX, index);485486if (*htblptr == NULL)487*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);488489MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));490MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));491}492493if (length != 0)494ERREXIT(cinfo, JERR_BAD_LENGTH);495496INPUT_SYNC(cinfo);497return TRUE;498}499500501LOCAL(boolean)502get_dqt (j_decompress_ptr cinfo)503/* Process a DQT marker */504{505INT32 length;506int n, i, prec;507unsigned int tmp;508JQUANT_TBL *quant_ptr;509INPUT_VARS(cinfo);510511INPUT_2BYTES(cinfo, length, return FALSE);512length -= 2;513514while (length > 0) {515INPUT_BYTE(cinfo, n, return FALSE);516prec = n >> 4;517n &= 0x0F;518519TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);520521if (n >= NUM_QUANT_TBLS)522ERREXIT1(cinfo, JERR_DQT_INDEX, n);523524if (cinfo->quant_tbl_ptrs[n] == NULL)525cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);526quant_ptr = cinfo->quant_tbl_ptrs[n];527528for (i = 0; i < DCTSIZE2; i++) {529if (prec)530INPUT_2BYTES(cinfo, tmp, return FALSE);531else532INPUT_BYTE(cinfo, tmp, return FALSE);533/* We convert the zigzag-order table to natural array order. */534quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp;535}536537if (cinfo->err->trace_level >= 2) {538for (i = 0; i < DCTSIZE2; i += 8) {539TRACEMS8(cinfo, 2, JTRC_QUANTVALS,540quant_ptr->quantval[i], quant_ptr->quantval[i+1],541quant_ptr->quantval[i+2], quant_ptr->quantval[i+3],542quant_ptr->quantval[i+4], quant_ptr->quantval[i+5],543quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]);544}545}546547length -= DCTSIZE2+1;548if (prec) length -= DCTSIZE2;549}550551if (length != 0)552ERREXIT(cinfo, JERR_BAD_LENGTH);553554INPUT_SYNC(cinfo);555return TRUE;556}557558559LOCAL(boolean)560get_dri (j_decompress_ptr cinfo)561/* Process a DRI marker */562{563INT32 length;564unsigned int tmp;565INPUT_VARS(cinfo);566567INPUT_2BYTES(cinfo, length, return FALSE);568569if (length != 4)570ERREXIT(cinfo, JERR_BAD_LENGTH);571572INPUT_2BYTES(cinfo, tmp, return FALSE);573574TRACEMS1(cinfo, 1, JTRC_DRI, tmp);575576cinfo->restart_interval = tmp;577578INPUT_SYNC(cinfo);579return TRUE;580}581582583/*584* Routines for processing APPn and COM markers.585* These are either saved in memory or discarded, per application request.586* APP0 and APP14 are specially checked to see if they are587* JFIF and Adobe markers, respectively.588*/589590#define APP0_DATA_LEN 14 /* Length of interesting data in APP0 */591#define APP14_DATA_LEN 12 /* Length of interesting data in APP14 */592#define APPN_DATA_LEN 14 /* Must be the largest of the above!! */593594595LOCAL(void)596examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,597unsigned int datalen, INT32 remaining)598/* Examine first few bytes from an APP0.599* Take appropriate action if it is a JFIF marker.600* datalen is # of bytes at data[], remaining is length of rest of marker data.601*/602{603INT32 totallen = (INT32) datalen + remaining;604605if (datalen >= APP0_DATA_LEN &&606GETJOCTET(data[0]) == 0x4A &&607GETJOCTET(data[1]) == 0x46 &&608GETJOCTET(data[2]) == 0x49 &&609GETJOCTET(data[3]) == 0x46 &&610GETJOCTET(data[4]) == 0) {611/* Found JFIF APP0 marker: save info */612cinfo->saw_JFIF_marker = TRUE;613cinfo->JFIF_major_version = GETJOCTET(data[5]);614cinfo->JFIF_minor_version = GETJOCTET(data[6]);615cinfo->density_unit = GETJOCTET(data[7]);616cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);617cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);618/* Check version.619* Major version must be 1, anything else signals an incompatible change.620* (We used to treat this as an error, but now it's a nonfatal warning,621* because some bozo at Hijaak couldn't read the spec.)622* Minor version should be 0..2, but process anyway if newer.623*/624if (cinfo->JFIF_major_version != 1)625WARNMS2(cinfo, JWRN_JFIF_MAJOR,626cinfo->JFIF_major_version, cinfo->JFIF_minor_version);627/* Generate trace messages */628TRACEMS5(cinfo, 1, JTRC_JFIF,629cinfo->JFIF_major_version, cinfo->JFIF_minor_version,630cinfo->X_density, cinfo->Y_density, cinfo->density_unit);631/* Validate thumbnail dimensions and issue appropriate messages */632if (GETJOCTET(data[12]) | GETJOCTET(data[13]))633TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,634GETJOCTET(data[12]), GETJOCTET(data[13]));635totallen -= APP0_DATA_LEN;636if (totallen !=637((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3))638TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);639} else if (datalen >= 6 &&640GETJOCTET(data[0]) == 0x4A &&641GETJOCTET(data[1]) == 0x46 &&642GETJOCTET(data[2]) == 0x58 &&643GETJOCTET(data[3]) == 0x58 &&644GETJOCTET(data[4]) == 0) {645/* Found JFIF "JFXX" extension APP0 marker */646/* The library doesn't actually do anything with these,647* but we try to produce a helpful trace message.648*/649switch (GETJOCTET(data[5])) {650case 0x10:651TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);652break;653case 0x11:654TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);655break;656case 0x13:657TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);658break;659default:660TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,661GETJOCTET(data[5]), (int) totallen);662break;663}664} else {665/* Start of APP0 does not match "JFIF" or "JFXX", or too short */666TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);667668/*669* In this case we have seen the APP0 marker but the remaining670* APP0 section may be corrupt. Regardless, we will set the671* saw_JFIF_marker flag as it is important for making the672* correct choice of JPEG color space later (we will assume673* YCbCr in this case). The version and density fields will674* contain default values, which should be sufficient for our needs.675*/676cinfo->saw_JFIF_marker = TRUE;677}678}679680681LOCAL(void)682examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data,683unsigned int datalen, INT32 remaining)684/* Examine first few bytes from an APP14.685* Take appropriate action if it is an Adobe marker.686* datalen is # of bytes at data[], remaining is length of rest of marker data.687*/688{689unsigned int version, flags0, flags1, transform;690691if (datalen >= APP14_DATA_LEN &&692GETJOCTET(data[0]) == 0x41 &&693GETJOCTET(data[1]) == 0x64 &&694GETJOCTET(data[2]) == 0x6F &&695GETJOCTET(data[3]) == 0x62 &&696GETJOCTET(data[4]) == 0x65) {697/* Found Adobe APP14 marker */698version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);699flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);700flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);701transform = GETJOCTET(data[11]);702TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);703cinfo->saw_Adobe_marker = TRUE;704cinfo->Adobe_transform = (UINT8) transform;705} else {706/* Start of APP14 does not match "Adobe", or too short */707TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));708}709}710711712METHODDEF(boolean)713get_interesting_appn (j_decompress_ptr cinfo)714/* Process an APP0 or APP14 marker without saving it */715{716INT32 length;717JOCTET b[APPN_DATA_LEN];718unsigned int i, numtoread;719INPUT_VARS(cinfo);720721INPUT_2BYTES(cinfo, length, return FALSE);722length -= 2;723724/* get the interesting part of the marker data */725if (length >= APPN_DATA_LEN)726numtoread = APPN_DATA_LEN;727else if (length > 0)728numtoread = (unsigned int) length;729else730numtoread = 0;731for (i = 0; i < numtoread; i++)732INPUT_BYTE(cinfo, b[i], return FALSE);733length -= numtoread;734735/* process it */736switch (cinfo->unread_marker) {737case M_APP0:738examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length);739break;740case M_APP14:741examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length);742break;743default:744/* can't get here unless jpeg_save_markers chooses wrong processor */745ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);746break;747}748749/* skip any remaining data -- could be lots */750INPUT_SYNC(cinfo);751if (length > 0)752(*cinfo->src->skip_input_data) (cinfo, (long) length);753754return TRUE;755}756757758#ifdef SAVE_MARKERS_SUPPORTED759760METHODDEF(boolean)761save_marker (j_decompress_ptr cinfo)762/* Save an APPn or COM marker into the marker list */763{764my_marker_ptr marker = (my_marker_ptr) cinfo->marker;765jpeg_saved_marker_ptr cur_marker = marker->cur_marker;766unsigned int bytes_read, data_length;767JOCTET FAR * data;768INT32 length = 0;769INPUT_VARS(cinfo);770771if (cur_marker == NULL) {772/* begin reading a marker */773INPUT_2BYTES(cinfo, length, return FALSE);774length -= 2;775if (length >= 0) { /* watch out for bogus length word */776/* figure out how much we want to save */777unsigned int limit;778if (cinfo->unread_marker == (int) M_COM)779limit = marker->length_limit_COM;780else781limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];782if ((unsigned int) length < limit)783limit = (unsigned int) length;784/* allocate and initialize the marker item */785cur_marker = (jpeg_saved_marker_ptr)786(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,787SIZEOF(struct jpeg_marker_struct) + limit);788cur_marker->next = NULL;789cur_marker->marker = (UINT8) cinfo->unread_marker;790cur_marker->original_length = (unsigned int) length;791cur_marker->data_length = limit;792/* data area is just beyond the jpeg_marker_struct */793data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1);794marker->cur_marker = cur_marker;795marker->bytes_read = 0;796bytes_read = 0;797data_length = limit;798} else {799/* deal with bogus length word */800bytes_read = data_length = 0;801data = NULL;802}803} else {804/* resume reading a marker */805bytes_read = marker->bytes_read;806data_length = cur_marker->data_length;807data = cur_marker->data + bytes_read;808}809810while (bytes_read < data_length) {811INPUT_SYNC(cinfo); /* move the restart point to here */812marker->bytes_read = bytes_read;813/* If there's not at least one byte in buffer, suspend */814MAKE_BYTE_AVAIL(cinfo, return FALSE);815/* Copy bytes with reasonable rapidity */816while (bytes_read < data_length && bytes_in_buffer > 0) {817*data++ = *next_input_byte++;818bytes_in_buffer--;819bytes_read++;820}821}822823/* Done reading what we want to read */824if (cur_marker != NULL) { /* will be NULL if bogus length word */825/* Add new marker to end of list */826if (cinfo->marker_list == NULL) {827cinfo->marker_list = cur_marker;828} else {829jpeg_saved_marker_ptr prev = cinfo->marker_list;830while (prev->next != NULL)831prev = prev->next;832prev->next = cur_marker;833}834/* Reset pointer & calc remaining data length */835data = cur_marker->data;836length = cur_marker->original_length - data_length;837}838/* Reset to initial state for next marker */839marker->cur_marker = NULL;840841/* Process the marker if interesting; else just make a generic trace msg */842switch (cinfo->unread_marker) {843case M_APP0:844examine_app0(cinfo, data, data_length, length);845break;846case M_APP14:847examine_app14(cinfo, data, data_length, length);848break;849default:850TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,851(int) (data_length + length));852break;853}854855/* skip any remaining data -- could be lots */856INPUT_SYNC(cinfo); /* do before skip_input_data */857if (length > 0)858(*cinfo->src->skip_input_data) (cinfo, (long) length);859860return TRUE;861}862863#endif /* SAVE_MARKERS_SUPPORTED */864865866METHODDEF(boolean)867skip_variable (j_decompress_ptr cinfo)868/* Skip over an unknown or uninteresting variable-length marker */869{870INT32 length;871INPUT_VARS(cinfo);872873INPUT_2BYTES(cinfo, length, return FALSE);874length -= 2;875876TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);877878INPUT_SYNC(cinfo); /* do before skip_input_data */879if (length > 0)880(*cinfo->src->skip_input_data) (cinfo, (long) length);881882return TRUE;883}884885886/*887* Find the next JPEG marker, save it in cinfo->unread_marker.888* Returns FALSE if had to suspend before reaching a marker;889* in that case cinfo->unread_marker is unchanged.890*891* Note that the result might not be a valid marker code,892* but it will never be 0 or FF.893*/894895LOCAL(boolean)896next_marker (j_decompress_ptr cinfo)897{898int c;899INPUT_VARS(cinfo);900901for (;;) {902INPUT_BYTE(cinfo, c, return FALSE);903/* Skip any non-FF bytes.904* This may look a bit inefficient, but it will not occur in a valid file.905* We sync after each discarded byte so that a suspending data source906* can discard the byte from its buffer.907*/908while (c != 0xFF) {909cinfo->marker->discarded_bytes++;910INPUT_SYNC(cinfo);911INPUT_BYTE(cinfo, c, return FALSE);912}913/* This loop swallows any duplicate FF bytes. Extra FFs are legal as914* pad bytes, so don't count them in discarded_bytes. We assume there915* will not be so many consecutive FF bytes as to overflow a suspending916* data source's input buffer.917*/918do {919INPUT_BYTE(cinfo, c, return FALSE);920} while (c == 0xFF);921if (c != 0)922break; /* found a valid marker, exit loop */923/* Reach here if we found a stuffed-zero data sequence (FF/00).924* Discard it and loop back to try again.925*/926cinfo->marker->discarded_bytes += 2;927INPUT_SYNC(cinfo);928}929930if (cinfo->marker->discarded_bytes != 0) {931WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);932cinfo->marker->discarded_bytes = 0;933}934935cinfo->unread_marker = c;936937INPUT_SYNC(cinfo);938return TRUE;939}940941942LOCAL(boolean)943first_marker (j_decompress_ptr cinfo)944/* Like next_marker, but used to obtain the initial SOI marker. */945/* For this marker, we do not allow preceding garbage or fill; otherwise,946* we might well scan an entire input file before realizing it ain't JPEG.947* If an application wants to process non-JFIF files, it must seek to the948* SOI before calling the JPEG library.949*/950{951int c, c2;952INPUT_VARS(cinfo);953954INPUT_BYTE(cinfo, c, return FALSE);955INPUT_BYTE(cinfo, c2, return FALSE);956if (c != 0xFF || c2 != (int) M_SOI)957ERREXIT2(cinfo, JERR_NO_SOI, c, c2);958959cinfo->unread_marker = c2;960961INPUT_SYNC(cinfo);962return TRUE;963}964965966/*967* Read markers until SOS or EOI.968*969* Returns same codes as are defined for jpeg_consume_input:970* JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.971*/972973METHODDEF(int)974read_markers (j_decompress_ptr cinfo)975{976/* Outer loop repeats once for each marker. */977for (;;) {978/* Collect the marker proper, unless we already did. */979/* NB: first_marker() enforces the requirement that SOI appear first. */980if (cinfo->unread_marker == 0) {981if (! cinfo->marker->saw_SOI) {982if (! first_marker(cinfo))983return JPEG_SUSPENDED;984} else {985if (! next_marker(cinfo))986return JPEG_SUSPENDED;987}988}989/* At this point cinfo->unread_marker contains the marker code and the990* input point is just past the marker proper, but before any parameters.991* A suspension will cause us to return with this state still true.992*/993switch (cinfo->unread_marker) {994case M_SOI:995if (! get_soi(cinfo))996return JPEG_SUSPENDED;997break;998999case M_SOF0: /* Baseline */1000case M_SOF1: /* Extended sequential, Huffman */1001if (! get_sof(cinfo, FALSE, FALSE))1002return JPEG_SUSPENDED;1003break;10041005case M_SOF2: /* Progressive, Huffman */1006if (! get_sof(cinfo, TRUE, FALSE))1007return JPEG_SUSPENDED;1008break;10091010case M_SOF9: /* Extended sequential, arithmetic */1011if (! get_sof(cinfo, FALSE, TRUE))1012return JPEG_SUSPENDED;1013break;10141015case M_SOF10: /* Progressive, arithmetic */1016if (! get_sof(cinfo, TRUE, TRUE))1017return JPEG_SUSPENDED;1018break;10191020/* Currently unsupported SOFn types */1021case M_SOF3: /* Lossless, Huffman */1022case M_SOF5: /* Differential sequential, Huffman */1023case M_SOF6: /* Differential progressive, Huffman */1024case M_SOF7: /* Differential lossless, Huffman */1025case M_JPG: /* Reserved for JPEG extensions */1026case M_SOF11: /* Lossless, arithmetic */1027case M_SOF13: /* Differential sequential, arithmetic */1028case M_SOF14: /* Differential progressive, arithmetic */1029case M_SOF15: /* Differential lossless, arithmetic */1030ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);1031break;10321033case M_SOS:1034if (! get_sos(cinfo))1035return JPEG_SUSPENDED;1036cinfo->unread_marker = 0; /* processed the marker */1037return JPEG_REACHED_SOS;10381039case M_EOI:1040TRACEMS(cinfo, 1, JTRC_EOI);1041cinfo->unread_marker = 0; /* processed the marker */1042return JPEG_REACHED_EOI;10431044case M_DAC:1045if (! get_dac(cinfo))1046return JPEG_SUSPENDED;1047break;10481049case M_DHT:1050if (! get_dht(cinfo))1051return JPEG_SUSPENDED;1052break;10531054case M_DQT:1055if (! get_dqt(cinfo))1056return JPEG_SUSPENDED;1057break;10581059case M_DRI:1060if (! get_dri(cinfo))1061return JPEG_SUSPENDED;1062break;10631064case M_APP0:1065case M_APP1:1066case M_APP2:1067case M_APP3:1068case M_APP4:1069case M_APP5:1070case M_APP6:1071case M_APP7:1072case M_APP8:1073case M_APP9:1074case M_APP10:1075case M_APP11:1076case M_APP12:1077case M_APP13:1078case M_APP14:1079case M_APP15:1080if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[1081cinfo->unread_marker - (int) M_APP0]) (cinfo))1082return JPEG_SUSPENDED;1083break;10841085case M_COM:1086if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))1087return JPEG_SUSPENDED;1088break;10891090case M_RST0: /* these are all parameterless */1091case M_RST1:1092case M_RST2:1093case M_RST3:1094case M_RST4:1095case M_RST5:1096case M_RST6:1097case M_RST7:1098case M_TEM:1099TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);1100break;11011102case M_DNL: /* Ignore DNL ... perhaps the wrong thing */1103if (! skip_variable(cinfo))1104return JPEG_SUSPENDED;1105break;11061107default: /* must be DHP, EXP, JPGn, or RESn */1108/* For now, we treat the reserved markers as fatal errors since they are1109* likely to be used to signal incompatible JPEG Part 3 extensions.1110* Once the JPEG 3 version-number marker is well defined, this code1111* ought to change!1112* [To be behaviorally compatible with other popular image display1113* applications, we are now treating these unknown markers as warnings,1114* rather than errors. This allows processing to continue, although1115* any portions of the image after the bad marker may be corrupted1116* and/or rendered gray. See 4511441.]1117*/1118WARNMS1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);1119break;1120}1121/* Successfully processed marker, so reset state variable */1122cinfo->unread_marker = 0;1123} /* end loop */1124}112511261127/*1128* Read a restart marker, which is expected to appear next in the datastream;1129* if the marker is not there, take appropriate recovery action.1130* Returns FALSE if suspension is required.1131*1132* This is called by the entropy decoder after it has read an appropriate1133* number of MCUs. cinfo->unread_marker may be nonzero if the entropy decoder1134* has already read a marker from the data source. Under normal conditions1135* cinfo->unread_marker will be reset to 0 before returning; if not reset,1136* it holds a marker which the decoder will be unable to read past.1137*/11381139METHODDEF(boolean)1140read_restart_marker (j_decompress_ptr cinfo)1141{1142/* Obtain a marker unless we already did. */1143/* Note that next_marker will complain if it skips any data. */1144if (cinfo->unread_marker == 0) {1145if (! next_marker(cinfo))1146return FALSE;1147}11481149if (cinfo->unread_marker ==1150((int) M_RST0 + cinfo->marker->next_restart_num)) {1151/* Normal case --- swallow the marker and let entropy decoder continue */1152TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);1153cinfo->unread_marker = 0;1154} else {1155/* Uh-oh, the restart markers have been messed up. */1156/* Let the data source manager determine how to resync. */1157if (! (*cinfo->src->resync_to_restart) (cinfo,1158cinfo->marker->next_restart_num))1159return FALSE;1160}11611162/* Update next-restart state */1163cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;11641165return TRUE;1166}116711681169/*1170* This is the default resync_to_restart method for data source managers1171* to use if they don't have any better approach. Some data source managers1172* may be able to back up, or may have additional knowledge about the data1173* which permits a more intelligent recovery strategy; such managers would1174* presumably supply their own resync method.1175*1176* read_restart_marker calls resync_to_restart if it finds a marker other than1177* the restart marker it was expecting. (This code is *not* used unless1178* a nonzero restart interval has been declared.) cinfo->unread_marker is1179* the marker code actually found (might be anything, except 0 or FF).1180* The desired restart marker number (0..7) is passed as a parameter.1181* This routine is supposed to apply whatever error recovery strategy seems1182* appropriate in order to position the input stream to the next data segment.1183* Note that cinfo->unread_marker is treated as a marker appearing before1184* the current data-source input point; usually it should be reset to zero1185* before returning.1186* Returns FALSE if suspension is required.1187*1188* This implementation is substantially constrained by wanting to treat the1189* input as a data stream; this means we can't back up. Therefore, we have1190* only the following actions to work with:1191* 1. Simply discard the marker and let the entropy decoder resume at next1192* byte of file.1193* 2. Read forward until we find another marker, discarding intervening1194* data. (In theory we could look ahead within the current bufferload,1195* without having to discard data if we don't find the desired marker.1196* This idea is not implemented here, in part because it makes behavior1197* dependent on buffer size and chance buffer-boundary positions.)1198* 3. Leave the marker unread (by failing to zero cinfo->unread_marker).1199* This will cause the entropy decoder to process an empty data segment,1200* inserting dummy zeroes, and then we will reprocess the marker.1201*1202* #2 is appropriate if we think the desired marker lies ahead, while #3 is1203* appropriate if the found marker is a future restart marker (indicating1204* that we have missed the desired restart marker, probably because it got1205* corrupted).1206* We apply #2 or #3 if the found marker is a restart marker no more than1207* two counts behind or ahead of the expected one. We also apply #2 if the1208* found marker is not a legal JPEG marker code (it's certainly bogus data).1209* If the found marker is a restart marker more than 2 counts away, we do #11210* (too much risk that the marker is erroneous; with luck we will be able to1211* resync at some future point).1212* For any valid non-restart JPEG marker, we apply #3. This keeps us from1213* overrunning the end of a scan. An implementation limited to single-scan1214* files might find it better to apply #2 for markers other than EOI, since1215* any other marker would have to be bogus data in that case.1216*/12171218GLOBAL(boolean)1219jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)1220{1221int marker = cinfo->unread_marker;1222int action = 1;12231224/* Always put up a warning. */1225WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);12261227/* Outer loop handles repeated decision after scanning forward. */1228for (;;) {1229if (marker < (int) M_SOF0)1230action = 2; /* invalid marker */1231else if (marker < (int) M_RST0 || marker > (int) M_RST7)1232action = 3; /* valid non-restart marker */1233else {1234if (marker == ((int) M_RST0 + ((desired+1) & 7)) ||1235marker == ((int) M_RST0 + ((desired+2) & 7)))1236action = 3; /* one of the next two expected restarts */1237else if (marker == ((int) M_RST0 + ((desired-1) & 7)) ||1238marker == ((int) M_RST0 + ((desired-2) & 7)))1239action = 2; /* a prior restart, so advance */1240else1241action = 1; /* desired restart or too far away */1242}1243TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);1244switch (action) {1245case 1:1246/* Discard marker and let entropy decoder resume processing. */1247cinfo->unread_marker = 0;1248return TRUE;1249case 2:1250/* Scan to the next marker, and repeat the decision loop. */1251if (! next_marker(cinfo))1252return FALSE;1253marker = cinfo->unread_marker;1254break;1255case 3:1256/* Return without advancing past this marker. */1257/* Entropy decoder will be forced to process an empty segment. */1258return TRUE;1259}1260} /* end loop */1261}126212631264/*1265* Reset marker processing state to begin a fresh datastream.1266*/12671268METHODDEF(void)1269reset_marker_reader (j_decompress_ptr cinfo)1270{1271my_marker_ptr marker = (my_marker_ptr) cinfo->marker;12721273cinfo->comp_info = NULL; /* until allocated by get_sof */1274cinfo->input_scan_number = 0; /* no SOS seen yet */1275cinfo->unread_marker = 0; /* no pending marker */1276marker->pub.saw_SOI = FALSE; /* set internal state too */1277marker->pub.saw_SOF = FALSE;1278marker->pub.discarded_bytes = 0;1279marker->cur_marker = NULL;1280}128112821283/*1284* Initialize the marker reader module.1285* This is called only once, when the decompression object is created.1286*/12871288GLOBAL(void)1289jinit_marker_reader (j_decompress_ptr cinfo)1290{1291my_marker_ptr marker;1292int i;12931294/* Create subobject in permanent pool */1295marker = (my_marker_ptr)1296(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,1297SIZEOF(my_marker_reader));1298cinfo->marker = (struct jpeg_marker_reader *) marker;1299/* Initialize public method pointers */1300marker->pub.reset_marker_reader = reset_marker_reader;1301marker->pub.read_markers = read_markers;1302marker->pub.read_restart_marker = read_restart_marker;1303/* Initialize COM/APPn processing.1304* By default, we examine and then discard APP0 and APP14.1305* We also may need to save APP1 to detect the case of EXIF images (see 4881314).1306* COM and all other APPn are simply discarded.1307*/1308marker->process_COM = skip_variable;1309marker->length_limit_COM = 0;1310for (i = 0; i < 16; i++) {1311marker->process_APPn[i] = skip_variable;1312marker->length_limit_APPn[i] = 0;1313}1314marker->process_APPn[0] = get_interesting_appn;1315marker->process_APPn[1] = save_marker;1316marker->process_APPn[14] = get_interesting_appn;1317/* Reset marker processing state */1318reset_marker_reader(cinfo);1319}132013211322/*1323* Control saving of COM and APPn markers into marker_list.1324*/13251326#ifdef SAVE_MARKERS_SUPPORTED13271328GLOBAL(void)1329jpeg_save_markers (j_decompress_ptr cinfo, int marker_code,1330unsigned int length_limit)1331{1332my_marker_ptr marker = (my_marker_ptr) cinfo->marker;1333size_t maxlength;1334jpeg_marker_parser_method processor;13351336/* Length limit mustn't be larger than what we can allocate1337* (should only be a concern in a 16-bit environment).1338*/1339maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct);1340if (length_limit > maxlength)1341length_limit = (unsigned int) maxlength;13421343/* Choose processor routine to use.1344* APP0/APP14 have special requirements.1345*/1346if (length_limit) {1347processor = save_marker;1348/* If saving APP0/APP14, save at least enough for our internal use. */1349if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)1350length_limit = APP0_DATA_LEN;1351else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)1352length_limit = APP14_DATA_LEN;1353} else {1354processor = skip_variable;1355/* If discarding APP0/APP14, use our regular on-the-fly processor. */1356if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)1357processor = get_interesting_appn;1358}13591360if (marker_code == (int) M_COM) {1361marker->process_COM = processor;1362marker->length_limit_COM = length_limit;1363} else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {1364marker->process_APPn[marker_code - (int) M_APP0] = processor;1365marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;1366} else1367ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);1368}13691370#endif /* SAVE_MARKERS_SUPPORTED */137113721373/*1374* Install a special processing method for COM or APPn markers.1375*/13761377GLOBAL(void)1378jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,1379jpeg_marker_parser_method routine)1380{1381my_marker_ptr marker = (my_marker_ptr) cinfo->marker;13821383if (marker_code == (int) M_COM)1384marker->process_COM = routine;1385else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)1386marker->process_APPn[marker_code - (int) M_APP0] = routine;1387else1388ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);1389}139013911392