#include "tiffiop.h"
#ifdef OJPEG_SUPPORT
/* JPEG Compression support, as per the original TIFF 6.0 specification.
WARNING: KLUDGE ALERT! The type of JPEG encapsulation defined by the TIFF
Version 6.0 specification is now totally obsolete and
deprecated for new applications and images. This file is an unsupported hack
that was created solely in order to read (but NOT write!) a few old,
unconverted images still present on some users' computer systems. The code
isn't pretty or robust, and it won't read every "old format" JPEG-in-TIFF
file (see Samuel Leffler's draft "TIFF Technical Note No. 2" for a long and
incomplete list of known problems), but it seems to work well enough in the
few cases of practical interest to the author; so, "caveat emptor"! This
file should NEVER be enhanced to write new images using anything other than
the latest approved JPEG-in-TIFF encapsulation method, implemented by the
"tif_jpeg.c" file elsewhere in this library.
This file interfaces with Release 6B of the JPEG Library written by theu
Independent JPEG Group, which you can find on the Internet at:
ftp.uu.net:/graphics/jpeg/.
Contributed by Scott Marovich <marovich@hpl.hp.com> with considerable help
from Charles Auer <Bumble731@msn.com> to unravel the mysteries of image files
created by Microsoft's Wang Imaging application.
*/
#include <setjmp.h>
#include <stdio.h>
#ifdef FAR
#undef FAR /* Undefine FAR to avoid conflict with JPEG definition */
#endif
#define JPEG_INTERNALS /* Include "jpegint.h" for "DSTATE_*" symbols */
#undef INLINE
#include "../jpeg/jpeglib.h"
#undef JPEG_INTERNALS
/* Hack for Microsoft's Wang Imaging for Windows output files */
extern void jpeg_reset_huff_decode(j_decompress_ptr,float *);
/* On some machines, it may be worthwhile to use "_setjmp()" or "sigsetjmp()"
instead of "setjmp()". These macros make it easier:
*/
#define SETJMP(jbuf)setjmp(jbuf)
#define LONGJMP(jbuf,code)longjmp(jbuf,code)
#define JMP_BUF jmp_buf
#define TIFFTAG_WANG_PAGECONTROL 32934
/* Bit-vector offsets for keeping track of TIFF records that we've parsed. */
#define FIELD_JPEGPROC FIELD_CODEC
#define FIELD_JPEGIFOFFSET (FIELD_CODEC+1)
#define FIELD_JPEGIFBYTECOUNT (FIELD_CODEC+2)
#define FIELD_JPEGRESTARTINTERVAL (FIELD_CODEC+3)
#define FIELD_JPEGTABLES (FIELD_CODEC+4) /* New, post-6.0 JPEG-in-TIFF tag! */
#define FIELD_JPEGLOSSLESSPREDICTORS (FIELD_CODEC+5)
#define FIELD_JPEGPOINTTRANSFORM (FIELD_CODEC+6)
#define FIELD_JPEGQTABLES (FIELD_CODEC+7)
#define FIELD_JPEGDCTABLES (FIELD_CODEC+8)
#define FIELD_JPEGACTABLES (FIELD_CODEC+9)
#define FIELD_WANG_PAGECONTROL (FIELD_CODEC+10)
#define FIELD_JPEGCOLORMODE (FIELD_CODEC+11)
typedef struct jpeg_destination_mgr jpeg_destination_mgr;
typedef struct jpeg_source_mgr jpeg_source_mgr;
typedef struct jpeg_error_mgr jpeg_error_mgr;
/* State variable for each open TIFF file that uses "libjpeg" for JPEG
decompression. (Note: This file should NEVER perform JPEG compression
except in the manner implemented by the "tif_jpeg.c" file, elsewhere in this
library; see comments above.) JPEG Library internal state is recorded in a
"jpeg_{de}compress_struct", while a "jpeg_common_struct" records a few items
common to both compression and expansion. The "cinfo" field containing JPEG
Library state MUST be the 1st member of our own state variable, so that we
can safely "cast" pointers back and forth.
*/
typedef struct /* This module's private, per-image state variable */
{
union /* JPEG Library state variable; this MUST be our 1st field! */
{
/* struct jpeg_compress_struct c; */
struct jpeg_decompress_struct d;
struct jpeg_common_struct comm;
} cinfo;
jpeg_error_mgr err; /* JPEG Library error manager */
JMP_BUF exit_jmpbuf; /* ...for catching JPEG Library failures */
# ifdef never
/* (The following two fields could be a "union", but they're small enough that
it's not worth the effort.)
*/
jpeg_destination_mgr dest; /* Destination for compressed data */
# endif
jpeg_source_mgr src; /* Source of expanded data */
JSAMPARRAY ds_buffer[MAX_COMPONENTS]; /* ->Temporary downsampling buffers */
TIFF *tif; /* Reverse pointer, needed by some code */
TIFFVGetMethod vgetparent; /* "Super class" methods... */
TIFFVSetMethod vsetparent;
TIFFStripMethod defsparent;
TIFFTileMethod deftparent;
void *jpegtables; /* ->"New" JPEG tables, if we synthesized any */
uint32 is_WANG, /* <=> Microsoft Wang Imaging for Windows output file? */
jpegtables_length; /* Length of "new" JPEG tables, if they exist */
tsize_t bytesperline; /* No. of decompressed Bytes per scan line */
int jpegquality, /* Compression quality level */
jpegtablesmode, /* What to put in JPEGTables */
samplesperclump,
scancount; /* No. of scan lines accumulated */
uint16 h_sampling, /* Luminance sampling factors */
v_sampling,
photometric; /* Copy of "PhotometricInterpretation" tag value */
u_char jpegcolormode; /* Who performs RGB <-> YCbCr conversion? */
/* JPEGCOLORMODE_RAW <=> TIFF Library does conversion */
/* JPEGCOLORMODE_RGB <=> JPEG Library does conversion */
} OJPEGState;
#define OJState(tif)((OJPEGState*)(tif)->tif_data)
static const TIFFFieldInfo ojpegFieldInfo[]=/* JPEG-specific TIFF-record tags */
{
/* This is the current JPEG-in-TIFF metadata-encapsulation tag, and its
treatment in this file is idiosyncratic. It should never appear in a
"source" image conforming to the TIFF Version 6.0 specification, so we
arrange to report an error if it appears. But in order to support possible
future conversion of "old" JPEG-in-TIFF encapsulations to "new" ones, we
might wish to synthesize an equivalent value to be returned by the TIFF
Library's "getfield" method. So, this table tells the TIFF Library to pass
these records to us in order to filter them below.
*/
{
TIFFTAG_JPEGTABLES ,TIFF_VARIABLE,TIFF_VARIABLE,
TIFF_UNDEFINED,FIELD_JPEGTABLES ,FALSE,TRUE ,"JPEGTables"
},
/* These tags are defined by the TIFF Version 6.0 specification and are now
obsolete. This module reads them from an old "source" image, but it never
writes them to a new "destination" image.
*/
{
TIFFTAG_JPEGPROC ,1 ,1 ,
TIFF_SHORT ,FIELD_JPEGPROC ,FALSE,FALSE,"JPEGProc"
},
{
TIFFTAG_JPEGIFOFFSET ,1 ,1 ,
TIFF_LONG ,FIELD_JPEGIFOFFSET ,FALSE,FALSE,"JPEGInterchangeFormat"
},
{
TIFFTAG_JPEGIFBYTECOUNT ,1 ,1 ,
TIFF_LONG ,FIELD_JPEGIFBYTECOUNT ,FALSE,FALSE,"JPEGInterchangeFormatLength"
},
{
TIFFTAG_JPEGRESTARTINTERVAL ,1 ,1 ,
TIFF_SHORT ,FIELD_JPEGRESTARTINTERVAL ,FALSE,FALSE,"JPEGRestartInterval"
},
{
TIFFTAG_JPEGLOSSLESSPREDICTORS,TIFF_VARIABLE,TIFF_VARIABLE,
TIFF_SHORT ,FIELD_JPEGLOSSLESSPREDICTORS,FALSE,TRUE ,"JPEGLosslessPredictors"
},
{
TIFFTAG_JPEGPOINTTRANSFORM ,TIFF_VARIABLE,TIFF_VARIABLE,
TIFF_SHORT ,FIELD_JPEGPOINTTRANSFORM ,FALSE,TRUE ,"JPEGPointTransforms"
},
{
TIFFTAG_JPEGQTABLES ,TIFF_VARIABLE,TIFF_VARIABLE,
TIFF_LONG ,FIELD_JPEGQTABLES ,FALSE,TRUE ,"JPEGQTables"
},