roentgen b75cab
/* $Id: tif_ojpeg.c,v 1.56 2012-05-24 03:15:18 fwarmerdam Exp $ */
roentgen b75cab
roentgen b75cab
/* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0
roentgen b75cab
   specification is now totally obsolete and deprecated for new applications and
roentgen b75cab
   images. This file was was created solely in order to read unconverted images
roentgen b75cab
   still present on some users' computer systems. It will never be extended
roentgen b75cab
   to write such files. Writing new-style JPEG compressed TIFFs is implemented
roentgen b75cab
   in tif_jpeg.c.
roentgen b75cab
roentgen b75cab
   The code is carefully crafted to robustly read all gathered JPEG-in-TIFF
roentgen b75cab
   testfiles, and anticipate as much as possible all other... But still, it may
roentgen b75cab
   fail on some. If you encounter problems, please report them on the TIFF
roentgen b75cab
   mailing list and/or to Joris Van Damme <info@awaresystems.be>.</info@awaresystems.be>
roentgen b75cab
roentgen b75cab
   Please read the file called "TIFF Technical Note #2" if you need to be
roentgen b75cab
   convinced this compression scheme is bad and breaks TIFF. That document
roentgen b75cab
   is linked to from the LibTiff site <http: libtiff="" www.remotesensing.org=""></http:>
roentgen b75cab
   and from AWare Systems' TIFF section
roentgen b75cab
   <http: imaging="" tiff.html="" www.awaresystems.be="">. It is also absorbed</http:>
roentgen b75cab
   in Adobe's specification supplements, marked "draft" up to this day, but
roentgen b75cab
   supported by the TIFF community.
roentgen b75cab
roentgen b75cab
   This file interfaces with Release 6B of the JPEG Library written by the
roentgen b75cab
   Independent JPEG Group. Previous versions of this file required a hack inside
roentgen b75cab
   the LibJpeg library. This version no longer requires that. Remember to
roentgen b75cab
   remove the hack if you update from the old version.
roentgen b75cab
roentgen b75cab
   Copyright (c) Joris Van Damme <info@awaresystems.be></info@awaresystems.be>
roentgen b75cab
   Copyright (c) AWare Systems <http: www.awaresystems.be=""></http:>
roentgen b75cab
roentgen b75cab
   The licence agreement for this file is the same as the rest of the LibTiff
roentgen b75cab
   library.
roentgen b75cab
roentgen b75cab
   IN NO EVENT SHALL JORIS VAN DAMME OR AWARE SYSTEMS BE LIABLE FOR
roentgen b75cab
   ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
roentgen b75cab
   OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
roentgen b75cab
   WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
roentgen b75cab
   LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
roentgen b75cab
   OF THIS SOFTWARE.
roentgen b75cab
roentgen b75cab
   Joris Van Damme and/or AWare Systems may be available for custom
roentgen b75cab
   developement. If you like what you see, and need anything similar or related,
roentgen b75cab
   contact <info@awaresystems.be>.</info@awaresystems.be>
roentgen b75cab
*/
roentgen b75cab
roentgen b75cab
/* What is what, and what is not?
roentgen b75cab
roentgen b75cab
   This decoder starts with an input stream, that is essentially the JpegInterchangeFormat
roentgen b75cab
   stream, if any, followed by the strile data, if any. This stream is read in
roentgen b75cab
   OJPEGReadByte and related functions.
roentgen b75cab
roentgen b75cab
   It analyzes the start of this stream, until it encounters non-marker data, i.e.
roentgen b75cab
   compressed image data. Some of the header markers it sees have no actual content,
roentgen b75cab
   like the SOI marker, and APP/COM markers that really shouldn't even be there. Some
roentgen b75cab
   other markers do have content, and the valuable bits and pieces of information
roentgen b75cab
   in these markers are saved, checking all to verify that the stream is more or
roentgen b75cab
   less within expected bounds. This happens inside the OJPEGReadHeaderInfoSecStreamXxx
roentgen b75cab
   functions.
roentgen b75cab
roentgen b75cab
   Some OJPEG imagery contains no valid JPEG header markers. This situation is picked
roentgen b75cab
   up on if we've seen no SOF marker when we're at the start of the compressed image
roentgen b75cab
   data. In this case, the tables are read from JpegXxxTables tags, and the other
roentgen b75cab
   bits and pieces of information is initialized to its most basic value. This is
roentgen b75cab
   implemented in the OJPEGReadHeaderInfoSecTablesXxx functions.
roentgen b75cab
roentgen b75cab
   When this is complete, a good and valid JPEG header can be assembled, and this is
roentgen b75cab
   passed through to LibJpeg. When that's done, the remainder of the input stream, i.e.
roentgen b75cab
   the compressed image data, can be passed through unchanged. This is done in
roentgen b75cab
   OJPEGWriteStream functions.
roentgen b75cab
roentgen b75cab
   LibTiff rightly expects to know the subsampling values before decompression. Just like
roentgen b75cab
   in new-style JPEG-in-TIFF, though, or even more so, actually, the YCbCrsubsampling
roentgen b75cab
   tag is notoriously unreliable. To correct these tag values with the ones inside
roentgen b75cab
   the JPEG stream, the first part of the input stream is pre-scanned in
roentgen b75cab
   OJPEGSubsamplingCorrect, making no note of any other data, reporting no warnings
roentgen b75cab
   or errors, up to the point where either these values are read, or it's clear they
roentgen b75cab
   aren't there. This means that some of the data is read twice, but we feel speed
roentgen b75cab
   in correcting these values is important enough to warrant this sacrifice. Allthough
roentgen b75cab
   there is currently no define or other configuration mechanism to disable this behaviour,
roentgen b75cab
   the actual header scanning is build to robustly respond with error report if it
roentgen b75cab
   should encounter an uncorrected mismatch of subsampling values. See
roentgen b75cab
   OJPEGReadHeaderInfoSecStreamSof.
roentgen b75cab
roentgen b75cab
   The restart interval and restart markers are the most tricky part... The restart
roentgen b75cab
   interval can be specified in a tag. It can also be set inside the input JPEG stream.
roentgen b75cab
   It can be used inside the input JPEG stream. If reading from strile data, we've
roentgen b75cab
   consistenly discovered the need to insert restart markers in between the different
roentgen b75cab
   striles, as is also probably the most likely interpretation of the original TIFF 6.0
roentgen b75cab
   specification. With all this setting of interval, and actual use of markers that is not
roentgen b75cab
   predictable at the time of valid JPEG header assembly, the restart thing may turn
roentgen b75cab
   out the Achilles heel of this implementation. Fortunately, most OJPEG writer vendors
roentgen b75cab
   succeed in reading back what they write, which may be the reason why we've been able
roentgen b75cab
   to discover ways that seem to work.
roentgen b75cab
roentgen b75cab
   Some special provision is made for planarconfig separate OJPEG files. These seem
roentgen b75cab
   to consistently contain header info, a SOS marker, a plane, SOS marker, plane, SOS,
roentgen b75cab
   and plane. This may or may not be a valid JPEG configuration, we don't know and don't
roentgen b75cab
   care. We want LibTiff to be able to access the planes individually, without huge
roentgen b75cab
   buffering inside LibJpeg, anyway. So we compose headers to feed to LibJpeg, in this
roentgen b75cab
   case, that allow us to pass a single plane such that LibJpeg sees a valid
roentgen b75cab
   single-channel JPEG stream. Locating subsequent SOS markers, and thus subsequent
roentgen b75cab
   planes, is done inside OJPEGReadSecondarySos.
roentgen b75cab
roentgen b75cab
   The benefit of the scheme is... that it works, basically. We know of no other that
roentgen b75cab
   does. It works without checking software tag, or otherwise going about things in an
roentgen b75cab
   OJPEG flavor specific manner. Instead, it is a single scheme, that covers the cases
roentgen b75cab
   with and without JpegInterchangeFormat, with and without striles, with part of
roentgen b75cab
   the header in JpegInterchangeFormat and remainder in first strile, etc. It is forgiving
roentgen b75cab
   and robust, may likely work with OJPEG flavors we've not seen yet, and makes most out
roentgen b75cab
   of the data.
roentgen b75cab
roentgen b75cab
   Another nice side-effect is that a complete JPEG single valid stream is build if
roentgen b75cab
   planarconfig is not separate (vast majority). We may one day use that to build
roentgen b75cab
   converters to JPEG, and/or to new-style JPEG compression inside TIFF.
roentgen b75cab
roentgen b75cab
   A dissadvantage is the lack of random access to the individual striles. This is the
roentgen b75cab
   reason for much of the complicated restart-and-position stuff inside OJPEGPreDecode.
roentgen b75cab
   Applications would do well accessing all striles in order, as this will result in
roentgen b75cab
   a single sequential scan of the input stream, and no restarting of LibJpeg decoding
roentgen b75cab
   session.
roentgen b75cab
*/
roentgen b75cab
roentgen b75cab
#define WIN32_LEAN_AND_MEAN
roentgen b75cab
#define VC_EXTRALEAN
roentgen b75cab
roentgen b75cab
#include "tiffiop.h"
roentgen b75cab
#ifdef OJPEG_SUPPORT
roentgen b75cab
roentgen b75cab
/* Configuration defines here are:
roentgen b75cab
 * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some environments,
roentgen b75cab
 * 	like eg LibTiffDelphi, this is not possible. For this reason, the actual calls to
roentgen b75cab
 * 	libjpeg, with longjump stuff, are encapsulated in dedicated functions. When
roentgen b75cab
 * 	JPEG_ENCAP_EXTERNAL is defined, these encapsulating functions are declared external
roentgen b75cab
 * 	to this unit, and can be defined elsewhere to use stuff other then longjump.
roentgen b75cab
 * 	The default mode, without JPEG_ENCAP_EXTERNAL, implements the call encapsulators
roentgen b75cab
 * 	here, internally, with normal longjump.
roentgen b75cab
 * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent is
roentgen b75cab
 * 	conviniently available, but still it may be worthwhile to use _setjmp or sigsetjmp
roentgen b75cab
 * 	in place of plain setjmp. These macros will make it easier. It is useless
roentgen b75cab
 * 	to fiddle with these if you define JPEG_ENCAP_EXTERNAL.
roentgen b75cab
 * OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee
roentgen b75cab
 * 	instant processing, optimal streaming and optimal use of processor cache, but also big
roentgen b75cab
 * 	enough so as to not result in significant call overhead. It should be at least a few
roentgen b75cab
 * 	bytes to accomodate some structures (this is verified in asserts), but it would not be
roentgen b75cab
 * 	sensible to make it this small anyway, and it should be at most 64K since it is indexed
roentgen b75cab
 * 	with uint16. We recommend 2K.
roentgen b75cab
 * EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has
roentgen b75cab
 * 	absolutely no effect. That is why most people insist the EGYPTIANWALK is a bit silly.
roentgen b75cab
 */
roentgen b75cab
roentgen b75cab
/* define LIBJPEG_ENCAP_EXTERNAL */
roentgen b75cab
#define SETJMP(jbuf) setjmp(jbuf)
roentgen b75cab
#define LONGJMP(jbuf,code) longjmp(jbuf,code)
roentgen b75cab
#define JMP_BUF jmp_buf
roentgen b75cab
#define OJPEG_BUFFER 2048
roentgen b75cab
/* define EGYPTIANWALK */
roentgen b75cab
roentgen b75cab
#define JPEG_MARKER_SOF0 0xC0
roentgen b75cab
#define JPEG_MARKER_SOF1 0xC1
roentgen b75cab
#define JPEG_MARKER_SOF3 0xC3
roentgen b75cab
#define JPEG_MARKER_DHT 0xC4
roentgen b75cab
#define JPEG_MARKER_RST0 0XD0
roentgen b75cab
#define JPEG_MARKER_SOI 0xD8
roentgen b75cab
#define JPEG_MARKER_EOI 0xD9
roentgen b75cab
#define JPEG_MARKER_SOS 0xDA
roentgen b75cab
#define JPEG_MARKER_DQT 0xDB
roentgen b75cab
#define JPEG_MARKER_DRI 0xDD
roentgen b75cab
#define JPEG_MARKER_APP0 0xE0
roentgen b75cab
#define JPEG_MARKER_COM 0xFE
roentgen b75cab
roentgen b75cab
#define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC+0)
roentgen b75cab
#define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC+1)
roentgen b75cab
#define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC+2)
roentgen b75cab
#define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC+3)
roentgen b75cab
#define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC+4)
roentgen b75cab
#define FIELD_OJPEG_JPEGPROC (FIELD_CODEC+5)
roentgen b75cab
#define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC+6)
roentgen b75cab
roentgen b75cab
static const TIFFField ojpegFields[] = {
roentgen b75cab
	{TIFFTAG_JPEGIFOFFSET,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMAT,TRUE,FALSE,"JpegInterchangeFormat",NULL},
roentgen b75cab
	{TIFFTAG_JPEGIFBYTECOUNT,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH,TRUE,FALSE,"JpegInterchangeFormatLength",NULL},
roentgen b75cab
	{TIFFTAG_JPEGQTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGQTABLES,FALSE,TRUE,"JpegQTables",NULL},
roentgen b75cab
	{TIFFTAG_JPEGDCTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGDCTABLES,FALSE,TRUE,"JpegDcTables",NULL},
roentgen b75cab
	{TIFFTAG_JPEGACTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGACTABLES,FALSE,TRUE,"JpegAcTables",NULL},
roentgen b75cab
	{TIFFTAG_JPEGPROC,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGPROC,FALSE,FALSE,"JpegProc",NULL},
roentgen b75cab
	{TIFFTAG_JPEGRESTARTINTERVAL,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGRESTARTINTERVAL,FALSE,FALSE,"JpegRestartInterval",NULL},
roentgen b75cab
};
roentgen b75cab
roentgen b75cab
#ifndef LIBJPEG_ENCAP_EXTERNAL
roentgen b75cab
#include <setjmp.h></setjmp.h>
roentgen b75cab
#endif
roentgen b75cab
roentgen b75cab
/* We undefine FAR to avoid conflict with JPEG definition */
roentgen b75cab
roentgen b75cab
#ifdef FAR
roentgen b75cab
#undef FAR
roentgen b75cab
#endif
roentgen b75cab
roentgen b75cab
/*
roentgen b75cab
  Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
roentgen b75cab
  not defined.  Unfortunately, the MinGW and Borland compilers include
roentgen b75cab
  a typedef for INT32, which causes a conflict.  MSVC does not include
roentgen b75cab
  a conficting typedef given the headers which are included.
roentgen b75cab
*/
roentgen b75cab
#if defined(__BORLANDC__) || defined(__MINGW32__)
roentgen b75cab
# define XMD_H 1
roentgen b75cab
#endif
roentgen b75cab
roentgen b75cab
/* Define "boolean" as unsigned char, not int, per Windows custom. */
roentgen b75cab
#if defined(__WIN32__) && !defined(__MINGW32__)
roentgen b75cab
# ifndef __RPCNDR_H__            /* don't conflict if rpcndr.h already read */
roentgen b75cab
   typedef unsigned char boolean;
roentgen b75cab
# endif
roentgen b75cab
# define HAVE_BOOLEAN            /* prevent jmorecfg.h from redefining it */
roentgen b75cab
#endif
roentgen b75cab
roentgen b75cab
#include "jpeglib.h"
roentgen b75cab
#include "jerror.h"
roentgen b75cab
roentgen b75cab
typedef struct jpeg_error_mgr jpeg_error_mgr;
roentgen b75cab
typedef struct jpeg_common_struct jpeg_common_struct;
roentgen b75cab
typedef struct jpeg_decompress_struct jpeg_decompress_struct;
roentgen b75cab
typedef struct jpeg_source_mgr jpeg_source_mgr;
roentgen b75cab
roentgen b75cab
typedef enum {
roentgen b75cab
	osibsNotSetYet,
roentgen b75cab
	osibsJpegInterchangeFormat,
roentgen b75cab
	osibsStrile,
roentgen b75cab
	osibsEof
roentgen b75cab
} OJPEGStateInBufferSource;
roentgen b75cab
roentgen b75cab
typedef enum {
roentgen b75cab
	ososSoi,
roentgen b75cab
	ososQTable0,ososQTable1,ososQTable2,ososQTable3,
roentgen b75cab
	ososDcTable0,ososDcTable1,ososDcTable2,ososDcTable3,
roentgen b75cab
	ososAcTable0,ososAcTable1,ososAcTable2,ososAcTable3,
roentgen b75cab
	ososDri,
roentgen b75cab
	ososSof,
roentgen b75cab
	ososSos,
roentgen b75cab
	ososCompressed,
roentgen b75cab
	ososRst,
roentgen b75cab
	ososEoi
roentgen b75cab
} OJPEGStateOutState;
roentgen b75cab
roentgen b75cab
typedef struct {
roentgen b75cab
	TIFF* tif;
roentgen b75cab
	#ifndef LIBJPEG_ENCAP_EXTERNAL
roentgen b75cab
	JMP_BUF exit_jmpbuf;
roentgen b75cab
	#endif
roentgen b75cab
	TIFFVGetMethod vgetparent;
roentgen b75cab
	TIFFVSetMethod vsetparent;
roentgen b75cab
	TIFFPrintMethod printdir;
roentgen b75cab
	uint64 file_size;
roentgen b75cab
	uint32 image_width;
roentgen b75cab
	uint32 image_length;
roentgen b75cab
	uint32 strile_width;
roentgen b75cab
	uint32 strile_length;
roentgen b75cab
	uint32 strile_length_total;
roentgen b75cab
	uint8 samples_per_pixel;
roentgen b75cab
	uint8 plane_sample_offset;
roentgen b75cab
	uint8 samples_per_pixel_per_plane;
roentgen b75cab
	uint64 jpeg_interchange_format;
roentgen b75cab
	uint64 jpeg_interchange_format_length;
roentgen b75cab
	uint8 jpeg_proc;
roentgen b75cab
	uint8 subsamplingcorrect;
roentgen b75cab
	uint8 subsamplingcorrect_done;
roentgen b75cab
	uint8 subsampling_tag;
roentgen b75cab
	uint8 subsampling_hor;
roentgen b75cab
	uint8 subsampling_ver;
roentgen b75cab
	uint8 subsampling_force_desubsampling_inside_decompression;
roentgen b75cab
	uint8 qtable_offset_count;
roentgen b75cab
	uint8 dctable_offset_count;
roentgen b75cab
	uint8 actable_offset_count;
roentgen b75cab
	uint64 qtable_offset[3];
roentgen b75cab
	uint64 dctable_offset[3];
roentgen b75cab
	uint64 actable_offset[3];
roentgen b75cab
	uint8* qtable[4];
roentgen b75cab
	uint8* dctable[4];
roentgen b75cab
	uint8* actable[4];
roentgen b75cab
	uint16 restart_interval;
roentgen b75cab
	uint8 restart_index;
roentgen b75cab
	uint8 sof_log;
roentgen b75cab
	uint8 sof_marker_id;
roentgen b75cab
	uint32 sof_x;
roentgen b75cab
	uint32 sof_y;
roentgen b75cab
	uint8 sof_c[3];
roentgen b75cab
	uint8 sof_hv[3];
roentgen b75cab
	uint8 sof_tq[3];
roentgen b75cab
	uint8 sos_cs[3];
roentgen b75cab
	uint8 sos_tda[3];
roentgen b75cab
	struct {
roentgen b75cab
		uint8 log;
roentgen b75cab
		OJPEGStateInBufferSource in_buffer_source;
roentgen b75cab
		uint32 in_buffer_next_strile;
roentgen b75cab
		uint64 in_buffer_file_pos;
roentgen b75cab
		uint64 in_buffer_file_togo;
roentgen b75cab
	} sos_end[3];
roentgen b75cab
	uint8 readheader_done;
roentgen b75cab
	uint8 writeheader_done;
roentgen b75cab
	uint16 write_cursample;
roentgen b75cab
	uint32 write_curstrile;
roentgen b75cab
	uint8 libjpeg_session_active;
roentgen b75cab
	uint8 libjpeg_jpeg_query_style;
roentgen b75cab
	jpeg_error_mgr libjpeg_jpeg_error_mgr;
roentgen b75cab
	jpeg_decompress_struct libjpeg_jpeg_decompress_struct;
roentgen b75cab
	jpeg_source_mgr libjpeg_jpeg_source_mgr;
roentgen b75cab
	uint8 subsampling_convert_log;
roentgen b75cab
	uint32 subsampling_convert_ylinelen;
roentgen b75cab
	uint32 subsampling_convert_ylines;
roentgen b75cab
	uint32 subsampling_convert_clinelen;
roentgen b75cab
	uint32 subsampling_convert_clines;
roentgen b75cab
	uint32 subsampling_convert_ybuflen;
roentgen b75cab
	uint32 subsampling_convert_cbuflen;
roentgen b75cab
	uint32 subsampling_convert_ycbcrbuflen;
roentgen b75cab
	uint8* subsampling_convert_ycbcrbuf;
roentgen b75cab
	uint8* subsampling_convert_ybuf;
roentgen b75cab
	uint8* subsampling_convert_cbbuf;
roentgen b75cab
	uint8* subsampling_convert_crbuf;
roentgen b75cab
	uint32 subsampling_convert_ycbcrimagelen;
roentgen b75cab
	uint8** subsampling_convert_ycbcrimage;
roentgen b75cab
	uint32 subsampling_convert_clinelenout;
roentgen b75cab
	uint32 subsampling_convert_state;
roentgen b75cab
	uint32 bytes_per_line;   /* if the codec outputs subsampled data, a 'line' in bytes_per_line */
roentgen b75cab
	uint32 lines_per_strile; /* and lines_per_strile means subsampling_ver desubsampled rows     */
roentgen b75cab
	OJPEGStateInBufferSource in_buffer_source;
roentgen b75cab
	uint32 in_buffer_next_strile;
roentgen b75cab
	uint32 in_buffer_strile_count;
roentgen b75cab
	uint64 in_buffer_file_pos;
roentgen b75cab
	uint8 in_buffer_file_pos_log;
roentgen b75cab
	uint64 in_buffer_file_togo;
roentgen b75cab
	uint16 in_buffer_togo;
roentgen b75cab
	uint8* in_buffer_cur;
roentgen b75cab
	uint8 in_buffer[OJPEG_BUFFER];
roentgen b75cab
	OJPEGStateOutState out_state;
roentgen b75cab
	uint8 out_buffer[OJPEG_BUFFER];
roentgen b75cab
	uint8* skip_buffer;
roentgen b75cab
} OJPEGState;
roentgen b75cab
roentgen b75cab
static int OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap);
roentgen b75cab
static int OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap);
roentgen b75cab
static void OJPEGPrintDir(TIFF* tif, FILE* fd, long flags);
roentgen b75cab
roentgen b75cab
static int OJPEGFixupTags(TIFF* tif);
roentgen b75cab
static int OJPEGSetupDecode(TIFF* tif);
roentgen b75cab
static int OJPEGPreDecode(TIFF* tif, uint16 s);
roentgen b75cab
static int OJPEGPreDecodeSkipRaw(TIFF* tif);
roentgen b75cab
static int OJPEGPreDecodeSkipScanlines(TIFF* tif);
roentgen b75cab
static int OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
roentgen b75cab
static int OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc);
roentgen b75cab
static int OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc);
roentgen b75cab
static void OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc);
roentgen b75cab
static int OJPEGSetupEncode(TIFF* tif);
roentgen b75cab
static int OJPEGPreEncode(TIFF* tif, uint16 s);
roentgen b75cab
static int OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
roentgen b75cab
static int OJPEGPostEncode(TIFF* tif);
roentgen b75cab
static void OJPEGCleanup(TIFF* tif);
roentgen b75cab
roentgen b75cab
static void OJPEGSubsamplingCorrect(TIFF* tif);
roentgen b75cab
static int OJPEGReadHeaderInfo(TIFF* tif);
roentgen b75cab
static int OJPEGReadSecondarySos(TIFF* tif, uint16 s);
roentgen b75cab
static int OJPEGWriteHeaderInfo(TIFF* tif);
roentgen b75cab
static void OJPEGLibjpegSessionAbort(TIFF* tif);
roentgen b75cab
roentgen b75cab
static int OJPEGReadHeaderInfoSec(TIFF* tif);
roentgen b75cab
static int OJPEGReadHeaderInfoSecStreamDri(TIFF* tif);
roentgen b75cab
static int OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif);
roentgen b75cab
static int OJPEGReadHeaderInfoSecStreamDht(TIFF* tif);
roentgen b75cab
static int OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id);
roentgen b75cab
static int OJPEGReadHeaderInfoSecStreamSos(TIFF* tif);
roentgen b75cab
static int OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif);
roentgen b75cab
static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif);
roentgen b75cab
static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif);
roentgen b75cab
roentgen b75cab
static int OJPEGReadBufferFill(OJPEGState* sp);
roentgen b75cab
static int OJPEGReadByte(OJPEGState* sp, uint8* byte);
roentgen b75cab
static int OJPEGReadBytePeek(OJPEGState* sp, uint8* byte);
roentgen b75cab
static void OJPEGReadByteAdvance(OJPEGState* sp);
roentgen b75cab
static int OJPEGReadWord(OJPEGState* sp, uint16* word);
roentgen b75cab
static int OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem);
roentgen b75cab
static void OJPEGReadSkip(OJPEGState* sp, uint16 len);
roentgen b75cab
roentgen b75cab
static int OJPEGWriteStream(TIFF* tif, void** mem, uint32* len);
roentgen b75cab
static void OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len);
roentgen b75cab
static void OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
roentgen b75cab
static void OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
roentgen b75cab
static void OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
roentgen b75cab
static void OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len);
roentgen b75cab
static void OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len);
roentgen b75cab
static void OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len);
roentgen b75cab
static int OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len);
roentgen b75cab
static void OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len);
roentgen b75cab
static void OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len);
roentgen b75cab
roentgen b75cab
#ifdef LIBJPEG_ENCAP_EXTERNAL
roentgen b75cab
extern int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
roentgen b75cab
extern int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
roentgen b75cab
extern int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
roentgen b75cab
extern int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
roentgen b75cab
extern int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
roentgen b75cab
extern void jpeg_encap_unwind(TIFF* tif);
roentgen b75cab
#else
roentgen b75cab
static int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* j);
roentgen b75cab
static int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
roentgen b75cab
static int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
roentgen b75cab
static int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
roentgen b75cab
static int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
roentgen b75cab
static void jpeg_encap_unwind(TIFF* tif);
roentgen b75cab
#endif
roentgen b75cab
roentgen b75cab
static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo);
roentgen b75cab
static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo);
roentgen b75cab
static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo);
roentgen b75cab
static boolean OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo);
roentgen b75cab
static void OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes);
roentgen b75cab
static boolean OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired);
roentgen b75cab
static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo);
roentgen b75cab
roentgen b75cab
int
roentgen b75cab
TIFFInitOJPEG(TIFF* tif, int scheme)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="TIFFInitOJPEG";
roentgen b75cab
	OJPEGState* sp;
roentgen b75cab
roentgen b75cab
	assert(scheme==COMPRESSION_OJPEG);
roentgen b75cab
roentgen b75cab
        /*
roentgen b75cab
	 * Merge codec-specific tag information.
roentgen b75cab
	 */
roentgen b75cab
	if (!_TIFFMergeFields(tif, ojpegFields, TIFFArrayCount(ojpegFields))) {
roentgen b75cab
		TIFFErrorExt(tif->tif_clientdata, module,
roentgen b75cab
		    "Merging Old JPEG codec-specific tags failed");
roentgen b75cab
		return 0;
roentgen b75cab
	}
roentgen b75cab
roentgen b75cab
	/* state block */
roentgen b75cab
	sp=_TIFFmalloc(sizeof(OJPEGState));
roentgen b75cab
	if (sp==NULL)
roentgen b75cab
	{
roentgen b75cab
		TIFFErrorExt(tif->tif_clientdata,module,"No space for OJPEG state block");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	_TIFFmemset(sp,0,sizeof(OJPEGState));
roentgen b75cab
	sp->tif=tif;
roentgen b75cab
	sp->jpeg_proc=1;
roentgen b75cab
	sp->subsampling_hor=2;
roentgen b75cab
	sp->subsampling_ver=2;
roentgen b75cab
	TIFFSetField(tif,TIFFTAG_YCBCRSUBSAMPLING,2,2);
roentgen b75cab
	/* tif codec methods */
roentgen b75cab
	tif->tif_fixuptags=OJPEGFixupTags;  
roentgen b75cab
	tif->tif_setupdecode=OJPEGSetupDecode;
roentgen b75cab
	tif->tif_predecode=OJPEGPreDecode;
roentgen b75cab
	tif->tif_postdecode=OJPEGPostDecode;  
roentgen b75cab
	tif->tif_decoderow=OJPEGDecode;  
roentgen b75cab
	tif->tif_decodestrip=OJPEGDecode;  
roentgen b75cab
	tif->tif_decodetile=OJPEGDecode;  
roentgen b75cab
	tif->tif_setupencode=OJPEGSetupEncode;
roentgen b75cab
	tif->tif_preencode=OJPEGPreEncode;
roentgen b75cab
	tif->tif_postencode=OJPEGPostEncode;
roentgen b75cab
	tif->tif_encoderow=OJPEGEncode;  
roentgen b75cab
	tif->tif_encodestrip=OJPEGEncode;  
roentgen b75cab
	tif->tif_encodetile=OJPEGEncode;  
roentgen b75cab
	tif->tif_cleanup=OJPEGCleanup;
roentgen b75cab
	tif->tif_data=(uint8*)sp;
roentgen b75cab
	/* tif tag methods */
roentgen b75cab
	sp->vgetparent=tif->tif_tagmethods.vgetfield;
roentgen b75cab
	tif->tif_tagmethods.vgetfield=OJPEGVGetField;
roentgen b75cab
	sp->vsetparent=tif->tif_tagmethods.vsetfield;
roentgen b75cab
	tif->tif_tagmethods.vsetfield=OJPEGVSetField;
roentgen b75cab
	sp->printdir=tif->tif_tagmethods.printdir;
roentgen b75cab
	tif->tif_tagmethods.printdir=OJPEGPrintDir;
roentgen b75cab
	/* Some OJPEG files don't have strip or tile offsets or bytecounts tags.
roentgen b75cab
	   Some others do, but have totally meaningless or corrupt values
roentgen b75cab
	   in these tags. In these cases, the JpegInterchangeFormat stream is
roentgen b75cab
	   reliable. In any case, this decoder reads the compressed data itself,
roentgen b75cab
	   from the most reliable locations, and we need to notify encapsulating
roentgen b75cab
	   LibTiff not to read raw strips or tiles for us. */
roentgen b75cab
	tif->tif_flags|=TIFF_NOREADRAW;
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	switch(tag)
roentgen b75cab
	{
roentgen b75cab
		case TIFFTAG_JPEGIFOFFSET:
roentgen b75cab
			*va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format;
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_JPEGIFBYTECOUNT:
roentgen b75cab
			*va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format_length;
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_YCBCRSUBSAMPLING:
roentgen b75cab
			if (sp->subsamplingcorrect_done==0)
roentgen b75cab
				OJPEGSubsamplingCorrect(tif);
roentgen b75cab
			*va_arg(ap,uint16*)=(uint16)sp->subsampling_hor;
roentgen b75cab
			*va_arg(ap,uint16*)=(uint16)sp->subsampling_ver;
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_JPEGQTABLES:
roentgen b75cab
			*va_arg(ap,uint32*)=(uint32)sp->qtable_offset_count;
roentgen b75cab
			*va_arg(ap,void**)=(void*)sp->qtable_offset; 
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_JPEGDCTABLES:
roentgen b75cab
			*va_arg(ap,uint32*)=(uint32)sp->dctable_offset_count;
roentgen b75cab
			*va_arg(ap,void**)=(void*)sp->dctable_offset;  
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_JPEGACTABLES:
roentgen b75cab
			*va_arg(ap,uint32*)=(uint32)sp->actable_offset_count;
roentgen b75cab
			*va_arg(ap,void**)=(void*)sp->actable_offset;
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_JPEGPROC:
roentgen b75cab
			*va_arg(ap,uint16*)=(uint16)sp->jpeg_proc;
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_JPEGRESTARTINTERVAL:
roentgen b75cab
			*va_arg(ap,uint16*)=sp->restart_interval;
roentgen b75cab
			break;
roentgen b75cab
		default:
roentgen b75cab
			return (*sp->vgetparent)(tif,tag,ap);
roentgen b75cab
	}
roentgen b75cab
	return (1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGVSetField";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint32 ma;
roentgen b75cab
	uint64* mb;
roentgen b75cab
	uint32 n;
roentgen b75cab
	switch(tag)
roentgen b75cab
	{
roentgen b75cab
		case TIFFTAG_JPEGIFOFFSET:
roentgen b75cab
			sp->jpeg_interchange_format=(uint64)va_arg(ap,uint64);
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_JPEGIFBYTECOUNT:
roentgen b75cab
			sp->jpeg_interchange_format_length=(uint64)va_arg(ap,uint64);
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_YCBCRSUBSAMPLING:
roentgen b75cab
			sp->subsampling_tag=1;
roentgen b75cab
			sp->subsampling_hor=(uint8)va_arg(ap,uint16_vap);
roentgen b75cab
			sp->subsampling_ver=(uint8)va_arg(ap,uint16_vap);
roentgen b75cab
			tif->tif_dir.td_ycbcrsubsampling[0]=sp->subsampling_hor;
roentgen b75cab
			tif->tif_dir.td_ycbcrsubsampling[1]=sp->subsampling_ver;
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_JPEGQTABLES:
roentgen b75cab
			ma=(uint32)va_arg(ap,uint32);
roentgen b75cab
			if (ma!=0)
roentgen b75cab
			{
roentgen b75cab
				if (ma>3)
roentgen b75cab
				{
roentgen b75cab
					TIFFErrorExt(tif->tif_clientdata,module,"JpegQTables tag has incorrect count");
roentgen b75cab
					return(0);
roentgen b75cab
				}
roentgen b75cab
				sp->qtable_offset_count=(uint8)ma;
roentgen b75cab
				mb=(uint64*)va_arg(ap,uint64*);
roentgen b75cab
				for (n=0; n
roentgen b75cab
					sp->qtable_offset[n]=mb[n];
roentgen b75cab
			}
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_JPEGDCTABLES:
roentgen b75cab
			ma=(uint32)va_arg(ap,uint32);
roentgen b75cab
			if (ma!=0)
roentgen b75cab
			{
roentgen b75cab
				if (ma>3)
roentgen b75cab
				{
roentgen b75cab
					TIFFErrorExt(tif->tif_clientdata,module,"JpegDcTables tag has incorrect count");
roentgen b75cab
					return(0);
roentgen b75cab
				}
roentgen b75cab
				sp->dctable_offset_count=(uint8)ma;
roentgen b75cab
				mb=(uint64*)va_arg(ap,uint64*);
roentgen b75cab
				for (n=0; n
roentgen b75cab
					sp->dctable_offset[n]=mb[n];
roentgen b75cab
			}
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_JPEGACTABLES:
roentgen b75cab
			ma=(uint32)va_arg(ap,uint32);
roentgen b75cab
			if (ma!=0)
roentgen b75cab
			{
roentgen b75cab
				if (ma>3)
roentgen b75cab
				{
roentgen b75cab
					TIFFErrorExt(tif->tif_clientdata,module,"JpegAcTables tag has incorrect count");
roentgen b75cab
					return(0);
roentgen b75cab
				}
roentgen b75cab
				sp->actable_offset_count=(uint8)ma;
roentgen b75cab
				mb=(uint64*)va_arg(ap,uint64*);
roentgen b75cab
				for (n=0; n
roentgen b75cab
					sp->actable_offset[n]=mb[n];
roentgen b75cab
			}
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_JPEGPROC:
roentgen b75cab
			sp->jpeg_proc=(uint8)va_arg(ap,uint16_vap);
roentgen b75cab
			break;
roentgen b75cab
		case TIFFTAG_JPEGRESTARTINTERVAL:
roentgen b75cab
			sp->restart_interval=(uint16)va_arg(ap,uint16_vap);
roentgen b75cab
			break;
roentgen b75cab
		default:
roentgen b75cab
			return (*sp->vsetparent)(tif,tag,ap);
roentgen b75cab
	}
roentgen b75cab
	TIFFSetFieldBit(tif,TIFFFieldWithTag(tif,tag)->field_bit);
roentgen b75cab
	tif->tif_flags|=TIFF_DIRTYDIRECT;
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGPrintDir(TIFF* tif, FILE* fd, long flags)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint8 m;
roentgen b75cab
	(void)flags;
roentgen b75cab
	assert(sp!=NULL);
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMAT))
roentgen b75cab
		fprintf(fd,"  JpegInterchangeFormat: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format);  
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH))
roentgen b75cab
		fprintf(fd,"  JpegInterchangeFormatLength: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format_length);  
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGQTABLES))
roentgen b75cab
	{
roentgen b75cab
		fprintf(fd,"  JpegQTables:");
roentgen b75cab
		for (m=0; m<sp->qtable_offset_count; m++)</sp->
roentgen b75cab
			fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->qtable_offset[m]);
roentgen b75cab
		fprintf(fd,"\n");
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGDCTABLES))
roentgen b75cab
	{
roentgen b75cab
		fprintf(fd,"  JpegDcTables:");
roentgen b75cab
		for (m=0; m<sp->dctable_offset_count; m++)</sp->
roentgen b75cab
			fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->dctable_offset[m]);
roentgen b75cab
		fprintf(fd,"\n");
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGACTABLES))
roentgen b75cab
	{
roentgen b75cab
		fprintf(fd,"  JpegAcTables:");
roentgen b75cab
		for (m=0; m<sp->actable_offset_count; m++)</sp->
roentgen b75cab
			fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->actable_offset[m]);
roentgen b75cab
		fprintf(fd,"\n");
roentgen b75cab
	}
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGPROC))
roentgen b75cab
		fprintf(fd,"  JpegProc: %u\n",(unsigned int)sp->jpeg_proc);
roentgen b75cab
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGRESTARTINTERVAL))
roentgen b75cab
		fprintf(fd,"  JpegRestartInterval: %u\n",(unsigned int)sp->restart_interval);
roentgen b75cab
	if (sp->printdir)
roentgen b75cab
		(*sp->printdir)(tif, fd, flags);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGFixupTags(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	(void) tif;
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGSetupDecode(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGSetupDecode";
roentgen b75cab
	TIFFWarningExt(tif->tif_clientdata,module,"Depreciated and troublesome old-style JPEG compression mode, please convert to new-style JPEG compression and notify vendor of writing software");
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGPreDecode(TIFF* tif, uint16 s)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint32 m;
roentgen b75cab
	if (sp->subsamplingcorrect_done==0)
roentgen b75cab
		OJPEGSubsamplingCorrect(tif);
roentgen b75cab
	if (sp->readheader_done==0)
roentgen b75cab
	{
roentgen b75cab
		if (OJPEGReadHeaderInfo(tif)==0)
roentgen b75cab
			return(0);
roentgen b75cab
	}
roentgen b75cab
	if (sp->sos_end[s].log==0)
roentgen b75cab
	{
roentgen b75cab
		if (OJPEGReadSecondarySos(tif,s)==0)
roentgen b75cab
			return(0);
roentgen b75cab
	}
roentgen b75cab
	if isTiled(tif)
roentgen b75cab
		m=tif->tif_curtile;
roentgen b75cab
	else
roentgen b75cab
		m=tif->tif_curstrip;
roentgen b75cab
	if ((sp->writeheader_done!=0) && ((sp->write_cursample!=s) || (sp->write_curstrile>m)))
roentgen b75cab
	{
roentgen b75cab
		if (sp->libjpeg_session_active!=0)
roentgen b75cab
			OJPEGLibjpegSessionAbort(tif);
roentgen b75cab
		sp->writeheader_done=0;
roentgen b75cab
	}
roentgen b75cab
	if (sp->writeheader_done==0)
roentgen b75cab
	{
roentgen b75cab
		sp->plane_sample_offset=(uint8)s;
roentgen b75cab
		sp->write_cursample=s;
roentgen b75cab
		sp->write_curstrile=s*tif->tif_dir.td_stripsperimage;
roentgen b75cab
		if ((sp->in_buffer_file_pos_log==0) ||
roentgen b75cab
		    (sp->in_buffer_file_pos-sp->in_buffer_togo!=sp->sos_end[s].in_buffer_file_pos))
roentgen b75cab
		{
roentgen b75cab
			sp->in_buffer_source=sp->sos_end[s].in_buffer_source;
roentgen b75cab
			sp->in_buffer_next_strile=sp->sos_end[s].in_buffer_next_strile;
roentgen b75cab
			sp->in_buffer_file_pos=sp->sos_end[s].in_buffer_file_pos;
roentgen b75cab
			sp->in_buffer_file_pos_log=0;
roentgen b75cab
			sp->in_buffer_file_togo=sp->sos_end[s].in_buffer_file_togo;
roentgen b75cab
			sp->in_buffer_togo=0;
roentgen b75cab
			sp->in_buffer_cur=0;
roentgen b75cab
		}
roentgen b75cab
		if (OJPEGWriteHeaderInfo(tif)==0)
roentgen b75cab
			return(0);
roentgen b75cab
	}
roentgen b75cab
	while (sp->write_curstrile
roentgen b75cab
	{
roentgen b75cab
		if (sp->libjpeg_jpeg_query_style==0)
roentgen b75cab
		{
roentgen b75cab
			if (OJPEGPreDecodeSkipRaw(tif)==0)
roentgen b75cab
				return(0);
roentgen b75cab
		}
roentgen b75cab
		else
roentgen b75cab
		{
roentgen b75cab
			if (OJPEGPreDecodeSkipScanlines(tif)==0)
roentgen b75cab
				return(0);
roentgen b75cab
		}
roentgen b75cab
		sp->write_curstrile++;
roentgen b75cab
	}
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGPreDecodeSkipRaw(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint32 m;
roentgen b75cab
	m=sp->lines_per_strile;
roentgen b75cab
	if (sp->subsampling_convert_state!=0)
roentgen b75cab
	{
roentgen b75cab
		if (sp->subsampling_convert_clines-sp->subsampling_convert_state>=m)
roentgen b75cab
		{
roentgen b75cab
			sp->subsampling_convert_state+=m;
roentgen b75cab
			if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
roentgen b75cab
				sp->subsampling_convert_state=0;
roentgen b75cab
			return(1);
roentgen b75cab
		}
roentgen b75cab
		m-=sp->subsampling_convert_clines-sp->subsampling_convert_state;
roentgen b75cab
		sp->subsampling_convert_state=0;
roentgen b75cab
	}
roentgen b75cab
	while (m>=sp->subsampling_convert_clines)
roentgen b75cab
	{
roentgen b75cab
		if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		m-=sp->subsampling_convert_clines;
roentgen b75cab
	}
roentgen b75cab
	if (m>0)
roentgen b75cab
	{
roentgen b75cab
		if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		sp->subsampling_convert_state=m;
roentgen b75cab
	}
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGPreDecodeSkipScanlines(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGPreDecodeSkipScanlines";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint32 m;
roentgen b75cab
	if (sp->skip_buffer==NULL)
roentgen b75cab
	{
roentgen b75cab
		sp->skip_buffer=_TIFFmalloc(sp->bytes_per_line);
roentgen b75cab
		if (sp->skip_buffer==NULL)
roentgen b75cab
		{
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
roentgen b75cab
			return(0);
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
	for (m=0; m<sp->lines_per_strile; m++)</sp->
roentgen b75cab
	{
roentgen b75cab
		if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&sp->skip_buffer,1)==0)
roentgen b75cab
			return(0);
roentgen b75cab
	}
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	(void)s;
roentgen b75cab
	if (sp->libjpeg_jpeg_query_style==0)
roentgen b75cab
	{
roentgen b75cab
		if (OJPEGDecodeRaw(tif,buf,cc)==0)
roentgen b75cab
			return(0);
roentgen b75cab
	}
roentgen b75cab
	else
roentgen b75cab
	{
roentgen b75cab
		if (OJPEGDecodeScanlines(tif,buf,cc)==0)
roentgen b75cab
			return(0);
roentgen b75cab
	}
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGDecodeRaw";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint8* m;
roentgen b75cab
	tmsize_t n;
roentgen b75cab
	uint8* oy;
roentgen b75cab
	uint8* ocb;
roentgen b75cab
	uint8* ocr;
roentgen b75cab
	uint8* p;
roentgen b75cab
	uint32 q;
roentgen b75cab
	uint8* r;
roentgen b75cab
	uint8 sx,sy;
roentgen b75cab
	if (cc%sp->bytes_per_line!=0)
roentgen b75cab
	{
roentgen b75cab
		TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	assert(cc>0);
roentgen b75cab
	m=buf;
roentgen b75cab
	n=cc;
roentgen b75cab
	do
roentgen b75cab
	{
roentgen b75cab
		if (sp->subsampling_convert_state==0)
roentgen b75cab
		{
roentgen b75cab
			if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
roentgen b75cab
				return(0);
roentgen b75cab
		}
roentgen b75cab
		oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen;
roentgen b75cab
		ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
roentgen b75cab
		ocr=sp->subsampling_convert_crbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
roentgen b75cab
		p=m;
roentgen b75cab
		for (q=0; q<sp->subsampling_convert_clinelenout; q++)</sp->
roentgen b75cab
		{
roentgen b75cab
			r=oy;
roentgen b75cab
			for (sy=0; sy<sp->subsampling_ver; sy++)</sp->
roentgen b75cab
			{
roentgen b75cab
				for (sx=0; sx<sp->subsampling_hor; sx++)</sp->
roentgen b75cab
					*p++=*r++;
roentgen b75cab
				r+=sp->subsampling_convert_ylinelen-sp->subsampling_hor;
roentgen b75cab
			}
roentgen b75cab
			oy+=sp->subsampling_hor;
roentgen b75cab
			*p++=*ocb++;
roentgen b75cab
			*p++=*ocr++;
roentgen b75cab
		}
roentgen b75cab
		sp->subsampling_convert_state++;
roentgen b75cab
		if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
roentgen b75cab
			sp->subsampling_convert_state=0;
roentgen b75cab
		m+=sp->bytes_per_line;
roentgen b75cab
		n-=sp->bytes_per_line;
roentgen b75cab
	} while(n>0);
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGDecodeScanlines";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint8* m;
roentgen b75cab
	tmsize_t n;
roentgen b75cab
	if (cc%sp->bytes_per_line!=0)
roentgen b75cab
	{
roentgen b75cab
		TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	assert(cc>0);
roentgen b75cab
	m=buf;
roentgen b75cab
	n=cc;
roentgen b75cab
	do
roentgen b75cab
	{
roentgen b75cab
		if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&m,1)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		m+=sp->bytes_per_line;
roentgen b75cab
		n-=sp->bytes_per_line;
roentgen b75cab
	} while(n>0);
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	(void)buf;
roentgen b75cab
	(void)cc;
roentgen b75cab
	sp->write_curstrile++;
roentgen b75cab
	if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0)  
roentgen b75cab
	{
roentgen b75cab
		assert(sp->libjpeg_session_active!=0);
roentgen b75cab
		OJPEGLibjpegSessionAbort(tif);
roentgen b75cab
		sp->writeheader_done=0;
roentgen b75cab
	}
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGSetupEncode(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGSetupEncode";
roentgen b75cab
	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
roentgen b75cab
	return(0);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGPreEncode(TIFF* tif, uint16 s)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGPreEncode";
roentgen b75cab
	(void)s;
roentgen b75cab
	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
roentgen b75cab
	return(0);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGEncode";
roentgen b75cab
	(void)buf;
roentgen b75cab
	(void)cc;
roentgen b75cab
	(void)s;
roentgen b75cab
	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
roentgen b75cab
	return(0);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGPostEncode(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGPostEncode";
roentgen b75cab
	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
roentgen b75cab
	return(0);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGCleanup(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	if (sp!=0)
roentgen b75cab
	{
roentgen b75cab
		tif->tif_tagmethods.vgetfield=sp->vgetparent;
roentgen b75cab
		tif->tif_tagmethods.vsetfield=sp->vsetparent;
roentgen b75cab
		tif->tif_tagmethods.printdir=sp->printdir;
roentgen b75cab
		if (sp->qtable[0]!=0)
roentgen b75cab
			_TIFFfree(sp->qtable[0]);
roentgen b75cab
		if (sp->qtable[1]!=0)
roentgen b75cab
			_TIFFfree(sp->qtable[1]);
roentgen b75cab
		if (sp->qtable[2]!=0)
roentgen b75cab
			_TIFFfree(sp->qtable[2]);
roentgen b75cab
		if (sp->qtable[3]!=0)
roentgen b75cab
			_TIFFfree(sp->qtable[3]);
roentgen b75cab
		if (sp->dctable[0]!=0)
roentgen b75cab
			_TIFFfree(sp->dctable[0]);
roentgen b75cab
		if (sp->dctable[1]!=0)
roentgen b75cab
			_TIFFfree(sp->dctable[1]);
roentgen b75cab
		if (sp->dctable[2]!=0)
roentgen b75cab
			_TIFFfree(sp->dctable[2]);
roentgen b75cab
		if (sp->dctable[3]!=0)
roentgen b75cab
			_TIFFfree(sp->dctable[3]);
roentgen b75cab
		if (sp->actable[0]!=0)
roentgen b75cab
			_TIFFfree(sp->actable[0]);
roentgen b75cab
		if (sp->actable[1]!=0)
roentgen b75cab
			_TIFFfree(sp->actable[1]);
roentgen b75cab
		if (sp->actable[2]!=0)
roentgen b75cab
			_TIFFfree(sp->actable[2]);
roentgen b75cab
		if (sp->actable[3]!=0)
roentgen b75cab
			_TIFFfree(sp->actable[3]);
roentgen b75cab
		if (sp->libjpeg_session_active!=0)
roentgen b75cab
			OJPEGLibjpegSessionAbort(tif);
roentgen b75cab
		if (sp->subsampling_convert_ycbcrbuf!=0)
roentgen b75cab
			_TIFFfree(sp->subsampling_convert_ycbcrbuf);
roentgen b75cab
		if (sp->subsampling_convert_ycbcrimage!=0)
roentgen b75cab
			_TIFFfree(sp->subsampling_convert_ycbcrimage);
roentgen b75cab
		if (sp->skip_buffer!=0)
roentgen b75cab
			_TIFFfree(sp->skip_buffer);
roentgen b75cab
		_TIFFfree(sp);
roentgen b75cab
		tif->tif_data=NULL;
roentgen b75cab
		_TIFFSetDefaultCompressionState(tif);
roentgen b75cab
	}
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGSubsamplingCorrect(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGSubsamplingCorrect";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint8 mh;
roentgen b75cab
	uint8 mv;
roentgen b75cab
        _TIFFFillStriles( tif );
roentgen b75cab
        
roentgen b75cab
	assert(sp->subsamplingcorrect_done==0);
roentgen b75cab
	if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) &&
roentgen b75cab
	    (tif->tif_dir.td_photometric!=PHOTOMETRIC_ITULAB)))
roentgen b75cab
	{
roentgen b75cab
		if (sp->subsampling_tag!=0)
roentgen b75cab
			TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag not appropriate for this Photometric and/or SamplesPerPixel");
roentgen b75cab
		sp->subsampling_hor=1;
roentgen b75cab
		sp->subsampling_ver=1;
roentgen b75cab
		sp->subsampling_force_desubsampling_inside_decompression=0;
roentgen b75cab
	}
roentgen b75cab
	else
roentgen b75cab
	{
roentgen b75cab
		sp->subsamplingcorrect_done=1;
roentgen b75cab
		mh=sp->subsampling_hor;
roentgen b75cab
		mv=sp->subsampling_ver;
roentgen b75cab
		sp->subsamplingcorrect=1;
roentgen b75cab
		OJPEGReadHeaderInfoSec(tif);
roentgen b75cab
		if (sp->subsampling_force_desubsampling_inside_decompression!=0)
roentgen b75cab
		{
roentgen b75cab
			sp->subsampling_hor=1;
roentgen b75cab
			sp->subsampling_ver=1;
roentgen b75cab
		}
roentgen b75cab
		sp->subsamplingcorrect=0;
roentgen b75cab
		if (((sp->subsampling_hor!=mh) || (sp->subsampling_ver!=mv)) && (sp->subsampling_force_desubsampling_inside_decompression==0))
roentgen b75cab
		{
roentgen b75cab
			if (sp->subsampling_tag==0)
roentgen b75cab
				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data [%d,%d] does not match default values [2,2]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver);
roentgen b75cab
			else
roentgen b75cab
				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data [%d,%d] does not match subsampling tag values [%d,%d]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver,mh,mv);
roentgen b75cab
		}
roentgen b75cab
		if (sp->subsampling_force_desubsampling_inside_decompression!=0)
roentgen b75cab
		{
roentgen b75cab
			if (sp->subsampling_tag==0)
roentgen b75cab
				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data does not match default values [2,2] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression");
roentgen b75cab
			else
roentgen b75cab
				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data does not match subsampling tag values [%d,%d] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression",mh,mv);
roentgen b75cab
		}
roentgen b75cab
		if (sp->subsampling_force_desubsampling_inside_decompression==0)
roentgen b75cab
		{
roentgen b75cab
			if (sp->subsampling_hor<sp->subsampling_ver)</sp->
roentgen b75cab
				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling values [%d,%d] are not allowed in TIFF",sp->subsampling_hor,sp->subsampling_ver);
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
	sp->subsamplingcorrect_done=1;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadHeaderInfo(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGReadHeaderInfo";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	assert(sp->readheader_done==0);
roentgen b75cab
	sp->image_width=tif->tif_dir.td_imagewidth;
roentgen b75cab
	sp->image_length=tif->tif_dir.td_imagelength;
roentgen b75cab
	if isTiled(tif)
roentgen b75cab
	{
roentgen b75cab
		sp->strile_width=tif->tif_dir.td_tilewidth;
roentgen b75cab
		sp->strile_length=tif->tif_dir.td_tilelength;
roentgen b75cab
		sp->strile_length_total=((sp->image_length+sp->strile_length-1)/sp->strile_length)*sp->strile_length;
roentgen b75cab
	}
roentgen b75cab
	else
roentgen b75cab
	{
roentgen b75cab
		sp->strile_width=sp->image_width;
roentgen b75cab
		sp->strile_length=tif->tif_dir.td_rowsperstrip;
roentgen b75cab
		sp->strile_length_total=sp->image_length;
roentgen b75cab
	}
roentgen b75cab
	if (tif->tif_dir.td_samplesperpixel==1)
roentgen b75cab
	{
roentgen b75cab
		sp->samples_per_pixel=1;
roentgen b75cab
		sp->plane_sample_offset=0;
roentgen b75cab
		sp->samples_per_pixel_per_plane=sp->samples_per_pixel;
roentgen b75cab
		sp->subsampling_hor=1;
roentgen b75cab
		sp->subsampling_ver=1;
roentgen b75cab
	}
roentgen b75cab
	else
roentgen b75cab
	{
roentgen b75cab
		if (tif->tif_dir.td_samplesperpixel!=3)
roentgen b75cab
		{
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"SamplesPerPixel %d not supported for this compression scheme",sp->samples_per_pixel);
roentgen b75cab
			return(0);
roentgen b75cab
		}
roentgen b75cab
		sp->samples_per_pixel=3;
roentgen b75cab
		sp->plane_sample_offset=0;
roentgen b75cab
		if (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)
roentgen b75cab
			sp->samples_per_pixel_per_plane=3;
roentgen b75cab
		else
roentgen b75cab
			sp->samples_per_pixel_per_plane=1;
roentgen b75cab
	}
roentgen b75cab
	if (sp->strile_length<sp->image_length)</sp->
roentgen b75cab
	{
roentgen b75cab
		if (sp->strile_length%(sp->subsampling_ver*8)!=0)
roentgen b75cab
		{
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length");
roentgen b75cab
			return(0);
roentgen b75cab
		}
roentgen b75cab
		sp->restart_interval=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8))*(sp->strile_length/(sp->subsampling_ver*8));
roentgen b75cab
	}
roentgen b75cab
	if (OJPEGReadHeaderInfoSec(tif)==0)
roentgen b75cab
		return(0);
roentgen b75cab
	sp->sos_end[0].log=1;
roentgen b75cab
	sp->sos_end[0].in_buffer_source=sp->in_buffer_source;
roentgen b75cab
	sp->sos_end[0].in_buffer_next_strile=sp->in_buffer_next_strile;
roentgen b75cab
	sp->sos_end[0].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
roentgen b75cab
	sp->sos_end[0].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo; 
roentgen b75cab
	sp->readheader_done=1;
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadSecondarySos(TIFF* tif, uint16 s)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint8 m;
roentgen b75cab
	assert(s>0);
roentgen b75cab
	assert(s<3);
roentgen b75cab
	assert(sp->sos_end[0].log!=0);
roentgen b75cab
	assert(sp->sos_end[s].log==0);
roentgen b75cab
	sp->plane_sample_offset=s-1;
roentgen b75cab
	while(sp->sos_end[sp->plane_sample_offset].log==0)
roentgen b75cab
		sp->plane_sample_offset--;
roentgen b75cab
	sp->in_buffer_source=sp->sos_end[sp->plane_sample_offset].in_buffer_source;
roentgen b75cab
	sp->in_buffer_next_strile=sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile;
roentgen b75cab
	sp->in_buffer_file_pos=sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos;
roentgen b75cab
	sp->in_buffer_file_pos_log=0;
roentgen b75cab
	sp->in_buffer_file_togo=sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo;
roentgen b75cab
	sp->in_buffer_togo=0;
roentgen b75cab
	sp->in_buffer_cur=0;
roentgen b75cab
	while(sp->plane_sample_offset
roentgen b75cab
	{
roentgen b75cab
		do
roentgen b75cab
		{
roentgen b75cab
			if (OJPEGReadByte(sp,&m)==0)
roentgen b75cab
				return(0);
roentgen b75cab
			if (m==255)
roentgen b75cab
			{
roentgen b75cab
				do
roentgen b75cab
				{
roentgen b75cab
					if (OJPEGReadByte(sp,&m)==0)
roentgen b75cab
						return(0);
roentgen b75cab
					if (m!=255)
roentgen b75cab
						break;
roentgen b75cab
				} while(1);
roentgen b75cab
				if (m==JPEG_MARKER_SOS)
roentgen b75cab
					break;
roentgen b75cab
			}
roentgen b75cab
		} while(1);
roentgen b75cab
		sp->plane_sample_offset++;
roentgen b75cab
		if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		sp->sos_end[sp->plane_sample_offset].log=1;
roentgen b75cab
		sp->sos_end[sp->plane_sample_offset].in_buffer_source=sp->in_buffer_source;
roentgen b75cab
		sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile=sp->in_buffer_next_strile;
roentgen b75cab
		sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
roentgen b75cab
		sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo;
roentgen b75cab
	}
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGWriteHeaderInfo(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGWriteHeaderInfo";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint8** m;
roentgen b75cab
	uint32 n;
roentgen b75cab
	/* if a previous attempt failed, don't try again */
roentgen b75cab
	if (sp->libjpeg_session_active != 0) 
roentgen b75cab
		return 0;
roentgen b75cab
	sp->out_state=ososSoi;
roentgen b75cab
	sp->restart_index=0;
roentgen b75cab
	jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr));
roentgen b75cab
	sp->libjpeg_jpeg_error_mgr.output_message=OJPEGLibjpegJpegErrorMgrOutputMessage;
roentgen b75cab
	sp->libjpeg_jpeg_error_mgr.error_exit=OJPEGLibjpegJpegErrorMgrErrorExit;
roentgen b75cab
	sp->libjpeg_jpeg_decompress_struct.err=&(sp->libjpeg_jpeg_error_mgr);
roentgen b75cab
	sp->libjpeg_jpeg_decompress_struct.client_data=(void*)tif;
roentgen b75cab
	if (jpeg_create_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
roentgen b75cab
		return(0);
roentgen b75cab
	sp->libjpeg_session_active=1;
roentgen b75cab
	sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=0;
roentgen b75cab
	sp->libjpeg_jpeg_source_mgr.init_source=OJPEGLibjpegJpegSourceMgrInitSource;
roentgen b75cab
	sp->libjpeg_jpeg_source_mgr.fill_input_buffer=OJPEGLibjpegJpegSourceMgrFillInputBuffer;
roentgen b75cab
	sp->libjpeg_jpeg_source_mgr.skip_input_data=OJPEGLibjpegJpegSourceMgrSkipInputData;
roentgen b75cab
	sp->libjpeg_jpeg_source_mgr.resync_to_restart=OJPEGLibjpegJpegSourceMgrResyncToRestart;
roentgen b75cab
	sp->libjpeg_jpeg_source_mgr.term_source=OJPEGLibjpegJpegSourceMgrTermSource;
roentgen b75cab
	sp->libjpeg_jpeg_decompress_struct.src=&(sp->libjpeg_jpeg_source_mgr);
roentgen b75cab
	if (jpeg_read_header_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),1)==0)
roentgen b75cab
		return(0);
roentgen b75cab
	if ((sp->subsampling_force_desubsampling_inside_decompression==0) && (sp->samples_per_pixel_per_plane>1))
roentgen b75cab
	{
roentgen b75cab
		sp->libjpeg_jpeg_decompress_struct.raw_data_out=1;
roentgen b75cab
#if JPEG_LIB_VERSION >= 70
roentgen b75cab
		sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling=FALSE;
roentgen b75cab
#endif
roentgen b75cab
		sp->libjpeg_jpeg_query_style=0;
roentgen b75cab
		if (sp->subsampling_convert_log==0)
roentgen b75cab
		{
roentgen b75cab
			assert(sp->subsampling_convert_ycbcrbuf==0);
roentgen b75cab
			assert(sp->subsampling_convert_ycbcrimage==0);
roentgen b75cab
			sp->subsampling_convert_ylinelen=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8)*sp->subsampling_hor*8);
roentgen b75cab
			sp->subsampling_convert_ylines=sp->subsampling_ver*8;
roentgen b75cab
			sp->subsampling_convert_clinelen=sp->subsampling_convert_ylinelen/sp->subsampling_hor;
roentgen b75cab
			sp->subsampling_convert_clines=8;
roentgen b75cab
			sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines;
roentgen b75cab
			sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines;
roentgen b75cab
			sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen;
roentgen b75cab
			sp->subsampling_convert_ycbcrbuf=_TIFFmalloc(sp->subsampling_convert_ycbcrbuflen);
roentgen b75cab
			if (sp->subsampling_convert_ycbcrbuf==0)
roentgen b75cab
			{
roentgen b75cab
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
roentgen b75cab
				return(0);
roentgen b75cab
			}
roentgen b75cab
			sp->subsampling_convert_ybuf=sp->subsampling_convert_ycbcrbuf;
roentgen b75cab
			sp->subsampling_convert_cbbuf=sp->subsampling_convert_ybuf+sp->subsampling_convert_ybuflen;
roentgen b75cab
			sp->subsampling_convert_crbuf=sp->subsampling_convert_cbbuf+sp->subsampling_convert_cbuflen;
roentgen b75cab
			sp->subsampling_convert_ycbcrimagelen=3+sp->subsampling_convert_ylines+2*sp->subsampling_convert_clines;
roentgen b75cab
			sp->subsampling_convert_ycbcrimage=_TIFFmalloc(sp->subsampling_convert_ycbcrimagelen*sizeof(uint8*));
roentgen b75cab
			if (sp->subsampling_convert_ycbcrimage==0)
roentgen b75cab
			{
roentgen b75cab
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
roentgen b75cab
				return(0);
roentgen b75cab
			}
roentgen b75cab
			m=sp->subsampling_convert_ycbcrimage;
roentgen b75cab
			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3);
roentgen b75cab
			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines);
roentgen b75cab
			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines+sp->subsampling_convert_clines);
roentgen b75cab
			for (n=0; n<sp->subsampling_convert_ylines; n++)</sp->
roentgen b75cab
				*m++=sp->subsampling_convert_ybuf+n*sp->subsampling_convert_ylinelen;
roentgen b75cab
			for (n=0; n<sp->subsampling_convert_clines; n++)</sp->
roentgen b75cab
				*m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen;
roentgen b75cab
			for (n=0; n<sp->subsampling_convert_clines; n++)</sp->
roentgen b75cab
				*m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen;
roentgen b75cab
			sp->subsampling_convert_clinelenout=((sp->strile_width+sp->subsampling_hor-1)/sp->subsampling_hor);
roentgen b75cab
			sp->subsampling_convert_state=0;
roentgen b75cab
			sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2);
roentgen b75cab
			sp->lines_per_strile=((sp->strile_length+sp->subsampling_ver-1)/sp->subsampling_ver);
roentgen b75cab
			sp->subsampling_convert_log=1;
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
	else
roentgen b75cab
	{
roentgen b75cab
		sp->libjpeg_jpeg_decompress_struct.jpeg_color_space=JCS_UNKNOWN;
roentgen b75cab
		sp->libjpeg_jpeg_decompress_struct.out_color_space=JCS_UNKNOWN;
roentgen b75cab
		sp->libjpeg_jpeg_query_style=1;
roentgen b75cab
		sp->bytes_per_line=sp->samples_per_pixel_per_plane*sp->strile_width;
roentgen b75cab
		sp->lines_per_strile=sp->strile_length;
roentgen b75cab
	}
roentgen b75cab
	if (jpeg_start_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
roentgen b75cab
		return(0);
roentgen b75cab
	sp->writeheader_done=1;
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGLibjpegSessionAbort(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	assert(sp->libjpeg_session_active!=0);
roentgen b75cab
	jpeg_destroy((jpeg_common_struct*)(&(sp->libjpeg_jpeg_decompress_struct)));
roentgen b75cab
	sp->libjpeg_session_active=0;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadHeaderInfoSec(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGReadHeaderInfoSec";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint8 m;
roentgen b75cab
	uint16 n;
roentgen b75cab
	uint8 o;
roentgen b75cab
	if (sp->file_size==0)
roentgen b75cab
		sp->file_size=TIFFGetFileSize(tif);
roentgen b75cab
	if (sp->jpeg_interchange_format!=0)
roentgen b75cab
	{
roentgen b75cab
		if (sp->jpeg_interchange_format>=sp->file_size)
roentgen b75cab
		{
roentgen b75cab
			sp->jpeg_interchange_format=0;
roentgen b75cab
			sp->jpeg_interchange_format_length=0;
roentgen b75cab
		}
roentgen b75cab
		else
roentgen b75cab
		{
roentgen b75cab
			if ((sp->jpeg_interchange_format_length==0) || (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size))
roentgen b75cab
				sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format;
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
	sp->in_buffer_source=osibsNotSetYet;
roentgen b75cab
	sp->in_buffer_next_strile=0;
roentgen b75cab
	sp->in_buffer_strile_count=tif->tif_dir.td_nstrips;
roentgen b75cab
	sp->in_buffer_file_togo=0;
roentgen b75cab
	sp->in_buffer_togo=0;
roentgen b75cab
	do
roentgen b75cab
	{
roentgen b75cab
		if (OJPEGReadBytePeek(sp,&m)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		if (m!=255)
roentgen b75cab
			break;
roentgen b75cab
		OJPEGReadByteAdvance(sp);
roentgen b75cab
		do
roentgen b75cab
		{
roentgen b75cab
			if (OJPEGReadByte(sp,&m)==0)
roentgen b75cab
				return(0);
roentgen b75cab
		} while(m==255);
roentgen b75cab
		switch(m)
roentgen b75cab
		{
roentgen b75cab
			case JPEG_MARKER_SOI:
roentgen b75cab
				/* this type of marker has no data, and should be skipped */
roentgen b75cab
				break;
roentgen b75cab
			case JPEG_MARKER_COM:
roentgen b75cab
			case JPEG_MARKER_APP0:
roentgen b75cab
			case JPEG_MARKER_APP0+1:
roentgen b75cab
			case JPEG_MARKER_APP0+2:
roentgen b75cab
			case JPEG_MARKER_APP0+3:
roentgen b75cab
			case JPEG_MARKER_APP0+4:
roentgen b75cab
			case JPEG_MARKER_APP0+5:
roentgen b75cab
			case JPEG_MARKER_APP0+6:
roentgen b75cab
			case JPEG_MARKER_APP0+7:
roentgen b75cab
			case JPEG_MARKER_APP0+8:
roentgen b75cab
			case JPEG_MARKER_APP0+9:
roentgen b75cab
			case JPEG_MARKER_APP0+10:
roentgen b75cab
			case JPEG_MARKER_APP0+11:
roentgen b75cab
			case JPEG_MARKER_APP0+12:
roentgen b75cab
			case JPEG_MARKER_APP0+13:
roentgen b75cab
			case JPEG_MARKER_APP0+14:
roentgen b75cab
			case JPEG_MARKER_APP0+15:
roentgen b75cab
				/* this type of marker has data, but it has no use to us (and no place here) and should be skipped */
roentgen b75cab
				if (OJPEGReadWord(sp,&n)==0)
roentgen b75cab
					return(0);
roentgen b75cab
				if (n<2)
roentgen b75cab
				{
roentgen b75cab
					if (sp->subsamplingcorrect==0)
roentgen b75cab
						TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
roentgen b75cab
					return(0);
roentgen b75cab
				}
roentgen b75cab
				if (n>2)
roentgen b75cab
					OJPEGReadSkip(sp,n-2);
roentgen b75cab
				break;
roentgen b75cab
			case JPEG_MARKER_DRI:
roentgen b75cab
				if (OJPEGReadHeaderInfoSecStreamDri(tif)==0)
roentgen b75cab
					return(0);
roentgen b75cab
				break;
roentgen b75cab
			case JPEG_MARKER_DQT:
roentgen b75cab
				if (OJPEGReadHeaderInfoSecStreamDqt(tif)==0)
roentgen b75cab
					return(0);
roentgen b75cab
				break;
roentgen b75cab
			case JPEG_MARKER_DHT:
roentgen b75cab
				if (OJPEGReadHeaderInfoSecStreamDht(tif)==0)
roentgen b75cab
					return(0);
roentgen b75cab
				break;
roentgen b75cab
			case JPEG_MARKER_SOF0:
roentgen b75cab
			case JPEG_MARKER_SOF1:
roentgen b75cab
			case JPEG_MARKER_SOF3:
roentgen b75cab
				if (OJPEGReadHeaderInfoSecStreamSof(tif,m)==0)
roentgen b75cab
					return(0);
roentgen b75cab
				if (sp->subsamplingcorrect!=0)
roentgen b75cab
					return(1);
roentgen b75cab
				break;
roentgen b75cab
			case JPEG_MARKER_SOS:
roentgen b75cab
				if (sp->subsamplingcorrect!=0)
roentgen b75cab
					return(1);
roentgen b75cab
				assert(sp->plane_sample_offset==0);
roentgen b75cab
				if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
roentgen b75cab
					return(0);
roentgen b75cab
				break;
roentgen b75cab
			default:
roentgen b75cab
				TIFFErrorExt(tif->tif_clientdata,module,"Unknown marker type %d in JPEG data",m);
roentgen b75cab
				return(0);
roentgen b75cab
		}
roentgen b75cab
	} while(m!=JPEG_MARKER_SOS);
roentgen b75cab
	if (sp->subsamplingcorrect)
roentgen b75cab
		return(1);
roentgen b75cab
	if (sp->sof_log==0)
roentgen b75cab
	{
roentgen b75cab
		if (OJPEGReadHeaderInfoSecTablesQTable(tif)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		sp->sof_marker_id=JPEG_MARKER_SOF0;
roentgen b75cab
		for (o=0; o<sp->samples_per_pixel; o++)</sp->
roentgen b75cab
			sp->sof_c[o]=o;
roentgen b75cab
		sp->sof_hv[0]=((sp->subsampling_hor<<4)|sp->subsampling_ver);
roentgen b75cab
		for (o=1; o<sp->samples_per_pixel; o++)</sp->
roentgen b75cab
			sp->sof_hv[o]=17;
roentgen b75cab
		sp->sof_x=sp->strile_width;
roentgen b75cab
		sp->sof_y=sp->strile_length_total;
roentgen b75cab
		sp->sof_log=1;
roentgen b75cab
		if (OJPEGReadHeaderInfoSecTablesDcTable(tif)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		if (OJPEGReadHeaderInfoSecTablesAcTable(tif)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		for (o=1; o<sp->samples_per_pixel; o++)</sp->
roentgen b75cab
			sp->sos_cs[o]=o;
roentgen b75cab
	}
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadHeaderInfoSecStreamDri(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	/* this could easilly cause trouble in some cases... but no such cases have occured sofar */
roentgen b75cab
	static const char module[]="OJPEGReadHeaderInfoSecStreamDri";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint16 m;
roentgen b75cab
	if (OJPEGReadWord(sp,&m)==0)
roentgen b75cab
		return(0);
roentgen b75cab
	if (m!=4)
roentgen b75cab
	{
roentgen b75cab
		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DRI marker in JPEG data");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	if (OJPEGReadWord(sp,&m)==0)
roentgen b75cab
		return(0);
roentgen b75cab
	sp->restart_interval=m;
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	/* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
roentgen b75cab
	static const char module[]="OJPEGReadHeaderInfoSecStreamDqt";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint16 m;
roentgen b75cab
	uint32 na;
roentgen b75cab
	uint8* nb;
roentgen b75cab
	uint8 o;
roentgen b75cab
	if (OJPEGReadWord(sp,&m)==0)
roentgen b75cab
		return(0);
roentgen b75cab
	if (m<=2)
roentgen b75cab
	{
roentgen b75cab
		if (sp->subsamplingcorrect==0)
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	if (sp->subsamplingcorrect!=0)
roentgen b75cab
		OJPEGReadSkip(sp,m-2);
roentgen b75cab
	else
roentgen b75cab
	{
roentgen b75cab
		m-=2;
roentgen b75cab
		do
roentgen b75cab
		{
roentgen b75cab
			if (m<65)
roentgen b75cab
			{
roentgen b75cab
				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
roentgen b75cab
				return(0);
roentgen b75cab
			}
roentgen b75cab
			na=sizeof(uint32)+69;
roentgen b75cab
			nb=_TIFFmalloc(na);
roentgen b75cab
			if (nb==0)
roentgen b75cab
			{
roentgen b75cab
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
roentgen b75cab
				return(0);
roentgen b75cab
			}
roentgen b75cab
			*(uint32*)nb=na;
roentgen b75cab
			nb[sizeof(uint32)]=255;
roentgen b75cab
			nb[sizeof(uint32)+1]=JPEG_MARKER_DQT;
roentgen b75cab
			nb[sizeof(uint32)+2]=0;
roentgen b75cab
			nb[sizeof(uint32)+3]=67;
roentgen b75cab
			if (OJPEGReadBlock(sp,65,&nb[sizeof(uint32)+4])==0) {
roentgen b75cab
				_TIFFfree(nb);
roentgen b75cab
				return(0);
roentgen b75cab
			}
roentgen b75cab
			o=nb[sizeof(uint32)+4]&15;
roentgen b75cab
			if (3
roentgen b75cab
			{
roentgen b75cab
				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
roentgen b75cab
				_TIFFfree(nb);
roentgen b75cab
				return(0);
roentgen b75cab
			}
roentgen b75cab
			if (sp->qtable[o]!=0)
roentgen b75cab
				_TIFFfree(sp->qtable[o]);
roentgen b75cab
			sp->qtable[o]=nb;
roentgen b75cab
			m-=65;
roentgen b75cab
		} while(m>0);
roentgen b75cab
	}
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadHeaderInfoSecStreamDht(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	/* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
roentgen b75cab
	/* TODO: the following assumes there is only one table in this marker... but i'm not quite sure that assumption is guaranteed correct */
roentgen b75cab
	static const char module[]="OJPEGReadHeaderInfoSecStreamDht";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint16 m;
roentgen b75cab
	uint32 na;
roentgen b75cab
	uint8* nb;
roentgen b75cab
	uint8 o;
roentgen b75cab
	if (OJPEGReadWord(sp,&m)==0)
roentgen b75cab
		return(0);
roentgen b75cab
	if (m<=2)
roentgen b75cab
	{
roentgen b75cab
		if (sp->subsamplingcorrect==0)
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	if (sp->subsamplingcorrect!=0)
roentgen b75cab
	{
roentgen b75cab
		OJPEGReadSkip(sp,m-2);
roentgen b75cab
	}
roentgen b75cab
	else
roentgen b75cab
	{
roentgen b75cab
		na=sizeof(uint32)+2+m;
roentgen b75cab
		nb=_TIFFmalloc(na);
roentgen b75cab
		if (nb==0)
roentgen b75cab
		{
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
roentgen b75cab
			return(0);
roentgen b75cab
		}
roentgen b75cab
		*(uint32*)nb=na;
roentgen b75cab
		nb[sizeof(uint32)]=255;
roentgen b75cab
		nb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
roentgen b75cab
		nb[sizeof(uint32)+2]=(m>>8);
roentgen b75cab
		nb[sizeof(uint32)+3]=(m&255);
roentgen b75cab
		if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0)
roentgen b75cab
			return(0);
roentgen b75cab
		o=nb[sizeof(uint32)+4];
roentgen b75cab
		if ((o&240)==0)
roentgen b75cab
		{
roentgen b75cab
			if (3
roentgen b75cab
			{
roentgen b75cab
				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
roentgen b75cab
				return(0);
roentgen b75cab
			}
roentgen b75cab
			if (sp->dctable[o]!=0)
roentgen b75cab
				_TIFFfree(sp->dctable[o]);
roentgen b75cab
			sp->dctable[o]=nb;
roentgen b75cab
		}
roentgen b75cab
		else
roentgen b75cab
		{
roentgen b75cab
			if ((o&240)!=16)
roentgen b75cab
			{
roentgen b75cab
				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
roentgen b75cab
				return(0);
roentgen b75cab
			}
roentgen b75cab
			o&=15;
roentgen b75cab
			if (3
roentgen b75cab
			{
roentgen b75cab
				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
roentgen b75cab
				return(0);
roentgen b75cab
			}
roentgen b75cab
			if (sp->actable[o]!=0)
roentgen b75cab
				_TIFFfree(sp->actable[o]);
roentgen b75cab
			sp->actable[o]=nb;
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id)
roentgen b75cab
{
roentgen b75cab
	/* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
roentgen b75cab
	static const char module[]="OJPEGReadHeaderInfoSecStreamSof";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint16 m;
roentgen b75cab
	uint16 n;
roentgen b75cab
	uint8 o;
roentgen b75cab
	uint16 p;
roentgen b75cab
	uint16 q;
roentgen b75cab
	if (sp->sof_log!=0)
roentgen b75cab
	{
roentgen b75cab
		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	if (sp->subsamplingcorrect==0)
roentgen b75cab
		sp->sof_marker_id=marker_id;
roentgen b75cab
	/* Lf: data length */
roentgen b75cab
	if (OJPEGReadWord(sp,&m)==0)
roentgen b75cab
		return(0);
roentgen b75cab
	if (m<11)
roentgen b75cab
	{
roentgen b75cab
		if (sp->subsamplingcorrect==0)
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	m-=8;
roentgen b75cab
	if (m%3!=0)
roentgen b75cab
	{
roentgen b75cab
		if (sp->subsamplingcorrect==0)
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	n=m/3;
roentgen b75cab
	if (sp->subsamplingcorrect==0)
roentgen b75cab
	{
roentgen b75cab
		if (n!=sp->samples_per_pixel)
roentgen b75cab
		{
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of samples");
roentgen b75cab
			return(0);
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
	/* P: Sample precision */
roentgen b75cab
	if (OJPEGReadByte(sp,&o)==0)
roentgen b75cab
		return(0);
roentgen b75cab
	if (o!=8)
roentgen b75cab
	{
roentgen b75cab
		if (sp->subsamplingcorrect==0)
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of bits per sample");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	/* Y: Number of lines, X: Number of samples per line */
roentgen b75cab
	if (sp->subsamplingcorrect)
roentgen b75cab
		OJPEGReadSkip(sp,4);
roentgen b75cab
	else
roentgen b75cab
	{
roentgen b75cab
		/* Y: Number of lines */
roentgen b75cab
		if (OJPEGReadWord(sp,&p)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		if (((uint32)p<sp->image_length) && ((uint32)p<sp->strile_length_total))</sp-></sp->
roentgen b75cab
		{
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected height");
roentgen b75cab
			return(0);
roentgen b75cab
		}
roentgen b75cab
		sp->sof_y=p;
roentgen b75cab
		/* X: Number of samples per line */
roentgen b75cab
		if (OJPEGReadWord(sp,&p)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		if (((uint32)p<sp->image_width) && ((uint32)p<sp->strile_width))</sp-></sp->
roentgen b75cab
		{
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected width");
roentgen b75cab
			return(0);
roentgen b75cab
		}
roentgen b75cab
		if ((uint32)p>sp->strile_width)
roentgen b75cab
		{
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data image width exceeds expected image width");
roentgen b75cab
			return(0);
roentgen b75cab
		}
roentgen b75cab
		sp->sof_x=p;
roentgen b75cab
	}
roentgen b75cab
	/* Nf: Number of image components in frame */
roentgen b75cab
	if (OJPEGReadByte(sp,&o)==0)
roentgen b75cab
		return(0);
roentgen b75cab
	if (o!=n)
roentgen b75cab
	{
roentgen b75cab
		if (sp->subsamplingcorrect==0)
roentgen b75cab
			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	/* per component stuff */
roentgen b75cab
	/* TODO: double-check that flow implies that n cannot be as big as to make us overflow sof_c, sof_hv and sof_tq arrays */
roentgen b75cab
	for (q=0; q
roentgen b75cab
	{
roentgen b75cab
		/* C: Component identifier */
roentgen b75cab
		if (OJPEGReadByte(sp,&o)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		if (sp->subsamplingcorrect==0)
roentgen b75cab
			sp->sof_c[q]=o;
roentgen b75cab
		/* H: Horizontal sampling factor, and V: Vertical sampling factor */
roentgen b75cab
		if (OJPEGReadByte(sp,&o)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		if (sp->subsamplingcorrect!=0)
roentgen b75cab
		{
roentgen b75cab
			if (q==0)
roentgen b75cab
			{
roentgen b75cab
				sp->subsampling_hor=(o>>4);
roentgen b75cab
				sp->subsampling_ver=(o&15);
roentgen b75cab
				if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) ||
roentgen b75cab
					((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4)))
roentgen b75cab
					sp->subsampling_force_desubsampling_inside_decompression=1;
roentgen b75cab
			}
roentgen b75cab
			else
roentgen b75cab
			{
roentgen b75cab
				if (o!=17)
roentgen b75cab
					sp->subsampling_force_desubsampling_inside_decompression=1;
roentgen b75cab
			}
roentgen b75cab
		}
roentgen b75cab
		else
roentgen b75cab
		{
roentgen b75cab
			sp->sof_hv[q]=o;
roentgen b75cab
			if (sp->subsampling_force_desubsampling_inside_decompression==0)
roentgen b75cab
			{
roentgen b75cab
				if (q==0)
roentgen b75cab
				{
roentgen b75cab
					if (o!=((sp->subsampling_hor<<4)|sp->subsampling_ver))
roentgen b75cab
					{
roentgen b75cab
						TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
roentgen b75cab
						return(0);
roentgen b75cab
					}
roentgen b75cab
				}
roentgen b75cab
				else
roentgen b75cab
				{
roentgen b75cab
					if (o!=17)
roentgen b75cab
					{
roentgen b75cab
						TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
roentgen b75cab
						return(0);
roentgen b75cab
					}
roentgen b75cab
				}
roentgen b75cab
			}
roentgen b75cab
		}
roentgen b75cab
		/* Tq: Quantization table destination selector */
roentgen b75cab
		if (OJPEGReadByte(sp,&o)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		if (sp->subsamplingcorrect==0)
roentgen b75cab
			sp->sof_tq[q]=o;
roentgen b75cab
	}
roentgen b75cab
	if (sp->subsamplingcorrect==0)
roentgen b75cab
		sp->sof_log=1;
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadHeaderInfoSecStreamSos(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	/* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
roentgen b75cab
	static const char module[]="OJPEGReadHeaderInfoSecStreamSos";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint16 m;
roentgen b75cab
	uint8 n;
roentgen b75cab
	uint8 o;
roentgen b75cab
	assert(sp->subsamplingcorrect==0);
roentgen b75cab
	if (sp->sof_log==0)
roentgen b75cab
	{
roentgen b75cab
		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	/* Ls */
roentgen b75cab
	if (OJPEGReadWord(sp,&m)==0)
roentgen b75cab
		return(0);
roentgen b75cab
	if (m!=6+sp->samples_per_pixel_per_plane*2)
roentgen b75cab
	{
roentgen b75cab
		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	/* Ns */
roentgen b75cab
	if (OJPEGReadByte(sp,&n)==0)
roentgen b75cab
		return(0);
roentgen b75cab
	if (n!=sp->samples_per_pixel_per_plane)
roentgen b75cab
	{
roentgen b75cab
		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	/* Cs, Td, and Ta */
roentgen b75cab
	for (o=0; o<sp->samples_per_pixel_per_plane; o++)</sp->
roentgen b75cab
	{
roentgen b75cab
		/* Cs */
roentgen b75cab
		if (OJPEGReadByte(sp,&n)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		sp->sos_cs[sp->plane_sample_offset+o]=n;
roentgen b75cab
		/* Td and Ta */
roentgen b75cab
		if (OJPEGReadByte(sp,&n)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		sp->sos_tda[sp->plane_sample_offset+o]=n;
roentgen b75cab
	}
roentgen b75cab
	/* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as per LibJpeg source */
roentgen b75cab
	OJPEGReadSkip(sp,3);
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGReadHeaderInfoSecTablesQTable";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint8 m;
roentgen b75cab
	uint8 n;
roentgen b75cab
	uint32 oa;
roentgen b75cab
	uint8* ob;
roentgen b75cab
	uint32 p;
roentgen b75cab
	if (sp->qtable_offset[0]==0)
roentgen b75cab
	{
roentgen b75cab
		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	sp->in_buffer_file_pos_log=0;
roentgen b75cab
	for (m=0; m<sp->samples_per_pixel; m++)</sp->
roentgen b75cab
	{
roentgen b75cab
		if ((sp->qtable_offset[m]!=0) && ((m==0) || (sp->qtable_offset[m]!=sp->qtable_offset[m-1])))
roentgen b75cab
		{
roentgen b75cab
			for (n=0; n
roentgen b75cab
			{
roentgen b75cab
				if (sp->qtable_offset[m]==sp->qtable_offset[n])
roentgen b75cab
				{
roentgen b75cab
					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegQTables tag value");
roentgen b75cab
					return(0);
roentgen b75cab
				}
roentgen b75cab
			}
roentgen b75cab
			oa=sizeof(uint32)+69;
roentgen b75cab
			ob=_TIFFmalloc(oa);
roentgen b75cab
			if (ob==0)
roentgen b75cab
			{
roentgen b75cab
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
roentgen b75cab
				return(0);
roentgen b75cab
			}
roentgen b75cab
			*(uint32*)ob=oa;
roentgen b75cab
			ob[sizeof(uint32)]=255;
roentgen b75cab
			ob[sizeof(uint32)+1]=JPEG_MARKER_DQT;
roentgen b75cab
			ob[sizeof(uint32)+2]=0;
roentgen b75cab
			ob[sizeof(uint32)+3]=67;
roentgen b75cab
			ob[sizeof(uint32)+4]=m;
roentgen b75cab
			TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET); 
roentgen b75cab
			p=TIFFReadFile(tif,&ob[sizeof(uint32)+5],64);
roentgen b75cab
			if (p!=64)
roentgen b75cab
				return(0);
roentgen b75cab
			sp->qtable[m]=ob;
roentgen b75cab
			sp->sof_tq[m]=m;
roentgen b75cab
		}
roentgen b75cab
		else
roentgen b75cab
			sp->sof_tq[m]=sp->sof_tq[m-1];
roentgen b75cab
	}
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGReadHeaderInfoSecTablesDcTable";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint8 m;
roentgen b75cab
	uint8 n;
roentgen b75cab
	uint8 o[16];
roentgen b75cab
	uint32 p;
roentgen b75cab
	uint32 q;
roentgen b75cab
	uint32 ra;
roentgen b75cab
	uint8* rb;
roentgen b75cab
	if (sp->dctable_offset[0]==0)
roentgen b75cab
	{
roentgen b75cab
		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	sp->in_buffer_file_pos_log=0;
roentgen b75cab
	for (m=0; m<sp->samples_per_pixel; m++)</sp->
roentgen b75cab
	{
roentgen b75cab
		if ((sp->dctable_offset[m]!=0) && ((m==0) || (sp->dctable_offset[m]!=sp->dctable_offset[m-1])))
roentgen b75cab
		{
roentgen b75cab
			for (n=0; n
roentgen b75cab
			{
roentgen b75cab
				if (sp->dctable_offset[m]==sp->dctable_offset[n])
roentgen b75cab
				{
roentgen b75cab
					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegDcTables tag value");
roentgen b75cab
					return(0);
roentgen b75cab
				}
roentgen b75cab
			}
roentgen b75cab
			TIFFSeekFile(tif,sp->dctable_offset[m],SEEK_SET);
roentgen b75cab
			p=TIFFReadFile(tif,o,16);
roentgen b75cab
			if (p!=16)
roentgen b75cab
				return(0);
roentgen b75cab
			q=0;
roentgen b75cab
			for (n=0; n<16; n++)
roentgen b75cab
				q+=o[n];
roentgen b75cab
			ra=sizeof(uint32)+21+q;
roentgen b75cab
			rb=_TIFFmalloc(ra);
roentgen b75cab
			if (rb==0)
roentgen b75cab
			{
roentgen b75cab
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
roentgen b75cab
				return(0);
roentgen b75cab
			}
roentgen b75cab
			*(uint32*)rb=ra;
roentgen b75cab
			rb[sizeof(uint32)]=255;
roentgen b75cab
			rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
roentgen b75cab
			rb[sizeof(uint32)+2]=((19+q)>>8);
roentgen b75cab
			rb[sizeof(uint32)+3]=((19+q)&255);
roentgen b75cab
			rb[sizeof(uint32)+4]=m;
roentgen b75cab
			for (n=0; n<16; n++)
roentgen b75cab
				rb[sizeof(uint32)+5+n]=o[n];
roentgen b75cab
			p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
roentgen b75cab
			if (p!=q)
roentgen b75cab
				return(0);
roentgen b75cab
			sp->dctable[m]=rb;
roentgen b75cab
			sp->sos_tda[m]=(m<<4);
roentgen b75cab
		}
roentgen b75cab
		else
roentgen b75cab
			sp->sos_tda[m]=sp->sos_tda[m-1];
roentgen b75cab
	}
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	static const char module[]="OJPEGReadHeaderInfoSecTablesAcTable";
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint8 m;
roentgen b75cab
	uint8 n;
roentgen b75cab
	uint8 o[16];
roentgen b75cab
	uint32 p;
roentgen b75cab
	uint32 q;
roentgen b75cab
	uint32 ra;
roentgen b75cab
	uint8* rb;
roentgen b75cab
	if (sp->actable_offset[0]==0)
roentgen b75cab
	{
roentgen b75cab
		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
roentgen b75cab
		return(0);
roentgen b75cab
	}
roentgen b75cab
	sp->in_buffer_file_pos_log=0;
roentgen b75cab
	for (m=0; m<sp->samples_per_pixel; m++)</sp->
roentgen b75cab
	{
roentgen b75cab
		if ((sp->actable_offset[m]!=0) && ((m==0) || (sp->actable_offset[m]!=sp->actable_offset[m-1])))
roentgen b75cab
		{
roentgen b75cab
			for (n=0; n
roentgen b75cab
			{
roentgen b75cab
				if (sp->actable_offset[m]==sp->actable_offset[n])
roentgen b75cab
				{
roentgen b75cab
					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegAcTables tag value");
roentgen b75cab
					return(0);
roentgen b75cab
				}
roentgen b75cab
			}
roentgen b75cab
			TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET);  
roentgen b75cab
			p=TIFFReadFile(tif,o,16);
roentgen b75cab
			if (p!=16)
roentgen b75cab
				return(0);
roentgen b75cab
			q=0;
roentgen b75cab
			for (n=0; n<16; n++)
roentgen b75cab
				q+=o[n];
roentgen b75cab
			ra=sizeof(uint32)+21+q;
roentgen b75cab
			rb=_TIFFmalloc(ra);
roentgen b75cab
			if (rb==0)
roentgen b75cab
			{
roentgen b75cab
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
roentgen b75cab
				return(0);
roentgen b75cab
			}
roentgen b75cab
			*(uint32*)rb=ra;
roentgen b75cab
			rb[sizeof(uint32)]=255;
roentgen b75cab
			rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
roentgen b75cab
			rb[sizeof(uint32)+2]=((19+q)>>8);
roentgen b75cab
			rb[sizeof(uint32)+3]=((19+q)&255);
roentgen b75cab
			rb[sizeof(uint32)+4]=(16|m);
roentgen b75cab
			for (n=0; n<16; n++)
roentgen b75cab
				rb[sizeof(uint32)+5+n]=o[n];
roentgen b75cab
			p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
roentgen b75cab
			if (p!=q)
roentgen b75cab
				return(0);
roentgen b75cab
			sp->actable[m]=rb;
roentgen b75cab
			sp->sos_tda[m]=(sp->sos_tda[m]|m);
roentgen b75cab
		}
roentgen b75cab
		else
roentgen b75cab
			sp->sos_tda[m]=(sp->sos_tda[m]|(sp->sos_tda[m-1]&15));
roentgen b75cab
	}
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadBufferFill(OJPEGState* sp)
roentgen b75cab
{
roentgen b75cab
	uint16 m;
roentgen b75cab
	tmsize_t n;
roentgen b75cab
	/* TODO: double-check: when subsamplingcorrect is set, no call to TIFFErrorExt or TIFFWarningExt should be made
roentgen b75cab
	 * in any other case, seek or read errors should be passed through */
roentgen b75cab
	do
roentgen b75cab
	{
roentgen b75cab
		if (sp->in_buffer_file_togo!=0)
roentgen b75cab
		{
roentgen b75cab
			if (sp->in_buffer_file_pos_log==0)
roentgen b75cab
			{
roentgen b75cab
				TIFFSeekFile(sp->tif,sp->in_buffer_file_pos,SEEK_SET);
roentgen b75cab
				sp->in_buffer_file_pos_log=1;
roentgen b75cab
			}
roentgen b75cab
			m=OJPEG_BUFFER;
roentgen b75cab
			if ((uint64)m>sp->in_buffer_file_togo)
roentgen b75cab
				m=(uint16)sp->in_buffer_file_togo;
roentgen b75cab
			n=TIFFReadFile(sp->tif,sp->in_buffer,(tmsize_t)m);
roentgen b75cab
			if (n==0)
roentgen b75cab
				return(0);
roentgen b75cab
			assert(n>0);
roentgen b75cab
			assert(n<=OJPEG_BUFFER);
roentgen b75cab
			assert(n<65536);
roentgen b75cab
			assert((uint64)n<=sp->in_buffer_file_togo);
roentgen b75cab
			m=(uint16)n;
roentgen b75cab
			sp->in_buffer_togo=m;
roentgen b75cab
			sp->in_buffer_cur=sp->in_buffer;
roentgen b75cab
			sp->in_buffer_file_togo-=m;
roentgen b75cab
			sp->in_buffer_file_pos+=m;
roentgen b75cab
			break;
roentgen b75cab
		}
roentgen b75cab
		sp->in_buffer_file_pos_log=0;
roentgen b75cab
		switch(sp->in_buffer_source)
roentgen b75cab
		{
roentgen b75cab
			case osibsNotSetYet:
roentgen b75cab
				if (sp->jpeg_interchange_format!=0)
roentgen b75cab
				{
roentgen b75cab
					sp->in_buffer_file_pos=sp->jpeg_interchange_format;
roentgen b75cab
					sp->in_buffer_file_togo=sp->jpeg_interchange_format_length;
roentgen b75cab
				}
roentgen b75cab
				sp->in_buffer_source=osibsJpegInterchangeFormat;
roentgen b75cab
				break;
roentgen b75cab
			case osibsJpegInterchangeFormat:
roentgen b75cab
				sp->in_buffer_source=osibsStrile;
roentgen b75cab
			case osibsStrile:
roentgen b75cab
				if (!_TIFFFillStriles( sp->tif ) 
roentgen b75cab
				    || sp->tif->tif_dir.td_stripoffset == NULL
roentgen b75cab
				    || sp->tif->tif_dir.td_stripbytecount == NULL)
roentgen b75cab
					return 0;
roentgen b75cab
roentgen b75cab
				if (sp->in_buffer_next_strile==sp->in_buffer_strile_count)
roentgen b75cab
					sp->in_buffer_source=osibsEof;
roentgen b75cab
				else
roentgen b75cab
				{
roentgen b75cab
					sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile];
roentgen b75cab
					if (sp->in_buffer_file_pos!=0)
roentgen b75cab
					{
roentgen b75cab
						if (sp->in_buffer_file_pos>=sp->file_size)
roentgen b75cab
							sp->in_buffer_file_pos=0;
roentgen b75cab
						else if (sp->tif->tif_dir.td_stripbytecount==NULL)
roentgen b75cab
							sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
roentgen b75cab
						else
roentgen b75cab
						{
roentgen b75cab
							if (sp->tif->tif_dir.td_stripbytecount == 0) {
roentgen b75cab
								TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip byte counts are missing");
roentgen b75cab
								return(0);
roentgen b75cab
							}
roentgen b75cab
							sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];
roentgen b75cab
							if (sp->in_buffer_file_togo==0)
roentgen b75cab
								sp->in_buffer_file_pos=0;
roentgen b75cab
							else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
roentgen b75cab
								sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
roentgen b75cab
						}
roentgen b75cab
					}
roentgen b75cab
					sp->in_buffer_next_strile++;
roentgen b75cab
				}
roentgen b75cab
				break;
roentgen b75cab
			default:
roentgen b75cab
				return(0);
roentgen b75cab
		}
roentgen b75cab
	} while (1);
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadByte(OJPEGState* sp, uint8* byte)
roentgen b75cab
{
roentgen b75cab
	if (sp->in_buffer_togo==0)
roentgen b75cab
	{
roentgen b75cab
		if (OJPEGReadBufferFill(sp)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		assert(sp->in_buffer_togo>0);
roentgen b75cab
	}
roentgen b75cab
	*byte=*(sp->in_buffer_cur);
roentgen b75cab
	sp->in_buffer_cur++;
roentgen b75cab
	sp->in_buffer_togo--;
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadBytePeek(OJPEGState* sp, uint8* byte)
roentgen b75cab
{
roentgen b75cab
	if (sp->in_buffer_togo==0)
roentgen b75cab
	{
roentgen b75cab
		if (OJPEGReadBufferFill(sp)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		assert(sp->in_buffer_togo>0);
roentgen b75cab
	}
roentgen b75cab
	*byte=*(sp->in_buffer_cur);
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGReadByteAdvance(OJPEGState* sp)
roentgen b75cab
{
roentgen b75cab
	assert(sp->in_buffer_togo>0);
roentgen b75cab
	sp->in_buffer_cur++;
roentgen b75cab
	sp->in_buffer_togo--;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadWord(OJPEGState* sp, uint16* word)
roentgen b75cab
{
roentgen b75cab
	uint8 m;
roentgen b75cab
	if (OJPEGReadByte(sp,&m)==0)
roentgen b75cab
		return(0);
roentgen b75cab
	*word=(m<<8);
roentgen b75cab
	if (OJPEGReadByte(sp,&m)==0)
roentgen b75cab
		return(0);
roentgen b75cab
	*word|=m;
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem)
roentgen b75cab
{
roentgen b75cab
	uint16 mlen;
roentgen b75cab
	uint8* mmem;
roentgen b75cab
	uint16 n;
roentgen b75cab
	assert(len>0);
roentgen b75cab
	mlen=len;
roentgen b75cab
	mmem=mem;
roentgen b75cab
	do
roentgen b75cab
	{
roentgen b75cab
		if (sp->in_buffer_togo==0)
roentgen b75cab
		{
roentgen b75cab
			if (OJPEGReadBufferFill(sp)==0)
roentgen b75cab
				return(0);
roentgen b75cab
			assert(sp->in_buffer_togo>0);
roentgen b75cab
		}
roentgen b75cab
		n=mlen;
roentgen b75cab
		if (n>sp->in_buffer_togo)
roentgen b75cab
			n=sp->in_buffer_togo;
roentgen b75cab
		_TIFFmemcpy(mmem,sp->in_buffer_cur,n);
roentgen b75cab
		sp->in_buffer_cur+=n;
roentgen b75cab
		sp->in_buffer_togo-=n;
roentgen b75cab
		mlen-=n;
roentgen b75cab
		mmem+=n;
roentgen b75cab
	} while(mlen>0);
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGReadSkip(OJPEGState* sp, uint16 len)
roentgen b75cab
{
roentgen b75cab
	uint16 m;
roentgen b75cab
	uint16 n;
roentgen b75cab
	m=len;
roentgen b75cab
	n=m;
roentgen b75cab
	if (n>sp->in_buffer_togo)
roentgen b75cab
		n=sp->in_buffer_togo;
roentgen b75cab
	sp->in_buffer_cur+=n;
roentgen b75cab
	sp->in_buffer_togo-=n;
roentgen b75cab
	m-=n;
roentgen b75cab
	if (m>0)
roentgen b75cab
	{
roentgen b75cab
		assert(sp->in_buffer_togo==0);
roentgen b75cab
		n=m;
roentgen b75cab
		if ((uint64)n>sp->in_buffer_file_togo)
roentgen b75cab
			n=(uint16)sp->in_buffer_file_togo;
roentgen b75cab
		sp->in_buffer_file_pos+=n;
roentgen b75cab
		sp->in_buffer_file_togo-=n;
roentgen b75cab
		sp->in_buffer_file_pos_log=0;
roentgen b75cab
		/* we don't skip past jpeginterchangeformat/strile block...
roentgen b75cab
		 * if that is asked from us, we're dealing with totally bazurk
roentgen b75cab
		 * data anyway, and we've not seen this happening on any
roentgen b75cab
		 * testfile, so we might as well likely cause some other
roentgen b75cab
		 * meaningless error to be passed at some later time
roentgen b75cab
		 */
roentgen b75cab
	}
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGWriteStream(TIFF* tif, void** mem, uint32* len)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	*len=0;
roentgen b75cab
	do
roentgen b75cab
	{
roentgen b75cab
		assert(sp->out_state<=ososEoi);
roentgen b75cab
		switch(sp->out_state)
roentgen b75cab
		{
roentgen b75cab
			case ososSoi:
roentgen b75cab
				OJPEGWriteStreamSoi(tif,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososQTable0:
roentgen b75cab
				OJPEGWriteStreamQTable(tif,0,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososQTable1:
roentgen b75cab
				OJPEGWriteStreamQTable(tif,1,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososQTable2:
roentgen b75cab
				OJPEGWriteStreamQTable(tif,2,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososQTable3:
roentgen b75cab
				OJPEGWriteStreamQTable(tif,3,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososDcTable0:
roentgen b75cab
				OJPEGWriteStreamDcTable(tif,0,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososDcTable1:
roentgen b75cab
				OJPEGWriteStreamDcTable(tif,1,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososDcTable2:
roentgen b75cab
				OJPEGWriteStreamDcTable(tif,2,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososDcTable3:
roentgen b75cab
				OJPEGWriteStreamDcTable(tif,3,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososAcTable0:
roentgen b75cab
				OJPEGWriteStreamAcTable(tif,0,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososAcTable1:
roentgen b75cab
				OJPEGWriteStreamAcTable(tif,1,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososAcTable2:
roentgen b75cab
				OJPEGWriteStreamAcTable(tif,2,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososAcTable3:
roentgen b75cab
				OJPEGWriteStreamAcTable(tif,3,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososDri:
roentgen b75cab
				OJPEGWriteStreamDri(tif,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososSof:
roentgen b75cab
				OJPEGWriteStreamSof(tif,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososSos:
roentgen b75cab
				OJPEGWriteStreamSos(tif,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososCompressed:
roentgen b75cab
				if (OJPEGWriteStreamCompressed(tif,mem,len)==0)
roentgen b75cab
					return(0);
roentgen b75cab
				break;
roentgen b75cab
			case ososRst:
roentgen b75cab
				OJPEGWriteStreamRst(tif,mem,len);
roentgen b75cab
				break;
roentgen b75cab
			case ososEoi:
roentgen b75cab
				OJPEGWriteStreamEoi(tif,mem,len);
roentgen b75cab
				break;
roentgen b75cab
		}
roentgen b75cab
	} while (*len==0);
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	assert(OJPEG_BUFFER>=2);
roentgen b75cab
	sp->out_buffer[0]=255;
roentgen b75cab
	sp->out_buffer[1]=JPEG_MARKER_SOI;
roentgen b75cab
	*len=2;
roentgen b75cab
	*mem=(void*)sp->out_buffer;
roentgen b75cab
	sp->out_state++;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	if (sp->qtable[table_index]!=0)
roentgen b75cab
	{
roentgen b75cab
		*mem=(void*)(sp->qtable[table_index]+sizeof(uint32));
roentgen b75cab
		*len=*((uint32*)sp->qtable[table_index])-sizeof(uint32);
roentgen b75cab
	}
roentgen b75cab
	sp->out_state++;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	if (sp->dctable[table_index]!=0)
roentgen b75cab
	{
roentgen b75cab
		*mem=(void*)(sp->dctable[table_index]+sizeof(uint32));
roentgen b75cab
		*len=*((uint32*)sp->dctable[table_index])-sizeof(uint32);
roentgen b75cab
	}
roentgen b75cab
	sp->out_state++;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	if (sp->actable[table_index]!=0)
roentgen b75cab
	{
roentgen b75cab
		*mem=(void*)(sp->actable[table_index]+sizeof(uint32));
roentgen b75cab
		*len=*((uint32*)sp->actable[table_index])-sizeof(uint32);
roentgen b75cab
	}
roentgen b75cab
	sp->out_state++;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	assert(OJPEG_BUFFER>=6);
roentgen b75cab
	if (sp->restart_interval!=0)
roentgen b75cab
	{
roentgen b75cab
		sp->out_buffer[0]=255;
roentgen b75cab
		sp->out_buffer[1]=JPEG_MARKER_DRI;
roentgen b75cab
		sp->out_buffer[2]=0;
roentgen b75cab
		sp->out_buffer[3]=4;
roentgen b75cab
		sp->out_buffer[4]=(sp->restart_interval>>8);
roentgen b75cab
		sp->out_buffer[5]=(sp->restart_interval&255);
roentgen b75cab
		*len=6;
roentgen b75cab
		*mem=(void*)sp->out_buffer;
roentgen b75cab
	}
roentgen b75cab
	sp->out_state++;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint8 m;
roentgen b75cab
	assert(OJPEG_BUFFER>=2+8+sp->samples_per_pixel_per_plane*3);
roentgen b75cab
	assert(255>=8+sp->samples_per_pixel_per_plane*3);
roentgen b75cab
	sp->out_buffer[0]=255;
roentgen b75cab
	sp->out_buffer[1]=sp->sof_marker_id;
roentgen b75cab
	/* Lf */
roentgen b75cab
	sp->out_buffer[2]=0;
roentgen b75cab
	sp->out_buffer[3]=8+sp->samples_per_pixel_per_plane*3;
roentgen b75cab
	/* P */
roentgen b75cab
	sp->out_buffer[4]=8;
roentgen b75cab
	/* Y */
roentgen b75cab
	sp->out_buffer[5]=(sp->sof_y>>8);
roentgen b75cab
	sp->out_buffer[6]=(sp->sof_y&255);
roentgen b75cab
	/* X */
roentgen b75cab
	sp->out_buffer[7]=(sp->sof_x>>8);
roentgen b75cab
	sp->out_buffer[8]=(sp->sof_x&255);
roentgen b75cab
	/* Nf */
roentgen b75cab
	sp->out_buffer[9]=sp->samples_per_pixel_per_plane;
roentgen b75cab
	for (m=0; m<sp->samples_per_pixel_per_plane; m++)</sp->
roentgen b75cab
	{
roentgen b75cab
		/* C */
roentgen b75cab
		sp->out_buffer[10+m*3]=sp->sof_c[sp->plane_sample_offset+m];
roentgen b75cab
		/* H and V */
roentgen b75cab
		sp->out_buffer[10+m*3+1]=sp->sof_hv[sp->plane_sample_offset+m];
roentgen b75cab
		/* Tq */
roentgen b75cab
		sp->out_buffer[10+m*3+2]=sp->sof_tq[sp->plane_sample_offset+m];
roentgen b75cab
	}
roentgen b75cab
	*len=10+sp->samples_per_pixel_per_plane*3;
roentgen b75cab
	*mem=(void*)sp->out_buffer;
roentgen b75cab
	sp->out_state++;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	uint8 m;
roentgen b75cab
	assert(OJPEG_BUFFER>=2+6+sp->samples_per_pixel_per_plane*2);
roentgen b75cab
	assert(255>=6+sp->samples_per_pixel_per_plane*2);
roentgen b75cab
	sp->out_buffer[0]=255;
roentgen b75cab
	sp->out_buffer[1]=JPEG_MARKER_SOS;
roentgen b75cab
	/* Ls */
roentgen b75cab
	sp->out_buffer[2]=0;
roentgen b75cab
	sp->out_buffer[3]=6+sp->samples_per_pixel_per_plane*2;
roentgen b75cab
	/* Ns */
roentgen b75cab
	sp->out_buffer[4]=sp->samples_per_pixel_per_plane;
roentgen b75cab
	for (m=0; m<sp->samples_per_pixel_per_plane; m++)</sp->
roentgen b75cab
	{
roentgen b75cab
		/* Cs */
roentgen b75cab
		sp->out_buffer[5+m*2]=sp->sos_cs[sp->plane_sample_offset+m];
roentgen b75cab
		/* Td and Ta */
roentgen b75cab
		sp->out_buffer[5+m*2+1]=sp->sos_tda[sp->plane_sample_offset+m];
roentgen b75cab
	}
roentgen b75cab
	/* Ss */
roentgen b75cab
	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2]=0;
roentgen b75cab
	/* Se */
roentgen b75cab
	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+1]=63;
roentgen b75cab
	/* Ah and Al */
roentgen b75cab
	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+2]=0;
roentgen b75cab
	*len=8+sp->samples_per_pixel_per_plane*2;
roentgen b75cab
	*mem=(void*)sp->out_buffer;
roentgen b75cab
	sp->out_state++;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static int
roentgen b75cab
OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	if (sp->in_buffer_togo==0)
roentgen b75cab
	{
roentgen b75cab
		if (OJPEGReadBufferFill(sp)==0)
roentgen b75cab
			return(0);
roentgen b75cab
		assert(sp->in_buffer_togo>0);
roentgen b75cab
	}
roentgen b75cab
	*len=sp->in_buffer_togo;
roentgen b75cab
	*mem=(void*)sp->in_buffer_cur;
roentgen b75cab
	sp->in_buffer_togo=0;
roentgen b75cab
	if (sp->in_buffer_file_togo==0)
roentgen b75cab
	{
roentgen b75cab
		switch(sp->in_buffer_source)
roentgen b75cab
		{
roentgen b75cab
			case osibsStrile:
roentgen b75cab
				if (sp->in_buffer_next_strile<sp->in_buffer_strile_count)</sp->
roentgen b75cab
					sp->out_state=ososRst;
roentgen b75cab
				else
roentgen b75cab
					sp->out_state=ososEoi;
roentgen b75cab
				break;
roentgen b75cab
			case osibsEof:
roentgen b75cab
				sp->out_state=ososEoi;
roentgen b75cab
				break;
roentgen b75cab
			default:
roentgen b75cab
				break;
roentgen b75cab
		}
roentgen b75cab
	}
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	assert(OJPEG_BUFFER>=2);
roentgen b75cab
	sp->out_buffer[0]=255;
roentgen b75cab
	sp->out_buffer[1]=JPEG_MARKER_RST0+sp->restart_index;
roentgen b75cab
	sp->restart_index++;
roentgen b75cab
	if (sp->restart_index==8)
roentgen b75cab
		sp->restart_index=0;
roentgen b75cab
	*len=2;
roentgen b75cab
	*mem=(void*)sp->out_buffer;
roentgen b75cab
	sp->out_state=ososCompressed;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	assert(OJPEG_BUFFER>=2);
roentgen b75cab
	sp->out_buffer[0]=255;
roentgen b75cab
	sp->out_buffer[1]=JPEG_MARKER_EOI;
roentgen b75cab
	*len=2;
roentgen b75cab
	*mem=(void*)sp->out_buffer;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
#ifndef LIBJPEG_ENCAP_EXTERNAL
roentgen b75cab
static int
roentgen b75cab
jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
roentgen b75cab
{
roentgen b75cab
	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_create_decompress(cinfo),1));
roentgen b75cab
}
roentgen b75cab
#endif
roentgen b75cab
roentgen b75cab
#ifndef LIBJPEG_ENCAP_EXTERNAL
roentgen b75cab
static int
roentgen b75cab
jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image)
roentgen b75cab
{
roentgen b75cab
	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_header(cinfo,require_image),1));
roentgen b75cab
}
roentgen b75cab
#endif
roentgen b75cab
roentgen b75cab
#ifndef LIBJPEG_ENCAP_EXTERNAL
roentgen b75cab
static int
roentgen b75cab
jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
roentgen b75cab
{
roentgen b75cab
	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_start_decompress(cinfo),1));
roentgen b75cab
}
roentgen b75cab
#endif
roentgen b75cab
roentgen b75cab
#ifndef LIBJPEG_ENCAP_EXTERNAL
roentgen b75cab
static int
roentgen b75cab
jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines)
roentgen b75cab
{
roentgen b75cab
	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_scanlines(cinfo,scanlines,max_lines),1));
roentgen b75cab
}
roentgen b75cab
#endif
roentgen b75cab
roentgen b75cab
#ifndef LIBJPEG_ENCAP_EXTERNAL
roentgen b75cab
static int
roentgen b75cab
jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines)
roentgen b75cab
{
roentgen b75cab
	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_raw_data(cinfo,data,max_lines),1));
roentgen b75cab
}
roentgen b75cab
#endif
roentgen b75cab
roentgen b75cab
#ifndef LIBJPEG_ENCAP_EXTERNAL
roentgen b75cab
static void
roentgen b75cab
jpeg_encap_unwind(TIFF* tif)
roentgen b75cab
{
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	LONGJMP(sp->exit_jmpbuf,1);
roentgen b75cab
}
roentgen b75cab
#endif
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo)
roentgen b75cab
{
roentgen b75cab
	char buffer[JMSG_LENGTH_MAX];
roentgen b75cab
	(*cinfo->err->format_message)(cinfo,buffer);
roentgen b75cab
	TIFFWarningExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo)
roentgen b75cab
{
roentgen b75cab
	char buffer[JMSG_LENGTH_MAX];
roentgen b75cab
	(*cinfo->err->format_message)(cinfo,buffer);
roentgen b75cab
	TIFFErrorExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer);
roentgen b75cab
	jpeg_encap_unwind((TIFF*)(cinfo->client_data));
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo)
roentgen b75cab
{
roentgen b75cab
	(void)cinfo;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static boolean
roentgen b75cab
OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo)
roentgen b75cab
{
roentgen b75cab
	TIFF* tif=(TIFF*)cinfo->client_data;
roentgen b75cab
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
roentgen b75cab
	void* mem=0;
roentgen b75cab
	uint32 len=0U;
roentgen b75cab
	if (OJPEGWriteStream(tif,&mem,&len)==0)
roentgen b75cab
	{
roentgen b75cab
		TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Premature end of JPEG data");
roentgen b75cab
		jpeg_encap_unwind(tif);
roentgen b75cab
	}
roentgen b75cab
	sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=len;
roentgen b75cab
	sp->libjpeg_jpeg_source_mgr.next_input_byte=mem;
roentgen b75cab
	return(1);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes)
roentgen b75cab
{
roentgen b75cab
	TIFF* tif=(TIFF*)cinfo->client_data;
roentgen b75cab
	(void)num_bytes;
roentgen b75cab
	TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
roentgen b75cab
	jpeg_encap_unwind(tif);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static boolean
roentgen b75cab
OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired)
roentgen b75cab
{
roentgen b75cab
	TIFF* tif=(TIFF*)cinfo->client_data;
roentgen b75cab
	(void)desired;
roentgen b75cab
	TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
roentgen b75cab
	jpeg_encap_unwind(tif);
roentgen b75cab
	return(0);
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
static void
roentgen b75cab
OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo)
roentgen b75cab
{
roentgen b75cab
	(void)cinfo;
roentgen b75cab
}
roentgen b75cab
roentgen b75cab
#endif
roentgen b75cab
roentgen b75cab
roentgen b75cab
/*
roentgen b75cab
 * Local Variables:
roentgen b75cab
 * mode: c
roentgen b75cab
 * c-basic-offset: 8
roentgen b75cab
 * fill-column: 78
roentgen b75cab
 * End:
roentgen b75cab
 */