136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * jdmarker.c
336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
4a73e870ad02de20c2b34cb3a5382c2846c2afbe3DRC * This file was part of the Independent JPEG Group's software:
55ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * Copyright (C) 1991-1998, Thomas G. Lane.
6a6ef282a49f2d7d1b4d19cc89f63e81fd66b35b7DRC * libjpeg-turbo Modifications:
76eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis * Copyright (C) 2012, 2015, D. R. Commander.
86eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis * For conditions of distribution and use, see the accompanying README.ijg
96eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis * file.
1036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
1136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This file contains routines to decode JPEG datastream markers.
1236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Most of the complexity arises from our desire to support input
1336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * suspension: if not all of the data for a marker is available,
1436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * we must exit back to the application.  On resumption, we reprocess
1536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * the marker.
1636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
1736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
1836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#define JPEG_INTERNALS
1936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#include "jinclude.h"
2036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#include "jpeglib.h"
2136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
2236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
23e5eaf37440b8e337ab150c017df7c03faf846c51DRCtypedef enum {                  /* JPEG marker codes */
2436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOF0  = 0xc0,
2536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOF1  = 0xc1,
2636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOF2  = 0xc2,
2736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOF3  = 0xc3,
28e5eaf37440b8e337ab150c017df7c03faf846c51DRC
2936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOF5  = 0xc5,
3036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOF6  = 0xc6,
3136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOF7  = 0xc7,
32e5eaf37440b8e337ab150c017df7c03faf846c51DRC
3336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_JPG   = 0xc8,
3436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOF9  = 0xc9,
3536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOF10 = 0xca,
3636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOF11 = 0xcb,
37e5eaf37440b8e337ab150c017df7c03faf846c51DRC
3836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOF13 = 0xcd,
3936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOF14 = 0xce,
4036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOF15 = 0xcf,
41e5eaf37440b8e337ab150c017df7c03faf846c51DRC
4236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_DHT   = 0xc4,
43e5eaf37440b8e337ab150c017df7c03faf846c51DRC
4436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_DAC   = 0xcc,
45e5eaf37440b8e337ab150c017df7c03faf846c51DRC
4636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_RST0  = 0xd0,
4736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_RST1  = 0xd1,
4836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_RST2  = 0xd2,
4936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_RST3  = 0xd3,
5036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_RST4  = 0xd4,
5136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_RST5  = 0xd5,
5236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_RST6  = 0xd6,
5336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_RST7  = 0xd7,
54e5eaf37440b8e337ab150c017df7c03faf846c51DRC
5536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOI   = 0xd8,
5636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_EOI   = 0xd9,
5736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_SOS   = 0xda,
5836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_DQT   = 0xdb,
5936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_DNL   = 0xdc,
6036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_DRI   = 0xdd,
6136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_DHP   = 0xde,
6236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_EXP   = 0xdf,
63e5eaf37440b8e337ab150c017df7c03faf846c51DRC
6436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP0  = 0xe0,
6536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP1  = 0xe1,
6636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP2  = 0xe2,
6736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP3  = 0xe3,
6836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP4  = 0xe4,
6936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP5  = 0xe5,
7036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP6  = 0xe6,
7136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP7  = 0xe7,
7236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP8  = 0xe8,
7336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP9  = 0xe9,
7436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP10 = 0xea,
7536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP11 = 0xeb,
7636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP12 = 0xec,
7736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP13 = 0xed,
7836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP14 = 0xee,
7936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_APP15 = 0xef,
80e5eaf37440b8e337ab150c017df7c03faf846c51DRC
8136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_JPG0  = 0xf0,
8236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_JPG13 = 0xfd,
8336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_COM   = 0xfe,
84e5eaf37440b8e337ab150c017df7c03faf846c51DRC
8536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_TEM   = 0x01,
86e5eaf37440b8e337ab150c017df7c03faf846c51DRC
8736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  M_ERROR = 0x100
8836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} JPEG_MARKER;
8936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
9036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
915ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane/* Private state */
925ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
935ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lanetypedef struct {
945ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  struct jpeg_marker_reader pub; /* public fields */
955ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
965ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* Application-overridable marker processing methods */
975ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  jpeg_marker_parser_method process_COM;
985ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  jpeg_marker_parser_method process_APPn[16];
995ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
1005ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* Limit on marker data length to save for each marker type */
1015ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  unsigned int length_limit_COM;
1025ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  unsigned int length_limit_APPn[16];
1035ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
1045ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* Status of COM/APPn marker saving */
105e5eaf37440b8e337ab150c017df7c03faf846c51DRC  jpeg_saved_marker_ptr cur_marker;     /* NULL if not processing a marker */
106e5eaf37440b8e337ab150c017df7c03faf846c51DRC  unsigned int bytes_read;              /* data bytes read so far in marker */
1075ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* Note: cur_marker is not linked into marker_list until it's all read. */
1085ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane} my_marker_reader;
1095ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
1106eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidistypedef my_marker_reader *my_marker_ptr;
1115ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
1125ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
11336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
11436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Macros for fetching data from the data source module.
11536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
11636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect
11736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * the current restart point; we update them only when we have reached a
11836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * suitable place to restart if a suspension occurs.
11936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
12036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
12136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Declare and initialize local copies of input pointer/count */
12236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#define INPUT_VARS(cinfo)  \
1236eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis        struct jpeg_source_mgr *datasrc = (cinfo)->src;  \
1246eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis        const JOCTET *next_input_byte = datasrc->next_input_byte;  \
125e5eaf37440b8e337ab150c017df7c03faf846c51DRC        size_t bytes_in_buffer = datasrc->bytes_in_buffer
12636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
12736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Unload the local copies --- do this only at a restart boundary */
12836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#define INPUT_SYNC(cinfo)  \
129e5eaf37440b8e337ab150c017df7c03faf846c51DRC        ( datasrc->next_input_byte = next_input_byte,  \
130e5eaf37440b8e337ab150c017df7c03faf846c51DRC          datasrc->bytes_in_buffer = bytes_in_buffer )
13136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
1325ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */
13336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#define INPUT_RELOAD(cinfo)  \
134e5eaf37440b8e337ab150c017df7c03faf846c51DRC        ( next_input_byte = datasrc->next_input_byte,  \
135e5eaf37440b8e337ab150c017df7c03faf846c51DRC          bytes_in_buffer = datasrc->bytes_in_buffer )
13636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
13736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.
13836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
13936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * but we must reload the local copies after a successful fill.
14036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
14136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#define MAKE_BYTE_AVAIL(cinfo,action)  \
142e5eaf37440b8e337ab150c017df7c03faf846c51DRC        if (bytes_in_buffer == 0) {  \
143e5eaf37440b8e337ab150c017df7c03faf846c51DRC          if (! (*datasrc->fill_input_buffer) (cinfo))  \
144e5eaf37440b8e337ab150c017df7c03faf846c51DRC            { action; }  \
145e5eaf37440b8e337ab150c017df7c03faf846c51DRC          INPUT_RELOAD(cinfo);  \
146e5eaf37440b8e337ab150c017df7c03faf846c51DRC        }
14736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
14836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Read a byte into variable V.
14936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * If must suspend, take the specified action (typically "return FALSE").
15036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
15136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#define INPUT_BYTE(cinfo,V,action)  \
152e5eaf37440b8e337ab150c017df7c03faf846c51DRC        MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
153e5eaf37440b8e337ab150c017df7c03faf846c51DRC                  bytes_in_buffer--; \
154e5eaf37440b8e337ab150c017df7c03faf846c51DRC                  V = GETJOCTET(*next_input_byte++); )
15536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
15636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* As above, but read two bytes interpreted as an unsigned 16-bit integer.
1576eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis * V should be declared unsigned int or perhaps JLONG.
15836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
15936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#define INPUT_2BYTES(cinfo,V,action)  \
160e5eaf37440b8e337ab150c017df7c03faf846c51DRC        MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
161e5eaf37440b8e337ab150c017df7c03faf846c51DRC                  bytes_in_buffer--; \
162e5eaf37440b8e337ab150c017df7c03faf846c51DRC                  V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
163e5eaf37440b8e337ab150c017df7c03faf846c51DRC                  MAKE_BYTE_AVAIL(cinfo,action); \
164e5eaf37440b8e337ab150c017df7c03faf846c51DRC                  bytes_in_buffer--; \
165e5eaf37440b8e337ab150c017df7c03faf846c51DRC                  V += GETJOCTET(*next_input_byte++); )
16636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
16736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
16836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
16936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Routines to process JPEG markers.
17036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
17136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Entry condition: JPEG marker itself has been read and its code saved
17236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *   in cinfo->unread_marker; input restart point is just after the marker.
17336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
17436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Exit: if return TRUE, have read and processed any parameters, and have
17536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *   updated the restart point to point after the parameters.
17636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *   If return FALSE, was forced to suspend before reaching end of
17736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *   marker parameters; restart point has not been moved.  Same routine
17836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *   will be called again after application supplies more input data.
17936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
1805ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * This approach to suspension assumes that all of a marker's parameters
1815ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * can fit into a single input bufferload.  This should hold for "normal"
1825ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * markers.  Some COM/APPn markers might have large parameter segments
1835ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * that might not fit.  If we are simply dropping such a marker, we use
1845ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * skip_input_data to get past it, and thereby put the problem on the
1855ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * source manager's shoulders.  If we are saving the marker's contents
1865ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * into memory, we use a slightly different convention: when forced to
1875ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * suspend, the marker processor updates the restart point to the end of
1885ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * what it's consumed (ie, the end of the buffer) before returning FALSE.
1895ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * On resumption, cinfo->unread_marker still contains the marker code,
1905ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * but the data source will point to the next chunk of marker data.
1915ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * The marker processor must retain internal state to deal with this.
19236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
19336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Note that we don't bother to avoid duplicate trace messages if a
19436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * suspension occurs within marker parameters.  Other side effects
19536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * require more care.
19636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
19736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
19836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
199489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneLOCAL(boolean)
20036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneget_soi (j_decompress_ptr cinfo)
20136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Process an SOI marker */
20236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
20336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int i;
204e5eaf37440b8e337ab150c017df7c03faf846c51DRC
20536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  TRACEMS(cinfo, 1, JTRC_SOI);
20636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
20736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (cinfo->marker->saw_SOI)
20836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    ERREXIT(cinfo, JERR_SOI_DUPLICATE);
20936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
21036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Reset all parameters that are defined to be reset by SOI */
21136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
21236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  for (i = 0; i < NUM_ARITH_TBLS; i++) {
21336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    cinfo->arith_dc_L[i] = 0;
21436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    cinfo->arith_dc_U[i] = 1;
21536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    cinfo->arith_ac_K[i] = 5;
21636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
21736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->restart_interval = 0;
21836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
21936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Set initial assumptions for colorspace etc */
22036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
22136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->jpeg_color_space = JCS_UNKNOWN;
22236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
22336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
22436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->saw_JFIF_marker = FALSE;
2255ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */
2265ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  cinfo->JFIF_minor_version = 1;
2275ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  cinfo->density_unit = 0;
22836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->X_density = 1;
22936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->Y_density = 1;
23036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->saw_Adobe_marker = FALSE;
23136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->Adobe_transform = 0;
23236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
23336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->marker->saw_SOI = TRUE;
23436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
23536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  return TRUE;
23636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
23736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
23836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
239489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneLOCAL(boolean)
240bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Laneget_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
24136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Process a SOFn marker */
24236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
2436eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis  JLONG length;
24436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int c, ci;
2456eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis  jpeg_component_info *compptr;
24636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_VARS(cinfo);
24736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
248bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane  cinfo->progressive_mode = is_prog;
249bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane  cinfo->arith_code = is_arith;
250bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane
25136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_2BYTES(cinfo, length, return FALSE);
25236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
25336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);
25436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE);
25536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE);
25636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);
25736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
25836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  length -= 8;
25936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
26036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,
261e5eaf37440b8e337ab150c017df7c03faf846c51DRC           (int) cinfo->image_width, (int) cinfo->image_height,
262e5eaf37440b8e337ab150c017df7c03faf846c51DRC           cinfo->num_components);
26336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
26436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (cinfo->marker->saw_SOF)
26536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    ERREXIT(cinfo, JERR_SOF_DUPLICATE);
26636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
26736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* We don't support files in which the image height is initially specified */
26836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* as 0 and is later redefined by DNL.  As long as we have to check that,  */
26936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* might as well have a general sanity check. */
27036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (cinfo->image_height <= 0 || cinfo->image_width <= 0
27136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      || cinfo->num_components <= 0)
27236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    ERREXIT(cinfo, JERR_EMPTY_IMAGE);
27336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
27436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (length != (cinfo->num_components * 3))
27536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    ERREXIT(cinfo, JERR_BAD_LENGTH);
27636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
277e5eaf37440b8e337ab150c017df7c03faf846c51DRC  if (cinfo->comp_info == NULL) /* do only once, even if suspend */
27836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)
279e5eaf37440b8e337ab150c017df7c03faf846c51DRC                        ((j_common_ptr) cinfo, JPOOL_IMAGE,
2805de454b291f48382648a5d1dc2aa0fca8b5786d4DRC                         cinfo->num_components * sizeof(jpeg_component_info));
281e5eaf37440b8e337ab150c017df7c03faf846c51DRC
28236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
28336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane       ci++, compptr++) {
28436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    compptr->component_index = ci;
28536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
28636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    INPUT_BYTE(cinfo, c, return FALSE);
28736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    compptr->h_samp_factor = (c >> 4) & 15;
28836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    compptr->v_samp_factor = (c     ) & 15;
28936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);
29036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
29136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,
292e5eaf37440b8e337ab150c017df7c03faf846c51DRC             compptr->component_id, compptr->h_samp_factor,
293e5eaf37440b8e337ab150c017df7c03faf846c51DRC             compptr->v_samp_factor, compptr->quant_tbl_no);
29436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
29536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
29636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->marker->saw_SOF = TRUE;
29736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
29836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_SYNC(cinfo);
29936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  return TRUE;
30036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
30136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
30236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
303489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneLOCAL(boolean)
30436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneget_sos (j_decompress_ptr cinfo)
30536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Process a SOS marker */
30636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
3076eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis  JLONG length;
30843d8cf4d4572fa50a37cccadbe71b9bee37de55dDRC  int i, ci, n, c, cc, pi;
3096eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis  jpeg_component_info *compptr;
31036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_VARS(cinfo);
31136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
31236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (! cinfo->marker->saw_SOF)
31336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    ERREXIT(cinfo, JERR_SOS_NO_SOF);
31436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
31536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_2BYTES(cinfo, length, return FALSE);
31636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
31736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */
31836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
3195ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  TRACEMS1(cinfo, 1, JTRC_SOS, n);
3205ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
32136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
32236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    ERREXIT(cinfo, JERR_BAD_LENGTH);
32336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
32436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->comps_in_scan = n;
32536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
32636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Collect the component-spec parameters */
32736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
328dd2b651243125701dca2ed2f31b3d34056719b9cDRC  for (i = 0; i < MAX_COMPS_IN_SCAN; i++)
32912781cb5558bc1f6d66ed840ed15267d503ffffcDRC    cinfo->cur_comp_info[i] = NULL;
33012781cb5558bc1f6d66ed840ed15267d503ffffcDRC
33136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  for (i = 0; i < n; i++) {
33236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    INPUT_BYTE(cinfo, cc, return FALSE);
33336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    INPUT_BYTE(cinfo, c, return FALSE);
334e5eaf37440b8e337ab150c017df7c03faf846c51DRC
335dd2b651243125701dca2ed2f31b3d34056719b9cDRC    for (ci = 0, compptr = cinfo->comp_info;
336e5eaf37440b8e337ab150c017df7c03faf846c51DRC         ci < cinfo->num_components && ci < MAX_COMPS_IN_SCAN;
337e5eaf37440b8e337ab150c017df7c03faf846c51DRC         ci++, compptr++) {
33812781cb5558bc1f6d66ed840ed15267d503ffffcDRC      if (cc == compptr->component_id && !cinfo->cur_comp_info[ci])
339e5eaf37440b8e337ab150c017df7c03faf846c51DRC        goto id_found;
34036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
34136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
34236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
34336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
34436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  id_found:
34536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
34636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    cinfo->cur_comp_info[i] = compptr;
34736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    compptr->dc_tbl_no = (c >> 4) & 15;
34836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    compptr->ac_tbl_no = (c     ) & 15;
349e5eaf37440b8e337ab150c017df7c03faf846c51DRC
35036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,
351e5eaf37440b8e337ab150c017df7c03faf846c51DRC             compptr->dc_tbl_no, compptr->ac_tbl_no);
35243d8cf4d4572fa50a37cccadbe71b9bee37de55dDRC
35343d8cf4d4572fa50a37cccadbe71b9bee37de55dDRC    /* This CSi (cc) should differ from the previous CSi */
35443d8cf4d4572fa50a37cccadbe71b9bee37de55dDRC    for (pi = 0; pi < i; pi++) {
35543d8cf4d4572fa50a37cccadbe71b9bee37de55dDRC      if (cinfo->cur_comp_info[pi] == compptr) {
35643d8cf4d4572fa50a37cccadbe71b9bee37de55dDRC        ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
35743d8cf4d4572fa50a37cccadbe71b9bee37de55dDRC      }
35843d8cf4d4572fa50a37cccadbe71b9bee37de55dDRC    }
35936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
36036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
361bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane  /* Collect the additional scan parameters Ss, Se, Ah/Al. */
362bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane  INPUT_BYTE(cinfo, c, return FALSE);
363bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane  cinfo->Ss = c;
36436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_BYTE(cinfo, c, return FALSE);
365bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane  cinfo->Se = c;
366bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane  INPUT_BYTE(cinfo, c, return FALSE);
367bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane  cinfo->Ah = (c >> 4) & 15;
368bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane  cinfo->Al = (c     ) & 15;
369bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane
370bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane  TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,
371e5eaf37440b8e337ab150c017df7c03faf846c51DRC           cinfo->Ah, cinfo->Al);
37236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
37336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Prepare to scan data & restart markers */
37436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->marker->next_restart_num = 0;
37536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
376bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane  /* Count another SOS marker */
377bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane  cinfo->input_scan_number++;
378bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane
37936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_SYNC(cinfo);
38036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  return TRUE;
38136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
38236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
38336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
3845ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane#ifdef D_ARITH_CODING_SUPPORTED
38536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
386489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneLOCAL(boolean)
38736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneget_dac (j_decompress_ptr cinfo)
38836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Process a DAC marker */
38936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
3906eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis  JLONG length;
39136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int index, val;
39236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_VARS(cinfo);
39336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
39436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_2BYTES(cinfo, length, return FALSE);
39536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  length -= 2;
396e5eaf37440b8e337ab150c017df7c03faf846c51DRC
39736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  while (length > 0) {
39836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    INPUT_BYTE(cinfo, index, return FALSE);
39936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    INPUT_BYTE(cinfo, val, return FALSE);
40036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
40136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    length -= 2;
40236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
40336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    TRACEMS2(cinfo, 1, JTRC_DAC, index, val);
40436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
40536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    if (index < 0 || index >= (2*NUM_ARITH_TBLS))
40636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      ERREXIT1(cinfo, JERR_DAC_INDEX, index);
40736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
40836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    if (index >= NUM_ARITH_TBLS) { /* define AC table */
40936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
410e5eaf37440b8e337ab150c017df7c03faf846c51DRC    } else {                    /* define DC table */
41136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
41236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
41336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
414e5eaf37440b8e337ab150c017df7c03faf846c51DRC        ERREXIT1(cinfo, JERR_DAC_VALUE, val);
41536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
41636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
41736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
4185ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (length != 0)
4195ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    ERREXIT(cinfo, JERR_BAD_LENGTH);
4205ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
42136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_SYNC(cinfo);
42236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  return TRUE;
42336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
42436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
4255ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane#else /* ! D_ARITH_CODING_SUPPORTED */
4265ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
4275ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane#define get_dac(cinfo)  skip_variable(cinfo)
4285ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
4295ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane#endif /* D_ARITH_CODING_SUPPORTED */
4305ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
43136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
432489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneLOCAL(boolean)
43336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneget_dht (j_decompress_ptr cinfo)
43436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Process a DHT marker */
43536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
4366eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis  JLONG length;
43736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  UINT8 bits[17];
43836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  UINT8 huffval[256];
43936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int i, index, count;
44036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  JHUFF_TBL **htblptr;
44136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_VARS(cinfo);
44236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
44336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_2BYTES(cinfo, length, return FALSE);
44436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  length -= 2;
445e5eaf37440b8e337ab150c017df7c03faf846c51DRC
4465ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  while (length > 16) {
44736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    INPUT_BYTE(cinfo, index, return FALSE);
44836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
44936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    TRACEMS1(cinfo, 1, JTRC_DHT, index);
450e5eaf37440b8e337ab150c017df7c03faf846c51DRC
45136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    bits[0] = 0;
45236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    count = 0;
45336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    for (i = 1; i <= 16; i++) {
45436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      INPUT_BYTE(cinfo, bits[i], return FALSE);
45536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      count += bits[i];
45636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
45736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
45836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    length -= 1 + 16;
45936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
46036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
461e5eaf37440b8e337ab150c017df7c03faf846c51DRC             bits[1], bits[2], bits[3], bits[4],
462e5eaf37440b8e337ab150c017df7c03faf846c51DRC             bits[5], bits[6], bits[7], bits[8]);
46336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
464e5eaf37440b8e337ab150c017df7c03faf846c51DRC             bits[9], bits[10], bits[11], bits[12],
465e5eaf37440b8e337ab150c017df7c03faf846c51DRC             bits[13], bits[14], bits[15], bits[16]);
46636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
4675ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* Here we just do minimal validation of the counts to avoid walking
4685ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane     * off the end of our table space.  jdhuff.c will check more carefully.
4695ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane     */
4706eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis    if (count > 256 || ((JLONG) count) > length)
4715ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
47236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
47336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    for (i = 0; i < count; i++)
47436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      INPUT_BYTE(cinfo, huffval[i], return FALSE);
47536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
4765de454b291f48382648a5d1dc2aa0fca8b5786d4DRC    MEMZERO(&huffval[count], (256 - count) * sizeof(UINT8));
47743d8cf4d4572fa50a37cccadbe71b9bee37de55dDRC
47836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    length -= count;
47936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
480e5eaf37440b8e337ab150c017df7c03faf846c51DRC    if (index & 0x10) {         /* AC table definition */
48136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      index -= 0x10;
482d4ab63d191d69b0197215c39c8328a31b523ca0fDRC      if (index < 0 || index >= NUM_HUFF_TBLS)
483d4ab63d191d69b0197215c39c8328a31b523ca0fDRC        ERREXIT1(cinfo, JERR_DHT_INDEX, index);
48436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      htblptr = &cinfo->ac_huff_tbl_ptrs[index];
485e5eaf37440b8e337ab150c017df7c03faf846c51DRC    } else {                    /* DC table definition */
486d4ab63d191d69b0197215c39c8328a31b523ca0fDRC      if (index < 0 || index >= NUM_HUFF_TBLS)
487d4ab63d191d69b0197215c39c8328a31b523ca0fDRC        ERREXIT1(cinfo, JERR_DHT_INDEX, index);
48836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      htblptr = &cinfo->dc_huff_tbl_ptrs[index];
48936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
49036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
49136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    if (*htblptr == NULL)
49236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
493e5eaf37440b8e337ab150c017df7c03faf846c51DRC
4945de454b291f48382648a5d1dc2aa0fca8b5786d4DRC    MEMCOPY((*htblptr)->bits, bits, sizeof((*htblptr)->bits));
4955de454b291f48382648a5d1dc2aa0fca8b5786d4DRC    MEMCOPY((*htblptr)->huffval, huffval, sizeof((*htblptr)->huffval));
49636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
49736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
4985ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (length != 0)
4995ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    ERREXIT(cinfo, JERR_BAD_LENGTH);
5005ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
50136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_SYNC(cinfo);
50236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  return TRUE;
50336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
50436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
50536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
506489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneLOCAL(boolean)
50736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneget_dqt (j_decompress_ptr cinfo)
50836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Process a DQT marker */
50936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
5106eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis  JLONG length;
51136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int n, i, prec;
51236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  unsigned int tmp;
51336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  JQUANT_TBL *quant_ptr;
51436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_VARS(cinfo);
51536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
51636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_2BYTES(cinfo, length, return FALSE);
51736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  length -= 2;
51836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
51936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  while (length > 0) {
52036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    INPUT_BYTE(cinfo, n, return FALSE);
52136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    prec = n >> 4;
52236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    n &= 0x0F;
52336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
52436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);
52536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
52636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    if (n >= NUM_QUANT_TBLS)
52736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      ERREXIT1(cinfo, JERR_DQT_INDEX, n);
528e5eaf37440b8e337ab150c017df7c03faf846c51DRC
52936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    if (cinfo->quant_tbl_ptrs[n] == NULL)
53036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);
53136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    quant_ptr = cinfo->quant_tbl_ptrs[n];
53236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
53336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    for (i = 0; i < DCTSIZE2; i++) {
53436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      if (prec)
535e5eaf37440b8e337ab150c017df7c03faf846c51DRC        INPUT_2BYTES(cinfo, tmp, return FALSE);
53636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      else
537e5eaf37440b8e337ab150c017df7c03faf846c51DRC        INPUT_BYTE(cinfo, tmp, return FALSE);
538489583f5165e05d37302e8eeec58104ea0109127Thomas G. Lane      /* We convert the zigzag-order table to natural array order. */
539489583f5165e05d37302e8eeec58104ea0109127Thomas G. Lane      quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp;
54036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
54136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
542489583f5165e05d37302e8eeec58104ea0109127Thomas G. Lane    if (cinfo->err->trace_level >= 2) {
543489583f5165e05d37302e8eeec58104ea0109127Thomas G. Lane      for (i = 0; i < DCTSIZE2; i += 8) {
544e5eaf37440b8e337ab150c017df7c03faf846c51DRC        TRACEMS8(cinfo, 2, JTRC_QUANTVALS,
545e5eaf37440b8e337ab150c017df7c03faf846c51DRC                 quant_ptr->quantval[i],   quant_ptr->quantval[i+1],
546e5eaf37440b8e337ab150c017df7c03faf846c51DRC                 quant_ptr->quantval[i+2], quant_ptr->quantval[i+3],
547e5eaf37440b8e337ab150c017df7c03faf846c51DRC                 quant_ptr->quantval[i+4], quant_ptr->quantval[i+5],
548e5eaf37440b8e337ab150c017df7c03faf846c51DRC                 quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]);
549489583f5165e05d37302e8eeec58104ea0109127Thomas G. Lane      }
55036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
55136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
55236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    length -= DCTSIZE2+1;
55336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    if (prec) length -= DCTSIZE2;
55436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
55536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
5565ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (length != 0)
5575ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    ERREXIT(cinfo, JERR_BAD_LENGTH);
5585ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
55936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_SYNC(cinfo);
56036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  return TRUE;
56136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
56236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
56336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
564489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneLOCAL(boolean)
56536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneget_dri (j_decompress_ptr cinfo)
56636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Process a DRI marker */
56736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
5686eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis  JLONG length;
56936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  unsigned int tmp;
57036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_VARS(cinfo);
57136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
57236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_2BYTES(cinfo, length, return FALSE);
573e5eaf37440b8e337ab150c017df7c03faf846c51DRC
57436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (length != 4)
57536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    ERREXIT(cinfo, JERR_BAD_LENGTH);
57636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
57736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_2BYTES(cinfo, tmp, return FALSE);
57836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
57936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  TRACEMS1(cinfo, 1, JTRC_DRI, tmp);
58036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
58136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->restart_interval = tmp;
58236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
58336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_SYNC(cinfo);
58436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  return TRUE;
58536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
58636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
58736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
5885ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane/*
5895ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * Routines for processing APPn and COM markers.
5905ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * These are either saved in memory or discarded, per application request.
5915ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * APP0 and APP14 are specially checked to see if they are
5925ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * JFIF and Adobe markers, respectively.
5935ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane */
5945ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
595e5eaf37440b8e337ab150c017df7c03faf846c51DRC#define APP0_DATA_LEN   14      /* Length of interesting data in APP0 */
596e5eaf37440b8e337ab150c017df7c03faf846c51DRC#define APP14_DATA_LEN  12      /* Length of interesting data in APP14 */
597e5eaf37440b8e337ab150c017df7c03faf846c51DRC#define APPN_DATA_LEN   14      /* Must be the largest of the above!! */
5985ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
5995ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
6005ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. LaneLOCAL(void)
6016eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidisexamine_app0 (j_decompress_ptr cinfo, JOCTET *data,
6026eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis              unsigned int datalen, JLONG remaining)
6035ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane/* Examine first few bytes from an APP0.
6045ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * Take appropriate action if it is a JFIF marker.
6055ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * datalen is # of bytes at data[], remaining is length of rest of marker data.
6065ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane */
6075ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane{
6086eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis  JLONG totallen = (JLONG) datalen + remaining;
6095ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
6105ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (datalen >= APP0_DATA_LEN &&
6115ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[0]) == 0x4A &&
6125ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[1]) == 0x46 &&
6135ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[2]) == 0x49 &&
6145ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[3]) == 0x46 &&
6155ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[4]) == 0) {
6165ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* Found JFIF APP0 marker: save info */
6175ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    cinfo->saw_JFIF_marker = TRUE;
6185ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    cinfo->JFIF_major_version = GETJOCTET(data[5]);
6195ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    cinfo->JFIF_minor_version = GETJOCTET(data[6]);
6205ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    cinfo->density_unit = GETJOCTET(data[7]);
6215ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
6225ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
6235ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* Check version.
6245ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane     * Major version must be 1, anything else signals an incompatible change.
6255ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane     * (We used to treat this as an error, but now it's a nonfatal warning,
6265ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane     * because some bozo at Hijaak couldn't read the spec.)
6275ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane     * Minor version should be 0..2, but process anyway if newer.
6285ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane     */
6295ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    if (cinfo->JFIF_major_version != 1)
6305ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      WARNMS2(cinfo, JWRN_JFIF_MAJOR,
631e5eaf37440b8e337ab150c017df7c03faf846c51DRC              cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
6325ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* Generate trace messages */
6335ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    TRACEMS5(cinfo, 1, JTRC_JFIF,
634e5eaf37440b8e337ab150c017df7c03faf846c51DRC             cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
635e5eaf37440b8e337ab150c017df7c03faf846c51DRC             cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
6365ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* Validate thumbnail dimensions and issue appropriate messages */
6375ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
6385ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
639e5eaf37440b8e337ab150c017df7c03faf846c51DRC               GETJOCTET(data[12]), GETJOCTET(data[13]));
6405ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    totallen -= APP0_DATA_LEN;
6415ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    if (totallen !=
6426eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis        ((JLONG)GETJOCTET(data[12]) * (JLONG)GETJOCTET(data[13]) * (JLONG) 3))
6435ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);
6445ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  } else if (datalen >= 6 &&
6455ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[0]) == 0x4A &&
6465ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[1]) == 0x46 &&
6475ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[2]) == 0x58 &&
6485ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[3]) == 0x58 &&
6495ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[4]) == 0) {
6505ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* Found JFIF "JFXX" extension APP0 marker */
6515ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* The library doesn't actually do anything with these,
6525ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane     * but we try to produce a helpful trace message.
6535ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane     */
6545ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    switch (GETJOCTET(data[5])) {
6555ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    case 0x10:
6565ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);
6575ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      break;
6585ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    case 0x11:
6595ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);
6605ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      break;
6615ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    case 0x13:
6625ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);
6635ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      break;
6645ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    default:
6655ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
666e5eaf37440b8e337ab150c017df7c03faf846c51DRC               GETJOCTET(data[5]), (int) totallen);
6675ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      break;
6685ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    }
6695ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  } else {
6705ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* Start of APP0 does not match "JFIF" or "JFXX", or too short */
6715ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);
6725ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  }
6735ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane}
6745ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
6755ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
6765ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. LaneLOCAL(void)
6776eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidisexamine_app14 (j_decompress_ptr cinfo, JOCTET *data,
6786eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis               unsigned int datalen, JLONG remaining)
6795ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane/* Examine first few bytes from an APP14.
6805ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * Take appropriate action if it is an Adobe marker.
6815ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * datalen is # of bytes at data[], remaining is length of rest of marker data.
6825ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane */
6835ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane{
6845ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  unsigned int version, flags0, flags1, transform;
6855ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
6865ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (datalen >= APP14_DATA_LEN &&
6875ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[0]) == 0x41 &&
6885ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[1]) == 0x64 &&
6895ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[2]) == 0x6F &&
6905ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[3]) == 0x62 &&
6915ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      GETJOCTET(data[4]) == 0x65) {
6925ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* Found Adobe APP14 marker */
6935ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
6945ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
6955ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
6965ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    transform = GETJOCTET(data[11]);
6975ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
6985ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    cinfo->saw_Adobe_marker = TRUE;
6995ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    cinfo->Adobe_transform = (UINT8) transform;
7005ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  } else {
7015ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* Start of APP14 does not match "Adobe", or too short */
7025ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));
7035ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  }
7045ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane}
7055ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
7065ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
7075ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. LaneMETHODDEF(boolean)
7085ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Laneget_interesting_appn (j_decompress_ptr cinfo)
7095ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane/* Process an APP0 or APP14 marker without saving it */
7105ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane{
7116eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis  JLONG length;
7125ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  JOCTET b[APPN_DATA_LEN];
7135ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  unsigned int i, numtoread;
7145ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  INPUT_VARS(cinfo);
7155ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
7165ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  INPUT_2BYTES(cinfo, length, return FALSE);
7175ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  length -= 2;
7185ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
7195ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* get the interesting part of the marker data */
7205ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (length >= APPN_DATA_LEN)
7215ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    numtoread = APPN_DATA_LEN;
7225ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  else if (length > 0)
7235ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    numtoread = (unsigned int) length;
7245ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  else
7255ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    numtoread = 0;
7265ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  for (i = 0; i < numtoread; i++)
7275ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    INPUT_BYTE(cinfo, b[i], return FALSE);
7285ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  length -= numtoread;
7295ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
7305ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* process it */
7315ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  switch (cinfo->unread_marker) {
7325ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  case M_APP0:
7335033f3e19a31e8ad40c1a79700365aefe5664494DRC    examine_app0(cinfo, (JOCTET *) b, numtoread, length);
7345ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    break;
7355ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  case M_APP14:
7365033f3e19a31e8ad40c1a79700365aefe5664494DRC    examine_app14(cinfo, (JOCTET *) b, numtoread, length);
7375ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    break;
7385ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  default:
7395ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* can't get here unless jpeg_save_markers chooses wrong processor */
7405ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
7415ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    break;
7425ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  }
7435ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
7445ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* skip any remaining data -- could be lots */
7455ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  INPUT_SYNC(cinfo);
7465ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (length > 0)
7475ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    (*cinfo->src->skip_input_data) (cinfo, (long) length);
7485ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
7495ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  return TRUE;
7505ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane}
7515ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
7525ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
7535ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane#ifdef SAVE_MARKERS_SUPPORTED
7545ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
7555ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. LaneMETHODDEF(boolean)
7565ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lanesave_marker (j_decompress_ptr cinfo)
7575ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane/* Save an APPn or COM marker into the marker list */
7585ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane{
7595ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
7605ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  jpeg_saved_marker_ptr cur_marker = marker->cur_marker;
7615ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  unsigned int bytes_read, data_length;
7626eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis  JOCTET *data;
7636eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis  JLONG length = 0;
7645ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  INPUT_VARS(cinfo);
7655ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
7665ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (cur_marker == NULL) {
7675ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* begin reading a marker */
7685ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    INPUT_2BYTES(cinfo, length, return FALSE);
7695ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    length -= 2;
770e5eaf37440b8e337ab150c017df7c03faf846c51DRC    if (length >= 0) {          /* watch out for bogus length word */
7715ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      /* figure out how much we want to save */
7725ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      unsigned int limit;
7735ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      if (cinfo->unread_marker == (int) M_COM)
774e5eaf37440b8e337ab150c017df7c03faf846c51DRC        limit = marker->length_limit_COM;
7755ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      else
776e5eaf37440b8e337ab150c017df7c03faf846c51DRC        limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];
7775ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      if ((unsigned int) length < limit)
778e5eaf37440b8e337ab150c017df7c03faf846c51DRC        limit = (unsigned int) length;
7795ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      /* allocate and initialize the marker item */
7805ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      cur_marker = (jpeg_saved_marker_ptr)
781e5eaf37440b8e337ab150c017df7c03faf846c51DRC        (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
7825de454b291f48382648a5d1dc2aa0fca8b5786d4DRC                                    sizeof(struct jpeg_marker_struct) + limit);
7835ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      cur_marker->next = NULL;
7845ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      cur_marker->marker = (UINT8) cinfo->unread_marker;
7855ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      cur_marker->original_length = (unsigned int) length;
7865ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      cur_marker->data_length = limit;
7875ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      /* data area is just beyond the jpeg_marker_struct */
7885033f3e19a31e8ad40c1a79700365aefe5664494DRC      data = cur_marker->data = (JOCTET *) (cur_marker + 1);
7895ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      marker->cur_marker = cur_marker;
7905ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      marker->bytes_read = 0;
7915ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      bytes_read = 0;
7925ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      data_length = limit;
7935ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    } else {
7945ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      /* deal with bogus length word */
7955ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      bytes_read = data_length = 0;
7965ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      data = NULL;
7975ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    }
7985ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  } else {
7995ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* resume reading a marker */
8005ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    bytes_read = marker->bytes_read;
8015ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    data_length = cur_marker->data_length;
8025ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    data = cur_marker->data + bytes_read;
8035ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  }
8045ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
8055ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  while (bytes_read < data_length) {
806e5eaf37440b8e337ab150c017df7c03faf846c51DRC    INPUT_SYNC(cinfo);          /* move the restart point to here */
8075ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    marker->bytes_read = bytes_read;
8085ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* If there's not at least one byte in buffer, suspend */
8095ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    MAKE_BYTE_AVAIL(cinfo, return FALSE);
8105ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* Copy bytes with reasonable rapidity */
8115ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    while (bytes_read < data_length && bytes_in_buffer > 0) {
8125ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      *data++ = *next_input_byte++;
8135ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      bytes_in_buffer--;
8145ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      bytes_read++;
8155ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    }
8165ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  }
8175ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
8185ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* Done reading what we want to read */
819e5eaf37440b8e337ab150c017df7c03faf846c51DRC  if (cur_marker != NULL) {     /* will be NULL if bogus length word */
8205ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* Add new marker to end of list */
8215ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    if (cinfo->marker_list == NULL) {
8225ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      cinfo->marker_list = cur_marker;
8235ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    } else {
8245ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      jpeg_saved_marker_ptr prev = cinfo->marker_list;
8255ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      while (prev->next != NULL)
826e5eaf37440b8e337ab150c017df7c03faf846c51DRC        prev = prev->next;
8275ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      prev->next = cur_marker;
8285ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    }
8295ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* Reset pointer & calc remaining data length */
8305ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    data = cur_marker->data;
8315ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    length = cur_marker->original_length - data_length;
8325ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  }
8335ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* Reset to initial state for next marker */
8345ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  marker->cur_marker = NULL;
8355ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
8365ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* Process the marker if interesting; else just make a generic trace msg */
8375ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  switch (cinfo->unread_marker) {
8385ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  case M_APP0:
8395ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    examine_app0(cinfo, data, data_length, length);
8405ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    break;
8415ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  case M_APP14:
8425ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    examine_app14(cinfo, data, data_length, length);
8435ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    break;
8445ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  default:
8455ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
846e5eaf37440b8e337ab150c017df7c03faf846c51DRC             (int) (data_length + length));
8475ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    break;
8485ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  }
8495ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
8505ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* skip any remaining data -- could be lots */
851e5eaf37440b8e337ab150c017df7c03faf846c51DRC  INPUT_SYNC(cinfo);            /* do before skip_input_data */
8525ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (length > 0)
8535ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    (*cinfo->src->skip_input_data) (cinfo, (long) length);
8545ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
8555ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  return TRUE;
8565ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane}
8575ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
8585ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane#endif /* SAVE_MARKERS_SUPPORTED */
8595ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
8605ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
861489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(boolean)
86236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneskip_variable (j_decompress_ptr cinfo)
86336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Skip over an unknown or uninteresting variable-length marker */
86436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
8656eb7d3798b5a79347c62825fc4c16f7ce673bdd0Alex Naidis  JLONG length;
86636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_VARS(cinfo);
86736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
86836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_2BYTES(cinfo, length, return FALSE);
8695ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  length -= 2;
870e5eaf37440b8e337ab150c017df7c03faf846c51DRC
87136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);
87236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
873e5eaf37440b8e337ab150c017df7c03faf846c51DRC  INPUT_SYNC(cinfo);            /* do before skip_input_data */
8745ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (length > 0)
8755ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    (*cinfo->src->skip_input_data) (cinfo, (long) length);
87636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
87736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  return TRUE;
87836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
87936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
88036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
88136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
88236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Find the next JPEG marker, save it in cinfo->unread_marker.
88336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Returns FALSE if had to suspend before reaching a marker;
88436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * in that case cinfo->unread_marker is unchanged.
88536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
88636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Note that the result might not be a valid marker code,
88736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * but it will never be 0 or FF.
88836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
88936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
890489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneLOCAL(boolean)
89136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanenext_marker (j_decompress_ptr cinfo)
89236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
89336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int c;
89436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_VARS(cinfo);
89536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
89636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  for (;;) {
89736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    INPUT_BYTE(cinfo, c, return FALSE);
89836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Skip any non-FF bytes.
89936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     * This may look a bit inefficient, but it will not occur in a valid file.
90036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     * We sync after each discarded byte so that a suspending data source
90136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     * can discard the byte from its buffer.
90236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     */
90336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    while (c != 0xFF) {
90436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      cinfo->marker->discarded_bytes++;
90536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      INPUT_SYNC(cinfo);
90636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      INPUT_BYTE(cinfo, c, return FALSE);
90736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
90836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* This loop swallows any duplicate FF bytes.  Extra FFs are legal as
90936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     * pad bytes, so don't count them in discarded_bytes.  We assume there
91036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     * will not be so many consecutive FF bytes as to overflow a suspending
91136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     * data source's input buffer.
91236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     */
91336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    do {
91436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      INPUT_BYTE(cinfo, c, return FALSE);
91536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    } while (c == 0xFF);
91636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    if (c != 0)
917e5eaf37440b8e337ab150c017df7c03faf846c51DRC      break;                    /* found a valid marker, exit loop */
91836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Reach here if we found a stuffed-zero data sequence (FF/00).
91936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     * Discard it and loop back to try again.
92036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     */
92136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    cinfo->marker->discarded_bytes += 2;
92236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    INPUT_SYNC(cinfo);
92336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
92436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
92536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (cinfo->marker->discarded_bytes != 0) {
92636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);
92736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    cinfo->marker->discarded_bytes = 0;
92836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
92936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
93036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->unread_marker = c;
93136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
93236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_SYNC(cinfo);
93336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  return TRUE;
93436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
93536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
93636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
937489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneLOCAL(boolean)
93836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanefirst_marker (j_decompress_ptr cinfo)
93936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Like next_marker, but used to obtain the initial SOI marker. */
94036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* For this marker, we do not allow preceding garbage or fill; otherwise,
94136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * we might well scan an entire input file before realizing it ain't JPEG.
94236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * If an application wants to process non-JFIF files, it must seek to the
94336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * SOI before calling the JPEG library.
94436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
94536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
94636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int c, c2;
94736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_VARS(cinfo);
94836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
94936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_BYTE(cinfo, c, return FALSE);
95036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_BYTE(cinfo, c2, return FALSE);
95136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (c != 0xFF || c2 != (int) M_SOI)
95236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    ERREXIT2(cinfo, JERR_NO_SOI, c, c2);
95336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
95436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->unread_marker = c2;
95536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
95636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  INPUT_SYNC(cinfo);
95736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  return TRUE;
95836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
95936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
96036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
96136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
96236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Read markers until SOS or EOI.
96336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
964bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * Returns same codes as are defined for jpeg_consume_input:
965bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
96636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
96736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
968489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(int)
96936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneread_markers (j_decompress_ptr cinfo)
97036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
97136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Outer loop repeats once for each marker. */
97236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  for (;;) {
97336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Collect the marker proper, unless we already did. */
97436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* NB: first_marker() enforces the requirement that SOI appear first. */
97536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    if (cinfo->unread_marker == 0) {
97636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      if (! cinfo->marker->saw_SOI) {
977e5eaf37440b8e337ab150c017df7c03faf846c51DRC        if (! first_marker(cinfo))
978e5eaf37440b8e337ab150c017df7c03faf846c51DRC          return JPEG_SUSPENDED;
97936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      } else {
980e5eaf37440b8e337ab150c017df7c03faf846c51DRC        if (! next_marker(cinfo))
981e5eaf37440b8e337ab150c017df7c03faf846c51DRC          return JPEG_SUSPENDED;
98236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      }
98336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
98436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* At this point cinfo->unread_marker contains the marker code and the
98536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     * input point is just past the marker proper, but before any parameters.
98636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     * A suspension will cause us to return with this state still true.
98736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     */
98836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    switch (cinfo->unread_marker) {
98936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_SOI:
99036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      if (! get_soi(cinfo))
991e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return JPEG_SUSPENDED;
99236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
99336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
994e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_SOF0:                /* Baseline */
995e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_SOF1:                /* Extended sequential, Huffman */
996bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane      if (! get_sof(cinfo, FALSE, FALSE))
997e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return JPEG_SUSPENDED;
998bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane      break;
999bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane
1000e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_SOF2:                /* Progressive, Huffman */
1001bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane      if (! get_sof(cinfo, TRUE, FALSE))
1002e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return JPEG_SUSPENDED;
100336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
100436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
1005e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_SOF9:                /* Extended sequential, arithmetic */
1006bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane      if (! get_sof(cinfo, FALSE, TRUE))
1007e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return JPEG_SUSPENDED;
1008bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane      break;
1009bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane
1010e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_SOF10:               /* Progressive, arithmetic */
1011bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane      if (! get_sof(cinfo, TRUE, TRUE))
1012e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return JPEG_SUSPENDED;
101336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
101436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
101536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Currently unsupported SOFn types */
1016e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_SOF3:                /* Lossless, Huffman */
1017e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_SOF5:                /* Differential sequential, Huffman */
1018e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_SOF6:                /* Differential progressive, Huffman */
1019e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_SOF7:                /* Differential lossless, Huffman */
1020e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_JPG:                 /* Reserved for JPEG extensions */
1021e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_SOF11:               /* Lossless, arithmetic */
1022e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_SOF13:               /* Differential sequential, arithmetic */
1023e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_SOF14:               /* Differential progressive, arithmetic */
1024e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_SOF15:               /* Differential lossless, arithmetic */
102536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);
102636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
102736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
102836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_SOS:
102936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      if (! get_sos(cinfo))
1030e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return JPEG_SUSPENDED;
1031e5eaf37440b8e337ab150c017df7c03faf846c51DRC      cinfo->unread_marker = 0; /* processed the marker */
1032bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane      return JPEG_REACHED_SOS;
1033e5eaf37440b8e337ab150c017df7c03faf846c51DRC
103436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_EOI:
103536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      TRACEMS(cinfo, 1, JTRC_EOI);
1036e5eaf37440b8e337ab150c017df7c03faf846c51DRC      cinfo->unread_marker = 0; /* processed the marker */
1037bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane      return JPEG_REACHED_EOI;
1038e5eaf37440b8e337ab150c017df7c03faf846c51DRC
103936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_DAC:
104036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      if (! get_dac(cinfo))
1041e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return JPEG_SUSPENDED;
104236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
1043e5eaf37440b8e337ab150c017df7c03faf846c51DRC
104436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_DHT:
104536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      if (! get_dht(cinfo))
1046e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return JPEG_SUSPENDED;
104736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
1048e5eaf37440b8e337ab150c017df7c03faf846c51DRC
104936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_DQT:
105036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      if (! get_dqt(cinfo))
1051e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return JPEG_SUSPENDED;
105236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
1053e5eaf37440b8e337ab150c017df7c03faf846c51DRC
105436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_DRI:
105536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      if (! get_dri(cinfo))
1056e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return JPEG_SUSPENDED;
105736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
1058e5eaf37440b8e337ab150c017df7c03faf846c51DRC
105936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP0:
106036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP1:
106136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP2:
106236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP3:
106336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP4:
106436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP5:
106536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP6:
106636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP7:
106736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP8:
106836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP9:
106936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP10:
107036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP11:
107136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP12:
107236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP13:
107336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP14:
107436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_APP15:
10755ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[
1076e5eaf37440b8e337ab150c017df7c03faf846c51DRC                cinfo->unread_marker - (int) M_APP0]) (cinfo))
1077e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return JPEG_SUSPENDED;
107836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
1079e5eaf37440b8e337ab150c017df7c03faf846c51DRC
108036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_COM:
10815ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
1082e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return JPEG_SUSPENDED;
108336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
108436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
1085e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_RST0:                /* these are all parameterless */
108636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_RST1:
108736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_RST2:
108836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_RST3:
108936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_RST4:
109036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_RST5:
109136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_RST6:
109236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_RST7:
109336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case M_TEM:
109436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);
109536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
109636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
1097e5eaf37440b8e337ab150c017df7c03faf846c51DRC    case M_DNL:                 /* Ignore DNL ... perhaps the wrong thing */
109836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      if (! skip_variable(cinfo))
1099e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return JPEG_SUSPENDED;
110036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
110136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
1102e5eaf37440b8e337ab150c017df7c03faf846c51DRC    default:                    /* must be DHP, EXP, JPGn, or RESn */
110336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      /* For now, we treat the reserved markers as fatal errors since they are
110436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane       * likely to be used to signal incompatible JPEG Part 3 extensions.
110536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane       * Once the JPEG 3 version-number marker is well defined, this code
110636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane       * ought to change!
110736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane       */
110836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
110936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
111036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
111136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Successfully processed marker, so reset state variable */
111236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    cinfo->unread_marker = 0;
111336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  } /* end loop */
111436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
111536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
111636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
111736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
111836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Read a restart marker, which is expected to appear next in the datastream;
111936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * if the marker is not there, take appropriate recovery action.
112036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Returns FALSE if suspension is required.
112136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
112236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This is called by the entropy decoder after it has read an appropriate
112336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * number of MCUs.  cinfo->unread_marker may be nonzero if the entropy decoder
112436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * has already read a marker from the data source.  Under normal conditions
112536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * cinfo->unread_marker will be reset to 0 before returning; if not reset,
112636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * it holds a marker which the decoder will be unable to read past.
112736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
112836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
1129489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(boolean)
113036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneread_restart_marker (j_decompress_ptr cinfo)
113136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
113236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Obtain a marker unless we already did. */
113336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Note that next_marker will complain if it skips any data. */
113436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (cinfo->unread_marker == 0) {
113536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    if (! next_marker(cinfo))
113636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      return FALSE;
113736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
113836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
113936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (cinfo->unread_marker ==
114036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      ((int) M_RST0 + cinfo->marker->next_restart_num)) {
114136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Normal case --- swallow the marker and let entropy decoder continue */
1142489583f5165e05d37302e8eeec58104ea0109127Thomas G. Lane    TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);
114336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    cinfo->unread_marker = 0;
114436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  } else {
114536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Uh-oh, the restart markers have been messed up. */
114636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Let the data source manager determine how to resync. */
1147bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane    if (! (*cinfo->src->resync_to_restart) (cinfo,
1148e5eaf37440b8e337ab150c017df7c03faf846c51DRC                                            cinfo->marker->next_restart_num))
114936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      return FALSE;
115036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
115136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
115236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Update next-restart state */
115336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;
115436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
115536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  return TRUE;
115636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
115736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
115836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
115936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
116036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This is the default resync_to_restart method for data source managers
116136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * to use if they don't have any better approach.  Some data source managers
116236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * may be able to back up, or may have additional knowledge about the data
116336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * which permits a more intelligent recovery strategy; such managers would
116436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * presumably supply their own resync method.
116536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
116636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * read_restart_marker calls resync_to_restart if it finds a marker other than
116736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * the restart marker it was expecting.  (This code is *not* used unless
116836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * a nonzero restart interval has been declared.)  cinfo->unread_marker is
116936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * the marker code actually found (might be anything, except 0 or FF).
1170bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * The desired restart marker number (0..7) is passed as a parameter.
117136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This routine is supposed to apply whatever error recovery strategy seems
117236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * appropriate in order to position the input stream to the next data segment.
117336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Note that cinfo->unread_marker is treated as a marker appearing before
117436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * the current data-source input point; usually it should be reset to zero
117536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * before returning.
117636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Returns FALSE if suspension is required.
117736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
117836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This implementation is substantially constrained by wanting to treat the
117936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * input as a data stream; this means we can't back up.  Therefore, we have
118036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * only the following actions to work with:
118136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *   1. Simply discard the marker and let the entropy decoder resume at next
118236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *      byte of file.
118336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *   2. Read forward until we find another marker, discarding intervening
118436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *      data.  (In theory we could look ahead within the current bufferload,
118536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *      without having to discard data if we don't find the desired marker.
118636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *      This idea is not implemented here, in part because it makes behavior
118736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *      dependent on buffer size and chance buffer-boundary positions.)
118836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *   3. Leave the marker unread (by failing to zero cinfo->unread_marker).
118936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *      This will cause the entropy decoder to process an empty data segment,
119036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *      inserting dummy zeroes, and then we will reprocess the marker.
119136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
119236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * #2 is appropriate if we think the desired marker lies ahead, while #3 is
119336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * appropriate if the found marker is a future restart marker (indicating
119436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * that we have missed the desired restart marker, probably because it got
119536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * corrupted).
119636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * We apply #2 or #3 if the found marker is a restart marker no more than
119736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * two counts behind or ahead of the expected one.  We also apply #2 if the
119836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * found marker is not a legal JPEG marker code (it's certainly bogus data).
119936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * If the found marker is a restart marker more than 2 counts away, we do #1
120036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * (too much risk that the marker is erroneous; with luck we will be able to
120136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * resync at some future point).
120236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * For any valid non-restart JPEG marker, we apply #3.  This keeps us from
120336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * overrunning the end of a scan.  An implementation limited to single-scan
120436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * files might find it better to apply #2 for markers other than EOI, since
120536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * any other marker would have to be bogus data in that case.
120636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
120736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
1208489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneGLOBAL(boolean)
1209bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lanejpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
121036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
121136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int marker = cinfo->unread_marker;
121236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int action = 1;
1213e5eaf37440b8e337ab150c017df7c03faf846c51DRC
121436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Always put up a warning. */
121536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);
1216e5eaf37440b8e337ab150c017df7c03faf846c51DRC
121736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Outer loop handles repeated decision after scanning forward. */
121836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  for (;;) {
121936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    if (marker < (int) M_SOF0)
1220e5eaf37440b8e337ab150c017df7c03faf846c51DRC      action = 2;               /* invalid marker */
122136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    else if (marker < (int) M_RST0 || marker > (int) M_RST7)
1222e5eaf37440b8e337ab150c017df7c03faf846c51DRC      action = 3;               /* valid non-restart marker */
122336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    else {
122436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      if (marker == ((int) M_RST0 + ((desired+1) & 7)) ||
1225e5eaf37440b8e337ab150c017df7c03faf846c51DRC          marker == ((int) M_RST0 + ((desired+2) & 7)))
1226e5eaf37440b8e337ab150c017df7c03faf846c51DRC        action = 3;             /* one of the next two expected restarts */
122736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      else if (marker == ((int) M_RST0 + ((desired-1) & 7)) ||
1228e5eaf37440b8e337ab150c017df7c03faf846c51DRC               marker == ((int) M_RST0 + ((desired-2) & 7)))
1229e5eaf37440b8e337ab150c017df7c03faf846c51DRC        action = 2;             /* a prior restart, so advance */
123036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      else
1231e5eaf37440b8e337ab150c017df7c03faf846c51DRC        action = 1;             /* desired restart or too far away */
123236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
123336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);
123436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    switch (action) {
123536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case 1:
123636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      /* Discard marker and let entropy decoder resume processing. */
123736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      cinfo->unread_marker = 0;
123836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      return TRUE;
123936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case 2:
124036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      /* Scan to the next marker, and repeat the decision loop. */
124136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      if (! next_marker(cinfo))
1242e5eaf37440b8e337ab150c017df7c03faf846c51DRC        return FALSE;
124336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      marker = cinfo->unread_marker;
124436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      break;
124536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    case 3:
124636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      /* Return without advancing past this marker. */
124736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      /* Entropy decoder will be forced to process an empty segment. */
124836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      return TRUE;
124936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
125036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  } /* end loop */
125136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
125236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
125336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
125436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
125536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Reset marker processing state to begin a fresh datastream.
125636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
125736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
1258489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void)
125936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanereset_marker_reader (j_decompress_ptr cinfo)
126036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
12615ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
12625ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
1263e5eaf37440b8e337ab150c017df7c03faf846c51DRC  cinfo->comp_info = NULL;              /* until allocated by get_sof */
1264e5eaf37440b8e337ab150c017df7c03faf846c51DRC  cinfo->input_scan_number = 0;         /* no SOS seen yet */
1265e5eaf37440b8e337ab150c017df7c03faf846c51DRC  cinfo->unread_marker = 0;             /* no pending marker */
1266e5eaf37440b8e337ab150c017df7c03faf846c51DRC  marker->pub.saw_SOI = FALSE;          /* set internal state too */
12675ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  marker->pub.saw_SOF = FALSE;
12685ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  marker->pub.discarded_bytes = 0;
12695ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  marker->cur_marker = NULL;
127036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
127136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
127236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
127336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
127436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Initialize the marker reader module.
1275bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * This is called only once, when the decompression object is created.
127636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
127736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
1278489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneGLOBAL(void)
127936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanejinit_marker_reader (j_decompress_ptr cinfo)
128036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
12815ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  my_marker_ptr marker;
128236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int i;
128336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
128436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Create subobject in permanent pool */
12855ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  marker = (my_marker_ptr)
1286bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
12875de454b291f48382648a5d1dc2aa0fca8b5786d4DRC                                sizeof(my_marker_reader));
12885ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  cinfo->marker = (struct jpeg_marker_reader *) marker;
12895ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* Initialize public method pointers */
12905ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  marker->pub.reset_marker_reader = reset_marker_reader;
12915ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  marker->pub.read_markers = read_markers;
12925ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  marker->pub.read_restart_marker = read_restart_marker;
12935ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* Initialize COM/APPn processing.
12945ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane   * By default, we examine and then discard APP0 and APP14,
12955ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane   * but simply discard COM and all other APPn.
12965ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane   */
12975ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  marker->process_COM = skip_variable;
12985ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  marker->length_limit_COM = 0;
12995ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  for (i = 0; i < 16; i++) {
13005ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    marker->process_APPn[i] = skip_variable;
13015ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    marker->length_limit_APPn[i] = 0;
13025ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  }
13035ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  marker->process_APPn[0] = get_interesting_appn;
13045ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  marker->process_APPn[14] = get_interesting_appn;
130536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Reset marker processing state */
130636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  reset_marker_reader(cinfo);
130736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
13085ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
13095ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
13105ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane/*
13115ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * Control saving of COM and APPn markers into marker_list.
13125ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane */
13135ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
13145ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane#ifdef SAVE_MARKERS_SUPPORTED
13155ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
13165ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. LaneGLOBAL(void)
13175ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lanejpeg_save_markers (j_decompress_ptr cinfo, int marker_code,
1318e5eaf37440b8e337ab150c017df7c03faf846c51DRC                   unsigned int length_limit)
13195ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane{
13205ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
13215ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  long maxlength;
13225ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  jpeg_marker_parser_method processor;
13235ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
13245ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* Length limit mustn't be larger than what we can allocate
13255ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane   * (should only be a concern in a 16-bit environment).
13265ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane   */
13275de454b291f48382648a5d1dc2aa0fca8b5786d4DRC  maxlength = cinfo->mem->max_alloc_chunk - sizeof(struct jpeg_marker_struct);
13285ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (((long) length_limit) > maxlength)
13295ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    length_limit = (unsigned int) maxlength;
13305ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
13315ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  /* Choose processor routine to use.
13325ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane   * APP0/APP14 have special requirements.
13335ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane   */
13345ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (length_limit) {
13355ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    processor = save_marker;
13365ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* If saving APP0/APP14, save at least enough for our internal use. */
13375ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)
13385ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      length_limit = APP0_DATA_LEN;
13395ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)
13405ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      length_limit = APP14_DATA_LEN;
13415ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  } else {
13425ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    processor = skip_variable;
13435ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    /* If discarding APP0/APP14, use our regular on-the-fly processor. */
13445ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)
13455ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane      processor = get_interesting_appn;
13465ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  }
13475ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
13485ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (marker_code == (int) M_COM) {
13495ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    marker->process_COM = processor;
13505ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    marker->length_limit_COM = length_limit;
13515ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {
13525ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    marker->process_APPn[marker_code - (int) M_APP0] = processor;
13535ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;
13545ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  } else
13555ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
13565ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane}
13575ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
13585ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane#endif /* SAVE_MARKERS_SUPPORTED */
13595ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
13605ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
13615ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane/*
13625ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane * Install a special processing method for COM or APPn markers.
13635ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane */
13645ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
13655ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. LaneGLOBAL(void)
13665ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lanejpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
1367e5eaf37440b8e337ab150c017df7c03faf846c51DRC                           jpeg_marker_parser_method routine)
13685ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane{
13695ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
13705ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane
13715ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  if (marker_code == (int) M_COM)
13725ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    marker->process_COM = routine;
13735ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)
13745ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    marker->process_APPn[marker_code - (int) M_APP0] = routine;
13755ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane  else
13765ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane    ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
13775ead57a34a398aa798f35bd7a6abad19b2e453e2Thomas G. Lane}
1378