170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * jdmarker.c
370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Copyright (C) 1991-1998, Thomas G. Lane.
570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file is part of the Independent JPEG Group's software.
670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * For conditions of distribution and use, see the accompanying README file.
770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file contains routines to decode JPEG datastream markers.
970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Most of the complexity arises from our desire to support input
1070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * suspension: if not all of the data for a marker is available,
1170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * we must exit back to the application.  On resumption, we reprocess
1270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * the marker.
1370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
1470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
1570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define JPEG_INTERNALS
1670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "jinclude.h"
1770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "jpeglib.h"
1870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
1970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
2070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef enum {			/* JPEG marker codes */
2170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOF0  = 0xc0,
2270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOF1  = 0xc1,
2370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOF2  = 0xc2,
2470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOF3  = 0xc3,
2570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
2670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOF5  = 0xc5,
2770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOF6  = 0xc6,
2870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOF7  = 0xc7,
2970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
3070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_JPG   = 0xc8,
3170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOF9  = 0xc9,
3270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOF10 = 0xca,
3370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOF11 = 0xcb,
3470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
3570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOF13 = 0xcd,
3670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOF14 = 0xce,
3770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOF15 = 0xcf,
3870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
3970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_DHT   = 0xc4,
4070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
4170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_DAC   = 0xcc,
4270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
4370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_RST0  = 0xd0,
4470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_RST1  = 0xd1,
4570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_RST2  = 0xd2,
4670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_RST3  = 0xd3,
4770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_RST4  = 0xd4,
4870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_RST5  = 0xd5,
4970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_RST6  = 0xd6,
5070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_RST7  = 0xd7,
5170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
5270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOI   = 0xd8,
5370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_EOI   = 0xd9,
5470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_SOS   = 0xda,
5570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_DQT   = 0xdb,
5670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_DNL   = 0xdc,
5770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_DRI   = 0xdd,
5870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_DHP   = 0xde,
5970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_EXP   = 0xdf,
6070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
6170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP0  = 0xe0,
6270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP1  = 0xe1,
6370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP2  = 0xe2,
6470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP3  = 0xe3,
6570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP4  = 0xe4,
6670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP5  = 0xe5,
6770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP6  = 0xe6,
6870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP7  = 0xe7,
6970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP8  = 0xe8,
7070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP9  = 0xe9,
7170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP10 = 0xea,
7270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP11 = 0xeb,
7370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP12 = 0xec,
7470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP13 = 0xed,
7570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP14 = 0xee,
7670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_APP15 = 0xef,
7770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
7870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_JPG0  = 0xf0,
7970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_JPG13 = 0xfd,
8070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_COM   = 0xfe,
8170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
8270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_TEM   = 0x01,
8370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
8470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  M_ERROR = 0x100
8570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} JPEG_MARKER;
8670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
8770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
8870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Private state */
8970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
9070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef struct {
9170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  struct jpeg_marker_reader pub; /* public fields */
9270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
9370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Application-overridable marker processing methods */
9470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jpeg_marker_parser_method process_COM;
9570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jpeg_marker_parser_method process_APPn[16];
9670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
9770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Limit on marker data length to save for each marker type */
9870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  unsigned int length_limit_COM;
9970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  unsigned int length_limit_APPn[16];
10070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
10170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Status of COM/APPn marker saving */
10270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jpeg_saved_marker_ptr cur_marker;	/* NULL if not processing a marker */
10370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  unsigned int bytes_read;		/* data bytes read so far in marker */
10470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Note: cur_marker is not linked into marker_list until it's all read. */
10570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} my_marker_reader;
10670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
10770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef my_marker_reader * my_marker_ptr;
10870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
10970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
11070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
11170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Macros for fetching data from the data source module.
11270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
11370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect
11470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * the current restart point; we update them only when we have reached a
11570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * suitable place to restart if a suspension occurs.
11670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
11770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
11870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Declare and initialize local copies of input pointer/count */
11970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define INPUT_VARS(cinfo)  \
12070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	struct jpeg_source_mgr * datasrc = (cinfo)->src;  \
12170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	const JOCTET * next_input_byte = datasrc->next_input_byte;  \
12270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	size_t bytes_in_buffer = datasrc->bytes_in_buffer
12370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
12470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Unload the local copies --- do this only at a restart boundary */
12570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define INPUT_SYNC(cinfo)  \
12670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	( datasrc->next_input_byte = next_input_byte,  \
12770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	  datasrc->bytes_in_buffer = bytes_in_buffer )
12870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
12970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */
13070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define INPUT_RELOAD(cinfo)  \
13170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	( next_input_byte = datasrc->next_input_byte,  \
13270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	  bytes_in_buffer = datasrc->bytes_in_buffer )
13370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
13470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.
13570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
13670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * but we must reload the local copies after a successful fill.
13770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
13870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define MAKE_BYTE_AVAIL(cinfo,action)  \
13970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	if (bytes_in_buffer == 0) {  \
14070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	  if (! (*datasrc->fill_input_buffer) (cinfo))  \
14170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	    { action; }  \
14270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	  INPUT_RELOAD(cinfo);  \
14370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	}
14470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
14570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Read a byte into variable V.
14670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * If must suspend, take the specified action (typically "return FALSE").
14770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
14870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define INPUT_BYTE(cinfo,V,action)  \
14970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
15070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		  bytes_in_buffer--; \
15170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		  V = GETJOCTET(*next_input_byte++); )
15270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
15370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* As above, but read two bytes interpreted as an unsigned 16-bit integer.
15470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * V should be declared unsigned int or perhaps INT32.
15570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
15670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define INPUT_2BYTES(cinfo,V,action)  \
15770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
15870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		  bytes_in_buffer--; \
15970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		  V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
16070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		  MAKE_BYTE_AVAIL(cinfo,action); \
16170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		  bytes_in_buffer--; \
16270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		  V += GETJOCTET(*next_input_byte++); )
16370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
16470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
16570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
16670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Routines to process JPEG markers.
16770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
16870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Entry condition: JPEG marker itself has been read and its code saved
16970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *   in cinfo->unread_marker; input restart point is just after the marker.
17070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
17170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Exit: if return TRUE, have read and processed any parameters, and have
17270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *   updated the restart point to point after the parameters.
17370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *   If return FALSE, was forced to suspend before reaching end of
17470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *   marker parameters; restart point has not been moved.  Same routine
17570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *   will be called again after application supplies more input data.
17670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
17770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This approach to suspension assumes that all of a marker's parameters
17870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * can fit into a single input bufferload.  This should hold for "normal"
17970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * markers.  Some COM/APPn markers might have large parameter segments
18070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * that might not fit.  If we are simply dropping such a marker, we use
18170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * skip_input_data to get past it, and thereby put the problem on the
18270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * source manager's shoulders.  If we are saving the marker's contents
18370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * into memory, we use a slightly different convention: when forced to
18470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * suspend, the marker processor updates the restart point to the end of
18570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * what it's consumed (ie, the end of the buffer) before returning FALSE.
18670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * On resumption, cinfo->unread_marker still contains the marker code,
18770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * but the data source will point to the next chunk of marker data.
18870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * The marker processor must retain internal state to deal with this.
18970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
19070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Note that we don't bother to avoid duplicate trace messages if a
19170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * suspension occurs within marker parameters.  Other side effects
19270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * require more care.
19370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
19470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
19570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
19670a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(boolean)
19770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineget_soi (j_decompress_ptr cinfo)
19870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Process an SOI marker */
19970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
20070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  int i;
20170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
20270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  TRACEMS(cinfo, 1, JTRC_SOI);
20370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
20470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (cinfo->marker->saw_SOI)
20570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_SOI_DUPLICATE);
20670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
20770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Reset all parameters that are defined to be reset by SOI */
20870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
20970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  for (i = 0; i < NUM_ARITH_TBLS; i++) {
21070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->arith_dc_L[i] = 0;
21170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->arith_dc_U[i] = 1;
21270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->arith_ac_K[i] = 5;
21370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
21470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->restart_interval = 0;
21570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
21670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Set initial assumptions for colorspace etc */
21770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
21870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->jpeg_color_space = JCS_UNKNOWN;
21970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
22070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
22170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->saw_JFIF_marker = FALSE;
22270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */
22370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->JFIF_minor_version = 1;
22470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->density_unit = 0;
22570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->X_density = 1;
22670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->Y_density = 1;
22770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->saw_Adobe_marker = FALSE;
22870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->Adobe_transform = 0;
22970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
23070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->marker->saw_SOI = TRUE;
23170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
23270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;
23370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
23470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
23570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
23670a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(boolean)
23770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineget_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
23870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Process a SOFn marker */
23970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
24070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INT32 length;
24170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  int c, ci;
24270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jpeg_component_info * compptr;
24370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_VARS(cinfo);
24470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
24570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->progressive_mode = is_prog;
24670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->arith_code = is_arith;
24770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
24870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_2BYTES(cinfo, length, return FALSE);
24970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
25070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);
25170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE);
25270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE);
25370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);
25470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
25570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  length -= 8;
25670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
25770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,
25870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	   (int) cinfo->image_width, (int) cinfo->image_height,
25970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	   cinfo->num_components);
26070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
26170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (cinfo->marker->saw_SOF)
26270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_SOF_DUPLICATE);
26370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
26470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* We don't support files in which the image height is initially specified */
26570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* as 0 and is later redefined by DNL.  As long as we have to check that,  */
26670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* might as well have a general sanity check. */
26770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (cinfo->image_height <= 0 || cinfo->image_width <= 0
26870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      || cinfo->num_components <= 0)
26970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_EMPTY_IMAGE);
27070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
27170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (length != (cinfo->num_components * 3))
27270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_BAD_LENGTH);
27370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
27470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (cinfo->comp_info == NULL)	/* do only once, even if suspend */
27570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)
27670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine			((j_common_ptr) cinfo, JPOOL_IMAGE,
27770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine			 cinfo->num_components * SIZEOF(jpeg_component_info));
27870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
27970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
28070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine       ci++, compptr++) {
28170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    compptr->component_index = ci;
28270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
28370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_BYTE(cinfo, c, return FALSE);
28470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    compptr->h_samp_factor = (c >> 4) & 15;
28570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    compptr->v_samp_factor = (c     ) & 15;
28670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);
28770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
28870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,
28970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	     compptr->component_id, compptr->h_samp_factor,
29070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	     compptr->v_samp_factor, compptr->quant_tbl_no);
29170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
29270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
29370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->marker->saw_SOF = TRUE;
29470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
29570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_SYNC(cinfo);
29670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;
29770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
29870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
29970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
30070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(boolean)
30170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineget_sos (j_decompress_ptr cinfo)
30270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Process a SOS marker */
30370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
30470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INT32 length;
30570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  int i, ci, n, c, cc;
30670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jpeg_component_info * compptr;
30770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_VARS(cinfo);
30870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
30970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (! cinfo->marker->saw_SOF)
31070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_SOS_NO_SOF);
31170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
31270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_2BYTES(cinfo, length, return FALSE);
31370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
31470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */
31570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
31670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  TRACEMS1(cinfo, 1, JTRC_SOS, n);
31770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
31870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
31970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_BAD_LENGTH);
32070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
32170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->comps_in_scan = n;
32270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
32370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Collect the component-spec parameters */
32470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
32570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  for (i = 0; i < n; i++) {
32670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_BYTE(cinfo, cc, return FALSE);
32770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_BYTE(cinfo, c, return FALSE);
32870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
32970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
33070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	 ci++, compptr++) {
33170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (cc == compptr->component_id)
33270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	goto id_found;
33370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
33470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
33570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
33670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
33770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  id_found:
33870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
33970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->cur_comp_info[i] = compptr;
34070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    compptr->dc_tbl_no = (c >> 4) & 15;
34170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    compptr->ac_tbl_no = (c     ) & 15;
34270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
34370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,
34470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	     compptr->dc_tbl_no, compptr->ac_tbl_no);
34570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
34670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
34770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Collect the additional scan parameters Ss, Se, Ah/Al. */
34870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_BYTE(cinfo, c, return FALSE);
34970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->Ss = c;
35070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_BYTE(cinfo, c, return FALSE);
35170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->Se = c;
35270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_BYTE(cinfo, c, return FALSE);
35370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->Ah = (c >> 4) & 15;
35470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->Al = (c     ) & 15;
35570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
35670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,
35770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	   cinfo->Ah, cinfo->Al);
35870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
35970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Prepare to scan data & restart markers */
36070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->marker->next_restart_num = 0;
36170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
36270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Count another SOS marker */
36370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->input_scan_number++;
36470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
36570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_SYNC(cinfo);
36670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;
36770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
36870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
36970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
37070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef D_ARITH_CODING_SUPPORTED
37170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
37270a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(boolean)
37370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineget_dac (j_decompress_ptr cinfo)
37470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Process a DAC marker */
37570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
37670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INT32 length;
37770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  int index, val;
37870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_VARS(cinfo);
37970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
38070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_2BYTES(cinfo, length, return FALSE);
38170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  length -= 2;
38270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
38370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  while (length > 0) {
38470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_BYTE(cinfo, index, return FALSE);
38570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_BYTE(cinfo, val, return FALSE);
38670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
38770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    length -= 2;
38870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
38970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS2(cinfo, 1, JTRC_DAC, index, val);
39070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
39170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (index < 0 || index >= (2*NUM_ARITH_TBLS))
39270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      ERREXIT1(cinfo, JERR_DAC_INDEX, index);
39370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
39470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (index >= NUM_ARITH_TBLS) { /* define AC table */
39570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
39670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    } else {			/* define DC table */
39770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
39870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
39970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
40070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	ERREXIT1(cinfo, JERR_DAC_VALUE, val);
40170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
40270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
40370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
40470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (length != 0)
40570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_BAD_LENGTH);
40670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
40770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_SYNC(cinfo);
40870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;
40970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
41070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
41170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#else /* ! D_ARITH_CODING_SUPPORTED */
41270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
41370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define get_dac(cinfo)  skip_variable(cinfo)
41470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
41570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif /* D_ARITH_CODING_SUPPORTED */
41670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
41770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
41870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(boolean)
41970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineget_dht (j_decompress_ptr cinfo)
42070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Process a DHT marker */
42170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
42270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INT32 length;
42370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  UINT8 bits[17];
42470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  UINT8 huffval[256];
42570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  int i, index, count;
42670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  JHUFF_TBL **htblptr;
42770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_VARS(cinfo);
42870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
42970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_2BYTES(cinfo, length, return FALSE);
43070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  length -= 2;
43170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
43270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  while (length > 16) {
43370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_BYTE(cinfo, index, return FALSE);
43470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
43570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS1(cinfo, 1, JTRC_DHT, index);
43670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
43770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    bits[0] = 0;
43870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    count = 0;
43970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    for (i = 1; i <= 16; i++) {
44070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      INPUT_BYTE(cinfo, bits[i], return FALSE);
44170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      count += bits[i];
44270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
44370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
44470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    length -= 1 + 16;
44570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
44670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
44770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	     bits[1], bits[2], bits[3], bits[4],
44870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	     bits[5], bits[6], bits[7], bits[8]);
44970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
45070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	     bits[9], bits[10], bits[11], bits[12],
45170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	     bits[13], bits[14], bits[15], bits[16]);
45270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
45370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Here we just do minimal validation of the counts to avoid walking
45470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * off the end of our table space.  jdhuff.c will check more carefully.
45570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     */
45670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (count > 256 || ((INT32) count) > length)
45770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
45870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
45970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    for (i = 0; i < count; i++)
46070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      INPUT_BYTE(cinfo, huffval[i], return FALSE);
46170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
46270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    length -= count;
46370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
46470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (index & 0x10) {		/* AC table definition */
46570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      index -= 0x10;
46670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      htblptr = &cinfo->ac_huff_tbl_ptrs[index];
46770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    } else {			/* DC table definition */
46870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      htblptr = &cinfo->dc_huff_tbl_ptrs[index];
46970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
47070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
47170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (index < 0 || index >= NUM_HUFF_TBLS)
47270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      ERREXIT1(cinfo, JERR_DHT_INDEX, index);
47370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
47470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (*htblptr == NULL)
47570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
47670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
47770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
47870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
47970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
48070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
48170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (length != 0)
48270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_BAD_LENGTH);
48370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
48470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_SYNC(cinfo);
48570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;
48670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
48770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
48870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
48970a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(boolean)
49070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineget_dqt (j_decompress_ptr cinfo)
49170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Process a DQT marker */
49270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
49370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INT32 length;
49470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  int n, i, prec;
49570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  unsigned int tmp;
49670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  JQUANT_TBL *quant_ptr;
49770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_VARS(cinfo);
49870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
49970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_2BYTES(cinfo, length, return FALSE);
50070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  length -= 2;
50170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
50270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  while (length > 0) {
50370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_BYTE(cinfo, n, return FALSE);
50470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    prec = n >> 4;
50570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    n &= 0x0F;
50670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
50770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);
50870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
50970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (n >= NUM_QUANT_TBLS)
51070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      ERREXIT1(cinfo, JERR_DQT_INDEX, n);
51170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
51270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (cinfo->quant_tbl_ptrs[n] == NULL)
51370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);
51470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    quant_ptr = cinfo->quant_tbl_ptrs[n];
51570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
51670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    for (i = 0; i < DCTSIZE2; i++) {
51770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (prec)
51870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	INPUT_2BYTES(cinfo, tmp, return FALSE);
51970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      else
52070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	INPUT_BYTE(cinfo, tmp, return FALSE);
52170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* We convert the zigzag-order table to natural array order. */
52270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp;
52370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
52470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
52570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (cinfo->err->trace_level >= 2) {
52670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      for (i = 0; i < DCTSIZE2; i += 8) {
52770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	TRACEMS8(cinfo, 2, JTRC_QUANTVALS,
52870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		 quant_ptr->quantval[i],   quant_ptr->quantval[i+1],
52970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		 quant_ptr->quantval[i+2], quant_ptr->quantval[i+3],
53070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		 quant_ptr->quantval[i+4], quant_ptr->quantval[i+5],
53170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		 quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]);
53270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      }
53370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
53470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
53570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    length -= DCTSIZE2+1;
53670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (prec) length -= DCTSIZE2;
53770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
53870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
53970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (length != 0)
54070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_BAD_LENGTH);
54170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
54270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_SYNC(cinfo);
54370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;
54470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
54570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
54670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
54770a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(boolean)
54870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineget_dri (j_decompress_ptr cinfo)
54970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Process a DRI marker */
55070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
55170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INT32 length;
55270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  unsigned int tmp;
55370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_VARS(cinfo);
55470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
55570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_2BYTES(cinfo, length, return FALSE);
55670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
55770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (length != 4)
55870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT(cinfo, JERR_BAD_LENGTH);
55970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
56070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_2BYTES(cinfo, tmp, return FALSE);
56170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
56270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  TRACEMS1(cinfo, 1, JTRC_DRI, tmp);
56370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
56470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->restart_interval = tmp;
56570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
56670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_SYNC(cinfo);
56770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;
56870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
56970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
57070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
57170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
57270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Routines for processing APPn and COM markers.
57370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * These are either saved in memory or discarded, per application request.
57470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * APP0 and APP14 are specially checked to see if they are
57570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * JFIF and Adobe markers, respectively.
57670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
57770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
57870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define APP0_DATA_LEN	14	/* Length of interesting data in APP0 */
57970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define APP14_DATA_LEN	12	/* Length of interesting data in APP14 */
58070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define APPN_DATA_LEN	14	/* Must be the largest of the above!! */
58170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
58270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
58370a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void)
58470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineexamine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
58570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	      unsigned int datalen, INT32 remaining)
58670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Examine first few bytes from an APP0.
58770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Take appropriate action if it is a JFIF marker.
58870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * datalen is # of bytes at data[], remaining is length of rest of marker data.
58970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
59070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
59170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INT32 totallen = (INT32) datalen + remaining;
59270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
59370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (datalen >= APP0_DATA_LEN &&
59470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[0]) == 0x4A &&
59570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[1]) == 0x46 &&
59670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[2]) == 0x49 &&
59770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[3]) == 0x46 &&
59870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[4]) == 0) {
59970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Found JFIF APP0 marker: save info */
60070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->saw_JFIF_marker = TRUE;
60170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->JFIF_major_version = GETJOCTET(data[5]);
60270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->JFIF_minor_version = GETJOCTET(data[6]);
60370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->density_unit = GETJOCTET(data[7]);
60470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
60570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
60670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Check version.
60770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * Major version must be 1, anything else signals an incompatible change.
60870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * (We used to treat this as an error, but now it's a nonfatal warning,
60970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * because some bozo at Hijaak couldn't read the spec.)
61070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * Minor version should be 0..2, but process anyway if newer.
61170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     */
61270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (cinfo->JFIF_major_version != 1)
61370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      WARNMS2(cinfo, JWRN_JFIF_MAJOR,
61470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	      cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
61570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Generate trace messages */
61670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS5(cinfo, 1, JTRC_JFIF,
61770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	     cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
61870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	     cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
61970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Validate thumbnail dimensions and issue appropriate messages */
62070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
62170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
62270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	       GETJOCTET(data[12]), GETJOCTET(data[13]));
62370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    totallen -= APP0_DATA_LEN;
62470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (totallen !=
62570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3))
62670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);
62770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  } else if (datalen >= 6 &&
62870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[0]) == 0x4A &&
62970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[1]) == 0x46 &&
63070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[2]) == 0x58 &&
63170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[3]) == 0x58 &&
63270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[4]) == 0) {
63370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Found JFIF "JFXX" extension APP0 marker */
63470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* The library doesn't actually do anything with these,
63570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * but we try to produce a helpful trace message.
63670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     */
63770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    switch (GETJOCTET(data[5])) {
63870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case 0x10:
63970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);
64070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
64170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case 0x11:
64270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);
64370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
64470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case 0x13:
64570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);
64670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
64770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    default:
64870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
64970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	       GETJOCTET(data[5]), (int) totallen);
65070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
65170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
65270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  } else {
65370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Start of APP0 does not match "JFIF" or "JFXX", or too short */
65470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);
65570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
65670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
65770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
65870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
65970a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void)
66070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineexamine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data,
66170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	       unsigned int datalen, INT32 remaining)
66270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Examine first few bytes from an APP14.
66370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Take appropriate action if it is an Adobe marker.
66470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * datalen is # of bytes at data[], remaining is length of rest of marker data.
66570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
66670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
66770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  unsigned int version, flags0, flags1, transform;
66870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
66970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (datalen >= APP14_DATA_LEN &&
67070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[0]) == 0x41 &&
67170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[1]) == 0x64 &&
67270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[2]) == 0x6F &&
67370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[3]) == 0x62 &&
67470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      GETJOCTET(data[4]) == 0x65) {
67570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Found Adobe APP14 marker */
67670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
67770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
67870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
67970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    transform = GETJOCTET(data[11]);
68070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
68170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->saw_Adobe_marker = TRUE;
68270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->Adobe_transform = (UINT8) transform;
68370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  } else {
68470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Start of APP14 does not match "Adobe", or too short */
68570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));
68670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
68770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
68870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
68970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
69070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(boolean)
69170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineget_interesting_appn (j_decompress_ptr cinfo)
69270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Process an APP0 or APP14 marker without saving it */
69370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
69470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INT32 length;
69570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  JOCTET b[APPN_DATA_LEN];
69670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  unsigned int i, numtoread;
69770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_VARS(cinfo);
69870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
69970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_2BYTES(cinfo, length, return FALSE);
70070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  length -= 2;
70170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
70270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* get the interesting part of the marker data */
70370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (length >= APPN_DATA_LEN)
70470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    numtoread = APPN_DATA_LEN;
70570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  else if (length > 0)
70670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    numtoread = (unsigned int) length;
70770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  else
70870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    numtoread = 0;
70970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  for (i = 0; i < numtoread; i++)
71070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_BYTE(cinfo, b[i], return FALSE);
71170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  length -= numtoread;
71270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
71370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* process it */
71470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  switch (cinfo->unread_marker) {
71570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  case M_APP0:
71670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length);
71770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    break;
71870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  case M_APP14:
71970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length);
72070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    break;
72170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  default:
72270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* can't get here unless jpeg_save_markers chooses wrong processor */
72370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
72470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    break;
72570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
72670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
72770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* skip any remaining data -- could be lots */
72870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_SYNC(cinfo);
72970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (length > 0)
73070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    (*cinfo->src->skip_input_data) (cinfo, (long) length);
73170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
73270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;
73370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
73470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
73570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
73670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef SAVE_MARKERS_SUPPORTED
73770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
73870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(boolean)
73970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinesave_marker (j_decompress_ptr cinfo)
74070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Save an APPn or COM marker into the marker list */
74170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
74270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
74370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jpeg_saved_marker_ptr cur_marker = marker->cur_marker;
74470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  unsigned int bytes_read, data_length;
74570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  JOCTET FAR * data;
74670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INT32 length = 0;
74770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_VARS(cinfo);
74870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
74970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (cur_marker == NULL) {
75070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* begin reading a marker */
75170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_2BYTES(cinfo, length, return FALSE);
75270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    length -= 2;
75370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (length >= 0) {		/* watch out for bogus length word */
75470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* figure out how much we want to save */
75570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      unsigned int limit;
75670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (cinfo->unread_marker == (int) M_COM)
75770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	limit = marker->length_limit_COM;
75870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      else
75970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];
76070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if ((unsigned int) length < limit)
76170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	limit = (unsigned int) length;
76270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* allocate and initialize the marker item */
76370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cur_marker = (jpeg_saved_marker_ptr)
76470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	(*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
76570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine				    SIZEOF(struct jpeg_marker_struct) + limit);
76670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cur_marker->next = NULL;
76770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cur_marker->marker = (UINT8) cinfo->unread_marker;
76870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cur_marker->original_length = (unsigned int) length;
76970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cur_marker->data_length = limit;
77070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* data area is just beyond the jpeg_marker_struct */
77170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1);
77270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      marker->cur_marker = cur_marker;
77370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      marker->bytes_read = 0;
77470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      bytes_read = 0;
77570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      data_length = limit;
77670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    } else {
77770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* deal with bogus length word */
77870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      bytes_read = data_length = 0;
77970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      data = NULL;
78070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
78170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  } else {
78270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* resume reading a marker */
78370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    bytes_read = marker->bytes_read;
78470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    data_length = cur_marker->data_length;
78570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    data = cur_marker->data + bytes_read;
78670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
78770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
78870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  while (bytes_read < data_length) {
78970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_SYNC(cinfo);		/* move the restart point to here */
79070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    marker->bytes_read = bytes_read;
79170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* If there's not at least one byte in buffer, suspend */
79270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    MAKE_BYTE_AVAIL(cinfo, return FALSE);
79370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Copy bytes with reasonable rapidity */
79470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    while (bytes_read < data_length && bytes_in_buffer > 0) {
79570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      *data++ = *next_input_byte++;
79670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      bytes_in_buffer--;
79770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      bytes_read++;
79870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
79970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
80070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
80170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Done reading what we want to read */
80270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (cur_marker != NULL) {	/* will be NULL if bogus length word */
80370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Add new marker to end of list */
80470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (cinfo->marker_list == NULL) {
80570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cinfo->marker_list = cur_marker;
80670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    } else {
80770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      jpeg_saved_marker_ptr prev = cinfo->marker_list;
80870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      while (prev->next != NULL)
80970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	prev = prev->next;
81070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      prev->next = cur_marker;
81170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
81270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Reset pointer & calc remaining data length */
81370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    data = cur_marker->data;
81470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    length = cur_marker->original_length - data_length;
81570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
81670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Reset to initial state for next marker */
81770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->cur_marker = NULL;
81870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
81970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Process the marker if interesting; else just make a generic trace msg */
82070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  switch (cinfo->unread_marker) {
82170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  case M_APP0:
82270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    examine_app0(cinfo, data, data_length, length);
82370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    break;
82470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  case M_APP14:
82570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    examine_app14(cinfo, data, data_length, length);
82670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    break;
82770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  default:
82870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
82970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	     (int) (data_length + length));
83070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    break;
83170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
83270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
83370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* skip any remaining data -- could be lots */
83470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_SYNC(cinfo);		/* do before skip_input_data */
83570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (length > 0)
83670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    (*cinfo->src->skip_input_data) (cinfo, (long) length);
83770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
83870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;
83970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
84070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
84170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif /* SAVE_MARKERS_SUPPORTED */
84270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
84370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
84470a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(boolean)
84570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineskip_variable (j_decompress_ptr cinfo)
84670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Skip over an unknown or uninteresting variable-length marker */
84770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
84870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INT32 length;
84970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_VARS(cinfo);
85070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
85170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_2BYTES(cinfo, length, return FALSE);
85270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  length -= 2;
85370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
85470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);
85570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
85670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_SYNC(cinfo);		/* do before skip_input_data */
85770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (length > 0)
85870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    (*cinfo->src->skip_input_data) (cinfo, (long) length);
85970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
86070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;
86170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
86270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
86370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
86470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
86570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Find the next JPEG marker, save it in cinfo->unread_marker.
86670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Returns FALSE if had to suspend before reaching a marker;
86770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * in that case cinfo->unread_marker is unchanged.
86870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
86970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Note that the result might not be a valid marker code,
87070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * but it will never be 0 or FF.
87170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
87270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
87370a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(boolean)
87470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinenext_marker (j_decompress_ptr cinfo)
87570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
87670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  int c;
87770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_VARS(cinfo);
87870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
87970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  for (;;) {
88070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_BYTE(cinfo, c, return FALSE);
88170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Skip any non-FF bytes.
88270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * This may look a bit inefficient, but it will not occur in a valid file.
88370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * We sync after each discarded byte so that a suspending data source
88470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * can discard the byte from its buffer.
88570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     */
88670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    while (c != 0xFF) {
88770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cinfo->marker->discarded_bytes++;
88870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      INPUT_SYNC(cinfo);
88970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      INPUT_BYTE(cinfo, c, return FALSE);
89070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
89170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* This loop swallows any duplicate FF bytes.  Extra FFs are legal as
89270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * pad bytes, so don't count them in discarded_bytes.  We assume there
89370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * will not be so many consecutive FF bytes as to overflow a suspending
89470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * data source's input buffer.
89570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     */
89670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    do {
89770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      INPUT_BYTE(cinfo, c, return FALSE);
89870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    } while (c == 0xFF);
89970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (c != 0)
90070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;			/* found a valid marker, exit loop */
90170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Reach here if we found a stuffed-zero data sequence (FF/00).
90270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * Discard it and loop back to try again.
90370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     */
90470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->marker->discarded_bytes += 2;
90570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    INPUT_SYNC(cinfo);
90670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
90770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
90870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (cinfo->marker->discarded_bytes != 0) {
90970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);
91070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->marker->discarded_bytes = 0;
91170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
91270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
91370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->unread_marker = c;
91470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
91570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_SYNC(cinfo);
91670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;
91770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
91870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
91970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
92070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(boolean)
92170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinefirst_marker (j_decompress_ptr cinfo)
92270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Like next_marker, but used to obtain the initial SOI marker. */
92370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* For this marker, we do not allow preceding garbage or fill; otherwise,
92470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * we might well scan an entire input file before realizing it ain't JPEG.
92570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * If an application wants to process non-JFIF files, it must seek to the
92670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * SOI before calling the JPEG library.
92770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
92870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
92970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  int c, c2;
93070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_VARS(cinfo);
93170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
93270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_BYTE(cinfo, c, return FALSE);
93370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_BYTE(cinfo, c2, return FALSE);
93470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (c != 0xFF || c2 != (int) M_SOI)
93570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT2(cinfo, JERR_NO_SOI, c, c2);
93670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
93770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->unread_marker = c2;
93870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
93970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  INPUT_SYNC(cinfo);
94070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;
94170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
94270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
94370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
94470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
94570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Read markers until SOS or EOI.
94670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
94770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Returns same codes as are defined for jpeg_consume_input:
94870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
94970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
95070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
95170a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(int)
95270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineread_markers (j_decompress_ptr cinfo)
95370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
95470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Outer loop repeats once for each marker. */
95570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  for (;;) {
95670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Collect the marker proper, unless we already did. */
95770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* NB: first_marker() enforces the requirement that SOI appear first. */
95870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (cinfo->unread_marker == 0) {
95970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! cinfo->marker->saw_SOI) {
96070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	if (! first_marker(cinfo))
96170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	  return JPEG_SUSPENDED;
96270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      } else {
96370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	if (! next_marker(cinfo))
96470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	  return JPEG_SUSPENDED;
96570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      }
96670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
96770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
96870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /*
96970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * Save the position of the fist marker after SOF.
97070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     */
97170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (cinfo->marker->current_sos_marker_position == -1)
97270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cinfo->marker->current_sos_marker_position =
97370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine          jget_input_stream_position(cinfo) - 2;
97470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
97570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* At this point cinfo->unread_marker contains the marker code and the
97670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * input point is just past the marker proper, but before any parameters.
97770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     * A suspension will cause us to return with this state still true.
97870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine     */
97970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    switch (cinfo->unread_marker) {
98070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOI:
98170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! get_soi(cinfo))
98270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return JPEG_SUSPENDED;
98370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
98470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
98570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOF0:		/* Baseline */
98670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOF1:		/* Extended sequential, Huffman */
98770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! get_sof(cinfo, FALSE, FALSE))
98870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return JPEG_SUSPENDED;
98970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
99070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
99170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOF2:		/* Progressive, Huffman */
99270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cinfo->marker->current_sos_marker_position = -1;
99370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! get_sof(cinfo, TRUE, FALSE))
99470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return JPEG_SUSPENDED;
99570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
99670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
99770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOF9:		/* Extended sequential, arithmetic */
99870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! get_sof(cinfo, FALSE, TRUE))
99970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return JPEG_SUSPENDED;
100070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
100170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
100270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOF10:		/* Progressive, arithmetic */
100370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! get_sof(cinfo, TRUE, TRUE))
100470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return JPEG_SUSPENDED;
100570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
100670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
100770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Currently unsupported SOFn types */
100870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOF3:		/* Lossless, Huffman */
100970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOF5:		/* Differential sequential, Huffman */
101070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOF6:		/* Differential progressive, Huffman */
101170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOF7:		/* Differential lossless, Huffman */
101270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_JPG:			/* Reserved for JPEG extensions */
101370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOF11:		/* Lossless, arithmetic */
101470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOF13:		/* Differential sequential, arithmetic */
101570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOF14:		/* Differential progressive, arithmetic */
101670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOF15:		/* Differential lossless, arithmetic */
101770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);
101870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
101970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
102070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_SOS:
102170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! get_sos(cinfo))
102270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return JPEG_SUSPENDED;
102370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cinfo->unread_marker = 0;	/* processed the marker */
102470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      return JPEG_REACHED_SOS;
102570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
102670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_EOI:
102770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      TRACEMS(cinfo, 1, JTRC_EOI);
102870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cinfo->unread_marker = 0;	/* processed the marker */
102970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      return JPEG_REACHED_EOI;
103070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
103170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_DAC:
103270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! get_dac(cinfo))
103370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return JPEG_SUSPENDED;
103470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
103570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
103670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_DHT:
103770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! get_dht(cinfo))
103870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return JPEG_SUSPENDED;
103970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
104070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
104170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_DQT:
104270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! get_dqt(cinfo))
104370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return JPEG_SUSPENDED;
104470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
104570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
104670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_DRI:
104770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! get_dri(cinfo))
104870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return JPEG_SUSPENDED;
104970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
105070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
105170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP0:
105270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP1:
105370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP2:
105470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP3:
105570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP4:
105670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP5:
105770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP6:
105870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP7:
105970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP8:
106070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP9:
106170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP10:
106270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP11:
106370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP12:
106470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP13:
106570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP14:
106670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_APP15:
106770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[
106870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		cinfo->unread_marker - (int) M_APP0]) (cinfo))
106970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return JPEG_SUSPENDED;
107070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
107170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
107270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_COM:
107370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
107470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return JPEG_SUSPENDED;
107570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
107670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
107770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_RST0:		/* these are all parameterless */
107870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_RST1:
107970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_RST2:
108070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_RST3:
108170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_RST4:
108270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_RST5:
108370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_RST6:
108470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_RST7:
108570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_TEM:
108670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);
108770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
108870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
108970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case M_DNL:			/* Ignore DNL ... perhaps the wrong thing */
109070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! skip_variable(cinfo))
109170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return JPEG_SUSPENDED;
109270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
109370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
109470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    default:			/* must be DHP, EXP, JPGn, or RESn */
109570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* For now, we treat the reserved markers as fatal errors since they are
109670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine       * likely to be used to signal incompatible JPEG Part 3 extensions.
109770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine       * Once the JPEG 3 version-number marker is well defined, this code
109870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine       * ought to change!
109970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine       */
110070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
110170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
110270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
110370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Successfully processed marker, so reset state variable */
110470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->unread_marker = 0;
110570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  } /* end loop */
110670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
110770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
110870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
110970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
111070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Read a restart marker, which is expected to appear next in the datastream;
111170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * if the marker is not there, take appropriate recovery action.
111270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Returns FALSE if suspension is required.
111370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
111470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This is called by the entropy decoder after it has read an appropriate
111570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * number of MCUs.  cinfo->unread_marker may be nonzero if the entropy decoder
111670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * has already read a marker from the data source.  Under normal conditions
111770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * cinfo->unread_marker will be reset to 0 before returning; if not reset,
111870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * it holds a marker which the decoder will be unable to read past.
111970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
112070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
112170a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(boolean)
112270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineread_restart_marker (j_decompress_ptr cinfo)
112370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
112470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Obtain a marker unless we already did. */
112570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Note that next_marker will complain if it skips any data. */
112670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (cinfo->unread_marker == 0) {
112770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (! next_marker(cinfo))
112870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      return FALSE;
112970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
113070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
113170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (cinfo->unread_marker ==
113270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      ((int) M_RST0 + cinfo->marker->next_restart_num)) {
113370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Normal case --- swallow the marker and let entropy decoder continue */
113470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);
113570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    cinfo->unread_marker = 0;
113670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  } else {
113770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Uh-oh, the restart markers have been messed up. */
113870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* Let the data source manager determine how to resync. */
113970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (! (*cinfo->src->resync_to_restart) (cinfo,
114070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine					    cinfo->marker->next_restart_num))
114170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      return FALSE;
114270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
114370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
114470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Update next-restart state */
114570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;
114670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
114770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  return TRUE;
114870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
114970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
115070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
115170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
115270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This is the default resync_to_restart method for data source managers
115370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * to use if they don't have any better approach.  Some data source managers
115470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * may be able to back up, or may have additional knowledge about the data
115570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * which permits a more intelligent recovery strategy; such managers would
115670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * presumably supply their own resync method.
115770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
115870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * read_restart_marker calls resync_to_restart if it finds a marker other than
115970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * the restart marker it was expecting.  (This code is *not* used unless
116070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * a nonzero restart interval has been declared.)  cinfo->unread_marker is
116170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * the marker code actually found (might be anything, except 0 or FF).
116270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * The desired restart marker number (0..7) is passed as a parameter.
116370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This routine is supposed to apply whatever error recovery strategy seems
116470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * appropriate in order to position the input stream to the next data segment.
116570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Note that cinfo->unread_marker is treated as a marker appearing before
116670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * the current data-source input point; usually it should be reset to zero
116770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * before returning.
116870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Returns FALSE if suspension is required.
116970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
117070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This implementation is substantially constrained by wanting to treat the
117170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * input as a data stream; this means we can't back up.  Therefore, we have
117270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * only the following actions to work with:
117370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *   1. Simply discard the marker and let the entropy decoder resume at next
117470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *      byte of file.
117570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *   2. Read forward until we find another marker, discarding intervening
117670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *      data.  (In theory we could look ahead within the current bufferload,
117770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *      without having to discard data if we don't find the desired marker.
117870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *      This idea is not implemented here, in part because it makes behavior
117970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *      dependent on buffer size and chance buffer-boundary positions.)
118070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *   3. Leave the marker unread (by failing to zero cinfo->unread_marker).
118170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *      This will cause the entropy decoder to process an empty data segment,
118270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *      inserting dummy zeroes, and then we will reprocess the marker.
118370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *
118470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * #2 is appropriate if we think the desired marker lies ahead, while #3 is
118570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * appropriate if the found marker is a future restart marker (indicating
118670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * that we have missed the desired restart marker, probably because it got
118770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * corrupted).
118870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * We apply #2 or #3 if the found marker is a restart marker no more than
118970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * two counts behind or ahead of the expected one.  We also apply #2 if the
119070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * found marker is not a legal JPEG marker code (it's certainly bogus data).
119170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * If the found marker is a restart marker more than 2 counts away, we do #1
119270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * (too much risk that the marker is erroneous; with luck we will be able to
119370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * resync at some future point).
119470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * For any valid non-restart JPEG marker, we apply #3.  This keeps us from
119570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * overrunning the end of a scan.  An implementation limited to single-scan
119670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * files might find it better to apply #2 for markers other than EOI, since
119770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * any other marker would have to be bogus data in that case.
119870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
119970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
120070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(boolean)
120170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
120270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
120370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  int marker = cinfo->unread_marker;
120470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  int action = 1;
120570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
120670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Always put up a warning. */
120770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);
120870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
120970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Outer loop handles repeated decision after scanning forward. */
121070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  for (;;) {
121170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (marker < (int) M_SOF0)
121270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      action = 2;		/* invalid marker */
121370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    else if (marker < (int) M_RST0 || marker > (int) M_RST7)
121470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      action = 3;		/* valid non-restart marker */
121570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    else {
121670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (marker == ((int) M_RST0 + ((desired+1) & 7)) ||
121770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	  marker == ((int) M_RST0 + ((desired+2) & 7)))
121870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	action = 3;		/* one of the next two expected restarts */
121970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      else if (marker == ((int) M_RST0 + ((desired-1) & 7)) ||
122070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	       marker == ((int) M_RST0 + ((desired-2) & 7)))
122170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	action = 2;		/* a prior restart, so advance */
122270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      else
122370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	action = 1;		/* desired restart or too far away */
122470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
122570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);
122670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    switch (action) {
122770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case 1:
122870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* Discard marker and let entropy decoder resume processing. */
122970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cinfo->unread_marker = 0;
123070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      return TRUE;
123170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case 2:
123270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* Scan to the next marker, and repeat the decision loop. */
123370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      if (! next_marker(cinfo))
123470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine	return FALSE;
123570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      marker = cinfo->unread_marker;
123670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
123770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    case 3:
123870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* Return without advancing past this marker. */
123970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      /* Entropy decoder will be forced to process an empty segment. */
124070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      return TRUE;
124170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
124270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  } /* end loop */
124370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
124470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
124570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
124670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Get the position for all SOS markers in the image.
124770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
124870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
124970a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void)
125070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineget_sos_marker_position(j_decompress_ptr cinfo, huffman_index *index)
125170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
125270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  unsigned char *head;
125370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  int count = 0;
125470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  int retcode = JPEG_REACHED_SOS;
125570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
125670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  while (cinfo->src->bytes_in_buffer > 0) {
125770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (retcode == JPEG_REACHED_SOS) {
125870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      jpeg_configure_huffman_index_scan(cinfo, index, count++,
125970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine              cinfo->marker->current_sos_marker_position);
126070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      // Skips scan content to the next non-RST JPEG marker.
126170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      while(next_marker(cinfo) &&
126270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine              cinfo->unread_marker >= M_RST0 && cinfo->unread_marker <= M_RST7)
126370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine          ;
126470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      cinfo->marker->current_sos_marker_position =
126570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine        jget_input_stream_position(cinfo) - 2;
126670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      retcode = read_markers(cinfo);
126770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    } else {
126870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      break;
126970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    }
127070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
127170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
127270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
127370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
127470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Reset marker processing state to begin a fresh datastream.
127570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
127670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
127770a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void)
127870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinereset_marker_reader (j_decompress_ptr cinfo)
127970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
128070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
128170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
128270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->comp_info = NULL;		/* until allocated by get_sof */
128370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->input_scan_number = 0;		/* no SOS seen yet */
128470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->unread_marker = 0;		/* no pending marker */
128570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->pub.saw_SOI = FALSE;		/* set internal state too */
128670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->pub.saw_SOF = FALSE;
128770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->pub.discarded_bytes = 0;
128870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->cur_marker = NULL;
128970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
129070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
129170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
129270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
129370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Initialize the marker reader module.
129470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This is called only once, when the decompression object is created.
129570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
129670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
129770a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void)
129870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejinit_marker_reader (j_decompress_ptr cinfo)
129970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
130070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  my_marker_ptr marker;
130170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  int i;
130270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
130370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Create subobject in permanent pool */
130470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker = (my_marker_ptr)
130570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
130670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine				SIZEOF(my_marker_reader));
130770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  cinfo->marker = (struct jpeg_marker_reader *) marker;
130870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Initialize public method pointers */
130970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->pub.reset_marker_reader = reset_marker_reader;
131070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->pub.read_markers = read_markers;
131170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->pub.read_restart_marker = read_restart_marker;
131270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->pub.get_sos_marker_position = get_sos_marker_position;
131370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
131470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  // Initialize the SOS marker position to avoid underdefined behavior due to
131570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  // using a undefined field.
131670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->pub.current_sos_marker_position = 0;
131770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
131870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Initialize COM/APPn processing.
131970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   * By default, we examine and then discard APP0 and APP14,
132070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   * but simply discard COM and all other APPn.
132170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   */
132270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->process_COM = skip_variable;
132370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->length_limit_COM = 0;
132470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  for (i = 0; i < 16; i++) {
132570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    marker->process_APPn[i] = skip_variable;
132670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    marker->length_limit_APPn[i] = 0;
132770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
132870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->process_APPn[0] = get_interesting_appn;
132970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  marker->process_APPn[14] = get_interesting_appn;
133070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Reset marker processing state */
133170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  reset_marker_reader(cinfo);
133270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
133370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
133470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
133570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
133670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Control saving of COM and APPn markers into marker_list.
133770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
133870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
133970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef SAVE_MARKERS_SUPPORTED
134070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
134170a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void)
134270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejpeg_save_markers (j_decompress_ptr cinfo, int marker_code,
134370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine		   unsigned int length_limit)
134470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
134570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
134670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  long maxlength;
134770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  jpeg_marker_parser_method processor;
134870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
134970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Length limit mustn't be larger than what we can allocate
135070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   * (should only be a concern in a 16-bit environment).
135170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   */
135270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct);
135370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (((long) length_limit) > maxlength)
135470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    length_limit = (unsigned int) maxlength;
135570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
135670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  /* Choose processor routine to use.
135770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   * APP0/APP14 have special requirements.
135870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine   */
135970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (length_limit) {
136070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    processor = save_marker;
136170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* If saving APP0/APP14, save at least enough for our internal use. */
136270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)
136370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      length_limit = APP0_DATA_LEN;
136470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)
136570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      length_limit = APP14_DATA_LEN;
136670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  } else {
136770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    processor = skip_variable;
136870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    /* If discarding APP0/APP14, use our regular on-the-fly processor. */
136970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)
137070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine      processor = get_interesting_appn;
137170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  }
137270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
137370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (marker_code == (int) M_COM) {
137470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    marker->process_COM = processor;
137570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    marker->length_limit_COM = length_limit;
137670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {
137770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    marker->process_APPn[marker_code - (int) M_APP0] = processor;
137870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;
137970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  } else
138070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
138170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
138270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
138370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif /* SAVE_MARKERS_SUPPORTED */
138470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
138570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
138670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/*
138770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Install a special processing method for COM or APPn markers.
138870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */
138970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
139070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void)
139170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
139270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine			   jpeg_marker_parser_method routine)
139370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{
139470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
139570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine
139670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  if (marker_code == (int) M_COM)
139770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    marker->process_COM = routine;
139870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)
139970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    marker->process_APPn[marker_code - (int) M_APP0] = routine;
140070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine  else
140170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
140270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine}
1403