Blame libtiff/tif_jpeg.c

Packit 85355f
/* $Id: tif_jpeg.c,v 1.134 2017-10-17 19:04:47 erouault Exp $ */
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Copyright (c) 1994-1997 Sam Leffler
Packit 85355f
 * Copyright (c) 1994-1997 Silicon Graphics, Inc.
Packit 85355f
 *
Packit 85355f
 * Permission to use, copy, modify, distribute, and sell this software and 
Packit 85355f
 * its documentation for any purpose is hereby granted without fee, provided
Packit 85355f
 * that (i) the above copyright notices and this permission notice appear in
Packit 85355f
 * all copies of the software and related documentation, and (ii) the names of
Packit 85355f
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
Packit 85355f
 * publicity relating to the software without the specific, prior written
Packit 85355f
 * permission of Sam Leffler and Silicon Graphics.
Packit 85355f
 * 
Packit 85355f
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
Packit 85355f
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
Packit 85355f
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
Packit 85355f
 * 
Packit 85355f
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
Packit 85355f
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
Packit 85355f
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
Packit 85355f
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
Packit 85355f
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
Packit 85355f
 * OF THIS SOFTWARE.
Packit 85355f
 */
Packit 85355f
Packit 85355f
#define WIN32_LEAN_AND_MEAN
Packit 85355f
#define VC_EXTRALEAN
Packit 85355f
Packit 85355f
#include <stdlib.h>
Packit 85355f
Packit 85355f
#include "tiffiop.h"
Packit 85355f
#ifdef JPEG_SUPPORT
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * TIFF Library
Packit 85355f
 *
Packit 85355f
 * JPEG Compression support per TIFF Technical Note #2
Packit 85355f
 * (*not* per the original TIFF 6.0 spec).
Packit 85355f
 *
Packit 85355f
 * This file is simply an interface to the libjpeg library written by
Packit 85355f
 * the Independent JPEG Group.  You need release 5 or later of the IJG
Packit 85355f
 * code, which you can find on the Internet at ftp.uu.net:/graphics/jpeg/.
Packit 85355f
 *
Packit 85355f
 * Contributed by Tom Lane <tgl@sss.pgh.pa.us>.
Packit 85355f
 */
Packit 85355f
#include <setjmp.h>
Packit 85355f
Packit 85355f
int TIFFFillStrip(TIFF* tif, uint32 strip);
Packit 85355f
int TIFFFillTile(TIFF* tif, uint32 tile);
Packit 85355f
int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode );
Packit 85355f
int TIFFJPEGIsFullStripRequired_12(TIFF* tif);
Packit 85355f
Packit 85355f
/* We undefine FAR to avoid conflict with JPEG definition */
Packit 85355f
Packit 85355f
#ifdef FAR
Packit 85355f
#undef FAR
Packit 85355f
#endif
Packit 85355f
Packit 85355f
/*
Packit 85355f
  Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
Packit 85355f
  not defined.  Unfortunately, the MinGW and Borland compilers include
Packit 85355f
  a typedef for INT32, which causes a conflict.  MSVC does not include
Packit 85355f
  a conflicting typedef given the headers which are included.
Packit 85355f
*/
Packit 85355f
#if defined(__BORLANDC__) || defined(__MINGW32__)
Packit 85355f
# define XMD_H 1
Packit 85355f
#endif
Packit 85355f
Packit 85355f
/*
Packit 85355f
   The windows RPCNDR.H file defines boolean, but defines it with the
Packit 85355f
   unsigned char size.  You should compile JPEG library using appropriate
Packit 85355f
   definitions in jconfig.h header, but many users compile library in wrong
Packit 85355f
   way. That causes errors of the following type:
Packit 85355f
Packit 85355f
   "JPEGLib: JPEG parameter struct mismatch: library thinks size is 432,
Packit 85355f
   caller expects 464"
Packit 85355f
Packit 85355f
   For such users we wil fix the problem here. See install.doc file from
Packit 85355f
   the JPEG library distribution for details.
Packit 85355f
*/
Packit 85355f
Packit 85355f
/* Define "boolean" as unsigned char, not int, per Windows custom. */
Packit 85355f
#if defined(__WIN32__) && !defined(__MINGW32__)
Packit 85355f
# ifndef __RPCNDR_H__            /* don't conflict if rpcndr.h already read */
Packit 85355f
   typedef unsigned char boolean;
Packit 85355f
# endif
Packit 85355f
# define HAVE_BOOLEAN            /* prevent jmorecfg.h from redefining it */
Packit 85355f
#endif
Packit 85355f
Packit 85355f
#include "jpeglib.h"
Packit 85355f
#include "jerror.h"
Packit 85355f
Packit 85355f
/* 
Packit 85355f
 * Do we want to do special processing suitable for when JSAMPLE is a
Packit 85355f
 * 16bit value?  
Packit 85355f
 */
Packit 85355f
Packit 85355f
#if defined(JPEG_LIB_MK1)
Packit 85355f
#  define JPEG_LIB_MK1_OR_12BIT 1
Packit 85355f
#elif BITS_IN_JSAMPLE == 12
Packit 85355f
#  define JPEG_LIB_MK1_OR_12BIT 1
Packit 85355f
#endif
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * We are using width_in_blocks which is supposed to be private to
Packit 85355f
 * libjpeg. Unfortunately, the libjpeg delivered with Cygwin has
Packit 85355f
 * renamed this member to width_in_data_units.  Since the header has
Packit 85355f
 * also renamed a define, use that unique define name in order to
Packit 85355f
 * detect the problem header and adjust to suit.
Packit 85355f
 */
Packit 85355f
#if defined(D_MAX_DATA_UNITS_IN_MCU)
Packit 85355f
#define width_in_blocks width_in_data_units
Packit 85355f
#endif
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * On some machines it may be worthwhile to use _setjmp or sigsetjmp
Packit 85355f
 * in place of plain setjmp.  These macros will make it easier.
Packit 85355f
 */
Packit 85355f
#define SETJMP(jbuf)		setjmp(jbuf)
Packit 85355f
#define LONGJMP(jbuf,code)	longjmp(jbuf,code)
Packit 85355f
#define JMP_BUF			jmp_buf
Packit 85355f
Packit 85355f
typedef struct jpeg_destination_mgr jpeg_destination_mgr;
Packit 85355f
typedef struct jpeg_source_mgr jpeg_source_mgr;
Packit 85355f
typedef struct jpeg_error_mgr jpeg_error_mgr;
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * State block for each open TIFF file using
Packit 85355f
 * libjpeg to do JPEG compression/decompression.
Packit 85355f
 *
Packit 85355f
 * libjpeg's visible state is either a jpeg_compress_struct
Packit 85355f
 * or jpeg_decompress_struct depending on which way we
Packit 85355f
 * are going.  comm can be used to refer to the fields
Packit 85355f
 * which are common to both.
Packit 85355f
 *
Packit 85355f
 * NB: cinfo is required to be the first member of JPEGState,
Packit 85355f
 *     so we can safely cast JPEGState* -> jpeg_xxx_struct*
Packit 85355f
 *     and vice versa!
Packit 85355f
 */
Packit 85355f
typedef struct {
Packit 85355f
	union {
Packit 85355f
		struct jpeg_compress_struct c;
Packit 85355f
		struct jpeg_decompress_struct d;
Packit 85355f
		struct jpeg_common_struct comm;
Packit 85355f
	} cinfo;			/* NB: must be first */
Packit 85355f
	int             cinfo_initialized;
Packit 85355f
Packit 85355f
	jpeg_error_mgr	err;		/* libjpeg error manager */
Packit 85355f
	JMP_BUF		exit_jmpbuf;	/* for catching libjpeg failures */
Packit 85355f
	
Packit 85355f
	struct jpeg_progress_mgr progress;
Packit 85355f
	/*
Packit 85355f
	 * The following two members could be a union, but
Packit 85355f
	 * they're small enough that it's not worth the effort.
Packit 85355f
	 */
Packit 85355f
	jpeg_destination_mgr dest;	/* data dest for compression */
Packit 85355f
	jpeg_source_mgr	src;		/* data source for decompression */
Packit 85355f
					/* private state */
Packit 85355f
	TIFF*		tif;		/* back link needed by some code */
Packit 85355f
	uint16		photometric;	/* copy of PhotometricInterpretation */
Packit 85355f
	uint16		h_sampling;	/* luminance sampling factors */
Packit 85355f
	uint16		v_sampling;
Packit 85355f
	tmsize_t   	bytesperline;	/* decompressed bytes per scanline */
Packit 85355f
	/* pointers to intermediate buffers when processing downsampled data */
Packit 85355f
	JSAMPARRAY	ds_buffer[MAX_COMPONENTS];
Packit 85355f
	int		scancount;	/* number of "scanlines" accumulated */
Packit 85355f
	int		samplesperclump;
Packit 85355f
Packit 85355f
	TIFFVGetMethod	vgetparent;	/* super-class method */
Packit 85355f
	TIFFVSetMethod	vsetparent;	/* super-class method */
Packit 85355f
	TIFFPrintMethod printdir;	/* super-class method */
Packit 85355f
	TIFFStripMethod	defsparent;	/* super-class method */
Packit 85355f
	TIFFTileMethod	deftparent;	/* super-class method */
Packit 85355f
					/* pseudo-tag fields */
Packit 85355f
	void*		jpegtables;	/* JPEGTables tag value, or NULL */
Packit 85355f
	uint32		jpegtables_length; /* number of bytes in same */
Packit 85355f
	int		jpegquality;	/* Compression quality level */
Packit 85355f
	int		jpegcolormode;	/* Auto RGB<=>YCbCr convert? */
Packit 85355f
	int		jpegtablesmode;	/* What to put in JPEGTables */
Packit 85355f
Packit 85355f
        int             ycbcrsampling_fetched;
Packit 85355f
        int             max_allowed_scan_number;
Packit 85355f
} JPEGState;
Packit 85355f
Packit 85355f
#define	JState(tif)	((JPEGState*)(tif)->tif_data)
Packit 85355f
Packit 85355f
static int JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
Packit 85355f
static int JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
Packit 85355f
static int JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
Packit 85355f
static int JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
Packit 85355f
static int JPEGInitializeLibJPEG(TIFF * tif, int decode );
Packit 85355f
static int DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
Packit 85355f
Packit 85355f
#define	FIELD_JPEGTABLES	(FIELD_CODEC+0)
Packit 85355f
Packit 85355f
static const TIFFField jpegFields[] = {
Packit 85355f
    { TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL },
Packit 85355f
    { TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL },
Packit 85355f
    { TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL },
Packit 85355f
    { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL }
Packit 85355f
};
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * libjpeg interface layer.
Packit 85355f
 *
Packit 85355f
 * We use setjmp/longjmp to return control to libtiff
Packit 85355f
 * when a fatal error is encountered within the JPEG
Packit 85355f
 * library.  We also direct libjpeg error and warning
Packit 85355f
 * messages through the appropriate libtiff handlers.
Packit 85355f
 */
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Error handling routines (these replace corresponding
Packit 85355f
 * IJG routines from jerror.c).  These are used for both
Packit 85355f
 * compression and decompression.
Packit 85355f
 */
Packit 85355f
static void
Packit 85355f
TIFFjpeg_error_exit(j_common_ptr cinfo)
Packit 85355f
{
Packit 85355f
	JPEGState *sp = (JPEGState *) cinfo;	/* NB: cinfo assumed first */
Packit 85355f
	char buffer[JMSG_LENGTH_MAX];
Packit 85355f
Packit 85355f
	(*cinfo->err->format_message) (cinfo, buffer);
Packit 85355f
	TIFFErrorExt(sp->tif->tif_clientdata, "JPEGLib", "%s", buffer);		/* display the error message */
Packit 85355f
	jpeg_abort(cinfo);			/* clean up libjpeg state */
Packit 85355f
	LONGJMP(sp->exit_jmpbuf, 1);		/* return to libtiff caller */
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * This routine is invoked only for warning messages,
Packit 85355f
 * since error_exit does its own thing and trace_level
Packit 85355f
 * is never set > 0.
Packit 85355f
 */
Packit 85355f
static void
Packit 85355f
TIFFjpeg_output_message(j_common_ptr cinfo)
Packit 85355f
{
Packit 85355f
	char buffer[JMSG_LENGTH_MAX];
Packit 85355f
Packit 85355f
	(*cinfo->err->format_message) (cinfo, buffer);
Packit 85355f
	TIFFWarningExt(((JPEGState *) cinfo)->tif->tif_clientdata, "JPEGLib", "%s", buffer);
Packit 85355f
}
Packit 85355f
Packit 85355f
/* Avoid the risk of denial-of-service on crafted JPEGs with an insane */
Packit 85355f
/* number of scans. */
Packit 85355f
/* See http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */
Packit 85355f
static void
Packit 85355f
TIFFjpeg_progress_monitor(j_common_ptr cinfo)
Packit 85355f
{
Packit 85355f
    JPEGState *sp = (JPEGState *) cinfo;	/* NB: cinfo assumed first */
Packit 85355f
    if (cinfo->is_decompressor)
Packit 85355f
    {
Packit 85355f
        const int scan_no =
Packit 85355f
            ((j_decompress_ptr)cinfo)->input_scan_number;
Packit 85355f
        if (scan_no >= sp->max_allowed_scan_number)
Packit 85355f
        {
Packit 85355f
            TIFFErrorExt(((JPEGState *) cinfo)->tif->tif_clientdata, 
Packit 85355f
                     "TIFFjpeg_progress_monitor",
Packit 85355f
                     "Scan number %d exceeds maximum scans (%d). This limit "
Packit 85355f
                     "can be raised through the LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER "
Packit 85355f
                     "environment variable.",
Packit 85355f
                     scan_no, sp->max_allowed_scan_number);
Packit 85355f
Packit 85355f
            jpeg_abort(cinfo);			/* clean up libjpeg state */
Packit 85355f
            LONGJMP(sp->exit_jmpbuf, 1);		/* return to libtiff caller */
Packit 85355f
        }
Packit 85355f
    }
Packit 85355f
}
Packit 85355f
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Interface routines.  This layer of routines exists
Packit 85355f
 * primarily to limit side-effects from using setjmp.
Packit 85355f
 * Also, normal/error returns are converted into return
Packit 85355f
 * values per libtiff practice.
Packit 85355f
 */
Packit 85355f
#define	CALLJPEG(sp, fail, op)	(SETJMP((sp)->exit_jmpbuf) ? (fail) : (op))
Packit 85355f
#define	CALLVJPEG(sp, op)	CALLJPEG(sp, 0, ((op),1))
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_create_compress(JPEGState* sp)
Packit 85355f
{
Packit 85355f
	/* initialize JPEG error handling */
Packit 85355f
	sp->cinfo.c.err = jpeg_std_error(&sp->err);
Packit 85355f
	sp->err.error_exit = TIFFjpeg_error_exit;
Packit 85355f
	sp->err.output_message = TIFFjpeg_output_message;
Packit 85355f
Packit 85355f
	/* set client_data to avoid UMR warning from tools like Purify */
Packit 85355f
	sp->cinfo.c.client_data = NULL;
Packit 85355f
Packit 85355f
	return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_create_decompress(JPEGState* sp)
Packit 85355f
{
Packit 85355f
	/* initialize JPEG error handling */
Packit 85355f
	sp->cinfo.d.err = jpeg_std_error(&sp->err);
Packit 85355f
	sp->err.error_exit = TIFFjpeg_error_exit;
Packit 85355f
	sp->err.output_message = TIFFjpeg_output_message;
Packit 85355f
Packit 85355f
	/* set client_data to avoid UMR warning from tools like Purify */
Packit 85355f
	sp->cinfo.d.client_data = NULL;
Packit 85355f
Packit 85355f
	return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_set_defaults(JPEGState* sp)
Packit 85355f
{
Packit 85355f
	return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_set_colorspace(JPEGState* sp, J_COLOR_SPACE colorspace)
Packit 85355f
{
Packit 85355f
	return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_set_quality(JPEGState* sp, int quality, boolean force_baseline)
Packit 85355f
{
Packit 85355f
	return CALLVJPEG(sp,
Packit 85355f
	    jpeg_set_quality(&sp->cinfo.c, quality, force_baseline));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_suppress_tables(JPEGState* sp, boolean suppress)
Packit 85355f
{
Packit 85355f
	return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_start_compress(JPEGState* sp, boolean write_all_tables)
Packit 85355f
{
Packit 85355f
	return CALLVJPEG(sp,
Packit 85355f
	    jpeg_start_compress(&sp->cinfo.c, write_all_tables));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_write_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int num_lines)
Packit 85355f
{
Packit 85355f
	return CALLJPEG(sp, -1, (int) jpeg_write_scanlines(&sp->cinfo.c,
Packit 85355f
	    scanlines, (JDIMENSION) num_lines));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_write_raw_data(JPEGState* sp, JSAMPIMAGE data, int num_lines)
Packit 85355f
{
Packit 85355f
	return CALLJPEG(sp, -1, (int) jpeg_write_raw_data(&sp->cinfo.c,
Packit 85355f
	    data, (JDIMENSION) num_lines));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_finish_compress(JPEGState* sp)
Packit 85355f
{
Packit 85355f
	return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_write_tables(JPEGState* sp)
Packit 85355f
{
Packit 85355f
	return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_read_header(JPEGState* sp, boolean require_image)
Packit 85355f
{
Packit 85355f
	return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_has_multiple_scans(JPEGState* sp)
Packit 85355f
{
Packit 85355f
	return CALLJPEG(sp, 0, jpeg_has_multiple_scans(&sp->cinfo.d));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_start_decompress(JPEGState* sp)
Packit 85355f
{
Packit 85355f
        const char* sz_max_allowed_scan_number;
Packit 85355f
        /* progress monitor */
Packit 85355f
        sp->cinfo.d.progress = &sp->progress;
Packit 85355f
        sp->progress.progress_monitor = TIFFjpeg_progress_monitor;
Packit 85355f
        sp->max_allowed_scan_number = 100;
Packit 85355f
        sz_max_allowed_scan_number = getenv("LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER");
Packit 85355f
        if( sz_max_allowed_scan_number )
Packit 85355f
            sp->max_allowed_scan_number = atoi(sz_max_allowed_scan_number);
Packit 85355f
Packit 85355f
	return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_read_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int max_lines)
Packit 85355f
{
Packit 85355f
	return CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d,
Packit 85355f
	    scanlines, (JDIMENSION) max_lines));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_read_raw_data(JPEGState* sp, JSAMPIMAGE data, int max_lines)
Packit 85355f
{
Packit 85355f
	return CALLJPEG(sp, -1, (int) jpeg_read_raw_data(&sp->cinfo.d,
Packit 85355f
	    data, (JDIMENSION) max_lines));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_finish_decompress(JPEGState* sp)
Packit 85355f
{
Packit 85355f
	return CALLJPEG(sp, -1, (int) jpeg_finish_decompress(&sp->cinfo.d));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_abort(JPEGState* sp)
Packit 85355f
{
Packit 85355f
	return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm));
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_destroy(JPEGState* sp)
Packit 85355f
{
Packit 85355f
	return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm));
Packit 85355f
}
Packit 85355f
Packit 85355f
static JSAMPARRAY
Packit 85355f
TIFFjpeg_alloc_sarray(JPEGState* sp, int pool_id,
Packit 85355f
		      JDIMENSION samplesperrow, JDIMENSION numrows)
Packit 85355f
{
Packit 85355f
	return CALLJPEG(sp, (JSAMPARRAY) NULL,
Packit 85355f
	    (*sp->cinfo.comm.mem->alloc_sarray)
Packit 85355f
		(&sp->cinfo.comm, pool_id, samplesperrow, numrows));
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * JPEG library destination data manager.
Packit 85355f
 * These routines direct compressed data from libjpeg into the
Packit 85355f
 * libtiff output buffer.
Packit 85355f
 */
Packit 85355f
Packit 85355f
static void
Packit 85355f
std_init_destination(j_compress_ptr cinfo)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = (JPEGState*) cinfo;
Packit 85355f
	TIFF* tif = sp->tif;
Packit 85355f
Packit 85355f
	sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;
Packit 85355f
	sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;
Packit 85355f
}
Packit 85355f
Packit 85355f
static boolean
Packit 85355f
std_empty_output_buffer(j_compress_ptr cinfo)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = (JPEGState*) cinfo;
Packit 85355f
	TIFF* tif = sp->tif;
Packit 85355f
Packit 85355f
	/* the entire buffer has been filled */
Packit 85355f
	tif->tif_rawcc = tif->tif_rawdatasize;
Packit 85355f
Packit 85355f
#ifdef IPPJ_HUFF
Packit 85355f
       /*
Packit 85355f
        * The Intel IPP performance library does not necessarily fill up
Packit 85355f
        * the whole output buffer on each pass, so only dump out the parts
Packit 85355f
        * that have been filled.
Packit 85355f
        *   http://trac.osgeo.org/gdal/wiki/JpegIPP
Packit 85355f
        */
Packit 85355f
       if ( sp->dest.free_in_buffer >= 0 ) {
Packit 85355f
               tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer;
Packit 85355f
       }
Packit 85355f
#endif
Packit 85355f
Packit 85355f
	TIFFFlushData1(tif);
Packit 85355f
	sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;
Packit 85355f
	sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;
Packit 85355f
Packit 85355f
	return (TRUE);
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
std_term_destination(j_compress_ptr cinfo)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = (JPEGState*) cinfo;
Packit 85355f
	TIFF* tif = sp->tif;
Packit 85355f
Packit 85355f
	tif->tif_rawcp = (uint8*) sp->dest.next_output_byte;
Packit 85355f
	tif->tif_rawcc =
Packit 85355f
	    tif->tif_rawdatasize - (tmsize_t) sp->dest.free_in_buffer;
Packit 85355f
	/* NB: libtiff does the final buffer flush */
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
TIFFjpeg_data_dest(JPEGState* sp, TIFF* tif)
Packit 85355f
{
Packit 85355f
	(void) tif;
Packit 85355f
	sp->cinfo.c.dest = &sp->dest;
Packit 85355f
	sp->dest.init_destination = std_init_destination;
Packit 85355f
	sp->dest.empty_output_buffer = std_empty_output_buffer;
Packit 85355f
	sp->dest.term_destination = std_term_destination;
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Alternate destination manager for outputting to JPEGTables field.
Packit 85355f
 */
Packit 85355f
Packit 85355f
static void
Packit 85355f
tables_init_destination(j_compress_ptr cinfo)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = (JPEGState*) cinfo;
Packit 85355f
Packit 85355f
	/* while building, jpegtables_length is allocated buffer size */
Packit 85355f
	sp->dest.next_output_byte = (JOCTET*) sp->jpegtables;
Packit 85355f
	sp->dest.free_in_buffer = (size_t) sp->jpegtables_length;
Packit 85355f
}
Packit 85355f
Packit 85355f
static boolean
Packit 85355f
tables_empty_output_buffer(j_compress_ptr cinfo)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = (JPEGState*) cinfo;
Packit 85355f
	void* newbuf;
Packit 85355f
Packit 85355f
	/* the entire buffer has been filled; enlarge it by 1000 bytes */
Packit 85355f
	newbuf = _TIFFrealloc((void*) sp->jpegtables,
Packit 85355f
			      (tmsize_t) (sp->jpegtables_length + 1000));
Packit 85355f
	if (newbuf == NULL)
Packit 85355f
		ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100);
Packit 85355f
	sp->dest.next_output_byte = (JOCTET*) newbuf + sp->jpegtables_length;
Packit 85355f
	sp->dest.free_in_buffer = (size_t) 1000;
Packit 85355f
	sp->jpegtables = newbuf;
Packit 85355f
	sp->jpegtables_length += 1000;
Packit 85355f
	return (TRUE);
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
tables_term_destination(j_compress_ptr cinfo)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = (JPEGState*) cinfo;
Packit 85355f
Packit 85355f
	/* set tables length to number of bytes actually emitted */
Packit 85355f
	sp->jpegtables_length -= (uint32) sp->dest.free_in_buffer;
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif)
Packit 85355f
{
Packit 85355f
	(void) tif;
Packit 85355f
	/*
Packit 85355f
	 * Allocate a working buffer for building tables.
Packit 85355f
	 * Initial size is 1000 bytes, which is usually adequate.
Packit 85355f
	 */
Packit 85355f
	if (sp->jpegtables)
Packit 85355f
		_TIFFfree(sp->jpegtables);
Packit 85355f
	sp->jpegtables_length = 1000;
Packit 85355f
	sp->jpegtables = (void*) _TIFFmalloc((tmsize_t) sp->jpegtables_length);
Packit 85355f
	if (sp->jpegtables == NULL) {
Packit 85355f
		sp->jpegtables_length = 0;
Packit 85355f
		TIFFErrorExt(sp->tif->tif_clientdata, "TIFFjpeg_tables_dest", "No space for JPEGTables");
Packit 85355f
		return (0);
Packit 85355f
	}
Packit 85355f
	sp->cinfo.c.dest = &sp->dest;
Packit 85355f
	sp->dest.init_destination = tables_init_destination;
Packit 85355f
	sp->dest.empty_output_buffer = tables_empty_output_buffer;
Packit 85355f
	sp->dest.term_destination = tables_term_destination;
Packit 85355f
	return (1);
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * JPEG library source data manager.
Packit 85355f
 * These routines supply compressed data to libjpeg.
Packit 85355f
 */
Packit 85355f
Packit 85355f
static void
Packit 85355f
std_init_source(j_decompress_ptr cinfo)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = (JPEGState*) cinfo;
Packit 85355f
	TIFF* tif = sp->tif;
Packit 85355f
Packit 85355f
	sp->src.next_input_byte = (const JOCTET*) tif->tif_rawdata;
Packit 85355f
	sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;
Packit 85355f
}
Packit 85355f
Packit 85355f
static boolean
Packit 85355f
std_fill_input_buffer(j_decompress_ptr cinfo)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = (JPEGState* ) cinfo;
Packit 85355f
	static const JOCTET dummy_EOI[2] = { 0xFF, JPEG_EOI };
Packit 85355f
Packit 85355f
#ifdef IPPJ_HUFF
Packit 85355f
        /*
Packit 85355f
         * The Intel IPP performance library does not necessarily read the whole
Packit 85355f
         * input buffer in one pass, so it is possible to get here with data
Packit 85355f
         * yet to read. 
Packit 85355f
         * 
Packit 85355f
         * We just return without doing anything, until the entire buffer has
Packit 85355f
         * been read.  
Packit 85355f
         * http://trac.osgeo.org/gdal/wiki/JpegIPP
Packit 85355f
         */
Packit 85355f
        if( sp->src.bytes_in_buffer > 0 ) {
Packit 85355f
            return (TRUE);
Packit 85355f
        }
Packit 85355f
#endif
Packit 85355f
Packit 85355f
	/*
Packit 85355f
         * Normally the whole strip/tile is read and so we don't need to do
Packit 85355f
         * a fill.  In the case of CHUNKY_STRIP_READ_SUPPORT we might not have
Packit 85355f
         * all the data, but the rawdata is refreshed between scanlines and
Packit 85355f
         * we push this into the io machinery in JPEGDecode(). 	 
Packit 85355f
         * http://trac.osgeo.org/gdal/ticket/3894
Packit 85355f
	 */
Packit 85355f
        
Packit 85355f
	WARNMS(cinfo, JWRN_JPEG_EOF);
Packit 85355f
	/* insert a fake EOI marker */
Packit 85355f
	sp->src.next_input_byte = dummy_EOI;
Packit 85355f
	sp->src.bytes_in_buffer = 2;
Packit 85355f
	return (TRUE);
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
std_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = (JPEGState*) cinfo;
Packit 85355f
Packit 85355f
	if (num_bytes > 0) {
Packit 85355f
		if ((size_t)num_bytes > sp->src.bytes_in_buffer) {
Packit 85355f
			/* oops, buffer overrun */
Packit 85355f
			(void) std_fill_input_buffer(cinfo);
Packit 85355f
		} else {
Packit 85355f
			sp->src.next_input_byte += (size_t) num_bytes;
Packit 85355f
			sp->src.bytes_in_buffer -= (size_t) num_bytes;
Packit 85355f
		}
Packit 85355f
	}
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
std_term_source(j_decompress_ptr cinfo)
Packit 85355f
{
Packit 85355f
	/* No work necessary here */
Packit 85355f
	(void) cinfo;
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
TIFFjpeg_data_src(JPEGState* sp)
Packit 85355f
{
Packit 85355f
	sp->cinfo.d.src = &sp->src;
Packit 85355f
	sp->src.init_source = std_init_source;
Packit 85355f
	sp->src.fill_input_buffer = std_fill_input_buffer;
Packit 85355f
	sp->src.skip_input_data = std_skip_input_data;
Packit 85355f
	sp->src.resync_to_restart = jpeg_resync_to_restart;
Packit 85355f
	sp->src.term_source = std_term_source;
Packit 85355f
	sp->src.bytes_in_buffer = 0;		/* for safety */
Packit 85355f
	sp->src.next_input_byte = NULL;
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Alternate source manager for reading from JPEGTables.
Packit 85355f
 * We can share all the code except for the init routine.
Packit 85355f
 */
Packit 85355f
Packit 85355f
static void
Packit 85355f
tables_init_source(j_decompress_ptr cinfo)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = (JPEGState*) cinfo;
Packit 85355f
Packit 85355f
	sp->src.next_input_byte = (const JOCTET*) sp->jpegtables;
Packit 85355f
	sp->src.bytes_in_buffer = (size_t) sp->jpegtables_length;
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
TIFFjpeg_tables_src(JPEGState* sp)
Packit 85355f
{
Packit 85355f
	TIFFjpeg_data_src(sp);
Packit 85355f
	sp->src.init_source = tables_init_source;
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Allocate downsampled-data buffers needed for downsampled I/O.
Packit 85355f
 * We use values computed in jpeg_start_compress or jpeg_start_decompress.
Packit 85355f
 * We use libjpeg's allocator so that buffers will be released automatically
Packit 85355f
 * when done with strip/tile.
Packit 85355f
 * This is also a handy place to compute samplesperclump, bytesperline.
Packit 85355f
 */
Packit 85355f
static int
Packit 85355f
alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info,
Packit 85355f
			  int num_components)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = JState(tif);
Packit 85355f
	int ci;
Packit 85355f
	jpeg_component_info* compptr;
Packit 85355f
	JSAMPARRAY buf;
Packit 85355f
	int samples_per_clump = 0;
Packit 85355f
Packit 85355f
	for (ci = 0, compptr = comp_info; ci < num_components;
Packit 85355f
	     ci++, compptr++) {
Packit 85355f
		samples_per_clump += compptr->h_samp_factor *
Packit 85355f
			compptr->v_samp_factor;
Packit 85355f
		buf = TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE,
Packit 85355f
				compptr->width_in_blocks * DCTSIZE,
Packit 85355f
				(JDIMENSION) (compptr->v_samp_factor*DCTSIZE));
Packit 85355f
		if (buf == NULL)
Packit 85355f
			return (0);
Packit 85355f
		sp->ds_buffer[ci] = buf;
Packit 85355f
	}
Packit 85355f
	sp->samplesperclump = samples_per_clump;
Packit 85355f
	return (1);
Packit 85355f
}
Packit 85355f
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * JPEG Decoding.
Packit 85355f
 */
Packit 85355f
Packit 85355f
#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
Packit 85355f
Packit 85355f
#define JPEG_MARKER_SOF0 0xC0
Packit 85355f
#define JPEG_MARKER_SOF1 0xC1
Packit 85355f
#define JPEG_MARKER_SOF2 0xC2
Packit 85355f
#define JPEG_MARKER_SOF9 0xC9
Packit 85355f
#define JPEG_MARKER_SOF10 0xCA
Packit 85355f
#define JPEG_MARKER_DHT 0xC4
Packit 85355f
#define JPEG_MARKER_SOI 0xD8
Packit 85355f
#define JPEG_MARKER_SOS 0xDA
Packit 85355f
#define JPEG_MARKER_DQT 0xDB
Packit 85355f
#define JPEG_MARKER_DRI 0xDD
Packit 85355f
#define JPEG_MARKER_APP0 0xE0
Packit 85355f
#define JPEG_MARKER_COM 0xFE
Packit 85355f
struct JPEGFixupTagsSubsamplingData
Packit 85355f
{
Packit 85355f
	TIFF* tif;
Packit 85355f
	void* buffer;
Packit 85355f
	uint32 buffersize;
Packit 85355f
	uint8* buffercurrentbyte;
Packit 85355f
	uint32 bufferbytesleft;
Packit 85355f
	uint64 fileoffset;
Packit 85355f
	uint64 filebytesleft;
Packit 85355f
	uint8 filepositioned;
Packit 85355f
};
Packit 85355f
static void JPEGFixupTagsSubsampling(TIFF* tif);
Packit 85355f
static int JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data);
Packit 85355f
static int JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result);
Packit 85355f
static int JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result);
Packit 85355f
static void JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength);
Packit 85355f
Packit 85355f
#endif
Packit 85355f
Packit 85355f
static int
Packit 85355f
JPEGFixupTags(TIFF* tif)
Packit 85355f
{
Packit 85355f
#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
Packit 85355f
        JPEGState* sp = JState(tif);
Packit 85355f
	if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&&
Packit 85355f
	    (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&&
Packit 85355f
	    (tif->tif_dir.td_samplesperpixel==3) &&
Packit 85355f
            !sp->ycbcrsampling_fetched)
Packit 85355f
		JPEGFixupTagsSubsampling(tif);
Packit 85355f
#endif
Packit 85355f
        
Packit 85355f
	return(1);
Packit 85355f
}
Packit 85355f
Packit 85355f
#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
Packit 85355f
Packit 85355f
static void
Packit 85355f
JPEGFixupTagsSubsampling(TIFF* tif)
Packit 85355f
{
Packit 85355f
	/*
Packit 85355f
	 * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in
Packit 85355f
	 * the TIFF tags, but still use non-default (2,2) values within the jpeg
Packit 85355f
	 * data stream itself.  In order for TIFF applications to work properly
Packit 85355f
	 * - for instance to get the strip buffer size right - it is imperative
Packit 85355f
	 * that the subsampling be available before we start reading the image
Packit 85355f
	 * data normally.  This function will attempt to analyze the first strip in
Packit 85355f
	 * order to get the sampling values from the jpeg data stream.
Packit 85355f
	 *
Packit 85355f
	 * Note that JPEGPreDeocode() will produce a fairly loud warning when the
Packit 85355f
	 * discovered sampling does not match the default sampling (2,2) or whatever
Packit 85355f
	 * was actually in the tiff tags.
Packit 85355f
	 *
Packit 85355f
	 * See the bug in bugzilla for details:
Packit 85355f
	 *
Packit 85355f
	 * http://bugzilla.remotesensing.org/show_bug.cgi?id=168
Packit 85355f
	 *
Packit 85355f
	 * Frank Warmerdam, July 2002
Packit 85355f
	 * Joris Van Damme, May 2007
Packit 85355f
	 */
Packit 85355f
	static const char module[] = "JPEGFixupTagsSubsampling";
Packit 85355f
	struct JPEGFixupTagsSubsamplingData m;
Packit 85355f
Packit 85355f
        _TIFFFillStriles( tif );
Packit 85355f
        
Packit 85355f
        if( tif->tif_dir.td_stripbytecount == NULL
Packit 85355f
            || tif->tif_dir.td_stripoffset == NULL
Packit 85355f
            || tif->tif_dir.td_stripbytecount[0] == 0 )
Packit 85355f
        {
Packit 85355f
            /* Do not even try to check if the first strip/tile does not
Packit 85355f
               yet exist, as occurs when GDAL has created a new NULL file
Packit 85355f
               for instance. */
Packit 85355f
            return;
Packit 85355f
        }
Packit 85355f
Packit 85355f
	m.tif=tif;
Packit 85355f
	m.buffersize=2048;
Packit 85355f
	m.buffer=_TIFFmalloc(m.buffersize);
Packit 85355f
	if (m.buffer==NULL)
Packit 85355f
	{
Packit 85355f
		TIFFWarningExt(tif->tif_clientdata,module,
Packit 85355f
		    "Unable to allocate memory for auto-correcting of subsampling values; auto-correcting skipped");
Packit 85355f
		return;
Packit 85355f
	}
Packit 85355f
	m.buffercurrentbyte=NULL;
Packit 85355f
	m.bufferbytesleft=0;
Packit 85355f
	m.fileoffset=tif->tif_dir.td_stripoffset[0];
Packit 85355f
	m.filepositioned=0;
Packit 85355f
	m.filebytesleft=tif->tif_dir.td_stripbytecount[0];
Packit 85355f
	if (!JPEGFixupTagsSubsamplingSec(&m))
Packit 85355f
		TIFFWarningExt(tif->tif_clientdata,module,
Packit 85355f
		    "Unable to auto-correct subsampling values, likely corrupt JPEG compressed data in first strip/tile; auto-correcting skipped");
Packit 85355f
	_TIFFfree(m.buffer);
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data)
Packit 85355f
{
Packit 85355f
	static const char module[] = "JPEGFixupTagsSubsamplingSec";
Packit 85355f
	uint8 m;
Packit 85355f
	while (1)
Packit 85355f
	{
Packit 85355f
		while (1)
Packit 85355f
		{
Packit 85355f
			if (!JPEGFixupTagsSubsamplingReadByte(data,&m))
Packit 85355f
				return(0);
Packit 85355f
			if (m==255)
Packit 85355f
				break;
Packit 85355f
		}
Packit 85355f
		while (1)
Packit 85355f
		{
Packit 85355f
			if (!JPEGFixupTagsSubsamplingReadByte(data,&m))
Packit 85355f
				return(0);
Packit 85355f
			if (m!=255)
Packit 85355f
				break;
Packit 85355f
		}
Packit 85355f
		switch (m)
Packit 85355f
		{
Packit 85355f
			case JPEG_MARKER_SOI:
Packit 85355f
				/* this type of marker has no data and should be skipped */
Packit 85355f
				break;
Packit 85355f
			case JPEG_MARKER_COM:
Packit 85355f
			case JPEG_MARKER_APP0:
Packit 85355f
			case JPEG_MARKER_APP0+1:
Packit 85355f
			case JPEG_MARKER_APP0+2:
Packit 85355f
			case JPEG_MARKER_APP0+3:
Packit 85355f
			case JPEG_MARKER_APP0+4:
Packit 85355f
			case JPEG_MARKER_APP0+5:
Packit 85355f
			case JPEG_MARKER_APP0+6:
Packit 85355f
			case JPEG_MARKER_APP0+7:
Packit 85355f
			case JPEG_MARKER_APP0+8:
Packit 85355f
			case JPEG_MARKER_APP0+9:
Packit 85355f
			case JPEG_MARKER_APP0+10:
Packit 85355f
			case JPEG_MARKER_APP0+11:
Packit 85355f
			case JPEG_MARKER_APP0+12:
Packit 85355f
			case JPEG_MARKER_APP0+13:
Packit 85355f
			case JPEG_MARKER_APP0+14:
Packit 85355f
			case JPEG_MARKER_APP0+15:
Packit 85355f
			case JPEG_MARKER_DQT:
Packit 85355f
			case JPEG_MARKER_SOS:
Packit 85355f
			case JPEG_MARKER_DHT:
Packit 85355f
			case JPEG_MARKER_DRI:
Packit 85355f
				/* this type of marker has data, but it has no use to us and should be skipped */
Packit 85355f
				{
Packit 85355f
					uint16 n;
Packit 85355f
					if (!JPEGFixupTagsSubsamplingReadWord(data,&n))
Packit 85355f
						return(0);
Packit 85355f
					if (n<2)
Packit 85355f
						return(0);
Packit 85355f
					n-=2;
Packit 85355f
					if (n>0)
Packit 85355f
						JPEGFixupTagsSubsamplingSkip(data,n);
Packit 85355f
				}
Packit 85355f
				break;
Packit 85355f
			case JPEG_MARKER_SOF0: /* Baseline sequential Huffman */
Packit 85355f
			case JPEG_MARKER_SOF1: /* Extended sequential Huffman */
Packit 85355f
			case JPEG_MARKER_SOF2: /* Progressive Huffman: normally not allowed by TechNote, but that doesn't hurt supporting it */
Packit 85355f
			case JPEG_MARKER_SOF9: /* Extended sequential arithmetic */
Packit 85355f
			case JPEG_MARKER_SOF10: /* Progressive arithmetic: normally not allowed by TechNote, but that doesn't hurt supporting it */
Packit 85355f
				/* this marker contains the subsampling factors we're scanning for */
Packit 85355f
				{
Packit 85355f
					uint16 n;
Packit 85355f
					uint16 o;
Packit 85355f
					uint8 p;
Packit 85355f
					uint8 ph,pv;
Packit 85355f
					if (!JPEGFixupTagsSubsamplingReadWord(data,&n))
Packit 85355f
						return(0);
Packit 85355f
					if (n!=8+data->tif->tif_dir.td_samplesperpixel*3)
Packit 85355f
						return(0);
Packit 85355f
					JPEGFixupTagsSubsamplingSkip(data,7);
Packit 85355f
					if (!JPEGFixupTagsSubsamplingReadByte(data,&p))
Packit 85355f
						return(0);
Packit 85355f
					ph=(p>>4);
Packit 85355f
					pv=(p&15);
Packit 85355f
					JPEGFixupTagsSubsamplingSkip(data,1);
Packit 85355f
					for (o=1; o<data->tif->tif_dir.td_samplesperpixel; o++)
Packit 85355f
					{
Packit 85355f
						JPEGFixupTagsSubsamplingSkip(data,1);
Packit 85355f
						if (!JPEGFixupTagsSubsamplingReadByte(data,&p))
Packit 85355f
							return(0);
Packit 85355f
						if (p!=0x11)
Packit 85355f
						{
Packit 85355f
							TIFFWarningExt(data->tif->tif_clientdata,module,
Packit 85355f
							    "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed");
Packit 85355f
							return(1);
Packit 85355f
						}
Packit 85355f
						JPEGFixupTagsSubsamplingSkip(data,1);
Packit 85355f
					}
Packit 85355f
					if (((ph!=1)&&(ph!=2)&&(ph!=4))||((pv!=1)&&(pv!=2)&&(pv!=4)))
Packit 85355f
					{
Packit 85355f
						TIFFWarningExt(data->tif->tif_clientdata,module,
Packit 85355f
						    "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed");
Packit 85355f
						return(1);
Packit 85355f
					}
Packit 85355f
					if ((ph!=data->tif->tif_dir.td_ycbcrsubsampling[0])||(pv!=data->tif->tif_dir.td_ycbcrsubsampling[1]))
Packit 85355f
					{
Packit 85355f
						TIFFWarningExt(data->tif->tif_clientdata,module,
Packit 85355f
						    "Auto-corrected former TIFF subsampling values [%d,%d] to match subsampling values inside JPEG compressed data [%d,%d]",
Packit 85355f
						    (int)data->tif->tif_dir.td_ycbcrsubsampling[0],
Packit 85355f
						    (int)data->tif->tif_dir.td_ycbcrsubsampling[1],
Packit 85355f
						    (int)ph,(int)pv);
Packit 85355f
						data->tif->tif_dir.td_ycbcrsubsampling[0]=ph;
Packit 85355f
						data->tif->tif_dir.td_ycbcrsubsampling[1]=pv;
Packit 85355f
					}
Packit 85355f
				}
Packit 85355f
				return(1);
Packit 85355f
			default:
Packit 85355f
				return(0);
Packit 85355f
		}
Packit 85355f
	}
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result)
Packit 85355f
{
Packit 85355f
	if (data->bufferbytesleft==0)
Packit 85355f
	{
Packit 85355f
		uint32 m;
Packit 85355f
		if (data->filebytesleft==0)
Packit 85355f
			return(0);
Packit 85355f
		if (!data->filepositioned)
Packit 85355f
		{
Packit 85355f
			TIFFSeekFile(data->tif,data->fileoffset,SEEK_SET);
Packit 85355f
			data->filepositioned=1;
Packit 85355f
		}
Packit 85355f
		m=data->buffersize;
Packit 85355f
		if ((uint64)m>data->filebytesleft)
Packit 85355f
			m=(uint32)data->filebytesleft;
Packit 85355f
		assert(m<0x80000000UL);
Packit 85355f
		if (TIFFReadFile(data->tif,data->buffer,(tmsize_t)m)!=(tmsize_t)m)
Packit 85355f
			return(0);
Packit 85355f
		data->buffercurrentbyte=data->buffer;
Packit 85355f
		data->bufferbytesleft=m;
Packit 85355f
		data->fileoffset+=m;
Packit 85355f
		data->filebytesleft-=m;
Packit 85355f
	}
Packit 85355f
	*result=*data->buffercurrentbyte;
Packit 85355f
	data->buffercurrentbyte++;
Packit 85355f
	data->bufferbytesleft--;
Packit 85355f
	return(1);
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result)
Packit 85355f
{
Packit 85355f
	uint8 ma;
Packit 85355f
	uint8 mb;
Packit 85355f
	if (!JPEGFixupTagsSubsamplingReadByte(data,&ma))
Packit 85355f
		return(0);
Packit 85355f
	if (!JPEGFixupTagsSubsamplingReadByte(data,&mb))
Packit 85355f
		return(0);
Packit 85355f
	*result=(ma<<8)|mb;
Packit 85355f
	return(1);
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength)
Packit 85355f
{
Packit 85355f
	if ((uint32)skiplength<=data->bufferbytesleft)
Packit 85355f
	{
Packit 85355f
		data->buffercurrentbyte+=skiplength;
Packit 85355f
		data->bufferbytesleft-=skiplength;
Packit 85355f
	}
Packit 85355f
	else
Packit 85355f
	{
Packit 85355f
		uint16 m;
Packit 85355f
		m=(uint16)(skiplength-data->bufferbytesleft);
Packit 85355f
		if (m<=data->filebytesleft)
Packit 85355f
		{
Packit 85355f
			data->bufferbytesleft=0;
Packit 85355f
			data->fileoffset+=m;
Packit 85355f
			data->filebytesleft-=m;
Packit 85355f
			data->filepositioned=0;
Packit 85355f
		}
Packit 85355f
		else
Packit 85355f
		{
Packit 85355f
			data->bufferbytesleft=0;
Packit 85355f
			data->filebytesleft=0;
Packit 85355f
		}
Packit 85355f
	}
Packit 85355f
}
Packit 85355f
Packit 85355f
#endif
Packit 85355f
Packit 85355f
Packit 85355f
static int
Packit 85355f
JPEGSetupDecode(TIFF* tif)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = JState(tif);
Packit 85355f
	TIFFDirectory *td = &tif->tif_dir;
Packit 85355f
Packit 85355f
#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG)
Packit 85355f
        if( tif->tif_dir.td_bitspersample == 12 )
Packit 85355f
            return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 0 );
Packit 85355f
#endif
Packit 85355f
Packit 85355f
	JPEGInitializeLibJPEG( tif, TRUE );
Packit 85355f
Packit 85355f
	assert(sp != NULL);
Packit 85355f
	assert(sp->cinfo.comm.is_decompressor);
Packit 85355f
Packit 85355f
	/* Read JPEGTables if it is present */
Packit 85355f
	if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) {
Packit 85355f
		TIFFjpeg_tables_src(sp);
Packit 85355f
		if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) {
Packit 85355f
			TIFFErrorExt(tif->tif_clientdata, "JPEGSetupDecode", "Bogus JPEGTables field");
Packit 85355f
			return (0);
Packit 85355f
		}
Packit 85355f
	}
Packit 85355f
Packit 85355f
	/* Grab parameters that are same for all strips/tiles */
Packit 85355f
	sp->photometric = td->td_photometric;
Packit 85355f
	switch (sp->photometric) {
Packit 85355f
	case PHOTOMETRIC_YCBCR:
Packit 85355f
		sp->h_sampling = td->td_ycbcrsubsampling[0];
Packit 85355f
		sp->v_sampling = td->td_ycbcrsubsampling[1];
Packit 85355f
		break;
Packit 85355f
	default:
Packit 85355f
		/* TIFF 6.0 forbids subsampling of all other color spaces */
Packit 85355f
		sp->h_sampling = 1;
Packit 85355f
		sp->v_sampling = 1;
Packit 85355f
		break;
Packit 85355f
	}
Packit 85355f
Packit 85355f
	/* Set up for reading normal data */
Packit 85355f
	TIFFjpeg_data_src(sp);
Packit 85355f
	tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */
Packit 85355f
	return (1);
Packit 85355f
}
Packit 85355f
Packit 85355f
/* Returns 1 if the full strip should be read, even when doing scanline per */
Packit 85355f
/* scanline decoding. This happens when the JPEG stream uses multiple scans. */
Packit 85355f
/* Currently only called in CHUNKY_STRIP_READ_SUPPORT mode through */
Packit 85355f
/* scanline interface. */
Packit 85355f
/* Only reads tif->tif_dir.td_bitspersample, tif->tif_rawdata and */
Packit 85355f
/* tif->tif_rawcc members. */
Packit 85355f
/* Can be called independently of the usual setup/predecode/decode states */
Packit 85355f
int TIFFJPEGIsFullStripRequired(TIFF* tif)
Packit 85355f
{
Packit 85355f
    int ret;
Packit 85355f
    JPEGState state;
Packit 85355f
Packit 85355f
#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFJPEGIsFullStripRequired)
Packit 85355f
    if( tif->tif_dir.td_bitspersample == 12 )
Packit 85355f
        return TIFFJPEGIsFullStripRequired_12( tif );
Packit 85355f
#endif
Packit 85355f
Packit 85355f
    memset(&state, 0, sizeof(JPEGState));
Packit 85355f
    state.tif = tif;
Packit 85355f
Packit 85355f
    TIFFjpeg_create_decompress(&state);
Packit 85355f
Packit 85355f
    TIFFjpeg_data_src(&state);
Packit 85355f
Packit 85355f
    if (TIFFjpeg_read_header(&state, TRUE) != JPEG_HEADER_OK)
Packit 85355f
    {
Packit 85355f
        TIFFjpeg_destroy(&state);
Packit 85355f
        return (0);
Packit 85355f
    }
Packit 85355f
    ret = TIFFjpeg_has_multiple_scans(&state);
Packit 85355f
Packit 85355f
    TIFFjpeg_destroy(&state);
Packit 85355f
Packit 85355f
    return ret;
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Set up for decoding a strip or tile.
Packit 85355f
 */
Packit 85355f
/*ARGSUSED*/ static int
Packit 85355f
JPEGPreDecode(TIFF* tif, uint16 s)
Packit 85355f
{
Packit 85355f
	JPEGState *sp = JState(tif);
Packit 85355f
	TIFFDirectory *td = &tif->tif_dir;
Packit 85355f
	static const char module[] = "JPEGPreDecode";
Packit 85355f
	uint32 segment_width, segment_height;
Packit 85355f
	int downsampled_output;
Packit 85355f
	int ci;
Packit 85355f
Packit 85355f
	assert(sp != NULL);
Packit 85355f
  
Packit 85355f
	if (sp->cinfo.comm.is_decompressor == 0)
Packit 85355f
	{
Packit 85355f
		tif->tif_setupdecode( tif );
Packit 85355f
	}
Packit 85355f
  
Packit 85355f
	assert(sp->cinfo.comm.is_decompressor);
Packit 85355f
	/*
Packit 85355f
	 * Reset decoder state from any previous strip/tile,
Packit 85355f
	 * in case application didn't read the whole strip.
Packit 85355f
	 */
Packit 85355f
	if (!TIFFjpeg_abort(sp))
Packit 85355f
		return (0);
Packit 85355f
	/*
Packit 85355f
	 * Read the header for this strip/tile.
Packit 85355f
	 */
Packit 85355f
        
Packit 85355f
	if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK)
Packit 85355f
		return (0);
Packit 85355f
Packit 85355f
        tif->tif_rawcp = (uint8*) sp->src.next_input_byte;
Packit 85355f
        tif->tif_rawcc = sp->src.bytes_in_buffer;
Packit 85355f
Packit 85355f
	/*
Packit 85355f
	 * Check image parameters and set decompression parameters.
Packit 85355f
	 */
Packit 85355f
	if (isTiled(tif)) {
Packit 85355f
                segment_width = td->td_tilewidth;
Packit 85355f
                segment_height = td->td_tilelength;
Packit 85355f
		sp->bytesperline = TIFFTileRowSize(tif);
Packit 85355f
	} else {
Packit 85355f
		segment_width = td->td_imagewidth;
Packit 85355f
		segment_height = td->td_imagelength - tif->tif_row;
Packit 85355f
		if (segment_height > td->td_rowsperstrip)
Packit 85355f
			segment_height = td->td_rowsperstrip;
Packit 85355f
		sp->bytesperline = TIFFScanlineSize(tif);
Packit 85355f
	}
Packit 85355f
	if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) {
Packit 85355f
		/*
Packit 85355f
		 * For PC 2, scale down the expected strip/tile size
Packit 85355f
		 * to match a downsampled component
Packit 85355f
		 */
Packit 85355f
		segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
Packit 85355f
		segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
Packit 85355f
	}
Packit 85355f
	if (sp->cinfo.d.image_width < segment_width ||
Packit 85355f
	    sp->cinfo.d.image_height < segment_height) {
Packit 85355f
		TIFFWarningExt(tif->tif_clientdata, module,
Packit 85355f
			       "Improper JPEG strip/tile size, "
Packit 85355f
			       "expected %dx%d, got %dx%d",
Packit 85355f
			       segment_width, segment_height,
Packit 85355f
			       sp->cinfo.d.image_width,
Packit 85355f
			       sp->cinfo.d.image_height);
Packit 85355f
	}
Packit 85355f
	if( sp->cinfo.d.image_width == segment_width &&
Packit 85355f
	    sp->cinfo.d.image_height > segment_height &&
Packit 85355f
	    tif->tif_row + segment_height == td->td_imagelength &&
Packit 85355f
	    !isTiled(tif) ) {
Packit 85355f
		/* Some files have a last strip, that should be truncated, */
Packit 85355f
		/* but their JPEG codestream has still the maximum strip */
Packit 85355f
		/* height. Warn about this as this is non compliant, but */
Packit 85355f
		/* we can safely recover from that. */
Packit 85355f
		TIFFWarningExt(tif->tif_clientdata, module,
Packit 85355f
			     "JPEG strip size exceeds expected dimensions,"
Packit 85355f
			     " expected %dx%d, got %dx%d",
Packit 85355f
			     segment_width, segment_height,
Packit 85355f
			     sp->cinfo.d.image_width, sp->cinfo.d.image_height);
Packit 85355f
	}
Packit 85355f
	else if (sp->cinfo.d.image_width > segment_width ||
Packit 85355f
		 sp->cinfo.d.image_height > segment_height) {
Packit 85355f
		/*
Packit 85355f
		 * This case could be dangerous, if the strip or tile size has
Packit 85355f
		 * been reported as less than the amount of data jpeg will
Packit 85355f
		 * return, some potential security issues arise. Catch this
Packit 85355f
		 * case and error out.
Packit 85355f
		 */
Packit 85355f
		TIFFErrorExt(tif->tif_clientdata, module,
Packit 85355f
			     "JPEG strip/tile size exceeds expected dimensions,"
Packit 85355f
			     " expected %dx%d, got %dx%d",
Packit 85355f
			     segment_width, segment_height,
Packit 85355f
			     sp->cinfo.d.image_width, sp->cinfo.d.image_height);
Packit 85355f
		return (0);
Packit 85355f
	}
Packit 85355f
	if (sp->cinfo.d.num_components !=
Packit 85355f
	    (td->td_planarconfig == PLANARCONFIG_CONTIG ?
Packit 85355f
	     td->td_samplesperpixel : 1)) {
Packit 85355f
		TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG component count");
Packit 85355f
		return (0);
Packit 85355f
	}
Packit 85355f
#ifdef JPEG_LIB_MK1
Packit 85355f
	if (12 != td->td_bitspersample && 8 != td->td_bitspersample) {
Packit 85355f
		TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision");
Packit 85355f
		return (0);
Packit 85355f
	}
Packit 85355f
	sp->cinfo.d.data_precision = td->td_bitspersample;
Packit 85355f
	sp->cinfo.d.bits_in_jsample = td->td_bitspersample;
Packit 85355f
#else
Packit 85355f
	if (sp->cinfo.d.data_precision != td->td_bitspersample) {
Packit 85355f
		TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision");
Packit 85355f
		return (0);
Packit 85355f
	}
Packit 85355f
#endif
Packit 85355f
Packit 85355f
        /* In some cases, libjpeg needs to allocate a lot of memory */
Packit 85355f
        /* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf */
Packit 85355f
        if( TIFFjpeg_has_multiple_scans(sp) )
Packit 85355f
        {
Packit 85355f
            /* In this case libjpeg will need to allocate memory or backing */
Packit 85355f
            /* store for all coefficients */
Packit 85355f
            /* See call to jinit_d_coef_controller() from master_selection() */
Packit 85355f
            /* in libjpeg */
Packit 85355f
            toff_t nRequiredMemory = (toff_t)sp->cinfo.d.image_width *
Packit 85355f
                                     sp->cinfo.d.image_height *
Packit 85355f
                                     sp->cinfo.d.num_components *
Packit 85355f
                                     ((td->td_bitspersample+7)/8);
Packit 85355f
            /* BLOCK_SMOOTHING_SUPPORTED is generally defined, so we need */
Packit 85355f
            /* to replicate the logic of jinit_d_coef_controller() */
Packit 85355f
            if( sp->cinfo.d.progressive_mode )
Packit 85355f
                nRequiredMemory *= 3;
Packit 85355f
Packit 85355f
#ifndef TIFF_LIBJPEG_LARGEST_MEM_ALLOC
Packit 85355f
#define TIFF_LIBJPEG_LARGEST_MEM_ALLOC (100 * 1024 * 1024)
Packit 85355f
#endif
Packit 85355f
Packit 85355f
            if( nRequiredMemory > TIFF_LIBJPEG_LARGEST_MEM_ALLOC &&
Packit 85355f
                getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL )
Packit 85355f
            {
Packit 85355f
                    TIFFErrorExt(tif->tif_clientdata, module,
Packit 85355f
                        "Reading this strip would require libjpeg to allocate "
Packit 85355f
                        "at least %u bytes. "
Packit 85355f
                        "This is disabled since above the %u threshold. "
Packit 85355f
                        "You may override this restriction by defining the "
Packit 85355f
                        "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, "
Packit 85355f
                        "or recompile libtiff by defining the "
Packit 85355f
                        "TIFF_LIBJPEG_LARGEST_MEM_ALLOC macro to a value greater "
Packit 85355f
                        "than %u",
Packit 85355f
                        (unsigned)nRequiredMemory,
Packit 85355f
                        (unsigned)TIFF_LIBJPEG_LARGEST_MEM_ALLOC,
Packit 85355f
                        (unsigned)TIFF_LIBJPEG_LARGEST_MEM_ALLOC);
Packit 85355f
                    return (0);
Packit 85355f
            }
Packit 85355f
        }
Packit 85355f
Packit 85355f
	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
Packit 85355f
		/* Component 0 should have expected sampling factors */
Packit 85355f
		if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling ||
Packit 85355f
		    sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) {
Packit 85355f
			TIFFErrorExt(tif->tif_clientdata, module,
Packit 85355f
				       "Improper JPEG sampling factors %d,%d\n"
Packit 85355f
				       "Apparently should be %d,%d.",
Packit 85355f
				       sp->cinfo.d.comp_info[0].h_samp_factor,
Packit 85355f
				       sp->cinfo.d.comp_info[0].v_samp_factor,
Packit 85355f
				       sp->h_sampling, sp->v_sampling);
Packit 85355f
			return (0);
Packit 85355f
		}
Packit 85355f
		/* Rest should have sampling factors 1,1 */
Packit 85355f
		for (ci = 1; ci < sp->cinfo.d.num_components; ci++) {
Packit 85355f
			if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 ||
Packit 85355f
			    sp->cinfo.d.comp_info[ci].v_samp_factor != 1) {
Packit 85355f
				TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors");
Packit 85355f
				return (0);
Packit 85355f
			}
Packit 85355f
		}
Packit 85355f
	} else {
Packit 85355f
		/* PC 2's single component should have sampling factors 1,1 */
Packit 85355f
		if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 ||
Packit 85355f
		    sp->cinfo.d.comp_info[0].v_samp_factor != 1) {
Packit 85355f
			TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors");
Packit 85355f
			return (0);
Packit 85355f
		}
Packit 85355f
	}
Packit 85355f
	downsampled_output = FALSE;
Packit 85355f
	if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
Packit 85355f
	    sp->photometric == PHOTOMETRIC_YCBCR &&
Packit 85355f
	    sp->jpegcolormode == JPEGCOLORMODE_RGB) {
Packit 85355f
		/* Convert YCbCr to RGB */
Packit 85355f
		sp->cinfo.d.jpeg_color_space = JCS_YCbCr;
Packit 85355f
		sp->cinfo.d.out_color_space = JCS_RGB;
Packit 85355f
	} else {
Packit 85355f
		/* Suppress colorspace handling */
Packit 85355f
		sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN;
Packit 85355f
		sp->cinfo.d.out_color_space = JCS_UNKNOWN;
Packit 85355f
		if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
Packit 85355f
		    (sp->h_sampling != 1 || sp->v_sampling != 1))
Packit 85355f
			downsampled_output = TRUE;
Packit 85355f
		/* XXX what about up-sampling? */
Packit 85355f
	}
Packit 85355f
	if (downsampled_output) {
Packit 85355f
		/* Need to use raw-data interface to libjpeg */
Packit 85355f
		sp->cinfo.d.raw_data_out = TRUE;
Packit 85355f
#if JPEG_LIB_VERSION >= 70
Packit 85355f
		sp->cinfo.d.do_fancy_upsampling = FALSE;
Packit 85355f
#endif /* JPEG_LIB_VERSION >= 70 */
Packit 85355f
		tif->tif_decoderow = DecodeRowError;
Packit 85355f
		tif->tif_decodestrip = JPEGDecodeRaw;
Packit 85355f
		tif->tif_decodetile = JPEGDecodeRaw;
Packit 85355f
	} else {
Packit 85355f
		/* Use normal interface to libjpeg */
Packit 85355f
		sp->cinfo.d.raw_data_out = FALSE;
Packit 85355f
		tif->tif_decoderow = JPEGDecode;
Packit 85355f
		tif->tif_decodestrip = JPEGDecode;
Packit 85355f
		tif->tif_decodetile = JPEGDecode;  
Packit 85355f
	}
Packit 85355f
	/* Start JPEG decompressor */
Packit 85355f
	if (!TIFFjpeg_start_decompress(sp))
Packit 85355f
		return (0);
Packit 85355f
	/* Allocate downsampled-data buffers if needed */
Packit 85355f
	if (downsampled_output) {
Packit 85355f
		if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info,
Packit 85355f
					       sp->cinfo.d.num_components))
Packit 85355f
			return (0);
Packit 85355f
		sp->scancount = DCTSIZE;	/* mark buffer empty */
Packit 85355f
	}
Packit 85355f
	return (1);
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Decode a chunk of pixels.
Packit 85355f
 * "Standard" case: returned data is not downsampled.
Packit 85355f
 */
Packit 85355f
#if !JPEG_LIB_MK1_OR_12BIT
Packit 85355f
static int
Packit 85355f
JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
Packit 85355f
{
Packit 85355f
	JPEGState *sp = JState(tif);
Packit 85355f
	tmsize_t nrows;
Packit 85355f
	(void) s;
Packit 85355f
Packit 85355f
        /*
Packit 85355f
        ** Update available information, buffer may have been refilled
Packit 85355f
        ** between decode requests
Packit 85355f
        */
Packit 85355f
	sp->src.next_input_byte = (const JOCTET*) tif->tif_rawcp;
Packit 85355f
	sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;
Packit 85355f
Packit 85355f
        if( sp->bytesperline == 0 )
Packit 85355f
                return 0;
Packit 85355f
        
Packit 85355f
	nrows = cc / sp->bytesperline;
Packit 85355f
	if (cc % sp->bytesperline)
Packit 85355f
		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
Packit 85355f
                               "fractional scanline not read");
Packit 85355f
Packit 85355f
	if( nrows > (tmsize_t) sp->cinfo.d.image_height )
Packit 85355f
		nrows = sp->cinfo.d.image_height;
Packit 85355f
Packit 85355f
	/* data is expected to be read in multiples of a scanline */
Packit 85355f
	if (nrows)
Packit 85355f
        {
Packit 85355f
                do
Packit 85355f
                {
Packit 85355f
                        /*
Packit 85355f
                         * In the libjpeg6b-9a 8bit case.  We read directly into
Packit 85355f
                         * the TIFF buffer.
Packit 85355f
                         */
Packit 85355f
                        JSAMPROW bufptr = (JSAMPROW)buf;
Packit 85355f
Packit 85355f
                        if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
Packit 85355f
                                return (0);
Packit 85355f
Packit 85355f
                        ++tif->tif_row;
Packit 85355f
                        buf += sp->bytesperline;
Packit 85355f
                        cc -= sp->bytesperline;
Packit 85355f
                } while (--nrows > 0);
Packit 85355f
        }
Packit 85355f
Packit 85355f
        /* Update information on consumed data */
Packit 85355f
        tif->tif_rawcp = (uint8*) sp->src.next_input_byte;
Packit 85355f
        tif->tif_rawcc = sp->src.bytes_in_buffer;
Packit 85355f
                
Packit 85355f
	/* Close down the decompressor if we've finished the strip or tile. */
Packit 85355f
	return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
Packit 85355f
                || TIFFjpeg_finish_decompress(sp);
Packit 85355f
}
Packit 85355f
#endif /* !JPEG_LIB_MK1_OR_12BIT */
Packit 85355f
Packit 85355f
#if JPEG_LIB_MK1_OR_12BIT
Packit 85355f
/*ARGSUSED*/ static int
Packit 85355f
JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
Packit 85355f
{
Packit 85355f
	JPEGState *sp = JState(tif);
Packit 85355f
	tmsize_t nrows;
Packit 85355f
	(void) s;
Packit 85355f
Packit 85355f
        /*
Packit 85355f
        ** Update available information, buffer may have been refilled
Packit 85355f
        ** between decode requests
Packit 85355f
        */
Packit 85355f
	sp->src.next_input_byte = (const JOCTET*) tif->tif_rawcp;
Packit 85355f
	sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;
Packit 85355f
Packit 85355f
        if( sp->bytesperline == 0 )
Packit 85355f
                return 0;
Packit 85355f
        
Packit 85355f
	nrows = cc / sp->bytesperline;
Packit 85355f
	if (cc % sp->bytesperline)
Packit 85355f
		TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
Packit 85355f
                               "fractional scanline not read");
Packit 85355f
Packit 85355f
	if( nrows > (tmsize_t) sp->cinfo.d.image_height )
Packit 85355f
		nrows = sp->cinfo.d.image_height;
Packit 85355f
Packit 85355f
	/* data is expected to be read in multiples of a scanline */
Packit 85355f
	if (nrows)
Packit 85355f
        {
Packit 85355f
                JSAMPROW line_work_buf = NULL;
Packit 85355f
Packit 85355f
                /*
Packit 85355f
                 * For 6B, only use temporary buffer for 12 bit imagery.
Packit 85355f
                 * For Mk1 always use it.
Packit 85355f
                 */
Packit 85355f
                if( sp->cinfo.d.data_precision == 12 )
Packit 85355f
                {
Packit 85355f
                        line_work_buf = (JSAMPROW)
Packit 85355f
                                _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width
Packit 85355f
                                            * sp->cinfo.d.num_components );
Packit 85355f
                }
Packit 85355f
Packit 85355f
               do
Packit 85355f
               {
Packit 85355f
                       if( line_work_buf != NULL )
Packit 85355f
                       {
Packit 85355f
                               /*
Packit 85355f
                                * In the MK1 case, we always read into a 16bit
Packit 85355f
                                * buffer, and then pack down to 12bit or 8bit.
Packit 85355f
                                * In 6B case we only read into 16 bit buffer
Packit 85355f
                                * for 12bit data, which we need to repack.
Packit 85355f
                                */
Packit 85355f
                               if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1)
Packit 85355f
                                       return (0);
Packit 85355f
Packit 85355f
                               if( sp->cinfo.d.data_precision == 12 )
Packit 85355f
                               {
Packit 85355f
                                       int value_pairs = (sp->cinfo.d.output_width
Packit 85355f
                                                          * sp->cinfo.d.num_components) / 2;
Packit 85355f
                                       int iPair;
Packit 85355f
Packit 85355f
                                       for( iPair = 0; iPair < value_pairs; iPair++ )
Packit 85355f
                                       {
Packit 85355f
                                               unsigned char *out_ptr =
Packit 85355f
                                                       ((unsigned char *) buf) + iPair * 3;
Packit 85355f
                                               JSAMPLE *in_ptr = line_work_buf + iPair * 2;
Packit 85355f
Packit 85355f
                                               out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4);
Packit 85355f
                                               out_ptr[1] = (unsigned char)(((in_ptr[0] & 0xf) << 4)
Packit 85355f
                                                       | ((in_ptr[1] & 0xf00) >> 8));
Packit 85355f
                                               out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0));
Packit 85355f
                                       }
Packit 85355f
                               }
Packit 85355f
                               else if( sp->cinfo.d.data_precision == 8 )
Packit 85355f
                               {
Packit 85355f
                                       int value_count = (sp->cinfo.d.output_width
Packit 85355f
                                                          * sp->cinfo.d.num_components);
Packit 85355f
                                       int iValue;
Packit 85355f
Packit 85355f
                                       for( iValue = 0; iValue < value_count; iValue++ )
Packit 85355f
                                       {
Packit 85355f
                                               ((unsigned char *) buf)[iValue] =
Packit 85355f
                                                       line_work_buf[iValue] & 0xff;
Packit 85355f
                                       }
Packit 85355f
                               }
Packit 85355f
                       }
Packit 85355f
Packit 85355f
                       ++tif->tif_row;
Packit 85355f
                       buf += sp->bytesperline;
Packit 85355f
                       cc -= sp->bytesperline;
Packit 85355f
               } while (--nrows > 0);
Packit 85355f
Packit 85355f
               if( line_work_buf != NULL )
Packit 85355f
                       _TIFFfree( line_work_buf );
Packit 85355f
        }
Packit 85355f
Packit 85355f
        /* Update information on consumed data */
Packit 85355f
        tif->tif_rawcp = (uint8*) sp->src.next_input_byte;
Packit 85355f
        tif->tif_rawcc = sp->src.bytes_in_buffer;
Packit 85355f
                
Packit 85355f
	/* Close down the decompressor if we've finished the strip or tile. */
Packit 85355f
	return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
Packit 85355f
                || TIFFjpeg_finish_decompress(sp);
Packit 85355f
}
Packit 85355f
#endif /* JPEG_LIB_MK1_OR_12BIT */
Packit 85355f
Packit 85355f
/*ARGSUSED*/ static int
Packit 85355f
DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
Packit 85355f
Packit 85355f
{
Packit 85355f
    (void) buf;
Packit 85355f
    (void) cc;
Packit 85355f
    (void) s;
Packit 85355f
Packit 85355f
    TIFFErrorExt(tif->tif_clientdata, "TIFFReadScanline",
Packit 85355f
                 "scanline oriented access is not supported for downsampled JPEG compressed images, consider enabling TIFF_JPEGCOLORMODE as JPEGCOLORMODE_RGB." );
Packit 85355f
    return 0;
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Decode a chunk of pixels.
Packit 85355f
 * Returned data is downsampled per sampling factors.
Packit 85355f
 */
Packit 85355f
/*ARGSUSED*/ static int
Packit 85355f
JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
Packit 85355f
{
Packit 85355f
	JPEGState *sp = JState(tif);
Packit 85355f
	tmsize_t nrows;
Packit 85355f
        TIFFDirectory *td = &tif->tif_dir;
Packit 85355f
	(void) s;
Packit 85355f
Packit 85355f
        nrows = sp->cinfo.d.image_height;
Packit 85355f
        /* For last strip, limit number of rows to its truncated height */
Packit 85355f
        /* even if the codestream height is larger (which is not compliant, */
Packit 85355f
        /* but that we tolerate) */
Packit 85355f
        if( (uint32)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif) )
Packit 85355f
            nrows = td->td_imagelength - tif->tif_row;
Packit 85355f
Packit 85355f
	/* data is expected to be read in multiples of a scanline */
Packit 85355f
	if ( nrows != 0 ) {
Packit 85355f
Packit 85355f
		/* Cb,Cr both have sampling factors 1, so this is correct */
Packit 85355f
		JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;            
Packit 85355f
		int samples_per_clump = sp->samplesperclump;
Packit 85355f
Packit 85355f
#if defined(JPEG_LIB_MK1_OR_12BIT)
Packit 85355f
		unsigned short* tmpbuf = _TIFFmalloc(sizeof(unsigned short) *
Packit 85355f
						     sp->cinfo.d.output_width *
Packit 85355f
						     sp->cinfo.d.num_components);
Packit 85355f
		if(tmpbuf==NULL) {
Packit 85355f
                        TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
Packit 85355f
				     "Out of memory");
Packit 85355f
			return 0;
Packit 85355f
                }
Packit 85355f
#endif
Packit 85355f
Packit 85355f
		do {
Packit 85355f
			jpeg_component_info *compptr;
Packit 85355f
			int ci, clumpoffset;
Packit 85355f
Packit 85355f
                        if( cc < sp->bytesperline ) {
Packit 85355f
				TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
Packit 85355f
					     "application buffer not large enough for all data.");
Packit 85355f
				return 0;
Packit 85355f
                        }
Packit 85355f
Packit 85355f
			/* Reload downsampled-data buffer if needed */
Packit 85355f
			if (sp->scancount >= DCTSIZE) {
Packit 85355f
				int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE;
Packit 85355f
				if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n)
Packit 85355f
					return (0);
Packit 85355f
				sp->scancount = 0;
Packit 85355f
			}
Packit 85355f
			/*
Packit 85355f
			 * Fastest way to unseparate data is to make one pass
Packit 85355f
			 * over the scanline for each row of each component.
Packit 85355f
			 */
Packit 85355f
			clumpoffset = 0;    /* first sample in clump */
Packit 85355f
			for (ci = 0, compptr = sp->cinfo.d.comp_info;
Packit 85355f
			     ci < sp->cinfo.d.num_components;
Packit 85355f
			     ci++, compptr++) {
Packit 85355f
				int hsamp = compptr->h_samp_factor;
Packit 85355f
				int vsamp = compptr->v_samp_factor;
Packit 85355f
				int ypos;
Packit 85355f
Packit 85355f
				for (ypos = 0; ypos < vsamp; ypos++) {
Packit 85355f
					JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];
Packit 85355f
					JDIMENSION nclump;
Packit 85355f
#if defined(JPEG_LIB_MK1_OR_12BIT)
Packit 85355f
					JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset;
Packit 85355f
#else
Packit 85355f
					JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;
Packit 85355f
					if (cc < (tmsize_t) (clumpoffset + samples_per_clump*(clumps_per_line-1) + hsamp)) {
Packit 85355f
						TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
Packit 85355f
							     "application buffer not large enough for all data, possible subsampling issue");
Packit 85355f
						return 0;
Packit 85355f
					}
Packit 85355f
#endif
Packit 85355f
Packit 85355f
					if (hsamp == 1) {
Packit 85355f
						/* fast path for at least Cb and Cr */
Packit 85355f
						for (nclump = clumps_per_line; nclump-- > 0; ) {
Packit 85355f
							outptr[0] = *inptr++;
Packit 85355f
							outptr += samples_per_clump;
Packit 85355f
						}
Packit 85355f
					} else {
Packit 85355f
						int xpos;
Packit 85355f
Packit 85355f
						/* general case */
Packit 85355f
						for (nclump = clumps_per_line; nclump-- > 0; ) {
Packit 85355f
							for (xpos = 0; xpos < hsamp; xpos++)
Packit 85355f
								outptr[xpos] = *inptr++;
Packit 85355f
							outptr += samples_per_clump;
Packit 85355f
						}
Packit 85355f
					}
Packit 85355f
					clumpoffset += hsamp;
Packit 85355f
				}
Packit 85355f
			}
Packit 85355f
Packit 85355f
#if defined(JPEG_LIB_MK1_OR_12BIT)
Packit 85355f
			{
Packit 85355f
				if (sp->cinfo.d.data_precision == 8)
Packit 85355f
				{
Packit 85355f
					int i=0;
Packit 85355f
					int len = sp->cinfo.d.output_width * sp->cinfo.d.num_components;
Packit 85355f
					for (i=0; i
Packit 85355f
					{
Packit 85355f
						((unsigned char*)buf)[i] = tmpbuf[i] & 0xff;
Packit 85355f
					}
Packit 85355f
				}
Packit 85355f
				else
Packit 85355f
				{         /* 12-bit */
Packit 85355f
					int value_pairs = (sp->cinfo.d.output_width
Packit 85355f
							   * sp->cinfo.d.num_components) / 2;
Packit 85355f
					int iPair;
Packit 85355f
					for( iPair = 0; iPair < value_pairs; iPair++ )
Packit 85355f
					{
Packit 85355f
						unsigned char *out_ptr = ((unsigned char *) buf) + iPair * 3;
Packit 85355f
						JSAMPLE *in_ptr = (JSAMPLE *) (tmpbuf + iPair * 2);
Packit 85355f
						out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4);
Packit 85355f
						out_ptr[1] = (unsigned char)(((in_ptr[0] & 0xf) << 4)
Packit 85355f
							| ((in_ptr[1] & 0xf00) >> 8));
Packit 85355f
						out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0));
Packit 85355f
					}
Packit 85355f
				}
Packit 85355f
			}
Packit 85355f
#endif
Packit 85355f
Packit 85355f
			sp->scancount ++;
Packit 85355f
			tif->tif_row += sp->v_sampling;
Packit 85355f
Packit 85355f
			buf += sp->bytesperline;
Packit 85355f
			cc -= sp->bytesperline;
Packit 85355f
Packit 85355f
			nrows -= sp->v_sampling;
Packit 85355f
		} while (nrows > 0);
Packit 85355f
Packit 85355f
#if defined(JPEG_LIB_MK1_OR_12BIT)
Packit 85355f
		_TIFFfree(tmpbuf);
Packit 85355f
#endif
Packit 85355f
Packit 85355f
	}
Packit 85355f
Packit 85355f
	/* Close down the decompressor if done. */
Packit 85355f
	return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
Packit 85355f
		|| TIFFjpeg_finish_decompress(sp);
Packit 85355f
}
Packit 85355f
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * JPEG Encoding.
Packit 85355f
 */
Packit 85355f
Packit 85355f
static void
Packit 85355f
unsuppress_quant_table (JPEGState* sp, int tblno)
Packit 85355f
{
Packit 85355f
	JQUANT_TBL* qtbl;
Packit 85355f
Packit 85355f
	if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)
Packit 85355f
		qtbl->sent_table = FALSE;
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
suppress_quant_table (JPEGState* sp, int tblno)
Packit 85355f
{
Packit 85355f
	JQUANT_TBL* qtbl;
Packit 85355f
Packit 85355f
	if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)
Packit 85355f
		qtbl->sent_table = TRUE;
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
unsuppress_huff_table (JPEGState* sp, int tblno)
Packit 85355f
{
Packit 85355f
	JHUFF_TBL* htbl;
Packit 85355f
Packit 85355f
	if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)
Packit 85355f
		htbl->sent_table = FALSE;
Packit 85355f
	if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)
Packit 85355f
		htbl->sent_table = FALSE;
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
suppress_huff_table (JPEGState* sp, int tblno)
Packit 85355f
{
Packit 85355f
	JHUFF_TBL* htbl;
Packit 85355f
Packit 85355f
	if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)
Packit 85355f
		htbl->sent_table = TRUE;
Packit 85355f
	if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)
Packit 85355f
		htbl->sent_table = TRUE;
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
prepare_JPEGTables(TIFF* tif)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = JState(tif);
Packit 85355f
Packit 85355f
	/* Initialize quant tables for current quality setting */
Packit 85355f
	if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))
Packit 85355f
		return (0);
Packit 85355f
	/* Mark only the tables we want for output */
Packit 85355f
	/* NB: chrominance tables are currently used only with YCbCr */
Packit 85355f
	if (!TIFFjpeg_suppress_tables(sp, TRUE))
Packit 85355f
		return (0);
Packit 85355f
	if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) {
Packit 85355f
		unsuppress_quant_table(sp, 0);
Packit 85355f
		if (sp->photometric == PHOTOMETRIC_YCBCR)
Packit 85355f
			unsuppress_quant_table(sp, 1);
Packit 85355f
	}
Packit 85355f
	if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) {
Packit 85355f
		unsuppress_huff_table(sp, 0);
Packit 85355f
		if (sp->photometric == PHOTOMETRIC_YCBCR)
Packit 85355f
			unsuppress_huff_table(sp, 1);
Packit 85355f
	}
Packit 85355f
	/* Direct libjpeg output into jpegtables */
Packit 85355f
	if (!TIFFjpeg_tables_dest(sp, tif))
Packit 85355f
		return (0);
Packit 85355f
	/* Emit tables-only datastream */
Packit 85355f
	if (!TIFFjpeg_write_tables(sp))
Packit 85355f
		return (0);
Packit 85355f
Packit 85355f
	return (1);
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
JPEGSetupEncode(TIFF* tif)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = JState(tif);
Packit 85355f
	TIFFDirectory *td = &tif->tif_dir;
Packit 85355f
	static const char module[] = "JPEGSetupEncode";
Packit 85355f
Packit 85355f
#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG)
Packit 85355f
        if( tif->tif_dir.td_bitspersample == 12 )
Packit 85355f
            return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 1 );
Packit 85355f
#endif
Packit 85355f
Packit 85355f
        JPEGInitializeLibJPEG( tif, FALSE );
Packit 85355f
Packit 85355f
	assert(sp != NULL);
Packit 85355f
	assert(!sp->cinfo.comm.is_decompressor);
Packit 85355f
Packit 85355f
	sp->photometric = td->td_photometric;
Packit 85355f
Packit 85355f
	/*
Packit 85355f
	 * Initialize all JPEG parameters to default values.
Packit 85355f
	 * Note that jpeg_set_defaults needs legal values for
Packit 85355f
	 * in_color_space and input_components.
Packit 85355f
	 */
Packit 85355f
	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
Packit 85355f
		sp->cinfo.c.input_components = td->td_samplesperpixel;
Packit 85355f
		if (sp->photometric == PHOTOMETRIC_YCBCR) {
Packit 85355f
			if (sp->jpegcolormode == JPEGCOLORMODE_RGB) {
Packit 85355f
				sp->cinfo.c.in_color_space = JCS_RGB;
Packit 85355f
			} else {
Packit 85355f
				sp->cinfo.c.in_color_space = JCS_YCbCr;
Packit 85355f
			}
Packit 85355f
		} else {
Packit 85355f
			if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || td->td_photometric == PHOTOMETRIC_MINISBLACK) && td->td_samplesperpixel == 1)
Packit 85355f
				sp->cinfo.c.in_color_space = JCS_GRAYSCALE;
Packit 85355f
			else if (td->td_photometric == PHOTOMETRIC_RGB && td->td_samplesperpixel == 3)
Packit 85355f
				sp->cinfo.c.in_color_space = JCS_RGB;
Packit 85355f
			else if (td->td_photometric == PHOTOMETRIC_SEPARATED && td->td_samplesperpixel == 4)
Packit 85355f
				sp->cinfo.c.in_color_space = JCS_CMYK;
Packit 85355f
			else
Packit 85355f
				sp->cinfo.c.in_color_space = JCS_UNKNOWN;
Packit 85355f
		}
Packit 85355f
	} else {
Packit 85355f
		sp->cinfo.c.input_components = 1;
Packit 85355f
		sp->cinfo.c.in_color_space = JCS_UNKNOWN;
Packit 85355f
	}
Packit 85355f
	if (!TIFFjpeg_set_defaults(sp))
Packit 85355f
		return (0);
Packit 85355f
	/* Set per-file parameters */
Packit 85355f
	switch (sp->photometric) {
Packit 85355f
	case PHOTOMETRIC_YCBCR:
Packit 85355f
		sp->h_sampling = td->td_ycbcrsubsampling[0];
Packit 85355f
		sp->v_sampling = td->td_ycbcrsubsampling[1];
Packit 85355f
                if( sp->h_sampling == 0 || sp->v_sampling == 0 )
Packit 85355f
                {
Packit 85355f
                    TIFFErrorExt(tif->tif_clientdata, module,
Packit 85355f
                            "Invalig horizontal/vertical sampling value");
Packit 85355f
                    return (0);
Packit 85355f
                }
Packit 85355f
                if( td->td_bitspersample > 16 )
Packit 85355f
                {
Packit 85355f
                    TIFFErrorExt(tif->tif_clientdata, module,
Packit 85355f
                                 "BitsPerSample %d not allowed for JPEG",
Packit 85355f
                                 td->td_bitspersample);
Packit 85355f
                    return (0);
Packit 85355f
                }
Packit 85355f
Packit 85355f
		/*
Packit 85355f
		 * A ReferenceBlackWhite field *must* be present since the
Packit 85355f
		 * default value is inappropriate for YCbCr.  Fill in the
Packit 85355f
		 * proper value if application didn't set it.
Packit 85355f
		 */
Packit 85355f
		{
Packit 85355f
			float *ref;
Packit 85355f
			if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE,
Packit 85355f
					  &ref)) {
Packit 85355f
				float refbw[6];
Packit 85355f
				long top = 1L << td->td_bitspersample;
Packit 85355f
				refbw[0] = 0;
Packit 85355f
				refbw[1] = (float)(top-1L);
Packit 85355f
				refbw[2] = (float)(top>>1);
Packit 85355f
				refbw[3] = refbw[1];
Packit 85355f
				refbw[4] = refbw[2];
Packit 85355f
				refbw[5] = refbw[1];
Packit 85355f
				TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE,
Packit 85355f
					     refbw);
Packit 85355f
			}
Packit 85355f
		}
Packit 85355f
		break;
Packit 85355f
	case PHOTOMETRIC_PALETTE:		/* disallowed by Tech Note */
Packit 85355f
	case PHOTOMETRIC_MASK:
Packit 85355f
		TIFFErrorExt(tif->tif_clientdata, module,
Packit 85355f
			  "PhotometricInterpretation %d not allowed for JPEG",
Packit 85355f
			  (int) sp->photometric);
Packit 85355f
		return (0);
Packit 85355f
	default:
Packit 85355f
		/* TIFF 6.0 forbids subsampling of all other color spaces */
Packit 85355f
		sp->h_sampling = 1;
Packit 85355f
		sp->v_sampling = 1;
Packit 85355f
		break;
Packit 85355f
	}
Packit 85355f
Packit 85355f
	/* Verify miscellaneous parameters */
Packit 85355f
Packit 85355f
	/*
Packit 85355f
	 * This would need work if libtiff ever supports different
Packit 85355f
	 * depths for different components, or if libjpeg ever supports
Packit 85355f
	 * run-time selection of depth.  Neither is imminent.
Packit 85355f
	 */
Packit 85355f
#ifdef JPEG_LIB_MK1
Packit 85355f
        /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */
Packit 85355f
	if (td->td_bitspersample != 8 && td->td_bitspersample != 12) 
Packit 85355f
#else
Packit 85355f
	if (td->td_bitspersample != BITS_IN_JSAMPLE )
Packit 85355f
#endif
Packit 85355f
	{
Packit 85355f
		TIFFErrorExt(tif->tif_clientdata, module, "BitsPerSample %d not allowed for JPEG",
Packit 85355f
			  (int) td->td_bitspersample);
Packit 85355f
		return (0);
Packit 85355f
	}
Packit 85355f
	sp->cinfo.c.data_precision = td->td_bitspersample;
Packit 85355f
#ifdef JPEG_LIB_MK1
Packit 85355f
        sp->cinfo.c.bits_in_jsample = td->td_bitspersample;
Packit 85355f
#endif
Packit 85355f
	if (isTiled(tif)) {
Packit 85355f
		if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) {
Packit 85355f
			TIFFErrorExt(tif->tif_clientdata, module,
Packit 85355f
				  "JPEG tile height must be multiple of %d",
Packit 85355f
				  sp->v_sampling * DCTSIZE);
Packit 85355f
			return (0);
Packit 85355f
		}
Packit 85355f
		if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) {
Packit 85355f
			TIFFErrorExt(tif->tif_clientdata, module,
Packit 85355f
				  "JPEG tile width must be multiple of %d",
Packit 85355f
				  sp->h_sampling * DCTSIZE);
Packit 85355f
			return (0);
Packit 85355f
		}
Packit 85355f
	} else {
Packit 85355f
		if (td->td_rowsperstrip < td->td_imagelength &&
Packit 85355f
		    (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) {
Packit 85355f
			TIFFErrorExt(tif->tif_clientdata, module,
Packit 85355f
				  "RowsPerStrip must be multiple of %d for JPEG",
Packit 85355f
				  sp->v_sampling * DCTSIZE);
Packit 85355f
			return (0);
Packit 85355f
		}
Packit 85355f
	}
Packit 85355f
Packit 85355f
	/* Create a JPEGTables field if appropriate */
Packit 85355f
	if (sp->jpegtablesmode & (JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF)) {
Packit 85355f
                if( sp->jpegtables == NULL
Packit 85355f
                    || memcmp(sp->jpegtables,"\0\0\0\0\0\0\0\0\0",8) == 0 )
Packit 85355f
                {
Packit 85355f
                        if (!prepare_JPEGTables(tif))
Packit 85355f
                                return (0);
Packit 85355f
                        /* Mark the field present */
Packit 85355f
                        /* Can't use TIFFSetField since BEENWRITING is already set! */
Packit 85355f
                        tif->tif_flags |= TIFF_DIRTYDIRECT;
Packit 85355f
                        TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
Packit 85355f
                }
Packit 85355f
	} else {
Packit 85355f
		/* We do not support application-supplied JPEGTables, */
Packit 85355f
		/* so mark the field not present */
Packit 85355f
		TIFFClrFieldBit(tif, FIELD_JPEGTABLES);
Packit 85355f
	}
Packit 85355f
Packit 85355f
	/* Direct libjpeg output to libtiff's output buffer */
Packit 85355f
	TIFFjpeg_data_dest(sp, tif);
Packit 85355f
Packit 85355f
	return (1);
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Set encoding state at the start of a strip or tile.
Packit 85355f
 */
Packit 85355f
static int
Packit 85355f
JPEGPreEncode(TIFF* tif, uint16 s)
Packit 85355f
{
Packit 85355f
	JPEGState *sp = JState(tif);
Packit 85355f
	TIFFDirectory *td = &tif->tif_dir;
Packit 85355f
	static const char module[] = "JPEGPreEncode";
Packit 85355f
	uint32 segment_width, segment_height;
Packit 85355f
	int downsampled_input;
Packit 85355f
Packit 85355f
	assert(sp != NULL);
Packit 85355f
  
Packit 85355f
	if (sp->cinfo.comm.is_decompressor == 1)
Packit 85355f
	{
Packit 85355f
		tif->tif_setupencode( tif );
Packit 85355f
	}
Packit 85355f
  
Packit 85355f
	assert(!sp->cinfo.comm.is_decompressor);
Packit 85355f
	/*
Packit 85355f
	 * Set encoding parameters for this strip/tile.
Packit 85355f
	 */
Packit 85355f
	if (isTiled(tif)) {
Packit 85355f
		segment_width = td->td_tilewidth;
Packit 85355f
		segment_height = td->td_tilelength;
Packit 85355f
		sp->bytesperline = TIFFTileRowSize(tif);
Packit 85355f
	} else {
Packit 85355f
		segment_width = td->td_imagewidth;
Packit 85355f
		segment_height = td->td_imagelength - tif->tif_row;
Packit 85355f
		if (segment_height > td->td_rowsperstrip)
Packit 85355f
			segment_height = td->td_rowsperstrip;
Packit 85355f
		sp->bytesperline = TIFFScanlineSize(tif);
Packit 85355f
	}
Packit 85355f
	if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) {
Packit 85355f
		/* for PC 2, scale down the strip/tile size
Packit 85355f
		 * to match a downsampled component
Packit 85355f
		 */
Packit 85355f
		segment_width = TIFFhowmany_32(segment_width, sp->h_sampling); 
Packit 85355f
		segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
Packit 85355f
	}
Packit 85355f
	if (segment_width > 65535 || segment_height > 65535) {
Packit 85355f
		TIFFErrorExt(tif->tif_clientdata, module, "Strip/tile too large for JPEG");
Packit 85355f
		return (0);
Packit 85355f
	}
Packit 85355f
	sp->cinfo.c.image_width = segment_width;
Packit 85355f
	sp->cinfo.c.image_height = segment_height;
Packit 85355f
	downsampled_input = FALSE;
Packit 85355f
	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
Packit 85355f
		sp->cinfo.c.input_components = td->td_samplesperpixel;
Packit 85355f
		if (sp->photometric == PHOTOMETRIC_YCBCR) {
Packit 85355f
			if (sp->jpegcolormode != JPEGCOLORMODE_RGB) {
Packit 85355f
				if (sp->h_sampling != 1 || sp->v_sampling != 1)
Packit 85355f
					downsampled_input = TRUE;
Packit 85355f
			}
Packit 85355f
			if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr))
Packit 85355f
				return (0);
Packit 85355f
			/*
Packit 85355f
			 * Set Y sampling factors;
Packit 85355f
			 * we assume jpeg_set_colorspace() set the rest to 1
Packit 85355f
			 */
Packit 85355f
			sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling;
Packit 85355f
			sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling;
Packit 85355f
		} else {
Packit 85355f
			if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space))
Packit 85355f
				return (0);
Packit 85355f
			/* jpeg_set_colorspace set all sampling factors to 1 */
Packit 85355f
		}
Packit 85355f
	} else {
Packit 85355f
		if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN))
Packit 85355f
			return (0);
Packit 85355f
		sp->cinfo.c.comp_info[0].component_id = s;
Packit 85355f
		/* jpeg_set_colorspace() set sampling factors to 1 */
Packit 85355f
		if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) {
Packit 85355f
			sp->cinfo.c.comp_info[0].quant_tbl_no = 1;
Packit 85355f
			sp->cinfo.c.comp_info[0].dc_tbl_no = 1;
Packit 85355f
			sp->cinfo.c.comp_info[0].ac_tbl_no = 1;
Packit 85355f
		}
Packit 85355f
	}
Packit 85355f
	/* ensure libjpeg won't write any extraneous markers */
Packit 85355f
	sp->cinfo.c.write_JFIF_header = FALSE;
Packit 85355f
	sp->cinfo.c.write_Adobe_marker = FALSE;
Packit 85355f
	/* set up table handling correctly */
Packit 85355f
	/* calling TIFFjpeg_set_quality() causes quantization tables to be flagged */
Packit 85355f
	/* as being to be emitted, which we don't want in the JPEGTABLESMODE_QUANT */
Packit 85355f
	/* mode, so we must manually suppress them. However TIFFjpeg_set_quality() */
Packit 85355f
	/* should really be called when dealing with files with directories with */
Packit 85355f
	/* mixed qualities. see http://trac.osgeo.org/gdal/ticket/3539 */
Packit 85355f
	if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))
Packit 85355f
		return (0);
Packit 85355f
	if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) {
Packit 85355f
		suppress_quant_table(sp, 0);
Packit 85355f
		suppress_quant_table(sp, 1);
Packit 85355f
	}
Packit 85355f
	else {
Packit 85355f
		unsuppress_quant_table(sp, 0);
Packit 85355f
		unsuppress_quant_table(sp, 1);
Packit 85355f
	}
Packit 85355f
	if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF)
Packit 85355f
	{
Packit 85355f
		/* Explicit suppression is only needed if we did not go through the */
Packit 85355f
		/* prepare_JPEGTables() code path, which may be the case if updating */
Packit 85355f
		/* an existing file */
Packit 85355f
		suppress_huff_table(sp, 0);
Packit 85355f
		suppress_huff_table(sp, 1);
Packit 85355f
		sp->cinfo.c.optimize_coding = FALSE;
Packit 85355f
	}
Packit 85355f
	else
Packit 85355f
		sp->cinfo.c.optimize_coding = TRUE;
Packit 85355f
	if (downsampled_input) {
Packit 85355f
		/* Need to use raw-data interface to libjpeg */
Packit 85355f
		sp->cinfo.c.raw_data_in = TRUE;
Packit 85355f
		tif->tif_encoderow = JPEGEncodeRaw;
Packit 85355f
		tif->tif_encodestrip = JPEGEncodeRaw;
Packit 85355f
		tif->tif_encodetile = JPEGEncodeRaw;
Packit 85355f
	} else {
Packit 85355f
		/* Use normal interface to libjpeg */
Packit 85355f
		sp->cinfo.c.raw_data_in = FALSE;
Packit 85355f
		tif->tif_encoderow = JPEGEncode;
Packit 85355f
		tif->tif_encodestrip = JPEGEncode;
Packit 85355f
		tif->tif_encodetile = JPEGEncode;
Packit 85355f
	}
Packit 85355f
	/* Start JPEG compressor */
Packit 85355f
	if (!TIFFjpeg_start_compress(sp, FALSE))
Packit 85355f
		return (0);
Packit 85355f
	/* Allocate downsampled-data buffers if needed */
Packit 85355f
	if (downsampled_input) {
Packit 85355f
		if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info,
Packit 85355f
					       sp->cinfo.c.num_components))
Packit 85355f
			return (0);
Packit 85355f
	}
Packit 85355f
	sp->scancount = 0;
Packit 85355f
Packit 85355f
	return (1);
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Encode a chunk of pixels.
Packit 85355f
 * "Standard" case: incoming data is not downsampled.
Packit 85355f
 */
Packit 85355f
static int
Packit 85355f
JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
Packit 85355f
{
Packit 85355f
	JPEGState *sp = JState(tif);
Packit 85355f
	tmsize_t nrows;
Packit 85355f
	JSAMPROW bufptr[1];
Packit 85355f
        short *line16 = NULL;
Packit 85355f
        int    line16_count = 0;
Packit 85355f
Packit 85355f
	(void) s;
Packit 85355f
	assert(sp != NULL);
Packit 85355f
	/* data is expected to be supplied in multiples of a scanline */
Packit 85355f
	nrows = cc / sp->bytesperline;
Packit 85355f
	if (cc % sp->bytesperline)
Packit 85355f
            TIFFWarningExt(tif->tif_clientdata, tif->tif_name, 
Packit 85355f
                           "fractional scanline discarded");
Packit 85355f
Packit 85355f
        /* The last strip will be limited to image size */
Packit 85355f
        if( !isTiled(tif) && tif->tif_row+nrows > tif->tif_dir.td_imagelength )
Packit 85355f
            nrows = tif->tif_dir.td_imagelength - tif->tif_row;
Packit 85355f
Packit 85355f
        if( sp->cinfo.c.data_precision == 12 )
Packit 85355f
        {
Packit 85355f
            line16_count = (int)((sp->bytesperline * 2) / 3);
Packit 85355f
            line16 = (short *) _TIFFmalloc(sizeof(short) * line16_count);
Packit 85355f
            if (!line16)
Packit 85355f
            {
Packit 85355f
                TIFFErrorExt(tif->tif_clientdata,
Packit 85355f
			     "JPEGEncode",
Packit 85355f
                             "Failed to allocate memory");
Packit 85355f
Packit 85355f
                return 0;
Packit 85355f
            }
Packit 85355f
        }
Packit 85355f
            
Packit 85355f
	while (nrows-- > 0) {
Packit 85355f
Packit 85355f
            if( sp->cinfo.c.data_precision == 12 )
Packit 85355f
            {
Packit 85355f
Packit 85355f
                int value_pairs = line16_count / 2;
Packit 85355f
                int iPair;
Packit 85355f
Packit 85355f
		bufptr[0] = (JSAMPROW) line16;
Packit 85355f
Packit 85355f
                for( iPair = 0; iPair < value_pairs; iPair++ )
Packit 85355f
                {
Packit 85355f
                    unsigned char *in_ptr =
Packit 85355f
                        ((unsigned char *) buf) + iPair * 3;
Packit 85355f
                    JSAMPLE *out_ptr = (JSAMPLE *) (line16 + iPair * 2);
Packit 85355f
Packit 85355f
                    out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4);
Packit 85355f
                    out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2];
Packit 85355f
                }
Packit 85355f
            }
Packit 85355f
            else
Packit 85355f
            {
Packit 85355f
		bufptr[0] = (JSAMPROW) buf;
Packit 85355f
            }
Packit 85355f
            if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1)
Packit 85355f
                return (0);
Packit 85355f
            if (nrows > 0)
Packit 85355f
                tif->tif_row++;
Packit 85355f
            buf += sp->bytesperline;
Packit 85355f
	}
Packit 85355f
Packit 85355f
        if( sp->cinfo.c.data_precision == 12 )
Packit 85355f
        {
Packit 85355f
            _TIFFfree( line16 );
Packit 85355f
        }
Packit 85355f
            
Packit 85355f
	return (1);
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Encode a chunk of pixels.
Packit 85355f
 * Incoming data is expected to be downsampled per sampling factors.
Packit 85355f
 */
Packit 85355f
static int
Packit 85355f
JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
Packit 85355f
{
Packit 85355f
	JPEGState *sp = JState(tif);
Packit 85355f
	JSAMPLE* inptr;
Packit 85355f
	JSAMPLE* outptr;
Packit 85355f
	tmsize_t nrows;
Packit 85355f
	JDIMENSION clumps_per_line, nclump;
Packit 85355f
	int clumpoffset, ci, xpos, ypos;
Packit 85355f
	jpeg_component_info* compptr;
Packit 85355f
	int samples_per_clump = sp->samplesperclump;
Packit 85355f
	tmsize_t bytesperclumpline;
Packit 85355f
Packit 85355f
	(void) s;
Packit 85355f
	assert(sp != NULL);
Packit 85355f
	/* data is expected to be supplied in multiples of a clumpline */
Packit 85355f
	/* a clumpline is equivalent to v_sampling desubsampled scanlines */
Packit 85355f
	/* TODO: the following calculation of bytesperclumpline, should substitute calculation of sp->bytesperline, except that it is per v_sampling lines */
Packit 85355f
	bytesperclumpline = (((sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling)
Packit 85355f
			     *(sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7)
Packit 85355f
			    /8;
Packit 85355f
Packit 85355f
	nrows = ( cc / bytesperclumpline ) * sp->v_sampling;
Packit 85355f
	if (cc % bytesperclumpline)
Packit 85355f
		TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline discarded");
Packit 85355f
Packit 85355f
	/* Cb,Cr both have sampling factors 1, so this is correct */
Packit 85355f
	clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width;
Packit 85355f
Packit 85355f
	while (nrows > 0) {
Packit 85355f
		/*
Packit 85355f
		 * Fastest way to separate the data is to make one pass
Packit 85355f
		 * over the scanline for each row of each component.
Packit 85355f
		 */
Packit 85355f
		clumpoffset = 0;		/* first sample in clump */
Packit 85355f
		for (ci = 0, compptr = sp->cinfo.c.comp_info;
Packit 85355f
		     ci < sp->cinfo.c.num_components;
Packit 85355f
		     ci++, compptr++) {
Packit 85355f
		    int hsamp = compptr->h_samp_factor;
Packit 85355f
		    int vsamp = compptr->v_samp_factor;
Packit 85355f
		    int padding = (int) (compptr->width_in_blocks * DCTSIZE -
Packit 85355f
					 clumps_per_line * hsamp);
Packit 85355f
		    for (ypos = 0; ypos < vsamp; ypos++) {
Packit 85355f
			inptr = ((JSAMPLE*) buf) + clumpoffset;
Packit 85355f
			outptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];
Packit 85355f
			if (hsamp == 1) {
Packit 85355f
			    /* fast path for at least Cb and Cr */
Packit 85355f
			    for (nclump = clumps_per_line; nclump-- > 0; ) {
Packit 85355f
				*outptr++ = inptr[0];
Packit 85355f
				inptr += samples_per_clump;
Packit 85355f
			    }
Packit 85355f
			} else {
Packit 85355f
			    /* general case */
Packit 85355f
			    for (nclump = clumps_per_line; nclump-- > 0; ) {
Packit 85355f
				for (xpos = 0; xpos < hsamp; xpos++)
Packit 85355f
				    *outptr++ = inptr[xpos];
Packit 85355f
				inptr += samples_per_clump;
Packit 85355f
			    }
Packit 85355f
			}
Packit 85355f
			/* pad each scanline as needed */
Packit 85355f
			for (xpos = 0; xpos < padding; xpos++) {
Packit 85355f
			    *outptr = outptr[-1];
Packit 85355f
			    outptr++;
Packit 85355f
			}
Packit 85355f
			clumpoffset += hsamp;
Packit 85355f
		    }
Packit 85355f
		}
Packit 85355f
		sp->scancount++;
Packit 85355f
		if (sp->scancount >= DCTSIZE) {
Packit 85355f
			int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
Packit 85355f
			if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
Packit 85355f
				return (0);
Packit 85355f
			sp->scancount = 0;
Packit 85355f
		}
Packit 85355f
		tif->tif_row += sp->v_sampling;
Packit 85355f
		buf += bytesperclumpline;
Packit 85355f
		nrows -= sp->v_sampling;
Packit 85355f
	}
Packit 85355f
	return (1);
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Finish up at the end of a strip or tile.
Packit 85355f
 */
Packit 85355f
static int
Packit 85355f
JPEGPostEncode(TIFF* tif)
Packit 85355f
{
Packit 85355f
	JPEGState *sp = JState(tif);
Packit 85355f
Packit 85355f
	if (sp->scancount > 0) {
Packit 85355f
		/*
Packit 85355f
		 * Need to emit a partial bufferload of downsampled data.
Packit 85355f
		 * Pad the data vertically.
Packit 85355f
		 */
Packit 85355f
		int ci, ypos, n;
Packit 85355f
		jpeg_component_info* compptr;
Packit 85355f
Packit 85355f
		for (ci = 0, compptr = sp->cinfo.c.comp_info;
Packit 85355f
		     ci < sp->cinfo.c.num_components;
Packit 85355f
		     ci++, compptr++) {
Packit 85355f
			int vsamp = compptr->v_samp_factor;
Packit 85355f
			tmsize_t row_width = compptr->width_in_blocks * DCTSIZE
Packit 85355f
				* sizeof(JSAMPLE);
Packit 85355f
			for (ypos = sp->scancount * vsamp;
Packit 85355f
			     ypos < DCTSIZE * vsamp; ypos++) {
Packit 85355f
				_TIFFmemcpy((void*)sp->ds_buffer[ci][ypos],
Packit 85355f
					    (void*)sp->ds_buffer[ci][ypos-1],
Packit 85355f
					    row_width);
Packit 85355f
Packit 85355f
			}
Packit 85355f
		}
Packit 85355f
		n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
Packit 85355f
		if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
Packit 85355f
			return (0);
Packit 85355f
	}
Packit 85355f
Packit 85355f
	return (TIFFjpeg_finish_compress(JState(tif)));
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
JPEGCleanup(TIFF* tif)
Packit 85355f
{
Packit 85355f
	JPEGState *sp = JState(tif);
Packit 85355f
	
Packit 85355f
	assert(sp != 0);
Packit 85355f
Packit 85355f
	tif->tif_tagmethods.vgetfield = sp->vgetparent;
Packit 85355f
	tif->tif_tagmethods.vsetfield = sp->vsetparent;
Packit 85355f
	tif->tif_tagmethods.printdir = sp->printdir;
Packit 85355f
        if( sp->cinfo_initialized )
Packit 85355f
                TIFFjpeg_destroy(sp);	/* release libjpeg resources */
Packit 85355f
        if (sp->jpegtables)		/* tag value */
Packit 85355f
                _TIFFfree(sp->jpegtables);
Packit 85355f
	_TIFFfree(tif->tif_data);	/* release local state */
Packit 85355f
	tif->tif_data = NULL;
Packit 85355f
Packit 85355f
	_TIFFSetDefaultCompressionState(tif);
Packit 85355f
}
Packit 85355f
Packit 85355f
static void 
Packit 85355f
JPEGResetUpsampled( TIFF* tif )
Packit 85355f
{
Packit 85355f
	JPEGState* sp = JState(tif);
Packit 85355f
	TIFFDirectory* td = &tif->tif_dir;
Packit 85355f
Packit 85355f
	/*
Packit 85355f
	 * Mark whether returned data is up-sampled or not so TIFFStripSize
Packit 85355f
	 * and TIFFTileSize return values that reflect the true amount of
Packit 85355f
	 * data.
Packit 85355f
	 */
Packit 85355f
	tif->tif_flags &= ~TIFF_UPSAMPLED;
Packit 85355f
	if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
Packit 85355f
		if (td->td_photometric == PHOTOMETRIC_YCBCR &&
Packit 85355f
		    sp->jpegcolormode == JPEGCOLORMODE_RGB) {
Packit 85355f
			tif->tif_flags |= TIFF_UPSAMPLED;
Packit 85355f
		} else {
Packit 85355f
#ifdef notdef
Packit 85355f
			if (td->td_ycbcrsubsampling[0] != 1 ||
Packit 85355f
			    td->td_ycbcrsubsampling[1] != 1)
Packit 85355f
				; /* XXX what about up-sampling? */
Packit 85355f
#endif
Packit 85355f
		}
Packit 85355f
	}
Packit 85355f
Packit 85355f
	/*
Packit 85355f
	 * Must recalculate cached tile size in case sampling state changed.
Packit 85355f
	 * Should we really be doing this now if image size isn't set? 
Packit 85355f
	 */
Packit 85355f
        if( tif->tif_tilesize > 0 )
Packit 85355f
            tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);   
Packit 85355f
        if( tif->tif_scanlinesize > 0 )
Packit 85355f
            tif->tif_scanlinesize = TIFFScanlineSize(tif); 
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
JPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = JState(tif);
Packit 85355f
	const TIFFField* fip;
Packit 85355f
	uint32 v32;
Packit 85355f
Packit 85355f
	assert(sp != NULL);
Packit 85355f
Packit 85355f
	switch (tag) {
Packit 85355f
	case TIFFTAG_JPEGTABLES:
Packit 85355f
		v32 = (uint32) va_arg(ap, uint32);
Packit 85355f
		if (v32 == 0) {
Packit 85355f
			/* XXX */
Packit 85355f
			return (0);
Packit 85355f
		}
Packit 85355f
		_TIFFsetByteArray(&sp->jpegtables, va_arg(ap, void*), v32);
Packit 85355f
		sp->jpegtables_length = v32;
Packit 85355f
		TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
Packit 85355f
		break;
Packit 85355f
	case TIFFTAG_JPEGQUALITY:
Packit 85355f
		sp->jpegquality = (int) va_arg(ap, int);
Packit 85355f
		return (1);			/* pseudo tag */
Packit 85355f
	case TIFFTAG_JPEGCOLORMODE:
Packit 85355f
		sp->jpegcolormode = (int) va_arg(ap, int);
Packit 85355f
		JPEGResetUpsampled( tif );
Packit 85355f
		return (1);			/* pseudo tag */
Packit 85355f
	case TIFFTAG_PHOTOMETRIC:
Packit 85355f
	{
Packit 85355f
		int ret_value = (*sp->vsetparent)(tif, tag, ap);
Packit 85355f
		JPEGResetUpsampled( tif );
Packit 85355f
		return ret_value;
Packit 85355f
	}
Packit 85355f
	case TIFFTAG_JPEGTABLESMODE:
Packit 85355f
		sp->jpegtablesmode = (int) va_arg(ap, int);
Packit 85355f
		return (1);			/* pseudo tag */
Packit 85355f
	case TIFFTAG_YCBCRSUBSAMPLING:
Packit 85355f
		/* mark the fact that we have a real ycbcrsubsampling! */
Packit 85355f
		sp->ycbcrsampling_fetched = 1;
Packit 85355f
		/* should we be recomputing upsampling info here? */
Packit 85355f
		return (*sp->vsetparent)(tif, tag, ap);
Packit 85355f
	default:
Packit 85355f
		return (*sp->vsetparent)(tif, tag, ap);
Packit 85355f
	}
Packit 85355f
Packit 85355f
	if ((fip = TIFFFieldWithTag(tif, tag)) != NULL) {
Packit 85355f
		TIFFSetFieldBit(tif, fip->field_bit);
Packit 85355f
	} else {
Packit 85355f
		return (0);
Packit 85355f
	}
Packit 85355f
Packit 85355f
	tif->tif_flags |= TIFF_DIRTYDIRECT;
Packit 85355f
	return (1);
Packit 85355f
}
Packit 85355f
Packit 85355f
static int
Packit 85355f
JPEGVGetField(TIFF* tif, uint32 tag, va_list ap)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = JState(tif);
Packit 85355f
Packit 85355f
	assert(sp != NULL);
Packit 85355f
Packit 85355f
	switch (tag) {
Packit 85355f
		case TIFFTAG_JPEGTABLES:
Packit 85355f
			*va_arg(ap, uint32*) = sp->jpegtables_length;
Packit 85355f
			*va_arg(ap, void**) = sp->jpegtables;
Packit 85355f
			break;
Packit 85355f
		case TIFFTAG_JPEGQUALITY:
Packit 85355f
			*va_arg(ap, int*) = sp->jpegquality;
Packit 85355f
			break;
Packit 85355f
		case TIFFTAG_JPEGCOLORMODE:
Packit 85355f
			*va_arg(ap, int*) = sp->jpegcolormode;
Packit 85355f
			break;
Packit 85355f
		case TIFFTAG_JPEGTABLESMODE:
Packit 85355f
			*va_arg(ap, int*) = sp->jpegtablesmode;
Packit 85355f
			break;
Packit 85355f
		default:
Packit 85355f
			return (*sp->vgetparent)(tif, tag, ap);
Packit 85355f
	}
Packit 85355f
	return (1);
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
JPEGPrintDir(TIFF* tif, FILE* fd, long flags)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = JState(tif);
Packit 85355f
Packit 85355f
	assert(sp != NULL);
Packit 85355f
	(void) flags;
Packit 85355f
Packit 85355f
        if( sp != NULL ) {
Packit 85355f
		if (TIFFFieldSet(tif,FIELD_JPEGTABLES))
Packit 85355f
			fprintf(fd, "  JPEG Tables: (%lu bytes)\n",
Packit 85355f
				(unsigned long) sp->jpegtables_length);
Packit 85355f
		if (sp->printdir)
Packit 85355f
			(*sp->printdir)(tif, fd, flags);
Packit 85355f
	}
Packit 85355f
}
Packit 85355f
Packit 85355f
static uint32
Packit 85355f
JPEGDefaultStripSize(TIFF* tif, uint32 s)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = JState(tif);
Packit 85355f
	TIFFDirectory *td = &tif->tif_dir;
Packit 85355f
Packit 85355f
	s = (*sp->defsparent)(tif, s);
Packit 85355f
	if (s < td->td_imagelength)
Packit 85355f
		s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE);
Packit 85355f
	return (s);
Packit 85355f
}
Packit 85355f
Packit 85355f
static void
Packit 85355f
JPEGDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
Packit 85355f
{
Packit 85355f
	JPEGState* sp = JState(tif);
Packit 85355f
	TIFFDirectory *td = &tif->tif_dir;
Packit 85355f
Packit 85355f
	(*sp->deftparent)(tif, tw, th);
Packit 85355f
	*tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE);
Packit 85355f
	*th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE);
Packit 85355f
}
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * The JPEG library initialized used to be done in TIFFInitJPEG(), but
Packit 85355f
 * now that we allow a TIFF file to be opened in update mode it is necessary
Packit 85355f
 * to have some way of deciding whether compression or decompression is
Packit 85355f
 * desired other than looking at tif->tif_mode.  We accomplish this by 
Packit 85355f
 * examining {TILE/STRIP}BYTECOUNTS to see if there is a non-zero entry.
Packit 85355f
 * If so, we assume decompression is desired. 
Packit 85355f
 *
Packit 85355f
 * This is tricky, because TIFFInitJPEG() is called while the directory is
Packit 85355f
 * being read, and generally speaking the BYTECOUNTS tag won't have been read
Packit 85355f
 * at that point.  So we try to defer jpeg library initialization till we
Packit 85355f
 * do have that tag ... basically any access that might require the compressor
Packit 85355f
 * or decompressor that occurs after the reading of the directory. 
Packit 85355f
 *
Packit 85355f
 * In an ideal world compressors or decompressors would be setup
Packit 85355f
 * at the point where a single tile or strip was accessed (for read or write)
Packit 85355f
 * so that stuff like update of missing tiles, or replacement of tiles could
Packit 85355f
 * be done. However, we aren't trying to crack that nut just yet ...
Packit 85355f
 *
Packit 85355f
 * NFW, Feb 3rd, 2003.
Packit 85355f
 */
Packit 85355f
Packit 85355f
static int JPEGInitializeLibJPEG( TIFF * tif, int decompress )
Packit 85355f
{
Packit 85355f
    JPEGState* sp = JState(tif);
Packit 85355f
Packit 85355f
    if(sp->cinfo_initialized)
Packit 85355f
    {
Packit 85355f
        if( !decompress && sp->cinfo.comm.is_decompressor )
Packit 85355f
            TIFFjpeg_destroy( sp );
Packit 85355f
        else if( decompress && !sp->cinfo.comm.is_decompressor )
Packit 85355f
            TIFFjpeg_destroy( sp );
Packit 85355f
        else
Packit 85355f
            return 1;
Packit 85355f
Packit 85355f
        sp->cinfo_initialized = 0;
Packit 85355f
    }
Packit 85355f
Packit 85355f
    /*
Packit 85355f
     * Initialize libjpeg.
Packit 85355f
     */
Packit 85355f
    if ( decompress ) {
Packit 85355f
        if (!TIFFjpeg_create_decompress(sp))
Packit 85355f
            return (0);
Packit 85355f
    } else {
Packit 85355f
        if (!TIFFjpeg_create_compress(sp))
Packit 85355f
            return (0);
Packit 85355f
#ifndef TIFF_JPEG_MAX_MEMORY_TO_USE
Packit 85355f
#define TIFF_JPEG_MAX_MEMORY_TO_USE (10 * 1024 * 1024)
Packit 85355f
#endif
Packit 85355f
        /* libjpeg turbo 1.5.2 honours max_memory_to_use, but has no backing */
Packit 85355f
        /* store implementation, so better not set max_memory_to_use ourselves. */
Packit 85355f
        /* See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 */
Packit 85355f
        if( sp->cinfo.c.mem->max_memory_to_use > 0 )
Packit 85355f
        {
Packit 85355f
            /* This is to address bug related in ticket GDAL #1795. */
Packit 85355f
            if (getenv("JPEGMEM") == NULL)
Packit 85355f
            {
Packit 85355f
                /* Increase the max memory usable. This helps when creating files */
Packit 85355f
                /* with "big" tile, without using libjpeg temporary files. */
Packit 85355f
                /* For example a 512x512 tile with 3 bands */
Packit 85355f
                /* requires 1.5 MB which is above libjpeg 1MB default */
Packit 85355f
                if( sp->cinfo.c.mem->max_memory_to_use < TIFF_JPEG_MAX_MEMORY_TO_USE )
Packit 85355f
                    sp->cinfo.c.mem->max_memory_to_use = TIFF_JPEG_MAX_MEMORY_TO_USE;
Packit 85355f
            }
Packit 85355f
        }
Packit 85355f
    }
Packit 85355f
Packit 85355f
    sp->cinfo_initialized = TRUE;
Packit 85355f
Packit 85355f
    return 1;
Packit 85355f
}
Packit 85355f
Packit 85355f
int
Packit 85355f
TIFFInitJPEG(TIFF* tif, int scheme)
Packit 85355f
{
Packit 85355f
	JPEGState* sp;
Packit 85355f
Packit 85355f
	assert(scheme == COMPRESSION_JPEG);
Packit 85355f
Packit 85355f
	/*
Packit 85355f
	 * Merge codec-specific tag information.
Packit 85355f
	 */
Packit 85355f
	if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields))) {
Packit 85355f
		TIFFErrorExt(tif->tif_clientdata,
Packit 85355f
			     "TIFFInitJPEG",
Packit 85355f
			     "Merging JPEG codec-specific tags failed");
Packit 85355f
		return 0;
Packit 85355f
	}
Packit 85355f
Packit 85355f
	/*
Packit 85355f
	 * Allocate state block so tag methods have storage to record values.
Packit 85355f
	 */
Packit 85355f
	tif->tif_data = (uint8*) _TIFFmalloc(sizeof (JPEGState));
Packit 85355f
Packit 85355f
	if (tif->tif_data == NULL) {
Packit 85355f
		TIFFErrorExt(tif->tif_clientdata,
Packit 85355f
			     "TIFFInitJPEG", "No space for JPEG state block");
Packit 85355f
		return 0;
Packit 85355f
	}
Packit 85355f
        _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState));
Packit 85355f
Packit 85355f
	sp = JState(tif);
Packit 85355f
	sp->tif = tif;				/* back link */
Packit 85355f
Packit 85355f
	/*
Packit 85355f
	 * Override parent get/set field methods.
Packit 85355f
	 */
Packit 85355f
	sp->vgetparent = tif->tif_tagmethods.vgetfield;
Packit 85355f
	tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */
Packit 85355f
	sp->vsetparent = tif->tif_tagmethods.vsetfield;
Packit 85355f
	tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */
Packit 85355f
	sp->printdir = tif->tif_tagmethods.printdir;
Packit 85355f
	tif->tif_tagmethods.printdir = JPEGPrintDir;   /* hook for codec tags */
Packit 85355f
Packit 85355f
	/* Default values for codec-specific fields */
Packit 85355f
	sp->jpegtables = NULL;
Packit 85355f
	sp->jpegtables_length = 0;
Packit 85355f
	sp->jpegquality = 75;			/* Default IJG quality */
Packit 85355f
	sp->jpegcolormode = JPEGCOLORMODE_RAW;
Packit 85355f
	sp->jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF;
Packit 85355f
        sp->ycbcrsampling_fetched = 0;
Packit 85355f
Packit 85355f
	/*
Packit 85355f
	 * Install codec methods.
Packit 85355f
	 */
Packit 85355f
	tif->tif_fixuptags = JPEGFixupTags;
Packit 85355f
	tif->tif_setupdecode = JPEGSetupDecode;
Packit 85355f
	tif->tif_predecode = JPEGPreDecode;
Packit 85355f
	tif->tif_decoderow = JPEGDecode;
Packit 85355f
	tif->tif_decodestrip = JPEGDecode;
Packit 85355f
	tif->tif_decodetile = JPEGDecode;
Packit 85355f
	tif->tif_setupencode = JPEGSetupEncode;
Packit 85355f
	tif->tif_preencode = JPEGPreEncode;
Packit 85355f
	tif->tif_postencode = JPEGPostEncode;
Packit 85355f
	tif->tif_encoderow = JPEGEncode;
Packit 85355f
	tif->tif_encodestrip = JPEGEncode;
Packit 85355f
	tif->tif_encodetile = JPEGEncode;  
Packit 85355f
	tif->tif_cleanup = JPEGCleanup;
Packit 85355f
	sp->defsparent = tif->tif_defstripsize;
Packit 85355f
	tif->tif_defstripsize = JPEGDefaultStripSize;
Packit 85355f
	sp->deftparent = tif->tif_deftilesize;
Packit 85355f
	tif->tif_deftilesize = JPEGDefaultTileSize;
Packit 85355f
	tif->tif_flags |= TIFF_NOBITREV;	/* no bit reversal, please */
Packit 85355f
Packit 85355f
        sp->cinfo_initialized = FALSE;
Packit 85355f
Packit 85355f
	/*
Packit 85355f
        ** Create a JPEGTables field if no directory has yet been created. 
Packit 85355f
        ** We do this just to ensure that sufficient space is reserved for
Packit 85355f
        ** the JPEGTables field.  It will be properly created the right
Packit 85355f
        ** size later. 
Packit 85355f
        */
Packit 85355f
        if( tif->tif_diroff == 0 )
Packit 85355f
        {
Packit 85355f
#define SIZE_OF_JPEGTABLES 2000
Packit 85355f
/*
Packit 85355f
The following line assumes incorrectly that all JPEG-in-TIFF files will have
Packit 85355f
a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags to be written
Packit 85355f
when the JPEG data is placed with TIFFWriteRawStrip.  The field bit should be 
Packit 85355f
set, anyway, later when actual JPEGTABLES header is generated, so removing it 
Packit 85355f
here hopefully is harmless.
Packit 85355f
            TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
Packit 85355f
*/
Packit 85355f
            sp->jpegtables_length = SIZE_OF_JPEGTABLES;
Packit 85355f
            sp->jpegtables = (void *) _TIFFmalloc(sp->jpegtables_length);
Packit 85355f
            if (sp->jpegtables)
Packit 85355f
            {
Packit 85355f
                _TIFFmemset(sp->jpegtables, 0, SIZE_OF_JPEGTABLES);
Packit 85355f
            }
Packit 85355f
            else
Packit 85355f
            {
Packit 85355f
                TIFFErrorExt(tif->tif_clientdata,
Packit 85355f
			     "TIFFInitJPEG",
Packit 85355f
                             "Failed to allocate memory for JPEG tables");
Packit 85355f
                return 0;
Packit 85355f
            }
Packit 85355f
#undef SIZE_OF_JPEGTABLES
Packit 85355f
        }
Packit 85355f
Packit 85355f
	return 1;
Packit 85355f
}
Packit 85355f
#endif /* JPEG_SUPPORT */
Packit 85355f
Packit 85355f
/* vim: set ts=8 sts=8 sw=8 noet: */
Packit 85355f
Packit 85355f
/*
Packit 85355f
 * Local Variables:
Packit 85355f
 * mode: c
Packit 85355f
 * c-basic-offset: 8
Packit 85355f
 * fill-column: 78
Packit 85355f
 * End:
Packit 85355f
 */