/* $Id: tif_ojpeg.c,v 1.25 2009/09/06 13:11:28 drolon Exp $ */

/* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0
   specification is now totally obsolete and deprecated for new applications and
   images. This file was was created solely in order to read unconverted images
   still present on some users' computer systems. It will never be extended
   to write such files. Writing new-style JPEG compressed TIFFs is implemented
   in tif_jpeg.c.

   The code is carefully crafted to robustly read all gathered JPEG-in-TIFF
   testfiles, and anticipate as much as possible all other... But still, it may
   fail on some. If you encounter problems, please report them on the TIFF
   mailing list and/or to Joris Van Damme <info@awaresystems.be>.

   Please read the file called "TIFF Technical Note #2" if you need to be
   convinced this compression scheme is bad and breaks TIFF. That document
   is linked to from the LibTiff site <http://www.remotesensing.org/libtiff/>
   and from AWare Systems' TIFF section
   <http://www.awaresystems.be/imaging/tiff.html>. It is also absorbed
   in Adobe's specification supplements, marked "draft" up to this day, but
   supported by the TIFF community.

   This file interfaces with Release 6B of the JPEG Library written by the
   Independent JPEG Group. Previous versions of this file required a hack inside
   the LibJpeg library. This version no longer requires that. Remember to
   remove the hack if you update from the old version.

   Copyright (c) Joris Van Damme <info@awaresystems.be>
   Copyright (c) AWare Systems <http://www.awaresystems.be/>

   The licence agreement for this file is the same as the rest of the LibTiff
   library.

   IN NO EVENT SHALL JORIS VAN DAMME OR AWARE SYSTEMS BE LIABLE FOR
   ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
   OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
   WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
   LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
   OF THIS SOFTWARE.

   Joris Van Damme and/or AWare Systems may be available for custom
   developement. If you like what you see, and need anything similar or related,
   contact <info@awaresystems.be>.
*/

/* What is what, and what is not?

   This decoder starts with an input stream, that is essentially the JpegInterchangeFormat
   stream, if any, followed by the strile data, if any. This stream is read in
   OJPEGReadByte and related functions.

   It analyzes the start of this stream, until it encounters non-marker data, i.e.
   compressed image data. Some of the header markers it sees have no actual content,
   like the SOI marker, and APP/COM markers that really shouldn't even be there. Some
   other markers do have content, and the valuable bits and pieces of information
   in these markers are saved, checking all to verify that the stream is more or
   less within expected bounds. This happens inside the OJPEGReadHeaderInfoSecStreamXxx
   functions.

   Some OJPEG imagery contains no valid JPEG header markers. This situation is picked
   up on if we've seen no SOF marker when we're at the start of the compressed image
   data. In this case, the tables are read from JpegXxxTables tags, and the other
   bits and pieces of information is initialized to its most basic value. This is
   implemented in the OJPEGReadHeaderInfoSecTablesXxx functions.

   When this is complete, a good and valid JPEG header can be assembled, and this is
   passed through to LibJpeg. When that's done, the remainder of the input stream, i.e.
   the compressed image data, can be passed through unchanged. This is done in
   OJPEGWriteStream functions.

   LibTiff rightly expects to know the subsampling values before decompression. Just like
   in new-style JPEG-in-TIFF, though, or even more so, actually, the YCbCrsubsampling
   tag is notoriously unreliable. To correct these tag values with the ones inside
   the JPEG stream, the first part of the input stream is pre-scanned in
   OJPEGSubsamplingCorrect, making no note of any other data, reporting no warnings
   or errors, up to the point where either these values are read, or it's clear they
   aren't there. This means that some of the data is read twice, but we feel speed
   in correcting these values is important enough to warrant this sacrifice. Allthough
   there is currently no define or other configuration mechanism to disable this behaviour,
   the actual header scanning is build to robustly respond with error report if it
   should encounter an uncorrected mismatch of subsampling values. See
   OJPEGReadHeaderInfoSecStreamSof.

   The restart interval and restart markers are the most tricky part... The restart
   interval can be specified in a tag. It can also be set inside the input JPEG stream.
   It can be used inside the input JPEG stream. If reading from strile data, we've
   consistenly discovered the need to insert restart markers in between the different
   striles, as is also probably the most likely interpretation of the original TIFF 6.0
   specification. With all this setting of interval, and actual use of markers that is not
   predictable at the time of valid JPEG header assembly, the restart thing may turn
   out the Achilles heel of this implementation. Fortunately, most OJPEG writer vendors
   succeed in reading back what they write, which may be the reason why we've been able
   to discover ways that seem to work.

   Some special provision is made for planarconfig separate OJPEG files. These seem
   to consistently contain header info, a SOS marker, a plane, SOS marker, plane, SOS,
   and plane. This may or may not be a valid JPEG configuration, we don't know and don't
   care. We want LibTiff to be able to access the planes individually, without huge
   buffering inside LibJpeg, anyway. So we compose headers to feed to LibJpeg, in this
   case, that allow us to pass a single plane such that LibJpeg sees a valid
   single-channel JPEG stream. Locating subsequent SOS markers, and thus subsequent
   planes, is done inside OJPEGReadSecondarySos.

   The benefit of the scheme is... that it works, basically. We know of no other that
   does. It works without checking software tag, or otherwise going about things in an
   OJPEG flavor specific manner. Instead, it is a single scheme, that covers the cases
   with and without JpegInterchangeFormat, with and without striles, with part of
   the header in JpegInterchangeFormat and remainder in first strile, etc. It is forgiving
   and robust, may likely work with OJPEG flavors we've not seen yet, and makes most out
   of the data.

   Another nice side-effect is that a complete JPEG single valid stream is build if
   planarconfig is not separate (vast majority). We may one day use that to build
   converters to JPEG, and/or to new-style JPEG compression inside TIFF.

   A dissadvantage is the lack of random access to the individual striles. This is the
   reason for much of the complicated restart-and-position stuff inside OJPEGPreDecode.
   Applications would do well accessing all striles in order, as this will result in
   a single sequential scan of the input stream, and no restarting of LibJpeg decoding
   session.
*/


#include "tiffiop.h"
#ifdef OJPEG_SUPPORT

/* Configuration defines here are:
 * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some environments,
 * 	like eg LibTiffDelphi, this is not possible. For this reason, the actual calls to
 * 	libjpeg, with longjump stuff, are encapsulated in dedicated functions. When
 * 	JPEG_ENCAP_EXTERNAL is defined, these encapsulating functions are declared external
 * 	to this unit, and can be defined elsewhere to use stuff other then longjump.
 * 	The default mode, without JPEG_ENCAP_EXTERNAL, implements the call encapsulators
 * 	here, internally, with normal longjump.
 * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent is
 * 	conviniently available, but still it may be worthwhile to use _setjmp or sigsetjmp
 * 	in place of plain setjmp. These macros will make it easier. It is useless
 * 	to fiddle with these if you define JPEG_ENCAP_EXTERNAL.
 * OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee
 * 	instant processing, optimal streaming and optimal use of processor cache, but also big
 * 	enough so as to not result in significant call overhead. It should be at least a few
 * 	bytes to accomodate some structures (this is verified in asserts), but it would not be
 * 	sensible to make it this small anyway, and it should be at most 64K since it is indexed
 * 	with uint16. We recommend 2K.
 * EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has
 * 	absolutely no effect. That is why most people insist the EGYPTIANWALK is a bit silly.
 */

/* #define LIBJPEG_ENCAP_EXTERNAL */
#define SETJMP(jbuf) setjmp(jbuf)
#define LONGJMP(jbuf,code) longjmp(jbuf,code)
#define JMP_BUF jmp_buf
#define OJPEG_BUFFER 2048
/* define EGYPTIANWALK */

#define JPEG_MARKER_SOF0 0xC0
#define JPEG_MARKER_SOF1 0xC1
#define JPEG_MARKER_SOF3 0xC3
#define JPEG_MARKER_DHT 0xC4
#define JPEG_MARKER_RST0 0XD0
#define JPEG_MARKER_SOI 0xD8
#define JPEG_MARKER_EOI 0xD9
#define JPEG_MARKER_SOS 0xDA
#define JPEG_MARKER_DQT 0xDB
#define JPEG_MARKER_DRI 0xDD
#define JPEG_MARKER_APP0 0xE0
#define JPEG_MARKER_COM 0xFE

#define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC+0)
#define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC+1)
#define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC+2)
#define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC+3)
#define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC+4)
#define FIELD_OJPEG_JPEGPROC (FIELD_CODEC+5)
#define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC+6)
#define FIELD_OJPEG_COUNT 7

static const TIFFFieldInfo ojpeg_field_info[] = {
	{TIFFTAG_JPEGIFOFFSET,1,1,TIFF_LONG,FIELD_OJPEG_JPEGINTERCHANGEFORMAT,TRUE,FALSE,"JpegInterchangeFormat"},
	{TIFFTAG_JPEGIFBYTECOUNT,1,1,TIFF_LONG,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH,TRUE,FALSE,"JpegInterchangeFormatLength"},
	{TIFFTAG_JPEGQTABLES,TIFF_VARIABLE,TIFF_VARIABLE,TIFF_LONG,FIELD_OJPEG_JPEGQTABLES,FALSE,TRUE,"JpegQTables"},
	{TIFFTAG_JPEGDCTABLES,TIFF_VARIABLE,TIFF_VARIABLE,TIFF_LONG,FIELD_OJPEG_JPEGDCTABLES,FALSE,TRUE,"JpegDcTables"},
	{TIFFTAG_JPEGACTABLES,TIFF_VARIABLE,TIFF_VARIABLE,TIFF_LONG,FIELD_OJPEG_JPEGACTABLES,FALSE,TRUE,"JpegAcTables"},
	{TIFFTAG_JPEGPROC,1,1,TIFF_SHORT,FIELD_OJPEG_JPEGPROC,FALSE,FALSE,"JpegProc"},
	{TIFFTAG_JPEGRESTARTINTERVAL,1,1,TIFF_SHORT,FIELD_OJPEG_JPEGRESTARTINTERVAL,FALSE,FALSE,"JpegRestartInterval"},
};

#ifndef LIBJPEG_ENCAP_EXTERNAL
#include <setjmp.h>
#endif

#include "jpeglib.h"
#include "jerror.h"

typedef struct jpeg_error_mgr jpeg_error_mgr;
typedef struct jpeg_common_struct jpeg_common_struct;
typedef struct jpeg_decompress_struct jpeg_decompress_struct;
typedef struct jpeg_source_mgr jpeg_source_mgr;

typedef enum {
	osibsNotSetYet,
	osibsJpegInterchangeFormat,
	osibsStrile,
	osibsEof
} OJPEGStateInBufferSource;

typedef enum {
	ososSoi,
	ososQTable0,ososQTable1,ososQTable2,ososQTable3,
	ososDcTable0,ososDcTable1,ososDcTable2,ososDcTable3,
	ososAcTable0,ososAcTable1,ososAcTable2,ososAcTable3,
	ososDri,
	ososSof,
	ososSos,
	ososCompressed,
	ososRst,
	ososEoi
} OJPEGStateOutState;

typedef struct {
	TIFF* tif;
	#ifndef LIBJPEG_ENCAP_EXTERNAL
	JMP_BUF exit_jmpbuf;
	#endif
	TIFFVGetMethod vgetparent;
	TIFFVSetMethod vsetparent;
	toff_t file_size;
	uint32 image_width;
	uint32 image_length;
	uint32 strile_width;
	uint32 strile_length;
	uint32 strile_length_total;
	uint8 samples_per_pixel;
	uint8 plane_sample_offset;
	uint8 samples_per_pixel_per_plane;
	toff_t jpeg_interchange_format;
	toff_t jpeg_interchange_format_length;
	uint8 jpeg_proc;
	uint8 subsamplingcorrect;
	uint8 subsamplingcorrect_done;
	uint8 subsampling_tag;
	uint8 subsampling_hor;
	uint8 subsampling_ver;
	uint8 subsampling_force_desubsampling_inside_decompression;
	uint8 qtable_offset_count;
	uint8 dctable_offset_count;
	uint8 actable_offset_count;
	toff_t qtable_offset[3];
	toff_t dctable_offset[3];
	toff_t actable_offset[3];
	uint8* qtable[4];
	uint8* dctable[4];
	uint8* actable[4];
	uint16 restart_interval;
	uint8 restart_index;
	uint8 sof_log;
	uint8 sof_marker_id;
	uint32 sof_x;
	uint32 sof_y;
	uint8 sof_c[3];
	uint8 sof_hv[3];
	uint8 sof_tq[3];
	uint8 sos_cs[3];
	uint8 sos_tda[3];
	struct {
		uint8 log;
		OJPEGStateInBufferSource in_buffer_source;
		tstrile_t in_buffer_next_strile;
		toff_t in_buffer_file_pos;
		toff_t in_buffer_file_togo;
	} sos_end[3];
	uint8 readheader_done;
	uint8 writeheader_done;
	tsample_t write_cursample;
	tstrile_t write_curstrile;
	uint8 libjpeg_session_active;
	uint8 libjpeg_jpeg_query_style;
	jpeg_error_mgr libjpeg_jpeg_error_mgr;
	jpeg_decompress_struct libjpeg_jpeg_decompress_struct;
	jpeg_source_mgr libjpeg_jpeg_source_mgr;
	uint8 subsampling_convert_log;
	uint32 subsampling_convert_ylinelen;
	uint32 subsampling_convert_ylines;
	uint32 subsampling_convert_clinelen;
	uint32 subsampling_convert_clines;
	uint32 subsampling_convert_ybuflen;
	uint32 subsampling_convert_cbuflen;
	uint32 subsampling_convert_ycbcrbuflen;
	uint8* subsampling_convert_ycbcrbuf;
	uint8* subsampling_convert_ybuf;
	uint8* subsampling_convert_cbbuf;
	uint8* subsampling_convert_crbuf;
	uint32 subsampling_convert_ycbcrimagelen;
	uint8** subsampling_convert_ycbcrimage;
	uint32 subsampling_convert_clinelenout;
	uint32 subsampling_convert_state;
	uint32 bytes_per_line;   /* if the codec outputs subsampled data, a 'line' in bytes_per_line */
	uint32 lines_per_strile; /* and lines_per_strile means subsampling_ver desubsampled rows     */
	OJPEGStateInBufferSource in_buffer_source;
	tstrile_t in_buffer_next_strile;
	tstrile_t in_buffer_strile_count;
	toff_t in_buffer_file_pos;
	uint8 in_buffer_file_pos_log;
	toff_t in_buffer_file_togo;
	uint16 in_buffer_togo;
	uint8* in_buffer_cur;
	uint8 in_buffer[OJPEG_BUFFER];
	OJPEGStateOutState out_state;
	uint8 out_buffer[OJPEG_BUFFER];
	uint8* skip_buffer;
} OJPEGState;

static int OJPEGVGetField(TIFF* tif, ttag_t tag, va_list ap);
static int OJPEGVSetField(TIFF* tif, ttag_t tag, va_list ap);
static void OJPEGPrintDir(TIFF* tif, FILE* fd, long flags);

static int OJPEGSetupDecode(TIFF* tif);
static int OJPEGPreDecode(TIFF* tif, tsample_t s);
static int OJPEGPreDecodeSkipRaw(TIFF* tif);
static int OJPEGPreDecodeSkipScanlines(TIFF* tif);
static int OJPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s);
static int OJPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc);
static int OJPEGDecodeScanlines(TIFF* tif, tidata_t buf, tsize_t cc);
static void OJPEGPostDecode(TIFF* tif, tidata_t buf, tsize_t cc);
static int OJPEGSetupEncode(TIFF* tif);
static int OJPEGPreEncode(TIFF* tif, tsample_t s);
static int OJPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s);
static int OJPEGPostEncode(TIFF* tif);
static void OJPEGCleanup(TIFF* tif);

static void OJPEGSubsamplingCorrect(TIFF* tif);
static int OJPEGReadHeaderInfo(TIFF* tif);
static int OJPEGReadSecondarySos(TIFF* tif, tsample_t s);
static int OJPEGWriteHeaderInfo(TIFF* tif);
static void OJPEGLibjpegSessionAbort(TIFF* tif);

static int OJPEGReadHeaderInfoSec(TIFF* tif);
static int OJPEGReadHeaderInfoSecStreamDri(TIFF* tif);
static int OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif);
static int OJPEGReadHeaderInfoSecStreamDht(TIFF* tif);
static int OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id);
static int OJPEGReadHeaderInfoSecStreamSos(TIFF* tif);
static int OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif);
static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif);
static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif);

static int OJPEGReadBufferFill(OJPEGState* sp);
static int OJPEGReadByte(OJPEGState* sp, uint8* byte);
static int OJPEGReadBytePeek(OJPEGState* sp, uint8* byte);
static void OJPEGReadByteAdvance(OJPEGState* sp);
static int OJPEGReadWord(OJPEGState* sp, uint16* word);
static int OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem);
static void OJPEGReadSkip(OJPEGState* sp, uint16 len);

static int OJPEGWriteStream(TIFF* tif, void** mem, uint32* len);
static void OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len);
static void OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
static void OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
static void OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
static void OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len);
static void OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len);
static void OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len);
static int OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len);
static void OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len);
static void OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len);

#ifdef LIBJPEG_ENCAP_EXTERNAL
extern int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
extern int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
extern int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
extern int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
extern int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
extern void jpeg_encap_unwind(TIFF* tif);
#else
static int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* j);
static int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
static int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
static int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
static int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
static void jpeg_encap_unwind(TIFF* tif);
#endif

static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo);
static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo);
static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo);
static boolean OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo);
static void OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes);
static boolean OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired);
static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo);

int
TIFFInitOJPEG(TIFF* tif, int scheme)
{
	static const char module[]="TIFFInitOJPEG";
	OJPEGState* sp;

	assert(scheme==COMPRESSION_OJPEG);

        /*
	 * Merge codec-specific tag information.
	 */
	if (!_TIFFMergeFieldInfo(tif,ojpeg_field_info,FIELD_OJPEG_COUNT)) {
		TIFFErrorExt(tif->tif_clientdata, module,
			     "Merging Old JPEG codec-specific tags failed");
		return 0;
	}

	/* state block */
	sp=_TIFFmalloc(sizeof(OJPEGState));
	if (sp==NULL)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"No space for OJPEG state block");
		return(0);
	}
	_TIFFmemset(sp,0,sizeof(OJPEGState));
	sp->tif=tif;
	sp->jpeg_proc=1;
	sp->subsampling_hor=2;
	sp->subsampling_ver=2;
	TIFFSetField(tif,TIFFTAG_YCBCRSUBSAMPLING,2,2);
	/* tif codec methods */
	tif->tif_setupdecode=OJPEGSetupDecode;
	tif->tif_predecode=OJPEGPreDecode;
	tif->tif_postdecode=OJPEGPostDecode;
	tif->tif_decoderow=OJPEGDecode;
	tif->tif_decodestrip=OJPEGDecode;
	tif->tif_decodetile=OJPEGDecode;
	tif->tif_setupencode=OJPEGSetupEncode;
	tif->tif_preencode=OJPEGPreEncode;
	tif->tif_postencode=OJPEGPostEncode;
	tif->tif_encoderow=OJPEGEncode;
	tif->tif_encodestrip=OJPEGEncode;
	tif->tif_encodetile=OJPEGEncode;
	tif->tif_cleanup=OJPEGCleanup;
	tif->tif_data=(tidata_t)sp;
	/* tif tag methods */
	sp->vgetparent=tif->tif_tagmethods.vgetfield;
	tif->tif_tagmethods.vgetfield=OJPEGVGetField;
	sp->vsetparent=tif->tif_tagmethods.vsetfield;
	tif->tif_tagmethods.vsetfield=OJPEGVSetField;
	tif->tif_tagmethods.printdir=OJPEGPrintDir;
	/* Some OJPEG files don't have strip or tile offsets or bytecounts tags.
	   Some others do, but have totally meaningless or corrupt values
	   in these tags. In these cases, the JpegInterchangeFormat stream is
	   reliable. In any case, this decoder reads the compressed data itself,
	   from the most reliable locations, and we need to notify encapsulating
	   LibTiff not to read raw strips or tiles for us. */
	tif->tif_flags|=TIFF_NOREADRAW;
	return(1);
}

static int
OJPEGVGetField(TIFF* tif, ttag_t tag, va_list ap)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	switch(tag)
	{
		case TIFFTAG_JPEGIFOFFSET:
			*va_arg(ap,uint32*)=(uint32)sp->jpeg_interchange_format;
			break;
		case TIFFTAG_JPEGIFBYTECOUNT:
			*va_arg(ap,uint32*)=(uint32)sp->jpeg_interchange_format_length;
			break;
		case TIFFTAG_YCBCRSUBSAMPLING:
			if (sp->subsamplingcorrect_done==0)
				OJPEGSubsamplingCorrect(tif);
			*va_arg(ap,uint16*)=(uint16)sp->subsampling_hor;
			*va_arg(ap,uint16*)=(uint16)sp->subsampling_ver;
			break;
		case TIFFTAG_JPEGQTABLES:
			*va_arg(ap,uint32*)=(uint32)sp->qtable_offset_count;
			*va_arg(ap,void**)=(void*)sp->qtable_offset;
			break;
		case TIFFTAG_JPEGDCTABLES:
			*va_arg(ap,uint32*)=(uint32)sp->dctable_offset_count;
			*va_arg(ap,void**)=(void*)sp->dctable_offset;
			break;
		case TIFFTAG_JPEGACTABLES:
			*va_arg(ap,uint32*)=(uint32)sp->actable_offset_count;
			*va_arg(ap,void**)=(void*)sp->actable_offset;
			break;
		case TIFFTAG_JPEGPROC:
			*va_arg(ap,uint16*)=(uint16)sp->jpeg_proc;
			break;
		case TIFFTAG_JPEGRESTARTINTERVAL:
			*va_arg(ap,uint16*)=sp->restart_interval;
			break;
		default:
			return (*sp->vgetparent)(tif,tag,ap);
	}
	return (1);
}

static int
OJPEGVSetField(TIFF* tif, ttag_t tag, va_list ap)
{
	static const char module[]="OJPEGVSetField";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint32 ma;
	uint32* mb;
	uint32 n;
	switch(tag)
	{
		case TIFFTAG_JPEGIFOFFSET:
			sp->jpeg_interchange_format=(toff_t)va_arg(ap,uint32);  
			break;
		case TIFFTAG_JPEGIFBYTECOUNT:
			sp->jpeg_interchange_format_length=(toff_t)va_arg(ap,uint32);  
			break;
		case TIFFTAG_YCBCRSUBSAMPLING:
			sp->subsampling_tag=1;
			sp->subsampling_hor=(uint8)va_arg(ap,int);
			sp->subsampling_ver=(uint8)va_arg(ap,int);
			tif->tif_dir.td_ycbcrsubsampling[0]=sp->subsampling_hor;
			tif->tif_dir.td_ycbcrsubsampling[1]=sp->subsampling_ver;
			break;
		case TIFFTAG_JPEGQTABLES:
			ma=va_arg(ap,uint32);
			if (ma!=0)
			{
				if (ma>3)
				{
					TIFFErrorExt(tif->tif_clientdata,module,"JpegQTables tag has incorrect count");
					return(0);
				}
				sp->qtable_offset_count=(uint8)ma;
				mb=va_arg(ap,uint32*);
				for (n=0; n<ma; n++)
					sp->qtable_offset[n]=(toff_t)mb[n];
			}
			break;
		case TIFFTAG_JPEGDCTABLES:
			ma=va_arg(ap,uint32);
			if (ma!=0)
			{
				if (ma>3)
				{
					TIFFErrorExt(tif->tif_clientdata,module,"JpegDcTables tag has incorrect count");
					return(0);
				}
				sp->dctable_offset_count=(uint8)ma;
				mb=va_arg(ap,uint32*);
				for (n=0; n<ma; n++)
					sp->dctable_offset[n]=(toff_t)mb[n];
			}
			break;
		case TIFFTAG_JPEGACTABLES:
			ma=va_arg(ap,uint32);
			if (ma!=0)
			{
				if (ma>3)
				{
					TIFFErrorExt(tif->tif_clientdata,module,"JpegAcTables tag has incorrect count");
					return(0);
				}
				sp->actable_offset_count=(uint8)ma;
				mb=va_arg(ap,uint32*);
				for (n=0; n<ma; n++)
					sp->actable_offset[n]=(toff_t)mb[n];
			}
			break;
		case TIFFTAG_JPEGPROC:
			sp->jpeg_proc=(uint8)va_arg(ap,uint32);
			break;
		case TIFFTAG_JPEGRESTARTINTERVAL:
			sp->restart_interval=(uint16)va_arg(ap,uint32);
			break;
		default:
			return (*sp->vsetparent)(tif,tag,ap);
	}
	TIFFSetFieldBit(tif,_TIFFFieldWithTag(tif,tag)->field_bit);
	tif->tif_flags|=TIFF_DIRTYDIRECT;
	return(1);
}

static void
OJPEGPrintDir(TIFF* tif, FILE* fd, long flags)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8 m;
	(void)flags;
	assert(sp!=NULL);
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMAT))
		fprintf(fd,"  JpegInterchangeFormat: %lu\n",(unsigned long)sp->jpeg_interchange_format);
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH))
		fprintf(fd,"  JpegInterchangeFormatLength: %lu\n",(unsigned long)sp->jpeg_interchange_format_length);
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGQTABLES))
	{
		fprintf(fd,"  JpegQTables:");
		for (m=0; m<sp->qtable_offset_count; m++)
			fprintf(fd," %lu",(unsigned long)sp->qtable_offset[m]);
		fprintf(fd,"\n");
	}
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGDCTABLES))
	{
		fprintf(fd,"  JpegDcTables:");
		for (m=0; m<sp->dctable_offset_count; m++)
			fprintf(fd," %lu",(unsigned long)sp->dctable_offset[m]);
		fprintf(fd,"\n");
	}
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGACTABLES))
	{
		fprintf(fd,"  JpegAcTables:");
		for (m=0; m<sp->actable_offset_count; m++)
			fprintf(fd," %lu",(unsigned long)sp->actable_offset[m]);
		fprintf(fd,"\n");
	}
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGPROC))
		fprintf(fd,"  JpegProc: %u\n",(unsigned int)sp->jpeg_proc);
	if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGRESTARTINTERVAL))
		fprintf(fd,"  JpegRestartInterval: %u\n",(unsigned int)sp->restart_interval);
}

static int
OJPEGSetupDecode(TIFF* tif)
{
	static const char module[]="OJPEGSetupDecode";
	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");
	return(1);
}

static int
OJPEGPreDecode(TIFF* tif, tsample_t s)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	tstrile_t m;
	if (sp->subsamplingcorrect_done==0)
		OJPEGSubsamplingCorrect(tif);
	if (sp->readheader_done==0)
	{
		if (OJPEGReadHeaderInfo(tif)==0)
			return(0);
	}
	if (sp->sos_end[s].log==0)
	{
		if (OJPEGReadSecondarySos(tif,s)==0)
			return(0);
	}
	if isTiled(tif)
		m=(tstrile_t)tif->tif_curtile;
	else
		m=(tstrile_t)tif->tif_curstrip;
	if ((sp->writeheader_done!=0) && ((sp->write_cursample!=s) || (sp->write_curstrile>m)))
	{
		if (sp->libjpeg_session_active!=0)
			OJPEGLibjpegSessionAbort(tif);
		sp->writeheader_done=0;
	}
	if (sp->writeheader_done==0)
	{
		sp->plane_sample_offset=s;
		sp->write_cursample=s;
		sp->write_curstrile=s*tif->tif_dir.td_stripsperimage;
		if ((sp->in_buffer_file_pos_log==0) ||
		    (sp->in_buffer_file_pos-sp->in_buffer_togo!=sp->sos_end[s].in_buffer_file_pos))
		{
			sp->in_buffer_source=sp->sos_end[s].in_buffer_source;
			sp->in_buffer_next_strile=sp->sos_end[s].in_buffer_next_strile;
			sp->in_buffer_file_pos=sp->sos_end[s].in_buffer_file_pos;
			sp->in_buffer_file_pos_log=0;
			sp->in_buffer_file_togo=sp->sos_end[s].in_buffer_file_togo;
			sp->in_buffer_togo=0;
			sp->in_buffer_cur=0;
		}
		if (OJPEGWriteHeaderInfo(tif)==0)
			return(0);
	}
	while (sp->write_curstrile<m)          
	{
		if (sp->libjpeg_jpeg_query_style==0)
		{
			if (OJPEGPreDecodeSkipRaw(tif)==0)
				return(0);
		}
		else
		{
			if (OJPEGPreDecodeSkipScanlines(tif)==0)
				return(0);
		}
		sp->write_curstrile++;
	}
	return(1);
}

static int
OJPEGPreDecodeSkipRaw(TIFF* tif)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint32 m;
	m=sp->lines_per_strile;
	if (sp->subsampling_convert_state!=0)
	{
		if (sp->subsampling_convert_clines-sp->subsampling_convert_state>=m)
		{
			sp->subsampling_convert_state+=m;
			if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
				sp->subsampling_convert_state=0;
			return(1);
		}
		m-=sp->subsampling_convert_clines-sp->subsampling_convert_state;
		sp->subsampling_convert_state=0;
	}
	while (m>=sp->subsampling_convert_clines)
	{
		if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
			return(0);
		m-=sp->subsampling_convert_clines;
	}
	if (m>0)
	{
		if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
			return(0);
		sp->subsampling_convert_state=m;
	}
	return(1);
}

static int
OJPEGPreDecodeSkipScanlines(TIFF* tif)
{
	static const char module[]="OJPEGPreDecodeSkipScanlines";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint32 m;
	if (sp->skip_buffer==NULL)
	{
		sp->skip_buffer=_TIFFmalloc(sp->bytes_per_line);
		if (sp->skip_buffer==NULL)
		{
			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
			return(0);
		}
	}
	for (m=0; m<sp->lines_per_strile; m++)
	{
		if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&sp->skip_buffer,1)==0)
			return(0);
	}
	return(1);
}

static int
OJPEGDecode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	(void)s;
	if (sp->libjpeg_jpeg_query_style==0)
	{
		if (OJPEGDecodeRaw(tif,buf,cc)==0)
			return(0);
	}
	else
	{
		if (OJPEGDecodeScanlines(tif,buf,cc)==0)
			return(0);
	}
	return(1);
}

static int
OJPEGDecodeRaw(TIFF* tif, tidata_t buf, tsize_t cc)
{
	static const char module[]="OJPEGDecodeRaw";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8* m;
	uint32 n;
	uint8* oy;
	uint8* ocb;
	uint8* ocr;
	uint8* p;
	uint32 q;
	uint8* r;
	uint8 sx,sy;
	if (cc%sp->bytes_per_line!=0)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
		return(0);
	}
	assert(cc>0);
	m=buf;
	n=cc;
	do
	{
		if (sp->subsampling_convert_state==0)
		{
			if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
				return(0);
		}
		oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen;
		ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
		ocr=sp->subsampling_convert_crbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
		p=m;
		for (q=0; q<sp->subsampling_convert_clinelenout; q++)
		{
			r=oy;
			for (sy=0; sy<sp->subsampling_ver; sy++)
			{
				for (sx=0; sx<sp->subsampling_hor; sx++)
					*p++=*r++;
				r+=sp->subsampling_convert_ylinelen-sp->subsampling_hor;
			}
			oy+=sp->subsampling_hor;
			*p++=*ocb++;
			*p++=*ocr++;
		}
		sp->subsampling_convert_state++;
		if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
			sp->subsampling_convert_state=0;
		m+=sp->bytes_per_line;
		n-=sp->bytes_per_line;
	} while(n>0);
	return(1);
}

static int
OJPEGDecodeScanlines(TIFF* tif, tidata_t buf, tsize_t cc)
{
	static const char module[]="OJPEGDecodeScanlines";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8* m;
	uint32 n;
	if (cc%sp->bytes_per_line!=0)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
		return(0);
	}
	assert(cc>0);
	m=buf;
	n=cc;
	do
	{
		if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&m,1)==0)
			return(0);
		m+=sp->bytes_per_line;
		n-=sp->bytes_per_line;
	} while(n>0);
	return(1);
}

static void
OJPEGPostDecode(TIFF* tif, tidata_t buf, tsize_t cc)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	(void)buf;
	(void)cc;
	sp->write_curstrile++;
	if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0)
	{
		assert(sp->libjpeg_session_active!=0);
		OJPEGLibjpegSessionAbort(tif);
		sp->writeheader_done=0;
	}
}

static int
OJPEGSetupEncode(TIFF* tif)
{
	static const char module[]="OJPEGSetupEncode";
	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
	return(0);
}

static int
OJPEGPreEncode(TIFF* tif, tsample_t s)
{
	static const char module[]="OJPEGPreEncode";
	(void)s;
	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
	return(0);
}

static int
OJPEGEncode(TIFF* tif, tidata_t buf, tsize_t cc, tsample_t s)
{
	static const char module[]="OJPEGEncode";
	(void)buf;
	(void)cc;
	(void)s;
	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
	return(0);
}

static int
OJPEGPostEncode(TIFF* tif)
{
	static const char module[]="OJPEGPostEncode";
	TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
	return(0);
}

static void
OJPEGCleanup(TIFF* tif)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	if (sp!=0)
	{
		tif->tif_tagmethods.vgetfield=sp->vgetparent;
		tif->tif_tagmethods.vsetfield=sp->vsetparent;
		if (sp->qtable[0]!=0)
			_TIFFfree(sp->qtable[0]);
		if (sp->qtable[1]!=0)
			_TIFFfree(sp->qtable[1]);
		if (sp->qtable[2]!=0)
			_TIFFfree(sp->qtable[2]);
		if (sp->qtable[3]!=0)
			_TIFFfree(sp->qtable[3]);
		if (sp->dctable[0]!=0)
			_TIFFfree(sp->dctable[0]);
		if (sp->dctable[1]!=0)
			_TIFFfree(sp->dctable[1]);
		if (sp->dctable[2]!=0)
			_TIFFfree(sp->dctable[2]);
		if (sp->dctable[3]!=0)
			_TIFFfree(sp->dctable[3]);
		if (sp->actable[0]!=0)
			_TIFFfree(sp->actable[0]);
		if (sp->actable[1]!=0)
			_TIFFfree(sp->actable[1]);
		if (sp->actable[2]!=0)
			_TIFFfree(sp->actable[2]);
		if (sp->actable[3]!=0)
			_TIFFfree(sp->actable[3]);
		if (sp->libjpeg_session_active!=0)
			OJPEGLibjpegSessionAbort(tif);
		if (sp->subsampling_convert_ycbcrbuf!=0)
			_TIFFfree(sp->subsampling_convert_ycbcrbuf);
		if (sp->subsampling_convert_ycbcrimage!=0)
			_TIFFfree(sp->subsampling_convert_ycbcrimage);
		if (sp->skip_buffer!=0)
			_TIFFfree(sp->skip_buffer);
		_TIFFfree(sp);
		tif->tif_data=NULL;
		_TIFFSetDefaultCompressionState(tif);
	}
}

static void
OJPEGSubsamplingCorrect(TIFF* tif)
{
	static const char module[]="OJPEGSubsamplingCorrect";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8 mh;
	uint8 mv;
	assert(sp->subsamplingcorrect_done==0);
	if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) &&
	    (tif->tif_dir.td_photometric!=PHOTOMETRIC_ITULAB)))
	{
		if (sp->subsampling_tag!=0)
			TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag not appropriate for this Photometric and/or SamplesPerPixel");
		sp->subsampling_hor=1;
		sp->subsampling_ver=1;
		sp->subsampling_force_desubsampling_inside_decompression=0;
	}
	else
	{
		sp->subsamplingcorrect_done=1;
		mh=sp->subsampling_hor;
		mv=sp->subsampling_ver;
		sp->subsamplingcorrect=1;
		OJPEGReadHeaderInfoSec(tif);
		if (sp->subsampling_force_desubsampling_inside_decompression!=0)
		{
			sp->subsampling_hor=1;
			sp->subsampling_ver=1;
		}
		sp->subsamplingcorrect=0;
		if (((sp->subsampling_hor!=mh) || (sp->subsampling_ver!=mv)) && (sp->subsampling_force_desubsampling_inside_decompression==0))
		{
			if (sp->subsampling_tag==0)
				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);
			else
				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);
		}
		if (sp->subsampling_force_desubsampling_inside_decompression!=0)
		{
			if (sp->subsampling_tag==0)
				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");
			else
				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);
		}
		if (sp->subsampling_force_desubsampling_inside_decompression==0)
		{
			if (sp->subsampling_hor<sp->subsampling_ver)
				TIFFWarningExt(tif->tif_clientdata,module,"Subsampling values [%d,%d] are not allowed in TIFF",sp->subsampling_hor,sp->subsampling_ver);
		}
	}
	sp->subsamplingcorrect_done=1;
}

static int
OJPEGReadHeaderInfo(TIFF* tif)
{
	static const char module[]="OJPEGReadHeaderInfo";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	assert(sp->readheader_done==0);
	sp->image_width=tif->tif_dir.td_imagewidth;
	sp->image_length=tif->tif_dir.td_imagelength;
	if isTiled(tif)
	{
		sp->strile_width=tif->tif_dir.td_tilewidth;
		sp->strile_length=tif->tif_dir.td_tilelength;
		sp->strile_length_total=((sp->image_length+sp->strile_length-1)/sp->strile_length)*sp->strile_length;
	}
	else
	{
		sp->strile_width=sp->image_width;
		sp->strile_length=tif->tif_dir.td_rowsperstrip;
		sp->strile_length_total=sp->image_length;
	}
	sp->samples_per_pixel=tif->tif_dir.td_samplesperpixel;
	if (sp->samples_per_pixel==1)
	{
		sp->plane_sample_offset=0;
		sp->samples_per_pixel_per_plane=sp->samples_per_pixel;
		sp->subsampling_hor=1;
		sp->subsampling_ver=1;
	}
	else
	{
		if (sp->samples_per_pixel!=3)
		{
			TIFFErrorExt(tif->tif_clientdata,module,"SamplesPerPixel %d not supported for this compression scheme",sp->samples_per_pixel);
			return(0);
		}
		sp->plane_sample_offset=0;
		if (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)
			sp->samples_per_pixel_per_plane=3;
		else
			sp->samples_per_pixel_per_plane=1;
	}
	if (sp->strile_length<sp->image_length)
	{
		if (sp->strile_length%(sp->subsampling_ver*8)!=0)
		{
			TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length");
			return(0);
		}
		sp->restart_interval=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8))*(sp->strile_length/(sp->subsampling_ver*8));
	}
	if (OJPEGReadHeaderInfoSec(tif)==0)
		return(0);
	sp->sos_end[0].log=1;
	sp->sos_end[0].in_buffer_source=sp->in_buffer_source;
	sp->sos_end[0].in_buffer_next_strile=sp->in_buffer_next_strile;
	sp->sos_end[0].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
	sp->sos_end[0].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo;
	sp->readheader_done=1;
	return(1);
}

static int
OJPEGReadSecondarySos(TIFF* tif, tsample_t s)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8 m;
	assert(s>0);
	assert(s<3);
	assert(sp->sos_end[0].log!=0);
	assert(sp->sos_end[s].log==0);
	sp->plane_sample_offset=s-1;
	while(sp->sos_end[sp->plane_sample_offset].log==0)
		sp->plane_sample_offset--;
	sp->in_buffer_source=sp->sos_end[sp->plane_sample_offset].in_buffer_source;
	sp->in_buffer_next_strile=sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile;
	sp->in_buffer_file_pos=sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos;  
	sp->in_buffer_file_pos_log=0;
	sp->in_buffer_file_togo=sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo;
	sp->in_buffer_togo=0;
	sp->in_buffer_cur=0;
	while(sp->plane_sample_offset<s)
	{
		do
		{
			if (OJPEGReadByte(sp,&m)==0)
				return(0);
			if (m==255)
			{
				do
				{
					if (OJPEGReadByte(sp,&m)==0)
						return(0);
					if (m!=255)
						break;
				} while(1);
				if (m==JPEG_MARKER_SOS)
					break;
			}
		} while(1);
		sp->plane_sample_offset++;
		if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
			return(0);
		sp->sos_end[sp->plane_sample_offset].log=1;
		sp->sos_end[sp->plane_sample_offset].in_buffer_source=sp->in_buffer_source;
		sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile=sp->in_buffer_next_strile;
		sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
		sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo;
	}
	return(1);
}

static int
OJPEGWriteHeaderInfo(TIFF* tif)
{
	static const char module[]="OJPEGWriteHeaderInfo";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8** m;
	uint32 n;
	assert(sp->libjpeg_session_active==0);
	sp->out_state=ososSoi;
	sp->restart_index=0;
	jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr));
	sp->libjpeg_jpeg_error_mgr.output_message=OJPEGLibjpegJpegErrorMgrOutputMessage;
	sp->libjpeg_jpeg_error_mgr.error_exit=OJPEGLibjpegJpegErrorMgrErrorExit;
	sp->libjpeg_jpeg_decompress_struct.err=&(sp->libjpeg_jpeg_error_mgr);
	sp->libjpeg_jpeg_decompress_struct.client_data=(void*)tif;
	if (jpeg_create_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
		return(0);
	sp->libjpeg_session_active=1;
	sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=0;
	sp->libjpeg_jpeg_source_mgr.init_source=OJPEGLibjpegJpegSourceMgrInitSource;
	sp->libjpeg_jpeg_source_mgr.fill_input_buffer=OJPEGLibjpegJpegSourceMgrFillInputBuffer;
	sp->libjpeg_jpeg_source_mgr.skip_input_data=OJPEGLibjpegJpegSourceMgrSkipInputData;
	sp->libjpeg_jpeg_source_mgr.resync_to_restart=OJPEGLibjpegJpegSourceMgrResyncToRestart;
	sp->libjpeg_jpeg_source_mgr.term_source=OJPEGLibjpegJpegSourceMgrTermSource;
	sp->libjpeg_jpeg_decompress_struct.src=&(sp->libjpeg_jpeg_source_mgr);
	if (jpeg_read_header_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),1)==0)
		return(0);
	if ((sp->subsampling_force_desubsampling_inside_decompression==0) && (sp->samples_per_pixel_per_plane>1))
	{
		sp->libjpeg_jpeg_decompress_struct.raw_data_out=1;
		sp->libjpeg_jpeg_query_style=0;
		if (sp->subsampling_convert_log==0)
		{
			assert(sp->subsampling_convert_ycbcrbuf==0);
			assert(sp->subsampling_convert_ycbcrimage==0);
			sp->subsampling_convert_ylinelen=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8)*sp->subsampling_hor*8);
			sp->subsampling_convert_ylines=sp->subsampling_ver*8;
			sp->subsampling_convert_clinelen=sp->subsampling_convert_ylinelen/sp->subsampling_hor;
			sp->subsampling_convert_clines=8;
			sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines;
			sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines;
			sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen;
			sp->subsampling_convert_ycbcrbuf=_TIFFmalloc(sp->subsampling_convert_ycbcrbuflen);
			if (sp->subsampling_convert_ycbcrbuf==0)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
				return(0);
			}
			sp->subsampling_convert_ybuf=sp->subsampling_convert_ycbcrbuf;
			sp->subsampling_convert_cbbuf=sp->subsampling_convert_ybuf+sp->subsampling_convert_ybuflen;
			sp->subsampling_convert_crbuf=sp->subsampling_convert_cbbuf+sp->subsampling_convert_cbuflen;
			sp->subsampling_convert_ycbcrimagelen=3+sp->subsampling_convert_ylines+2*sp->subsampling_convert_clines;
			sp->subsampling_convert_ycbcrimage=_TIFFmalloc(sp->subsampling_convert_ycbcrimagelen*sizeof(uint8*));
			if (sp->subsampling_convert_ycbcrimage==0)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
				return(0);
			}
			m=sp->subsampling_convert_ycbcrimage;
			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3);
			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines);
			*m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines+sp->subsampling_convert_clines);
			for (n=0; n<sp->subsampling_convert_ylines; n++)
				*m++=sp->subsampling_convert_ybuf+n*sp->subsampling_convert_ylinelen;
			for (n=0; n<sp->subsampling_convert_clines; n++)
				*m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen;
			for (n=0; n<sp->subsampling_convert_clines; n++)
				*m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen;
			sp->subsampling_convert_clinelenout=((sp->strile_width+sp->subsampling_hor-1)/sp->subsampling_hor);
			sp->subsampling_convert_state=0;
			sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2);
			sp->lines_per_strile=((sp->strile_length+sp->subsampling_ver-1)/sp->subsampling_ver);
			sp->subsampling_convert_log=1;
		}
	}
	else
	{
		sp->libjpeg_jpeg_decompress_struct.jpeg_color_space=JCS_UNKNOWN;
		sp->libjpeg_jpeg_decompress_struct.out_color_space=JCS_UNKNOWN;
		sp->libjpeg_jpeg_query_style=1;
		sp->bytes_per_line=sp->samples_per_pixel_per_plane*sp->strile_width;
		sp->lines_per_strile=sp->strile_length;
	}
	if (jpeg_start_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
		return(0);
	sp->writeheader_done=1;
	return(1);
}

static void
OJPEGLibjpegSessionAbort(TIFF* tif)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	assert(sp->libjpeg_session_active!=0);
	jpeg_destroy((jpeg_common_struct*)(&(sp->libjpeg_jpeg_decompress_struct)));
	sp->libjpeg_session_active=0;
}

static int
OJPEGReadHeaderInfoSec(TIFF* tif)
{
	static const char module[]="OJPEGReadHeaderInfoSec";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8 m;
	uint16 n;
	uint8 o;
	if (sp->file_size==0)
		sp->file_size=TIFFGetFileSize(tif);
	if (sp->jpeg_interchange_format!=0)
	{
		if (sp->jpeg_interchange_format>=sp->file_size)
		{
			sp->jpeg_interchange_format=0;
			sp->jpeg_interchange_format_length=0;
		}
		else
		{
			if ((sp->jpeg_interchange_format_length==0) || (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size))
				sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format;
		}
	}
	sp->in_buffer_source=osibsNotSetYet;
	sp->in_buffer_next_strile=0;
	sp->in_buffer_strile_count=tif->tif_dir.td_nstrips;   
	sp->in_buffer_file_togo=0;
	sp->in_buffer_togo=0;
	do
	{
		if (OJPEGReadBytePeek(sp,&m)==0)
			return(0);
		if (m!=255)
			break;
		OJPEGReadByteAdvance(sp);
		do
		{
			if (OJPEGReadByte(sp,&m)==0)
				return(0);
		} while(m==255);
		switch(m)
		{
			case JPEG_MARKER_SOI:
				/* this type of marker has no data, and should be skipped */
				break;
			case JPEG_MARKER_COM:
			case JPEG_MARKER_APP0:
			case JPEG_MARKER_APP0+1:
			case JPEG_MARKER_APP0+2:
			case JPEG_MARKER_APP0+3:
			case JPEG_MARKER_APP0+4:
			case JPEG_MARKER_APP0+5:
			case JPEG_MARKER_APP0+6:
			case JPEG_MARKER_APP0+7:
			case JPEG_MARKER_APP0+8:
			case JPEG_MARKER_APP0+9:
			case JPEG_MARKER_APP0+10:
			case JPEG_MARKER_APP0+11:
			case JPEG_MARKER_APP0+12:
			case JPEG_MARKER_APP0+13:
			case JPEG_MARKER_APP0+14:
			case JPEG_MARKER_APP0+15:
				/* this type of marker has data, but it has no use to us (and no place here) and should be skipped */
				if (OJPEGReadWord(sp,&n)==0)
					return(0);
				if (n<2)
				{
					if (sp->subsamplingcorrect==0)
						TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
					return(0);
				}
				if (n>2)
					OJPEGReadSkip(sp,n-2);
				break;
			case JPEG_MARKER_DRI:
				if (OJPEGReadHeaderInfoSecStreamDri(tif)==0)
					return(0);
				break;
			case JPEG_MARKER_DQT:
				if (OJPEGReadHeaderInfoSecStreamDqt(tif)==0)
					return(0);
				break;
			case JPEG_MARKER_DHT:
				if (OJPEGReadHeaderInfoSecStreamDht(tif)==0)
					return(0);
				break;
			case JPEG_MARKER_SOF0:
			case JPEG_MARKER_SOF1:
			case JPEG_MARKER_SOF3:
				if (OJPEGReadHeaderInfoSecStreamSof(tif,m)==0)
					return(0);
				if (sp->subsamplingcorrect!=0)
					return(1);
				break;
			case JPEG_MARKER_SOS:
				if (sp->subsamplingcorrect!=0)
					return(1);
				assert(sp->plane_sample_offset==0);
				if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
					return(0);
				break;
			default:
				TIFFErrorExt(tif->tif_clientdata,module,"Unknown marker type %d in JPEG data",m);
				return(0);
		}
	} while(m!=JPEG_MARKER_SOS);
	if (sp->subsamplingcorrect)
		return(1);
	if (sp->sof_log==0)
	{
		if (OJPEGReadHeaderInfoSecTablesQTable(tif)==0)
			return(0);
		sp->sof_marker_id=JPEG_MARKER_SOF0;
		for (o=0; o<sp->samples_per_pixel; o++)
			sp->sof_c[o]=o;
		sp->sof_hv[0]=((sp->subsampling_hor<<4)|sp->subsampling_ver);
		for (o=1; o<sp->samples_per_pixel; o++)
			sp->sof_hv[o]=17;
		sp->sof_x=sp->strile_width;
		sp->sof_y=sp->strile_length_total;
		sp->sof_log=1;
		if (OJPEGReadHeaderInfoSecTablesDcTable(tif)==0)
			return(0);
		if (OJPEGReadHeaderInfoSecTablesAcTable(tif)==0)
			return(0);
		for (o=1; o<sp->samples_per_pixel; o++)
			sp->sos_cs[o]=o;
	}
	return(1);
}

static int
OJPEGReadHeaderInfoSecStreamDri(TIFF* tif)
{
	/* this could easilly cause trouble in some cases... but no such cases have occured sofar */
	static const char module[]="OJPEGReadHeaderInfoSecStreamDri";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint16 m;
	if (OJPEGReadWord(sp,&m)==0)
		return(0);
	if (m!=4)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DRI marker in JPEG data");
		return(0);
	}
	if (OJPEGReadWord(sp,&m)==0)
		return(0);
	sp->restart_interval=m;
	return(1);
}

static int
OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif)
{
	/* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
	static const char module[]="OJPEGReadHeaderInfoSecStreamDqt";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint16 m;
	uint32 na;
	uint8* nb;
	uint8 o;
	if (OJPEGReadWord(sp,&m)==0)
		return(0);
	if (m<=2)
	{
		if (sp->subsamplingcorrect==0)
			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
		return(0);
	}
	if (sp->subsamplingcorrect!=0)
		OJPEGReadSkip(sp,m-2);
	else
	{
		m-=2;
		do
		{
			if (m<65)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
				return(0);
			}
			na=sizeof(uint32)+69;
			nb=_TIFFmalloc(na);
			if (nb==0)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
				return(0);
			}
			*(uint32*)nb=na;
			nb[sizeof(uint32)]=255;
			nb[sizeof(uint32)+1]=JPEG_MARKER_DQT;
			nb[sizeof(uint32)+2]=0;
			nb[sizeof(uint32)+3]=67;
			if (OJPEGReadBlock(sp,65,&nb[sizeof(uint32)+4])==0)
				return(0);
			o=nb[sizeof(uint32)+4]&15;
			if (3<o)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
				return(0);
			}
			if (sp->qtable[o]!=0)
				_TIFFfree(sp->qtable[o]);
			sp->qtable[o]=nb;
			m-=65;
		} while(m>0);
	}
	return(1);
}

static int
OJPEGReadHeaderInfoSecStreamDht(TIFF* tif)
{
	/* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
	/* TODO: the following assumes there is only one table in this marker... but i'm not quite sure that assumption is guaranteed correct */
	static const char module[]="OJPEGReadHeaderInfoSecStreamDht";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint16 m;
	uint32 na;
	uint8* nb;
	uint8 o;
	if (OJPEGReadWord(sp,&m)==0)
		return(0);
	if (m<=2)
	{
		if (sp->subsamplingcorrect==0)
			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
		return(0);
	}
	if (sp->subsamplingcorrect!=0)
	{
		OJPEGReadSkip(sp,m-2);
	}
	else
	{
		na=sizeof(uint32)+2+m;
		nb=_TIFFmalloc(na);
		if (nb==0)
		{
			TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
			return(0);
		}
		*(uint32*)nb=na;
		nb[sizeof(uint32)]=255;
		nb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
		nb[sizeof(uint32)+2]=(m>>8);
		nb[sizeof(uint32)+3]=(m&255);
		if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0)
			return(0);
		o=nb[sizeof(uint32)+4];
		if ((o&240)==0)
		{
			if (3<o)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
				return(0);
			}
			if (sp->dctable[o]!=0)
				_TIFFfree(sp->dctable[o]);
			sp->dctable[o]=nb;
		}
		else
		{
			if ((o&240)!=16)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
				return(0);
			}
			o&=15;
			if (3<o)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
				return(0);
			}
			if (sp->actable[o]!=0)
				_TIFFfree(sp->actable[o]);
			sp->actable[o]=nb;
		}
	}
	return(1);
}

static int
OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id)
{
	/* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
	static const char module[]="OJPEGReadHeaderInfoSecStreamSof";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint16 m;
	uint16 n;
	uint8 o;
	uint16 p;
	uint16 q;
	if (sp->sof_log!=0)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
		return(0);
	}
	if (sp->subsamplingcorrect==0)
		sp->sof_marker_id=marker_id;
	/* Lf: data length */
	if (OJPEGReadWord(sp,&m)==0)
		return(0);
	if (m<11)
	{
		if (sp->subsamplingcorrect==0)
			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
		return(0);
	}
	m-=8;
	if (m%3!=0)
	{
		if (sp->subsamplingcorrect==0)
			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
		return(0);
	}
	n=m/3;
	if (sp->subsamplingcorrect==0)
	{
		if (n!=sp->samples_per_pixel)
		{
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of samples");
			return(0);
		}
	}
	/* P: Sample precision */
	if (OJPEGReadByte(sp,&o)==0)
		return(0);
	if (o!=8)
	{
		if (sp->subsamplingcorrect==0)
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of bits per sample");
		return(0);
	}
	/* Y: Number of lines, X: Number of samples per line */
	if (sp->subsamplingcorrect)
		OJPEGReadSkip(sp,4);
	else
	{
		/* TODO: probably best to also add check on allowed upper bound, especially x, may cause buffer overflow otherwise i think */
		/* Y: Number of lines */
		if (OJPEGReadWord(sp,&p)==0)
			return(0);
		if ((p<sp->image_length) && (p<sp->strile_length_total))
		{
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected height");
			return(0);
		}
		sp->sof_y=p;
		/* X: Number of samples per line */
		if (OJPEGReadWord(sp,&p)==0)
			return(0);
		if ((p<sp->image_width) && (p<sp->strile_width))
		{
			TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected width");
			return(0);
		}
		sp->sof_x=p;
	}
	/* Nf: Number of image components in frame */
	if (OJPEGReadByte(sp,&o)==0)
		return(0);
	if (o!=n)
	{
		if (sp->subsamplingcorrect==0)
			TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
		return(0);
	}
	/* per component stuff */
	/* 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 */
	for (q=0; q<n; q++)
	{
		/* C: Component identifier */
		if (OJPEGReadByte(sp,&o)==0)
			return(0);
		if (sp->subsamplingcorrect==0)
			sp->sof_c[q]=o;
		/* H: Horizontal sampling factor, and V: Vertical sampling factor */
		if (OJPEGReadByte(sp,&o)==0)
			return(0);
		if (sp->subsamplingcorrect!=0)
		{
			if (q==0)
			{
				sp->subsampling_hor=(o>>4);
				sp->subsampling_ver=(o&15);
				if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) ||
					((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4)))
					sp->subsampling_force_desubsampling_inside_decompression=1;
			}
			else
			{
				if (o!=17)
					sp->subsampling_force_desubsampling_inside_decompression=1;
			}
		}
		else
		{
			sp->sof_hv[q]=o;
			if (sp->subsampling_force_desubsampling_inside_decompression==0)
			{
				if (q==0)
				{
					if (o!=((sp->subsampling_hor<<4)|sp->subsampling_ver))
					{
						TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
						return(0);
					}
				}
				else
				{
					if (o!=17)
					{
						TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
						return(0);
					}
				}
			}
		}
		/* Tq: Quantization table destination selector */
		if (OJPEGReadByte(sp,&o)==0)
			return(0);
		if (sp->subsamplingcorrect==0)
			sp->sof_tq[q]=o;
	}
	if (sp->subsamplingcorrect==0)
		sp->sof_log=1;
	return(1);
}

static int
OJPEGReadHeaderInfoSecStreamSos(TIFF* tif)
{
	/* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
	static const char module[]="OJPEGReadHeaderInfoSecStreamSos";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint16 m;
	uint8 n;
	uint8 o;
	assert(sp->subsamplingcorrect==0);
	if (sp->sof_log==0)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
		return(0);
	}
	/* Ls */
	if (OJPEGReadWord(sp,&m)==0)
		return(0);
	if (m!=6+sp->samples_per_pixel_per_plane*2)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
		return(0);
	}
	/* Ns */
	if (OJPEGReadByte(sp,&n)==0)
		return(0);
	if (n!=sp->samples_per_pixel_per_plane)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
		return(0);
	}
	/* Cs, Td, and Ta */
	for (o=0; o<sp->samples_per_pixel_per_plane; o++)
	{
		/* Cs */
		if (OJPEGReadByte(sp,&n)==0)
			return(0);
		sp->sos_cs[sp->plane_sample_offset+o]=n;
		/* Td and Ta */
		if (OJPEGReadByte(sp,&n)==0)
			return(0);
		sp->sos_tda[sp->plane_sample_offset+o]=n;
	}
	/* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as per LibJpeg source */
	OJPEGReadSkip(sp,3);
	return(1);
}

static int
OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif)
{
	static const char module[]="OJPEGReadHeaderInfoSecTablesQTable";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8 m;
	uint8 n;
	uint32 oa;
	uint8* ob;
	uint32 p;
	if (sp->qtable_offset[0]==0)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
		return(0);
	}
	sp->in_buffer_file_pos_log=0;
	for (m=0; m<sp->samples_per_pixel; m++)
	{
		if ((sp->qtable_offset[m]!=0) && ((m==0) || (sp->qtable_offset[m]!=sp->qtable_offset[m-1])))
		{
			for (n=0; n<m-1; n++)
			{
				if (sp->qtable_offset[m]==sp->qtable_offset[n])
				{
					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegQTables tag value");
					return(0);
				}
			}
			oa=sizeof(uint32)+69;
			ob=_TIFFmalloc(oa);
			if (ob==0)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
				return(0);
			}
			*(uint32*)ob=oa;
			ob[sizeof(uint32)]=255;
			ob[sizeof(uint32)+1]=JPEG_MARKER_DQT;
			ob[sizeof(uint32)+2]=0;
			ob[sizeof(uint32)+3]=67;
			ob[sizeof(uint32)+4]=m;
			TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET);
			p=TIFFReadFile(tif,&ob[sizeof(uint32)+5],64);
			if (p!=64)
				return(0);
			sp->qtable[m]=ob;
			sp->sof_tq[m]=m;
		}
		else
			sp->sof_tq[m]=sp->sof_tq[m-1];
	}
	return(1);
}

static int
OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif)
{
	static const char module[]="OJPEGReadHeaderInfoSecTablesDcTable";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8 m;
	uint8 n;
	uint8 o[16];
	uint32 p;
	uint32 q;
	uint32 ra;
	uint8* rb;
	if (sp->dctable_offset[0]==0)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
		return(0);
	}
	sp->in_buffer_file_pos_log=0;
	for (m=0; m<sp->samples_per_pixel; m++)
	{
		if ((sp->dctable_offset[m]!=0) && ((m==0) || (sp->dctable_offset[m]!=sp->dctable_offset[m-1])))
		{
			for (n=0; n<m-1; n++)
			{
				if (sp->dctable_offset[m]==sp->dctable_offset[n])
				{
					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegDcTables tag value");
					return(0);
				}
			}
			TIFFSeekFile(tif,sp->dctable_offset[m],SEEK_SET);
			p=TIFFReadFile(tif,o,16);
			if (p!=16)
				return(0);
			q=0;
			for (n=0; n<16; n++)
				q+=o[n];
			ra=sizeof(uint32)+21+q;
			rb=_TIFFmalloc(ra);
			if (rb==0)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
				return(0);
			}
			*(uint32*)rb=ra;
			rb[sizeof(uint32)]=255;
			rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
			rb[sizeof(uint32)+2]=((19+q)>>8);
			rb[sizeof(uint32)+3]=((19+q)&255);
			rb[sizeof(uint32)+4]=m;
			for (n=0; n<16; n++)
				rb[sizeof(uint32)+5+n]=o[n];
			p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
			if (p!=q)
				return(0);
			sp->dctable[m]=rb;
			sp->sos_tda[m]=(m<<4);
		}
		else
			sp->sos_tda[m]=sp->sos_tda[m-1];
	}
	return(1);
}

static int
OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif)
{
	static const char module[]="OJPEGReadHeaderInfoSecTablesAcTable";
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8 m;
	uint8 n;
	uint8 o[16];
	uint32 p;
	uint32 q;
	uint32 ra;
	uint8* rb;
	if (sp->actable_offset[0]==0)
	{
		TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
		return(0);
	}
	sp->in_buffer_file_pos_log=0;
	for (m=0; m<sp->samples_per_pixel; m++)
	{
		if ((sp->actable_offset[m]!=0) && ((m==0) || (sp->actable_offset[m]!=sp->actable_offset[m-1])))
		{
			for (n=0; n<m-1; n++)
			{
				if (sp->actable_offset[m]==sp->actable_offset[n])
				{
					TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegAcTables tag value");
					return(0);
				}
			}
			TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET);
			p=TIFFReadFile(tif,o,16);
			if (p!=16)
				return(0);
			q=0;
			for (n=0; n<16; n++)
				q+=o[n];
			ra=sizeof(uint32)+21+q;
			rb=_TIFFmalloc(ra);
			if (rb==0)
			{
				TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
				return(0);
			}
			*(uint32*)rb=ra;
			rb[sizeof(uint32)]=255;
			rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
			rb[sizeof(uint32)+2]=((19+q)>>8);
			rb[sizeof(uint32)+3]=((19+q)&255);
			rb[sizeof(uint32)+4]=(16|m);
			for (n=0; n<16; n++)
				rb[sizeof(uint32)+5+n]=o[n];
			p=TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
			if (p!=q)
				return(0);
			sp->actable[m]=rb;
			sp->sos_tda[m]=(sp->sos_tda[m]|m);
		}
		else
			sp->sos_tda[m]=(sp->sos_tda[m]|(sp->sos_tda[m-1]&15));
	}
	return(1);
}

static int
OJPEGReadBufferFill(OJPEGState* sp)
{
	uint16 m;
	tsize_t n;
	/* TODO: double-check: when subsamplingcorrect is set, no call to TIFFErrorExt or TIFFWarningExt should be made
	 * in any other case, seek or read errors should be passed through */
	do
	{
		if (sp->in_buffer_file_togo!=0)
		{
			if (sp->in_buffer_file_pos_log==0)
			{
				TIFFSeekFile(sp->tif,sp->in_buffer_file_pos,SEEK_SET);
				sp->in_buffer_file_pos_log=1;
			}
			m=OJPEG_BUFFER;
			if (m>sp->in_buffer_file_togo)
				m=(uint16)sp->in_buffer_file_togo;
			n=TIFFReadFile(sp->tif,sp->in_buffer,(tsize_t)m);
			if (n==0)
				return(0);
			assert(n>0);
			assert(n<=OJPEG_BUFFER);
			assert(n<65536);
			assert((uint16)n<=sp->in_buffer_file_togo);
			m=(uint16)n;
			sp->in_buffer_togo=m;
			sp->in_buffer_cur=sp->in_buffer;
			sp->in_buffer_file_togo-=m;
			sp->in_buffer_file_pos+=m;
			break;
		}
		sp->in_buffer_file_pos_log=0;
		switch(sp->in_buffer_source)
		{
			case osibsNotSetYet:
				if (sp->jpeg_interchange_format!=0)
				{
					sp->in_buffer_file_pos=sp->jpeg_interchange_format;
					sp->in_buffer_file_togo=sp->jpeg_interchange_format_length;
				}
				sp->in_buffer_source=osibsJpegInterchangeFormat;
				break;
			case osibsJpegInterchangeFormat:
				sp->in_buffer_source=osibsStrile;
			case osibsStrile:
				if (sp->in_buffer_next_strile==sp->in_buffer_strile_count)  
					sp->in_buffer_source=osibsEof;
				else
				{
					sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile];  
					if (sp->in_buffer_file_pos!=0)
					{
						if (sp->in_buffer_file_pos>=sp->file_size)
							sp->in_buffer_file_pos=0;
						else
						{
							sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];  
							if (sp->in_buffer_file_togo==0)
								sp->in_buffer_file_pos=0;
							else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
								sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
						}
					}
					sp->in_buffer_next_strile++;
				}
				break;
			default:
				return(0);
		}
	} while (1);
	return(1);
}

static int
OJPEGReadByte(OJPEGState* sp, uint8* byte)
{
	if (sp->in_buffer_togo==0)
	{
		if (OJPEGReadBufferFill(sp)==0)
			return(0);
		assert(sp->in_buffer_togo>0);
	}
	*byte=*(sp->in_buffer_cur);
	sp->in_buffer_cur++;
	sp->in_buffer_togo--;
	return(1);
}

static int
OJPEGReadBytePeek(OJPEGState* sp, uint8* byte)
{
	if (sp->in_buffer_togo==0)
	{
		if (OJPEGReadBufferFill(sp)==0)
			return(0);
		assert(sp->in_buffer_togo>0);
	}
	*byte=*(sp->in_buffer_cur);
	return(1);
}

static void
OJPEGReadByteAdvance(OJPEGState* sp)
{
	assert(sp->in_buffer_togo>0);
	sp->in_buffer_cur++;
	sp->in_buffer_togo--;
}

static int
OJPEGReadWord(OJPEGState* sp, uint16* word)
{
	uint8 m;
	if (OJPEGReadByte(sp,&m)==0)
		return(0);
	*word=(m<<8);
	if (OJPEGReadByte(sp,&m)==0)
		return(0);
	*word|=m;
	return(1);
}

static int
OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem)
{
	uint16 mlen;
	uint8* mmem;
	uint16 n;
	assert(len>0);
	mlen=len;
	mmem=mem;
	do
	{
		if (sp->in_buffer_togo==0)
		{
			if (OJPEGReadBufferFill(sp)==0)
				return(0);
			assert(sp->in_buffer_togo>0);
		}
		n=mlen;
		if (n>sp->in_buffer_togo)
			n=sp->in_buffer_togo;
		_TIFFmemcpy(mmem,sp->in_buffer_cur,n);
		sp->in_buffer_cur+=n;
		sp->in_buffer_togo-=n;
		mlen-=n;
		mmem+=n;
	} while(mlen>0);
	return(1);
}

static void
OJPEGReadSkip(OJPEGState* sp, uint16 len)
{
	uint16 m;
	uint16 n;
	m=len;
	n=m;
	if (n>sp->in_buffer_togo)
		n=sp->in_buffer_togo;
	sp->in_buffer_cur+=n;
	sp->in_buffer_togo-=n;
	m-=n;
	if (m>0)
	{
		assert(sp->in_buffer_togo==0);
		n=m;
		if (n>sp->in_buffer_file_togo)
			n=sp->in_buffer_file_togo;
		sp->in_buffer_file_pos+=n;
		sp->in_buffer_file_togo-=n;
		sp->in_buffer_file_pos_log=0;
		/* we don't skip past jpeginterchangeformat/strile block...
		 * if that is asked from us, we're dealing with totally bazurk
		 * data anyway, and we've not seen this happening on any
		 * testfile, so we might as well likely cause some other
		 * meaningless error to be passed at some later time
		 */
	}
}

static int
OJPEGWriteStream(TIFF* tif, void** mem, uint32* len)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	*len=0;
	do
	{
		assert(sp->out_state<=ososEoi);
		switch(sp->out_state)
		{
			case ososSoi:
				OJPEGWriteStreamSoi(tif,mem,len);
				break;
			case ososQTable0:
				OJPEGWriteStreamQTable(tif,0,mem,len);
				break;
			case ososQTable1:
				OJPEGWriteStreamQTable(tif,1,mem,len);
				break;
			case ososQTable2:
				OJPEGWriteStreamQTable(tif,2,mem,len);
				break;
			case ososQTable3:
				OJPEGWriteStreamQTable(tif,3,mem,len);
				break;
			case ososDcTable0:
				OJPEGWriteStreamDcTable(tif,0,mem,len);
				break;
			case ososDcTable1:
				OJPEGWriteStreamDcTable(tif,1,mem,len);
				break;
			case ososDcTable2:
				OJPEGWriteStreamDcTable(tif,2,mem,len);
				break;
			case ososDcTable3:
				OJPEGWriteStreamDcTable(tif,3,mem,len);
				break;
			case ososAcTable0:
				OJPEGWriteStreamAcTable(tif,0,mem,len);
				break;
			case ososAcTable1:
				OJPEGWriteStreamAcTable(tif,1,mem,len);
				break;
			case ososAcTable2:
				OJPEGWriteStreamAcTable(tif,2,mem,len);
				break;
			case ososAcTable3:
				OJPEGWriteStreamAcTable(tif,3,mem,len);
				break;
			case ososDri:
				OJPEGWriteStreamDri(tif,mem,len);
				break;
			case ososSof:
				OJPEGWriteStreamSof(tif,mem,len);
				break;
			case ososSos:
				OJPEGWriteStreamSos(tif,mem,len);
				break;
			case ososCompressed:
				if (OJPEGWriteStreamCompressed(tif,mem,len)==0)
					return(0);
				break;
			case ososRst:
				OJPEGWriteStreamRst(tif,mem,len);
				break;
			case ososEoi:
				OJPEGWriteStreamEoi(tif,mem,len);
				break;
		}
	} while (*len==0);
	return(1);
}

static void
OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	assert(OJPEG_BUFFER>=2);
	sp->out_buffer[0]=255;
	sp->out_buffer[1]=JPEG_MARKER_SOI;
	*len=2;
	*mem=(void*)sp->out_buffer;
	sp->out_state++;
}

static void
OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	if (sp->qtable[table_index]!=0)
	{
		*mem=(void*)(sp->qtable[table_index]+sizeof(uint32));
		*len=*((uint32*)sp->qtable[table_index])-sizeof(uint32);
	}
	sp->out_state++;
}

static void
OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	if (sp->dctable[table_index]!=0)
	{
		*mem=(void*)(sp->dctable[table_index]+sizeof(uint32));
		*len=*((uint32*)sp->dctable[table_index])-sizeof(uint32);
	}
	sp->out_state++;
}

static void
OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	if (sp->actable[table_index]!=0)
	{
		*mem=(void*)(sp->actable[table_index]+sizeof(uint32));
		*len=*((uint32*)sp->actable[table_index])-sizeof(uint32);
	}
	sp->out_state++;
}

static void
OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	assert(OJPEG_BUFFER>=6);
	if (sp->restart_interval!=0)
	{
		sp->out_buffer[0]=255;
		sp->out_buffer[1]=JPEG_MARKER_DRI;
		sp->out_buffer[2]=0;
		sp->out_buffer[3]=4;
		sp->out_buffer[4]=(sp->restart_interval>>8);
		sp->out_buffer[5]=(sp->restart_interval&255);
		*len=6;
		*mem=(void*)sp->out_buffer;
	}
	sp->out_state++;
}

static void
OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8 m;
	assert(OJPEG_BUFFER>=2+8+sp->samples_per_pixel_per_plane*3);
	assert(255>=8+sp->samples_per_pixel_per_plane*3);
	sp->out_buffer[0]=255;
	sp->out_buffer[1]=sp->sof_marker_id;
	/* Lf */
	sp->out_buffer[2]=0;
	sp->out_buffer[3]=8+sp->samples_per_pixel_per_plane*3;
	/* P */
	sp->out_buffer[4]=8;
	/* Y */
	sp->out_buffer[5]=(sp->sof_y>>8);
	sp->out_buffer[6]=(sp->sof_y&255);
	/* X */
	sp->out_buffer[7]=(sp->sof_x>>8);
	sp->out_buffer[8]=(sp->sof_x&255);
	/* Nf */
	sp->out_buffer[9]=sp->samples_per_pixel_per_plane;
	for (m=0; m<sp->samples_per_pixel_per_plane; m++)
	{
		/* C */
		sp->out_buffer[10+m*3]=sp->sof_c[sp->plane_sample_offset+m];
		/* H and V */
		sp->out_buffer[10+m*3+1]=sp->sof_hv[sp->plane_sample_offset+m];
		/* Tq */
		sp->out_buffer[10+m*3+2]=sp->sof_tq[sp->plane_sample_offset+m];
	}
	*len=10+sp->samples_per_pixel_per_plane*3;
	*mem=(void*)sp->out_buffer;
	sp->out_state++;
}

static void
OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	uint8 m;
	assert(OJPEG_BUFFER>=2+6+sp->samples_per_pixel_per_plane*2);
	assert(255>=6+sp->samples_per_pixel_per_plane*2);
	sp->out_buffer[0]=255;
	sp->out_buffer[1]=JPEG_MARKER_SOS;
	/* Ls */
	sp->out_buffer[2]=0;
	sp->out_buffer[3]=6+sp->samples_per_pixel_per_plane*2;
	/* Ns */
	sp->out_buffer[4]=sp->samples_per_pixel_per_plane;
	for (m=0; m<sp->samples_per_pixel_per_plane; m++)
	{
		/* Cs */
		sp->out_buffer[5+m*2]=sp->sos_cs[sp->plane_sample_offset+m];
		/* Td and Ta */
		sp->out_buffer[5+m*2+1]=sp->sos_tda[sp->plane_sample_offset+m];
	}
	/* Ss */
	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2]=0;
	/* Se */
	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+1]=63;
	/* Ah and Al */
	sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+2]=0;
	*len=8+sp->samples_per_pixel_per_plane*2;
	*mem=(void*)sp->out_buffer;
	sp->out_state++;
}

static int
OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	if (sp->in_buffer_togo==0)
	{
		if (OJPEGReadBufferFill(sp)==0)
			return(0);
		assert(sp->in_buffer_togo>0);
	}
	*len=sp->in_buffer_togo;
	*mem=(void*)sp->in_buffer_cur;
	sp->in_buffer_togo=0;
	if (sp->in_buffer_file_togo==0)
	{
		switch(sp->in_buffer_source)
		{
			case osibsStrile:
				if (sp->in_buffer_next_strile<sp->in_buffer_strile_count)  
					sp->out_state=ososRst;
				else
					sp->out_state=ososEoi;
				break;
			case osibsEof:
				sp->out_state=ososEoi;
				break;
			default:
				break;
		}
	}
	return(1);
}

static void
OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	assert(OJPEG_BUFFER>=2);
	sp->out_buffer[0]=255;
	sp->out_buffer[1]=JPEG_MARKER_RST0+sp->restart_index;
	sp->restart_index++;
	if (sp->restart_index==8)
		sp->restart_index=0;
	*len=2;
	*mem=(void*)sp->out_buffer;
	sp->out_state=ososCompressed;
}

static void
OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	assert(OJPEG_BUFFER>=2);
	sp->out_buffer[0]=255;
	sp->out_buffer[1]=JPEG_MARKER_EOI;
	*len=2;
	*mem=(void*)sp->out_buffer;
}

#ifndef LIBJPEG_ENCAP_EXTERNAL
static int
jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
{
	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_create_decompress(cinfo),1));
}
#endif

#ifndef LIBJPEG_ENCAP_EXTERNAL
static int
jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image)
{
	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_header(cinfo,require_image),1));
}
#endif

#ifndef LIBJPEG_ENCAP_EXTERNAL
static int
jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
{
	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_start_decompress(cinfo),1));
}
#endif

#ifndef LIBJPEG_ENCAP_EXTERNAL
static int
jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines)
{
	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_scanlines(cinfo,scanlines,max_lines),1));
}
#endif

#ifndef LIBJPEG_ENCAP_EXTERNAL
static int
jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines)
{
	return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_raw_data(cinfo,data,max_lines),1));
}
#endif

#ifndef LIBJPEG_ENCAP_EXTERNAL
static void
jpeg_encap_unwind(TIFF* tif)
{
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	LONGJMP(sp->exit_jmpbuf,1);
}
#endif

static void
OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo)
{
	char buffer[JMSG_LENGTH_MAX];
	(*cinfo->err->format_message)(cinfo,buffer);
	TIFFWarningExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg",buffer);
}

static void
OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo)
{
	char buffer[JMSG_LENGTH_MAX];
	(*cinfo->err->format_message)(cinfo,buffer);
	TIFFErrorExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg",buffer);
	jpeg_encap_unwind((TIFF*)(cinfo->client_data));
}

static void
OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo)
{
	(void)cinfo;
}

static boolean
OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo)
{
	TIFF* tif=(TIFF*)cinfo->client_data;
	OJPEGState* sp=(OJPEGState*)tif->tif_data;
	void* mem=0;
	uint32 len=0;
	if (OJPEGWriteStream(tif,&mem,&len)==0)
	{
		TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Premature end of JPEG data");
		jpeg_encap_unwind(tif);
	}
	sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=len;
	sp->libjpeg_jpeg_source_mgr.next_input_byte=mem;
	return(1);
}

static void
OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes)
{
	TIFF* tif=(TIFF*)cinfo->client_data;
	(void)num_bytes;
	TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
	jpeg_encap_unwind(tif);
}

static boolean
OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired)
{
	TIFF* tif=(TIFF*)cinfo->client_data;
	(void)desired;
	TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
	jpeg_encap_unwind(tif);
	return(0);
}

static void
OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo)
{
	(void)cinfo;
}

#endif


