xref: /aosp_15_r20/external/pdfium/third_party/libtiff/tif_jpeg.c (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker /*
2*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 1994-1997 Sam Leffler
3*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 1994-1997 Silicon Graphics, Inc.
4*3ac0a46fSAndroid Build Coastguard Worker  *
5*3ac0a46fSAndroid Build Coastguard Worker  * Permission to use, copy, modify, distribute, and sell this software and
6*3ac0a46fSAndroid Build Coastguard Worker  * its documentation for any purpose is hereby granted without fee, provided
7*3ac0a46fSAndroid Build Coastguard Worker  * that (i) the above copyright notices and this permission notice appear in
8*3ac0a46fSAndroid Build Coastguard Worker  * all copies of the software and related documentation, and (ii) the names of
9*3ac0a46fSAndroid Build Coastguard Worker  * Sam Leffler and Silicon Graphics may not be used in any advertising or
10*3ac0a46fSAndroid Build Coastguard Worker  * publicity relating to the software without the specific, prior written
11*3ac0a46fSAndroid Build Coastguard Worker  * permission of Sam Leffler and Silicon Graphics.
12*3ac0a46fSAndroid Build Coastguard Worker  *
13*3ac0a46fSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14*3ac0a46fSAndroid Build Coastguard Worker  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15*3ac0a46fSAndroid Build Coastguard Worker  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16*3ac0a46fSAndroid Build Coastguard Worker  *
17*3ac0a46fSAndroid Build Coastguard Worker  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18*3ac0a46fSAndroid Build Coastguard Worker  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19*3ac0a46fSAndroid Build Coastguard Worker  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20*3ac0a46fSAndroid Build Coastguard Worker  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21*3ac0a46fSAndroid Build Coastguard Worker  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22*3ac0a46fSAndroid Build Coastguard Worker  * OF THIS SOFTWARE.
23*3ac0a46fSAndroid Build Coastguard Worker  */
24*3ac0a46fSAndroid Build Coastguard Worker 
25*3ac0a46fSAndroid Build Coastguard Worker #define WIN32_LEAN_AND_MEAN
26*3ac0a46fSAndroid Build Coastguard Worker #define VC_EXTRALEAN
27*3ac0a46fSAndroid Build Coastguard Worker 
28*3ac0a46fSAndroid Build Coastguard Worker #include "tiffiop.h"
29*3ac0a46fSAndroid Build Coastguard Worker #include <stdlib.h>
30*3ac0a46fSAndroid Build Coastguard Worker 
31*3ac0a46fSAndroid Build Coastguard Worker #ifdef JPEG_SUPPORT
32*3ac0a46fSAndroid Build Coastguard Worker 
33*3ac0a46fSAndroid Build Coastguard Worker /*
34*3ac0a46fSAndroid Build Coastguard Worker  * TIFF Library
35*3ac0a46fSAndroid Build Coastguard Worker  *
36*3ac0a46fSAndroid Build Coastguard Worker  * JPEG Compression support per TIFF Technical Note #2
37*3ac0a46fSAndroid Build Coastguard Worker  * (*not* per the original TIFF 6.0 spec).
38*3ac0a46fSAndroid Build Coastguard Worker  *
39*3ac0a46fSAndroid Build Coastguard Worker  * This file is simply an interface to the libjpeg library written by
40*3ac0a46fSAndroid Build Coastguard Worker  * the Independent JPEG Group.  You need release 5 or later of the IJG
41*3ac0a46fSAndroid Build Coastguard Worker  * code, which you can find on the Internet at ftp.uu.net:/graphics/jpeg/.
42*3ac0a46fSAndroid Build Coastguard Worker  *
43*3ac0a46fSAndroid Build Coastguard Worker  * Contributed by Tom Lane <[email protected]>.
44*3ac0a46fSAndroid Build Coastguard Worker  */
45*3ac0a46fSAndroid Build Coastguard Worker #include <setjmp.h>
46*3ac0a46fSAndroid Build Coastguard Worker 
47*3ac0a46fSAndroid Build Coastguard Worker /* Settings that are independent of libjpeg ABI. Used when reinitializing the */
48*3ac0a46fSAndroid Build Coastguard Worker /* JPEGState from libjpegs 8 bit to libjpeg 12 bits, which have potentially */
49*3ac0a46fSAndroid Build Coastguard Worker /* different ABI */
50*3ac0a46fSAndroid Build Coastguard Worker typedef struct
51*3ac0a46fSAndroid Build Coastguard Worker {
52*3ac0a46fSAndroid Build Coastguard Worker     TIFFVGetMethod vgetparent;  /* super-class method */
53*3ac0a46fSAndroid Build Coastguard Worker     TIFFVSetMethod vsetparent;  /* super-class method */
54*3ac0a46fSAndroid Build Coastguard Worker     TIFFPrintMethod printdir;   /* super-class method */
55*3ac0a46fSAndroid Build Coastguard Worker     TIFFStripMethod defsparent; /* super-class method */
56*3ac0a46fSAndroid Build Coastguard Worker     TIFFTileMethod deftparent;  /* super-class method */
57*3ac0a46fSAndroid Build Coastguard Worker 
58*3ac0a46fSAndroid Build Coastguard Worker     /* pseudo-tag fields */
59*3ac0a46fSAndroid Build Coastguard Worker     void *jpegtables;           /* JPEGTables tag value, or NULL */
60*3ac0a46fSAndroid Build Coastguard Worker     uint32_t jpegtables_length; /* number of bytes in same */
61*3ac0a46fSAndroid Build Coastguard Worker     int jpegquality;            /* Compression quality level */
62*3ac0a46fSAndroid Build Coastguard Worker     int jpegcolormode;          /* Auto RGB<=>YCbCr convert? */
63*3ac0a46fSAndroid Build Coastguard Worker     int jpegtablesmode;         /* What to put in JPEGTables */
64*3ac0a46fSAndroid Build Coastguard Worker 
65*3ac0a46fSAndroid Build Coastguard Worker     int ycbcrsampling_fetched;
66*3ac0a46fSAndroid Build Coastguard Worker     int max_allowed_scan_number;
67*3ac0a46fSAndroid Build Coastguard Worker     int has_warned_about_progressive_mode;
68*3ac0a46fSAndroid Build Coastguard Worker } JPEGOtherSettings;
69*3ac0a46fSAndroid Build Coastguard Worker 
70*3ac0a46fSAndroid Build Coastguard Worker int TIFFFillStrip(TIFF *tif, uint32_t strip);
71*3ac0a46fSAndroid Build Coastguard Worker int TIFFFillTile(TIFF *tif, uint32_t tile);
72*3ac0a46fSAndroid Build Coastguard Worker int TIFFReInitJPEG_12(TIFF *tif, const JPEGOtherSettings *otherSettings,
73*3ac0a46fSAndroid Build Coastguard Worker                       int scheme, int is_encode);
74*3ac0a46fSAndroid Build Coastguard Worker int TIFFJPEGIsFullStripRequired_12(TIFF *tif);
75*3ac0a46fSAndroid Build Coastguard Worker 
76*3ac0a46fSAndroid Build Coastguard Worker /* We undefine FAR to avoid conflict with JPEG definition */
77*3ac0a46fSAndroid Build Coastguard Worker 
78*3ac0a46fSAndroid Build Coastguard Worker #ifdef FAR
79*3ac0a46fSAndroid Build Coastguard Worker #undef FAR
80*3ac0a46fSAndroid Build Coastguard Worker #endif
81*3ac0a46fSAndroid Build Coastguard Worker 
82*3ac0a46fSAndroid Build Coastguard Worker /*
83*3ac0a46fSAndroid Build Coastguard Worker   Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
84*3ac0a46fSAndroid Build Coastguard Worker   not defined.  Unfortunately, the MinGW and Borland compilers include
85*3ac0a46fSAndroid Build Coastguard Worker   a typedef for INT32, which causes a conflict.  MSVC does not include
86*3ac0a46fSAndroid Build Coastguard Worker   a conflicting typedef given the headers which are included.
87*3ac0a46fSAndroid Build Coastguard Worker */
88*3ac0a46fSAndroid Build Coastguard Worker #if defined(__BORLANDC__) || defined(__MINGW32__)
89*3ac0a46fSAndroid Build Coastguard Worker #define XMD_H 1
90*3ac0a46fSAndroid Build Coastguard Worker #endif
91*3ac0a46fSAndroid Build Coastguard Worker 
92*3ac0a46fSAndroid Build Coastguard Worker /*
93*3ac0a46fSAndroid Build Coastguard Worker    The windows RPCNDR.H file defines boolean, but defines it with the
94*3ac0a46fSAndroid Build Coastguard Worker    unsigned char size.  You should compile JPEG library using appropriate
95*3ac0a46fSAndroid Build Coastguard Worker    definitions in jconfig.h header, but many users compile library in wrong
96*3ac0a46fSAndroid Build Coastguard Worker    way. That causes errors of the following type:
97*3ac0a46fSAndroid Build Coastguard Worker 
98*3ac0a46fSAndroid Build Coastguard Worker    "JPEGLib: JPEG parameter struct mismatch: library thinks size is 432,
99*3ac0a46fSAndroid Build Coastguard Worker    caller expects 464"
100*3ac0a46fSAndroid Build Coastguard Worker 
101*3ac0a46fSAndroid Build Coastguard Worker    For such users we will fix the problem here. See install.doc file from
102*3ac0a46fSAndroid Build Coastguard Worker    the JPEG library distribution for details.
103*3ac0a46fSAndroid Build Coastguard Worker */
104*3ac0a46fSAndroid Build Coastguard Worker 
105*3ac0a46fSAndroid Build Coastguard Worker /* Define "boolean" as unsigned char, not int, per Windows custom. */
106*3ac0a46fSAndroid Build Coastguard Worker #if defined(__WIN32__) && !defined(__MINGW32__)
107*3ac0a46fSAndroid Build Coastguard Worker #ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
108*3ac0a46fSAndroid Build Coastguard Worker typedef unsigned char boolean;
109*3ac0a46fSAndroid Build Coastguard Worker #endif
110*3ac0a46fSAndroid Build Coastguard Worker #define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
111*3ac0a46fSAndroid Build Coastguard Worker #endif
112*3ac0a46fSAndroid Build Coastguard Worker 
113*3ac0a46fSAndroid Build Coastguard Worker #if defined(USE_SYSTEM_LIBJPEG)
114*3ac0a46fSAndroid Build Coastguard Worker #include <jerror.h>
115*3ac0a46fSAndroid Build Coastguard Worker #include <jpeglib.h>
116*3ac0a46fSAndroid Build Coastguard Worker #elif defined(USE_LIBJPEG_TURBO)
117*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/libjpeg_turbo/jerror.h"
118*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/libjpeg_turbo/jpeglib.h"
119*3ac0a46fSAndroid Build Coastguard Worker #else
120*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/libjpeg/jerror.h"
121*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/libjpeg/jpeglib.h"
122*3ac0a46fSAndroid Build Coastguard Worker #endif
123*3ac0a46fSAndroid Build Coastguard Worker 
124*3ac0a46fSAndroid Build Coastguard Worker /* Do optional compile-time version check */
125*3ac0a46fSAndroid Build Coastguard Worker #if defined(EXPECTED_JPEG_LIB_VERSION) && !defined(LIBJPEG_12_PATH)
126*3ac0a46fSAndroid Build Coastguard Worker #if EXPECTED_JPEG_LIB_VERSION != JPEG_LIB_VERSION
127*3ac0a46fSAndroid Build Coastguard Worker #error EXPECTED_JPEG_LIB_VERSION != JPEG_LIB_VERSION
128*3ac0a46fSAndroid Build Coastguard Worker #endif
129*3ac0a46fSAndroid Build Coastguard Worker #endif
130*3ac0a46fSAndroid Build Coastguard Worker 
131*3ac0a46fSAndroid Build Coastguard Worker /*
132*3ac0a46fSAndroid Build Coastguard Worker  * Do we want to do special processing suitable for when JSAMPLE is a
133*3ac0a46fSAndroid Build Coastguard Worker  * 16bit value?
134*3ac0a46fSAndroid Build Coastguard Worker  */
135*3ac0a46fSAndroid Build Coastguard Worker 
136*3ac0a46fSAndroid Build Coastguard Worker /* HAVE_JPEGTURBO_DUAL_MODE_8_12 is defined for libjpeg-turbo >= 2.2 which
137*3ac0a46fSAndroid Build Coastguard Worker  * adds a dual-mode 8/12 bit API in the same library.
138*3ac0a46fSAndroid Build Coastguard Worker  */
139*3ac0a46fSAndroid Build Coastguard Worker 
140*3ac0a46fSAndroid Build Coastguard Worker #if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12)
141*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_DUAL_MODE_8_12
142*3ac0a46fSAndroid Build Coastguard Worker /* Start by undefining BITS_IN_JSAMPLE which is always set to 8 in libjpeg-turbo
143*3ac0a46fSAndroid Build Coastguard Worker  * >= 2.2 Cf
144*3ac0a46fSAndroid Build Coastguard Worker  * https://github.com/libjpeg-turbo/libjpeg-turbo/commit/8b9bc4b9635a2a047fb23ebe70c9acd728d3f99b
145*3ac0a46fSAndroid Build Coastguard Worker  */
146*3ac0a46fSAndroid Build Coastguard Worker #undef BITS_IN_JSAMPLE
147*3ac0a46fSAndroid Build Coastguard Worker /* libjpeg-turbo >= 2.2 adds J12xxxx datatypes for the 12-bit mode. */
148*3ac0a46fSAndroid Build Coastguard Worker #if defined(FROM_TIF_JPEG_12)
149*3ac0a46fSAndroid Build Coastguard Worker #define BITS_IN_JSAMPLE 12
150*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_JSAMPLE J12SAMPLE
151*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_JSAMPARRAY J12SAMPARRAY
152*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_JSAMPIMAGE J12SAMPIMAGE
153*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_JSAMPROW J12SAMPROW
154*3ac0a46fSAndroid Build Coastguard Worker #else
155*3ac0a46fSAndroid Build Coastguard Worker #define BITS_IN_JSAMPLE 8
156*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_JSAMPLE JSAMPLE
157*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_JSAMPARRAY JSAMPARRAY
158*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_JSAMPIMAGE JSAMPIMAGE
159*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_JSAMPROW JSAMPROW
160*3ac0a46fSAndroid Build Coastguard Worker #endif
161*3ac0a46fSAndroid Build Coastguard Worker #else
162*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_JSAMPLE JSAMPLE
163*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_JSAMPARRAY JSAMPARRAY
164*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_JSAMPIMAGE JSAMPIMAGE
165*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_JSAMPROW JSAMPROW
166*3ac0a46fSAndroid Build Coastguard Worker #endif
167*3ac0a46fSAndroid Build Coastguard Worker 
168*3ac0a46fSAndroid Build Coastguard Worker #if defined(JPEG_LIB_MK1)
169*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_LIB_MK1_OR_12BIT 1
170*3ac0a46fSAndroid Build Coastguard Worker #elif BITS_IN_JSAMPLE == 12
171*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_LIB_MK1_OR_12BIT 1
172*3ac0a46fSAndroid Build Coastguard Worker #endif
173*3ac0a46fSAndroid Build Coastguard Worker 
174*3ac0a46fSAndroid Build Coastguard Worker /*
175*3ac0a46fSAndroid Build Coastguard Worker  * We are using width_in_blocks which is supposed to be private to
176*3ac0a46fSAndroid Build Coastguard Worker  * libjpeg. Unfortunately, the libjpeg delivered with Cygwin has
177*3ac0a46fSAndroid Build Coastguard Worker  * renamed this member to width_in_data_units.  Since the header has
178*3ac0a46fSAndroid Build Coastguard Worker  * also renamed a define, use that unique define name in order to
179*3ac0a46fSAndroid Build Coastguard Worker  * detect the problem header and adjust to suit.
180*3ac0a46fSAndroid Build Coastguard Worker  */
181*3ac0a46fSAndroid Build Coastguard Worker #if defined(D_MAX_DATA_UNITS_IN_MCU)
182*3ac0a46fSAndroid Build Coastguard Worker #define width_in_blocks width_in_data_units
183*3ac0a46fSAndroid Build Coastguard Worker #endif
184*3ac0a46fSAndroid Build Coastguard Worker 
185*3ac0a46fSAndroid Build Coastguard Worker /*
186*3ac0a46fSAndroid Build Coastguard Worker  * On some machines it may be worthwhile to use _setjmp or sigsetjmp
187*3ac0a46fSAndroid Build Coastguard Worker  * in place of plain setjmp.  These macros will make it easier.
188*3ac0a46fSAndroid Build Coastguard Worker  */
189*3ac0a46fSAndroid Build Coastguard Worker #define SETJMP(jbuf) setjmp(jbuf)
190*3ac0a46fSAndroid Build Coastguard Worker #define LONGJMP(jbuf, code) longjmp(jbuf, code)
191*3ac0a46fSAndroid Build Coastguard Worker #define JMP_BUF jmp_buf
192*3ac0a46fSAndroid Build Coastguard Worker 
193*3ac0a46fSAndroid Build Coastguard Worker typedef struct jpeg_destination_mgr jpeg_destination_mgr;
194*3ac0a46fSAndroid Build Coastguard Worker typedef struct jpeg_source_mgr jpeg_source_mgr;
195*3ac0a46fSAndroid Build Coastguard Worker typedef struct jpeg_error_mgr jpeg_error_mgr;
196*3ac0a46fSAndroid Build Coastguard Worker 
197*3ac0a46fSAndroid Build Coastguard Worker /*
198*3ac0a46fSAndroid Build Coastguard Worker  * State block for each open TIFF file using
199*3ac0a46fSAndroid Build Coastguard Worker  * libjpeg to do JPEG compression/decompression.
200*3ac0a46fSAndroid Build Coastguard Worker  *
201*3ac0a46fSAndroid Build Coastguard Worker  * libjpeg's visible state is either a jpeg_compress_struct
202*3ac0a46fSAndroid Build Coastguard Worker  * or jpeg_decompress_struct depending on which way we
203*3ac0a46fSAndroid Build Coastguard Worker  * are going.  comm can be used to refer to the fields
204*3ac0a46fSAndroid Build Coastguard Worker  * which are common to both.
205*3ac0a46fSAndroid Build Coastguard Worker  *
206*3ac0a46fSAndroid Build Coastguard Worker  * NB: cinfo is required to be the first member of JPEGState,
207*3ac0a46fSAndroid Build Coastguard Worker  *     so we can safely cast JPEGState* -> jpeg_xxx_struct*
208*3ac0a46fSAndroid Build Coastguard Worker  *     and vice versa!
209*3ac0a46fSAndroid Build Coastguard Worker  */
210*3ac0a46fSAndroid Build Coastguard Worker typedef struct
211*3ac0a46fSAndroid Build Coastguard Worker {
212*3ac0a46fSAndroid Build Coastguard Worker     union
213*3ac0a46fSAndroid Build Coastguard Worker     {
214*3ac0a46fSAndroid Build Coastguard Worker         struct jpeg_compress_struct c;
215*3ac0a46fSAndroid Build Coastguard Worker         struct jpeg_decompress_struct d;
216*3ac0a46fSAndroid Build Coastguard Worker         struct jpeg_common_struct comm;
217*3ac0a46fSAndroid Build Coastguard Worker     } cinfo; /* NB: must be first */
218*3ac0a46fSAndroid Build Coastguard Worker     int cinfo_initialized;
219*3ac0a46fSAndroid Build Coastguard Worker 
220*3ac0a46fSAndroid Build Coastguard Worker     jpeg_error_mgr err;  /* libjpeg error manager */
221*3ac0a46fSAndroid Build Coastguard Worker     JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */
222*3ac0a46fSAndroid Build Coastguard Worker 
223*3ac0a46fSAndroid Build Coastguard Worker     struct jpeg_progress_mgr progress;
224*3ac0a46fSAndroid Build Coastguard Worker     /*
225*3ac0a46fSAndroid Build Coastguard Worker      * The following two members could be a union, but
226*3ac0a46fSAndroid Build Coastguard Worker      * they're small enough that it's not worth the effort.
227*3ac0a46fSAndroid Build Coastguard Worker      */
228*3ac0a46fSAndroid Build Coastguard Worker     jpeg_destination_mgr dest; /* data dest for compression */
229*3ac0a46fSAndroid Build Coastguard Worker     jpeg_source_mgr src;       /* data source for decompression */
230*3ac0a46fSAndroid Build Coastguard Worker                                /* private state */
231*3ac0a46fSAndroid Build Coastguard Worker     TIFF *tif;                 /* back link needed by some code */
232*3ac0a46fSAndroid Build Coastguard Worker     uint16_t photometric;      /* copy of PhotometricInterpretation */
233*3ac0a46fSAndroid Build Coastguard Worker     uint16_t h_sampling;       /* luminance sampling factors */
234*3ac0a46fSAndroid Build Coastguard Worker     uint16_t v_sampling;
235*3ac0a46fSAndroid Build Coastguard Worker     tmsize_t bytesperline; /* decompressed bytes per scanline */
236*3ac0a46fSAndroid Build Coastguard Worker     /* pointers to intermediate buffers when processing downsampled data */
237*3ac0a46fSAndroid Build Coastguard Worker     TIFF_JSAMPARRAY ds_buffer[MAX_COMPONENTS];
238*3ac0a46fSAndroid Build Coastguard Worker     int scancount; /* number of "scanlines" accumulated */
239*3ac0a46fSAndroid Build Coastguard Worker     int samplesperclump;
240*3ac0a46fSAndroid Build Coastguard Worker 
241*3ac0a46fSAndroid Build Coastguard Worker     JPEGOtherSettings otherSettings;
242*3ac0a46fSAndroid Build Coastguard Worker } JPEGState;
243*3ac0a46fSAndroid Build Coastguard Worker 
244*3ac0a46fSAndroid Build Coastguard Worker #define JState(tif) ((JPEGState *)(tif)->tif_data)
245*3ac0a46fSAndroid Build Coastguard Worker 
246*3ac0a46fSAndroid Build Coastguard Worker static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s);
247*3ac0a46fSAndroid Build Coastguard Worker static int JPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s);
248*3ac0a46fSAndroid Build Coastguard Worker static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s);
249*3ac0a46fSAndroid Build Coastguard Worker static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s);
250*3ac0a46fSAndroid Build Coastguard Worker static int JPEGInitializeLibJPEG(TIFF *tif, int decode);
251*3ac0a46fSAndroid Build Coastguard Worker static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s);
252*3ac0a46fSAndroid Build Coastguard Worker 
253*3ac0a46fSAndroid Build Coastguard Worker #define FIELD_JPEGTABLES (FIELD_CODEC + 0)
254*3ac0a46fSAndroid Build Coastguard Worker 
255*3ac0a46fSAndroid Build Coastguard Worker static const TIFFField jpegFields[] = {
256*3ac0a46fSAndroid Build Coastguard Worker     {TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8,
257*3ac0a46fSAndroid Build Coastguard Worker      TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL},
258*3ac0a46fSAndroid Build Coastguard Worker     {TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
259*3ac0a46fSAndroid Build Coastguard Worker      TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
260*3ac0a46fSAndroid Build Coastguard Worker     {TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
261*3ac0a46fSAndroid Build Coastguard Worker      TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL},
262*3ac0a46fSAndroid Build Coastguard Worker     {TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
263*3ac0a46fSAndroid Build Coastguard Worker      TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}};
264*3ac0a46fSAndroid Build Coastguard Worker 
265*3ac0a46fSAndroid Build Coastguard Worker /*
266*3ac0a46fSAndroid Build Coastguard Worker  * libjpeg interface layer.
267*3ac0a46fSAndroid Build Coastguard Worker  *
268*3ac0a46fSAndroid Build Coastguard Worker  * We use setjmp/longjmp to return control to libtiff
269*3ac0a46fSAndroid Build Coastguard Worker  * when a fatal error is encountered within the JPEG
270*3ac0a46fSAndroid Build Coastguard Worker  * library.  We also direct libjpeg error and warning
271*3ac0a46fSAndroid Build Coastguard Worker  * messages through the appropriate libtiff handlers.
272*3ac0a46fSAndroid Build Coastguard Worker  */
273*3ac0a46fSAndroid Build Coastguard Worker 
274*3ac0a46fSAndroid Build Coastguard Worker /*
275*3ac0a46fSAndroid Build Coastguard Worker  * Error handling routines (these replace corresponding
276*3ac0a46fSAndroid Build Coastguard Worker  * IJG routines from jerror.c).  These are used for both
277*3ac0a46fSAndroid Build Coastguard Worker  * compression and decompression.
278*3ac0a46fSAndroid Build Coastguard Worker  */
TIFFjpeg_error_exit(j_common_ptr cinfo)279*3ac0a46fSAndroid Build Coastguard Worker static void TIFFjpeg_error_exit(j_common_ptr cinfo)
280*3ac0a46fSAndroid Build Coastguard Worker {
281*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */
282*3ac0a46fSAndroid Build Coastguard Worker     char buffer[JMSG_LENGTH_MAX];
283*3ac0a46fSAndroid Build Coastguard Worker 
284*3ac0a46fSAndroid Build Coastguard Worker     (*cinfo->err->format_message)(cinfo, buffer);
285*3ac0a46fSAndroid Build Coastguard Worker     TIFFErrorExtR(sp->tif, "JPEGLib", "%s",
286*3ac0a46fSAndroid Build Coastguard Worker                   buffer);       /* display the error message */
287*3ac0a46fSAndroid Build Coastguard Worker     jpeg_abort(cinfo);           /* clean up libjpeg state */
288*3ac0a46fSAndroid Build Coastguard Worker     LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */
289*3ac0a46fSAndroid Build Coastguard Worker }
290*3ac0a46fSAndroid Build Coastguard Worker 
291*3ac0a46fSAndroid Build Coastguard Worker /*
292*3ac0a46fSAndroid Build Coastguard Worker  * This routine is invoked only for warning messages,
293*3ac0a46fSAndroid Build Coastguard Worker  * since error_exit does its own thing and trace_level
294*3ac0a46fSAndroid Build Coastguard Worker  * is never set > 0.
295*3ac0a46fSAndroid Build Coastguard Worker  */
TIFFjpeg_output_message(j_common_ptr cinfo)296*3ac0a46fSAndroid Build Coastguard Worker static void TIFFjpeg_output_message(j_common_ptr cinfo)
297*3ac0a46fSAndroid Build Coastguard Worker {
298*3ac0a46fSAndroid Build Coastguard Worker     char buffer[JMSG_LENGTH_MAX];
299*3ac0a46fSAndroid Build Coastguard Worker 
300*3ac0a46fSAndroid Build Coastguard Worker     (*cinfo->err->format_message)(cinfo, buffer);
301*3ac0a46fSAndroid Build Coastguard Worker     TIFFWarningExtR(((JPEGState *)cinfo)->tif, "JPEGLib", "%s", buffer);
302*3ac0a46fSAndroid Build Coastguard Worker }
303*3ac0a46fSAndroid Build Coastguard Worker 
304*3ac0a46fSAndroid Build Coastguard Worker /* Avoid the risk of denial-of-service on crafted JPEGs with an insane */
305*3ac0a46fSAndroid Build Coastguard Worker /* number of scans. */
306*3ac0a46fSAndroid Build Coastguard Worker /* See
307*3ac0a46fSAndroid Build Coastguard Worker  * http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf
308*3ac0a46fSAndroid Build Coastguard Worker  */
TIFFjpeg_progress_monitor(j_common_ptr cinfo)309*3ac0a46fSAndroid Build Coastguard Worker static void TIFFjpeg_progress_monitor(j_common_ptr cinfo)
310*3ac0a46fSAndroid Build Coastguard Worker {
311*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = (JPEGState *)cinfo; /* NB: cinfo assumed first */
312*3ac0a46fSAndroid Build Coastguard Worker     if (cinfo->is_decompressor)
313*3ac0a46fSAndroid Build Coastguard Worker     {
314*3ac0a46fSAndroid Build Coastguard Worker         const int scan_no = ((j_decompress_ptr)cinfo)->input_scan_number;
315*3ac0a46fSAndroid Build Coastguard Worker         if (scan_no >= sp->otherSettings.max_allowed_scan_number)
316*3ac0a46fSAndroid Build Coastguard Worker         {
317*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(
318*3ac0a46fSAndroid Build Coastguard Worker                 ((JPEGState *)cinfo)->tif, "TIFFjpeg_progress_monitor",
319*3ac0a46fSAndroid Build Coastguard Worker                 "Scan number %d exceeds maximum scans (%d). This limit "
320*3ac0a46fSAndroid Build Coastguard Worker                 "can be raised through the "
321*3ac0a46fSAndroid Build Coastguard Worker                 "LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER "
322*3ac0a46fSAndroid Build Coastguard Worker                 "environment variable.",
323*3ac0a46fSAndroid Build Coastguard Worker                 scan_no, sp->otherSettings.max_allowed_scan_number);
324*3ac0a46fSAndroid Build Coastguard Worker 
325*3ac0a46fSAndroid Build Coastguard Worker             jpeg_abort(cinfo);           /* clean up libjpeg state */
326*3ac0a46fSAndroid Build Coastguard Worker             LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */
327*3ac0a46fSAndroid Build Coastguard Worker         }
328*3ac0a46fSAndroid Build Coastguard Worker     }
329*3ac0a46fSAndroid Build Coastguard Worker }
330*3ac0a46fSAndroid Build Coastguard Worker 
331*3ac0a46fSAndroid Build Coastguard Worker /*
332*3ac0a46fSAndroid Build Coastguard Worker  * Interface routines.  This layer of routines exists
333*3ac0a46fSAndroid Build Coastguard Worker  * primarily to limit side-effects from using setjmp.
334*3ac0a46fSAndroid Build Coastguard Worker  * Also, normal/error returns are converted into return
335*3ac0a46fSAndroid Build Coastguard Worker  * values per libtiff practice.
336*3ac0a46fSAndroid Build Coastguard Worker  */
337*3ac0a46fSAndroid Build Coastguard Worker #define CALLJPEG(sp, fail, op) (SETJMP((sp)->exit_jmpbuf) ? (fail) : (op))
338*3ac0a46fSAndroid Build Coastguard Worker #define CALLVJPEG(sp, op) CALLJPEG(sp, 0, ((op), 1))
339*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_create_compress(JPEGState * sp)340*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_create_compress(JPEGState *sp)
341*3ac0a46fSAndroid Build Coastguard Worker {
342*3ac0a46fSAndroid Build Coastguard Worker     /* initialize JPEG error handling */
343*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.c.err = jpeg_std_error(&sp->err);
344*3ac0a46fSAndroid Build Coastguard Worker     sp->err.error_exit = TIFFjpeg_error_exit;
345*3ac0a46fSAndroid Build Coastguard Worker     sp->err.output_message = TIFFjpeg_output_message;
346*3ac0a46fSAndroid Build Coastguard Worker 
347*3ac0a46fSAndroid Build Coastguard Worker     /* set client_data to avoid UMR warning from tools like Purify */
348*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.c.client_data = NULL;
349*3ac0a46fSAndroid Build Coastguard Worker 
350*3ac0a46fSAndroid Build Coastguard Worker     return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c));
351*3ac0a46fSAndroid Build Coastguard Worker }
352*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_create_decompress(JPEGState * sp)353*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_create_decompress(JPEGState *sp)
354*3ac0a46fSAndroid Build Coastguard Worker {
355*3ac0a46fSAndroid Build Coastguard Worker     /* initialize JPEG error handling */
356*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.d.err = jpeg_std_error(&sp->err);
357*3ac0a46fSAndroid Build Coastguard Worker     sp->err.error_exit = TIFFjpeg_error_exit;
358*3ac0a46fSAndroid Build Coastguard Worker     sp->err.output_message = TIFFjpeg_output_message;
359*3ac0a46fSAndroid Build Coastguard Worker 
360*3ac0a46fSAndroid Build Coastguard Worker     /* set client_data to avoid UMR warning from tools like Purify */
361*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.d.client_data = NULL;
362*3ac0a46fSAndroid Build Coastguard Worker 
363*3ac0a46fSAndroid Build Coastguard Worker     return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d));
364*3ac0a46fSAndroid Build Coastguard Worker }
365*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_set_defaults(JPEGState * sp)366*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_set_defaults(JPEGState *sp)
367*3ac0a46fSAndroid Build Coastguard Worker {
368*3ac0a46fSAndroid Build Coastguard Worker     return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c));
369*3ac0a46fSAndroid Build Coastguard Worker }
370*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_set_colorspace(JPEGState * sp,J_COLOR_SPACE colorspace)371*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_set_colorspace(JPEGState *sp, J_COLOR_SPACE colorspace)
372*3ac0a46fSAndroid Build Coastguard Worker {
373*3ac0a46fSAndroid Build Coastguard Worker     return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace));
374*3ac0a46fSAndroid Build Coastguard Worker }
375*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_set_quality(JPEGState * sp,int quality,boolean force_baseline)376*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_set_quality(JPEGState *sp, int quality,
377*3ac0a46fSAndroid Build Coastguard Worker                                 boolean force_baseline)
378*3ac0a46fSAndroid Build Coastguard Worker {
379*3ac0a46fSAndroid Build Coastguard Worker     return CALLVJPEG(sp,
380*3ac0a46fSAndroid Build Coastguard Worker                      jpeg_set_quality(&sp->cinfo.c, quality, force_baseline));
381*3ac0a46fSAndroid Build Coastguard Worker }
382*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_suppress_tables(JPEGState * sp,boolean suppress)383*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_suppress_tables(JPEGState *sp, boolean suppress)
384*3ac0a46fSAndroid Build Coastguard Worker {
385*3ac0a46fSAndroid Build Coastguard Worker     return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress));
386*3ac0a46fSAndroid Build Coastguard Worker }
387*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_start_compress(JPEGState * sp,boolean write_all_tables)388*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_start_compress(JPEGState *sp, boolean write_all_tables)
389*3ac0a46fSAndroid Build Coastguard Worker {
390*3ac0a46fSAndroid Build Coastguard Worker     return CALLVJPEG(sp, jpeg_start_compress(&sp->cinfo.c, write_all_tables));
391*3ac0a46fSAndroid Build Coastguard Worker }
392*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_write_scanlines(JPEGState * sp,TIFF_JSAMPARRAY scanlines,int num_lines)393*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_write_scanlines(JPEGState *sp, TIFF_JSAMPARRAY scanlines,
394*3ac0a46fSAndroid Build Coastguard Worker                                     int num_lines)
395*3ac0a46fSAndroid Build Coastguard Worker {
396*3ac0a46fSAndroid Build Coastguard Worker #if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12
397*3ac0a46fSAndroid Build Coastguard Worker     return CALLJPEG(sp, -1,
398*3ac0a46fSAndroid Build Coastguard Worker                     (int)jpeg12_write_scanlines(&sp->cinfo.c, scanlines,
399*3ac0a46fSAndroid Build Coastguard Worker                                                 (JDIMENSION)num_lines));
400*3ac0a46fSAndroid Build Coastguard Worker #else
401*3ac0a46fSAndroid Build Coastguard Worker     return CALLJPEG(sp, -1,
402*3ac0a46fSAndroid Build Coastguard Worker                     (int)jpeg_write_scanlines(&sp->cinfo.c, scanlines,
403*3ac0a46fSAndroid Build Coastguard Worker                                               (JDIMENSION)num_lines));
404*3ac0a46fSAndroid Build Coastguard Worker #endif
405*3ac0a46fSAndroid Build Coastguard Worker }
406*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_write_raw_data(JPEGState * sp,TIFF_JSAMPIMAGE data,int num_lines)407*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_write_raw_data(JPEGState *sp, TIFF_JSAMPIMAGE data,
408*3ac0a46fSAndroid Build Coastguard Worker                                    int num_lines)
409*3ac0a46fSAndroid Build Coastguard Worker {
410*3ac0a46fSAndroid Build Coastguard Worker #if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12
411*3ac0a46fSAndroid Build Coastguard Worker     return CALLJPEG(
412*3ac0a46fSAndroid Build Coastguard Worker         sp, -1,
413*3ac0a46fSAndroid Build Coastguard Worker         (int)jpeg12_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines));
414*3ac0a46fSAndroid Build Coastguard Worker #else
415*3ac0a46fSAndroid Build Coastguard Worker     return CALLJPEG(
416*3ac0a46fSAndroid Build Coastguard Worker         sp, -1,
417*3ac0a46fSAndroid Build Coastguard Worker         (int)jpeg_write_raw_data(&sp->cinfo.c, data, (JDIMENSION)num_lines));
418*3ac0a46fSAndroid Build Coastguard Worker #endif
419*3ac0a46fSAndroid Build Coastguard Worker }
420*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_finish_compress(JPEGState * sp)421*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_finish_compress(JPEGState *sp)
422*3ac0a46fSAndroid Build Coastguard Worker {
423*3ac0a46fSAndroid Build Coastguard Worker     return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c));
424*3ac0a46fSAndroid Build Coastguard Worker }
425*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_write_tables(JPEGState * sp)426*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_write_tables(JPEGState *sp)
427*3ac0a46fSAndroid Build Coastguard Worker {
428*3ac0a46fSAndroid Build Coastguard Worker     return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c));
429*3ac0a46fSAndroid Build Coastguard Worker }
430*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_read_header(JPEGState * sp,boolean require_image)431*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_read_header(JPEGState *sp, boolean require_image)
432*3ac0a46fSAndroid Build Coastguard Worker {
433*3ac0a46fSAndroid Build Coastguard Worker     return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image));
434*3ac0a46fSAndroid Build Coastguard Worker }
435*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_has_multiple_scans(JPEGState * sp)436*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_has_multiple_scans(JPEGState *sp)
437*3ac0a46fSAndroid Build Coastguard Worker {
438*3ac0a46fSAndroid Build Coastguard Worker     return CALLJPEG(sp, 0, jpeg_has_multiple_scans(&sp->cinfo.d));
439*3ac0a46fSAndroid Build Coastguard Worker }
440*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_start_decompress(JPEGState * sp)441*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_start_decompress(JPEGState *sp)
442*3ac0a46fSAndroid Build Coastguard Worker {
443*3ac0a46fSAndroid Build Coastguard Worker     const char *sz_max_allowed_scan_number;
444*3ac0a46fSAndroid Build Coastguard Worker     /* progress monitor */
445*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.d.progress = &sp->progress;
446*3ac0a46fSAndroid Build Coastguard Worker     sp->progress.progress_monitor = TIFFjpeg_progress_monitor;
447*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.max_allowed_scan_number = 100;
448*3ac0a46fSAndroid Build Coastguard Worker     sz_max_allowed_scan_number = getenv("LIBTIFF_JPEG_MAX_ALLOWED_SCAN_NUMBER");
449*3ac0a46fSAndroid Build Coastguard Worker     if (sz_max_allowed_scan_number)
450*3ac0a46fSAndroid Build Coastguard Worker         sp->otherSettings.max_allowed_scan_number =
451*3ac0a46fSAndroid Build Coastguard Worker             atoi(sz_max_allowed_scan_number);
452*3ac0a46fSAndroid Build Coastguard Worker 
453*3ac0a46fSAndroid Build Coastguard Worker     return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d));
454*3ac0a46fSAndroid Build Coastguard Worker }
455*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_read_scanlines(JPEGState * sp,TIFF_JSAMPARRAY scanlines,int max_lines)456*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_read_scanlines(JPEGState *sp, TIFF_JSAMPARRAY scanlines,
457*3ac0a46fSAndroid Build Coastguard Worker                                    int max_lines)
458*3ac0a46fSAndroid Build Coastguard Worker {
459*3ac0a46fSAndroid Build Coastguard Worker #if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12
460*3ac0a46fSAndroid Build Coastguard Worker     return CALLJPEG(sp, -1,
461*3ac0a46fSAndroid Build Coastguard Worker                     (int)jpeg12_read_scanlines(&sp->cinfo.d, scanlines,
462*3ac0a46fSAndroid Build Coastguard Worker                                                (JDIMENSION)max_lines));
463*3ac0a46fSAndroid Build Coastguard Worker #else
464*3ac0a46fSAndroid Build Coastguard Worker     return CALLJPEG(sp, -1,
465*3ac0a46fSAndroid Build Coastguard Worker                     (int)jpeg_read_scanlines(&sp->cinfo.d, scanlines,
466*3ac0a46fSAndroid Build Coastguard Worker                                              (JDIMENSION)max_lines));
467*3ac0a46fSAndroid Build Coastguard Worker #endif
468*3ac0a46fSAndroid Build Coastguard Worker }
469*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_read_raw_data(JPEGState * sp,TIFF_JSAMPIMAGE data,int max_lines)470*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_read_raw_data(JPEGState *sp, TIFF_JSAMPIMAGE data,
471*3ac0a46fSAndroid Build Coastguard Worker                                   int max_lines)
472*3ac0a46fSAndroid Build Coastguard Worker {
473*3ac0a46fSAndroid Build Coastguard Worker #if defined(HAVE_JPEGTURBO_DUAL_MODE_8_12) && BITS_IN_JSAMPLE == 12
474*3ac0a46fSAndroid Build Coastguard Worker     return CALLJPEG(
475*3ac0a46fSAndroid Build Coastguard Worker         sp, -1,
476*3ac0a46fSAndroid Build Coastguard Worker         (int)jpeg12_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines));
477*3ac0a46fSAndroid Build Coastguard Worker #else
478*3ac0a46fSAndroid Build Coastguard Worker     return CALLJPEG(
479*3ac0a46fSAndroid Build Coastguard Worker         sp, -1,
480*3ac0a46fSAndroid Build Coastguard Worker         (int)jpeg_read_raw_data(&sp->cinfo.d, data, (JDIMENSION)max_lines));
481*3ac0a46fSAndroid Build Coastguard Worker #endif
482*3ac0a46fSAndroid Build Coastguard Worker }
483*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_finish_decompress(JPEGState * sp)484*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_finish_decompress(JPEGState *sp)
485*3ac0a46fSAndroid Build Coastguard Worker {
486*3ac0a46fSAndroid Build Coastguard Worker     return CALLJPEG(sp, -1, (int)jpeg_finish_decompress(&sp->cinfo.d));
487*3ac0a46fSAndroid Build Coastguard Worker }
488*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_abort(JPEGState * sp)489*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_abort(JPEGState *sp)
490*3ac0a46fSAndroid Build Coastguard Worker {
491*3ac0a46fSAndroid Build Coastguard Worker     return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm));
492*3ac0a46fSAndroid Build Coastguard Worker }
493*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_destroy(JPEGState * sp)494*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_destroy(JPEGState *sp)
495*3ac0a46fSAndroid Build Coastguard Worker {
496*3ac0a46fSAndroid Build Coastguard Worker     return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm));
497*3ac0a46fSAndroid Build Coastguard Worker }
498*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_alloc_sarray(JPEGState * sp,int pool_id,JDIMENSION samplesperrow,JDIMENSION numrows)499*3ac0a46fSAndroid Build Coastguard Worker static JSAMPARRAY TIFFjpeg_alloc_sarray(JPEGState *sp, int pool_id,
500*3ac0a46fSAndroid Build Coastguard Worker                                         JDIMENSION samplesperrow,
501*3ac0a46fSAndroid Build Coastguard Worker                                         JDIMENSION numrows)
502*3ac0a46fSAndroid Build Coastguard Worker {
503*3ac0a46fSAndroid Build Coastguard Worker     return CALLJPEG(sp, (JSAMPARRAY)NULL,
504*3ac0a46fSAndroid Build Coastguard Worker                     (*sp->cinfo.comm.mem->alloc_sarray)(
505*3ac0a46fSAndroid Build Coastguard Worker                         &sp->cinfo.comm, pool_id, samplesperrow, numrows));
506*3ac0a46fSAndroid Build Coastguard Worker }
507*3ac0a46fSAndroid Build Coastguard Worker 
508*3ac0a46fSAndroid Build Coastguard Worker /*
509*3ac0a46fSAndroid Build Coastguard Worker  * JPEG library destination data manager.
510*3ac0a46fSAndroid Build Coastguard Worker  * These routines direct compressed data from libjpeg into the
511*3ac0a46fSAndroid Build Coastguard Worker  * libtiff output buffer.
512*3ac0a46fSAndroid Build Coastguard Worker  */
513*3ac0a46fSAndroid Build Coastguard Worker 
std_init_destination(j_compress_ptr cinfo)514*3ac0a46fSAndroid Build Coastguard Worker static void std_init_destination(j_compress_ptr cinfo)
515*3ac0a46fSAndroid Build Coastguard Worker {
516*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = (JPEGState *)cinfo;
517*3ac0a46fSAndroid Build Coastguard Worker     TIFF *tif = sp->tif;
518*3ac0a46fSAndroid Build Coastguard Worker 
519*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata;
520*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize;
521*3ac0a46fSAndroid Build Coastguard Worker }
522*3ac0a46fSAndroid Build Coastguard Worker 
std_empty_output_buffer(j_compress_ptr cinfo)523*3ac0a46fSAndroid Build Coastguard Worker static boolean std_empty_output_buffer(j_compress_ptr cinfo)
524*3ac0a46fSAndroid Build Coastguard Worker {
525*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = (JPEGState *)cinfo;
526*3ac0a46fSAndroid Build Coastguard Worker     TIFF *tif = sp->tif;
527*3ac0a46fSAndroid Build Coastguard Worker 
528*3ac0a46fSAndroid Build Coastguard Worker     /* the entire buffer has been filled */
529*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_rawcc = tif->tif_rawdatasize;
530*3ac0a46fSAndroid Build Coastguard Worker 
531*3ac0a46fSAndroid Build Coastguard Worker #ifdef IPPJ_HUFF
532*3ac0a46fSAndroid Build Coastguard Worker     /*
533*3ac0a46fSAndroid Build Coastguard Worker      * The Intel IPP performance library does not necessarily fill up
534*3ac0a46fSAndroid Build Coastguard Worker      * the whole output buffer on each pass, so only dump out the parts
535*3ac0a46fSAndroid Build Coastguard Worker      * that have been filled.
536*3ac0a46fSAndroid Build Coastguard Worker      *   http://trac.osgeo.org/gdal/wiki/JpegIPP
537*3ac0a46fSAndroid Build Coastguard Worker      */
538*3ac0a46fSAndroid Build Coastguard Worker     if (sp->dest.free_in_buffer >= 0)
539*3ac0a46fSAndroid Build Coastguard Worker     {
540*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer;
541*3ac0a46fSAndroid Build Coastguard Worker     }
542*3ac0a46fSAndroid Build Coastguard Worker #endif
543*3ac0a46fSAndroid Build Coastguard Worker 
544*3ac0a46fSAndroid Build Coastguard Worker     if (!TIFFFlushData1(tif))
545*3ac0a46fSAndroid Build Coastguard Worker         return FALSE;
546*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.next_output_byte = (JOCTET *)tif->tif_rawdata;
547*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.free_in_buffer = (size_t)tif->tif_rawdatasize;
548*3ac0a46fSAndroid Build Coastguard Worker 
549*3ac0a46fSAndroid Build Coastguard Worker     return (TRUE);
550*3ac0a46fSAndroid Build Coastguard Worker }
551*3ac0a46fSAndroid Build Coastguard Worker 
std_term_destination(j_compress_ptr cinfo)552*3ac0a46fSAndroid Build Coastguard Worker static void std_term_destination(j_compress_ptr cinfo)
553*3ac0a46fSAndroid Build Coastguard Worker {
554*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = (JPEGState *)cinfo;
555*3ac0a46fSAndroid Build Coastguard Worker     TIFF *tif = sp->tif;
556*3ac0a46fSAndroid Build Coastguard Worker 
557*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_rawcp = (uint8_t *)sp->dest.next_output_byte;
558*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_rawcc = tif->tif_rawdatasize - (tmsize_t)sp->dest.free_in_buffer;
559*3ac0a46fSAndroid Build Coastguard Worker     /* NB: libtiff does the final buffer flush */
560*3ac0a46fSAndroid Build Coastguard Worker }
561*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_data_dest(JPEGState * sp,TIFF * tif)562*3ac0a46fSAndroid Build Coastguard Worker static void TIFFjpeg_data_dest(JPEGState *sp, TIFF *tif)
563*3ac0a46fSAndroid Build Coastguard Worker {
564*3ac0a46fSAndroid Build Coastguard Worker     (void)tif;
565*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.c.dest = &sp->dest;
566*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.init_destination = std_init_destination;
567*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.empty_output_buffer = std_empty_output_buffer;
568*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.term_destination = std_term_destination;
569*3ac0a46fSAndroid Build Coastguard Worker }
570*3ac0a46fSAndroid Build Coastguard Worker 
571*3ac0a46fSAndroid Build Coastguard Worker /*
572*3ac0a46fSAndroid Build Coastguard Worker  * Alternate destination manager for outputting to JPEGTables field.
573*3ac0a46fSAndroid Build Coastguard Worker  */
574*3ac0a46fSAndroid Build Coastguard Worker 
tables_init_destination(j_compress_ptr cinfo)575*3ac0a46fSAndroid Build Coastguard Worker static void tables_init_destination(j_compress_ptr cinfo)
576*3ac0a46fSAndroid Build Coastguard Worker {
577*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = (JPEGState *)cinfo;
578*3ac0a46fSAndroid Build Coastguard Worker 
579*3ac0a46fSAndroid Build Coastguard Worker     /* while building, otherSettings.jpegtables_length is allocated buffer size
580*3ac0a46fSAndroid Build Coastguard Worker      */
581*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.next_output_byte = (JOCTET *)sp->otherSettings.jpegtables;
582*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.free_in_buffer = (size_t)sp->otherSettings.jpegtables_length;
583*3ac0a46fSAndroid Build Coastguard Worker }
584*3ac0a46fSAndroid Build Coastguard Worker 
tables_empty_output_buffer(j_compress_ptr cinfo)585*3ac0a46fSAndroid Build Coastguard Worker static boolean tables_empty_output_buffer(j_compress_ptr cinfo)
586*3ac0a46fSAndroid Build Coastguard Worker {
587*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = (JPEGState *)cinfo;
588*3ac0a46fSAndroid Build Coastguard Worker     void *newbuf;
589*3ac0a46fSAndroid Build Coastguard Worker 
590*3ac0a46fSAndroid Build Coastguard Worker     /* the entire buffer has been filled; enlarge it by 1000 bytes */
591*3ac0a46fSAndroid Build Coastguard Worker     newbuf =
592*3ac0a46fSAndroid Build Coastguard Worker         _TIFFreallocExt(sp->tif, (void *)sp->otherSettings.jpegtables,
593*3ac0a46fSAndroid Build Coastguard Worker                         (tmsize_t)(sp->otherSettings.jpegtables_length + 1000));
594*3ac0a46fSAndroid Build Coastguard Worker     if (newbuf == NULL)
595*3ac0a46fSAndroid Build Coastguard Worker         ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100);
596*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.next_output_byte =
597*3ac0a46fSAndroid Build Coastguard Worker         (JOCTET *)newbuf + sp->otherSettings.jpegtables_length;
598*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.free_in_buffer = (size_t)1000;
599*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.jpegtables = newbuf;
600*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.jpegtables_length += 1000;
601*3ac0a46fSAndroid Build Coastguard Worker     return (TRUE);
602*3ac0a46fSAndroid Build Coastguard Worker }
603*3ac0a46fSAndroid Build Coastguard Worker 
tables_term_destination(j_compress_ptr cinfo)604*3ac0a46fSAndroid Build Coastguard Worker static void tables_term_destination(j_compress_ptr cinfo)
605*3ac0a46fSAndroid Build Coastguard Worker {
606*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = (JPEGState *)cinfo;
607*3ac0a46fSAndroid Build Coastguard Worker 
608*3ac0a46fSAndroid Build Coastguard Worker     /* set tables length to number of bytes actually emitted */
609*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.jpegtables_length -= (uint32_t)sp->dest.free_in_buffer;
610*3ac0a46fSAndroid Build Coastguard Worker }
611*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_tables_dest(JPEGState * sp,TIFF * tif)612*3ac0a46fSAndroid Build Coastguard Worker static int TIFFjpeg_tables_dest(JPEGState *sp, TIFF *tif)
613*3ac0a46fSAndroid Build Coastguard Worker {
614*3ac0a46fSAndroid Build Coastguard Worker     (void)tif;
615*3ac0a46fSAndroid Build Coastguard Worker     /*
616*3ac0a46fSAndroid Build Coastguard Worker      * Allocate a working buffer for building tables.
617*3ac0a46fSAndroid Build Coastguard Worker      * Initial size is 1000 bytes, which is usually adequate.
618*3ac0a46fSAndroid Build Coastguard Worker      */
619*3ac0a46fSAndroid Build Coastguard Worker     if (sp->otherSettings.jpegtables)
620*3ac0a46fSAndroid Build Coastguard Worker         _TIFFfreeExt(tif, sp->otherSettings.jpegtables);
621*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.jpegtables_length = 1000;
622*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.jpegtables = (void *)_TIFFmallocExt(
623*3ac0a46fSAndroid Build Coastguard Worker         tif, (tmsize_t)sp->otherSettings.jpegtables_length);
624*3ac0a46fSAndroid Build Coastguard Worker     if (sp->otherSettings.jpegtables == NULL)
625*3ac0a46fSAndroid Build Coastguard Worker     {
626*3ac0a46fSAndroid Build Coastguard Worker         sp->otherSettings.jpegtables_length = 0;
627*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(sp->tif, "TIFFjpeg_tables_dest",
628*3ac0a46fSAndroid Build Coastguard Worker                       "No space for JPEGTables");
629*3ac0a46fSAndroid Build Coastguard Worker         return (0);
630*3ac0a46fSAndroid Build Coastguard Worker     }
631*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.c.dest = &sp->dest;
632*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.init_destination = tables_init_destination;
633*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.empty_output_buffer = tables_empty_output_buffer;
634*3ac0a46fSAndroid Build Coastguard Worker     sp->dest.term_destination = tables_term_destination;
635*3ac0a46fSAndroid Build Coastguard Worker     return (1);
636*3ac0a46fSAndroid Build Coastguard Worker }
637*3ac0a46fSAndroid Build Coastguard Worker 
638*3ac0a46fSAndroid Build Coastguard Worker /*
639*3ac0a46fSAndroid Build Coastguard Worker  * JPEG library source data manager.
640*3ac0a46fSAndroid Build Coastguard Worker  * These routines supply compressed data to libjpeg.
641*3ac0a46fSAndroid Build Coastguard Worker  */
642*3ac0a46fSAndroid Build Coastguard Worker 
std_init_source(j_decompress_ptr cinfo)643*3ac0a46fSAndroid Build Coastguard Worker static void std_init_source(j_decompress_ptr cinfo)
644*3ac0a46fSAndroid Build Coastguard Worker {
645*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = (JPEGState *)cinfo;
646*3ac0a46fSAndroid Build Coastguard Worker     TIFF *tif = sp->tif;
647*3ac0a46fSAndroid Build Coastguard Worker 
648*3ac0a46fSAndroid Build Coastguard Worker     sp->src.next_input_byte = (const JOCTET *)tif->tif_rawdata;
649*3ac0a46fSAndroid Build Coastguard Worker     sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc;
650*3ac0a46fSAndroid Build Coastguard Worker }
651*3ac0a46fSAndroid Build Coastguard Worker 
std_fill_input_buffer(j_decompress_ptr cinfo)652*3ac0a46fSAndroid Build Coastguard Worker static boolean std_fill_input_buffer(j_decompress_ptr cinfo)
653*3ac0a46fSAndroid Build Coastguard Worker {
654*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = (JPEGState *)cinfo;
655*3ac0a46fSAndroid Build Coastguard Worker     static const JOCTET dummy_EOI[2] = {0xFF, JPEG_EOI};
656*3ac0a46fSAndroid Build Coastguard Worker 
657*3ac0a46fSAndroid Build Coastguard Worker #ifdef IPPJ_HUFF
658*3ac0a46fSAndroid Build Coastguard Worker     /*
659*3ac0a46fSAndroid Build Coastguard Worker      * The Intel IPP performance library does not necessarily read the whole
660*3ac0a46fSAndroid Build Coastguard Worker      * input buffer in one pass, so it is possible to get here with data
661*3ac0a46fSAndroid Build Coastguard Worker      * yet to read.
662*3ac0a46fSAndroid Build Coastguard Worker      *
663*3ac0a46fSAndroid Build Coastguard Worker      * We just return without doing anything, until the entire buffer has
664*3ac0a46fSAndroid Build Coastguard Worker      * been read.
665*3ac0a46fSAndroid Build Coastguard Worker      * http://trac.osgeo.org/gdal/wiki/JpegIPP
666*3ac0a46fSAndroid Build Coastguard Worker      */
667*3ac0a46fSAndroid Build Coastguard Worker     if (sp->src.bytes_in_buffer > 0)
668*3ac0a46fSAndroid Build Coastguard Worker     {
669*3ac0a46fSAndroid Build Coastguard Worker         return (TRUE);
670*3ac0a46fSAndroid Build Coastguard Worker     }
671*3ac0a46fSAndroid Build Coastguard Worker #endif
672*3ac0a46fSAndroid Build Coastguard Worker 
673*3ac0a46fSAndroid Build Coastguard Worker     /*
674*3ac0a46fSAndroid Build Coastguard Worker      * Normally the whole strip/tile is read and so we don't need to do
675*3ac0a46fSAndroid Build Coastguard Worker      * a fill.  In the case of CHUNKY_STRIP_READ_SUPPORT we might not have
676*3ac0a46fSAndroid Build Coastguard Worker      * all the data, but the rawdata is refreshed between scanlines and
677*3ac0a46fSAndroid Build Coastguard Worker      * we push this into the io machinery in JPEGDecode().
678*3ac0a46fSAndroid Build Coastguard Worker      * http://trac.osgeo.org/gdal/ticket/3894
679*3ac0a46fSAndroid Build Coastguard Worker      */
680*3ac0a46fSAndroid Build Coastguard Worker 
681*3ac0a46fSAndroid Build Coastguard Worker     WARNMS(cinfo, JWRN_JPEG_EOF);
682*3ac0a46fSAndroid Build Coastguard Worker     /* insert a fake EOI marker */
683*3ac0a46fSAndroid Build Coastguard Worker     sp->src.next_input_byte = dummy_EOI;
684*3ac0a46fSAndroid Build Coastguard Worker     sp->src.bytes_in_buffer = 2;
685*3ac0a46fSAndroid Build Coastguard Worker     return (TRUE);
686*3ac0a46fSAndroid Build Coastguard Worker }
687*3ac0a46fSAndroid Build Coastguard Worker 
std_skip_input_data(j_decompress_ptr cinfo,long num_bytes)688*3ac0a46fSAndroid Build Coastguard Worker static void std_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
689*3ac0a46fSAndroid Build Coastguard Worker {
690*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = (JPEGState *)cinfo;
691*3ac0a46fSAndroid Build Coastguard Worker 
692*3ac0a46fSAndroid Build Coastguard Worker     if (num_bytes > 0)
693*3ac0a46fSAndroid Build Coastguard Worker     {
694*3ac0a46fSAndroid Build Coastguard Worker         if ((size_t)num_bytes > sp->src.bytes_in_buffer)
695*3ac0a46fSAndroid Build Coastguard Worker         {
696*3ac0a46fSAndroid Build Coastguard Worker             /* oops, buffer overrun */
697*3ac0a46fSAndroid Build Coastguard Worker             (void)std_fill_input_buffer(cinfo);
698*3ac0a46fSAndroid Build Coastguard Worker         }
699*3ac0a46fSAndroid Build Coastguard Worker         else
700*3ac0a46fSAndroid Build Coastguard Worker         {
701*3ac0a46fSAndroid Build Coastguard Worker             sp->src.next_input_byte += (size_t)num_bytes;
702*3ac0a46fSAndroid Build Coastguard Worker             sp->src.bytes_in_buffer -= (size_t)num_bytes;
703*3ac0a46fSAndroid Build Coastguard Worker         }
704*3ac0a46fSAndroid Build Coastguard Worker     }
705*3ac0a46fSAndroid Build Coastguard Worker }
706*3ac0a46fSAndroid Build Coastguard Worker 
std_term_source(j_decompress_ptr cinfo)707*3ac0a46fSAndroid Build Coastguard Worker static void std_term_source(j_decompress_ptr cinfo)
708*3ac0a46fSAndroid Build Coastguard Worker {
709*3ac0a46fSAndroid Build Coastguard Worker     /* No work necessary here */
710*3ac0a46fSAndroid Build Coastguard Worker     (void)cinfo;
711*3ac0a46fSAndroid Build Coastguard Worker }
712*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_data_src(JPEGState * sp)713*3ac0a46fSAndroid Build Coastguard Worker static void TIFFjpeg_data_src(JPEGState *sp)
714*3ac0a46fSAndroid Build Coastguard Worker {
715*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.d.src = &sp->src;
716*3ac0a46fSAndroid Build Coastguard Worker     sp->src.init_source = std_init_source;
717*3ac0a46fSAndroid Build Coastguard Worker     sp->src.fill_input_buffer = std_fill_input_buffer;
718*3ac0a46fSAndroid Build Coastguard Worker     sp->src.skip_input_data = std_skip_input_data;
719*3ac0a46fSAndroid Build Coastguard Worker     sp->src.resync_to_restart = jpeg_resync_to_restart;
720*3ac0a46fSAndroid Build Coastguard Worker     sp->src.term_source = std_term_source;
721*3ac0a46fSAndroid Build Coastguard Worker     sp->src.bytes_in_buffer = 0; /* for safety */
722*3ac0a46fSAndroid Build Coastguard Worker     sp->src.next_input_byte = NULL;
723*3ac0a46fSAndroid Build Coastguard Worker }
724*3ac0a46fSAndroid Build Coastguard Worker 
725*3ac0a46fSAndroid Build Coastguard Worker /*
726*3ac0a46fSAndroid Build Coastguard Worker  * Alternate source manager for reading from JPEGTables.
727*3ac0a46fSAndroid Build Coastguard Worker  * We can share all the code except for the init routine.
728*3ac0a46fSAndroid Build Coastguard Worker  */
729*3ac0a46fSAndroid Build Coastguard Worker 
tables_init_source(j_decompress_ptr cinfo)730*3ac0a46fSAndroid Build Coastguard Worker static void tables_init_source(j_decompress_ptr cinfo)
731*3ac0a46fSAndroid Build Coastguard Worker {
732*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = (JPEGState *)cinfo;
733*3ac0a46fSAndroid Build Coastguard Worker 
734*3ac0a46fSAndroid Build Coastguard Worker     sp->src.next_input_byte = (const JOCTET *)sp->otherSettings.jpegtables;
735*3ac0a46fSAndroid Build Coastguard Worker     sp->src.bytes_in_buffer = (size_t)sp->otherSettings.jpegtables_length;
736*3ac0a46fSAndroid Build Coastguard Worker }
737*3ac0a46fSAndroid Build Coastguard Worker 
TIFFjpeg_tables_src(JPEGState * sp)738*3ac0a46fSAndroid Build Coastguard Worker static void TIFFjpeg_tables_src(JPEGState *sp)
739*3ac0a46fSAndroid Build Coastguard Worker {
740*3ac0a46fSAndroid Build Coastguard Worker     TIFFjpeg_data_src(sp);
741*3ac0a46fSAndroid Build Coastguard Worker     sp->src.init_source = tables_init_source;
742*3ac0a46fSAndroid Build Coastguard Worker }
743*3ac0a46fSAndroid Build Coastguard Worker 
744*3ac0a46fSAndroid Build Coastguard Worker /*
745*3ac0a46fSAndroid Build Coastguard Worker  * Allocate downsampled-data buffers needed for downsampled I/O.
746*3ac0a46fSAndroid Build Coastguard Worker  * We use values computed in jpeg_start_compress or jpeg_start_decompress.
747*3ac0a46fSAndroid Build Coastguard Worker  * We use libjpeg's allocator so that buffers will be released automatically
748*3ac0a46fSAndroid Build Coastguard Worker  * when done with strip/tile.
749*3ac0a46fSAndroid Build Coastguard Worker  * This is also a handy place to compute samplesperclump, bytesperline.
750*3ac0a46fSAndroid Build Coastguard Worker  */
alloc_downsampled_buffers(TIFF * tif,jpeg_component_info * comp_info,int num_components)751*3ac0a46fSAndroid Build Coastguard Worker static int alloc_downsampled_buffers(TIFF *tif, jpeg_component_info *comp_info,
752*3ac0a46fSAndroid Build Coastguard Worker                                      int num_components)
753*3ac0a46fSAndroid Build Coastguard Worker {
754*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
755*3ac0a46fSAndroid Build Coastguard Worker     int ci;
756*3ac0a46fSAndroid Build Coastguard Worker     jpeg_component_info *compptr;
757*3ac0a46fSAndroid Build Coastguard Worker     TIFF_JSAMPARRAY buf;
758*3ac0a46fSAndroid Build Coastguard Worker     int samples_per_clump = 0;
759*3ac0a46fSAndroid Build Coastguard Worker 
760*3ac0a46fSAndroid Build Coastguard Worker     for (ci = 0, compptr = comp_info; ci < num_components; ci++, compptr++)
761*3ac0a46fSAndroid Build Coastguard Worker     {
762*3ac0a46fSAndroid Build Coastguard Worker         samples_per_clump += compptr->h_samp_factor * compptr->v_samp_factor;
763*3ac0a46fSAndroid Build Coastguard Worker         buf = (TIFF_JSAMPARRAY)TIFFjpeg_alloc_sarray(
764*3ac0a46fSAndroid Build Coastguard Worker             sp, JPOOL_IMAGE, compptr->width_in_blocks * DCTSIZE,
765*3ac0a46fSAndroid Build Coastguard Worker             (JDIMENSION)(compptr->v_samp_factor * DCTSIZE));
766*3ac0a46fSAndroid Build Coastguard Worker         if (buf == NULL)
767*3ac0a46fSAndroid Build Coastguard Worker             return (0);
768*3ac0a46fSAndroid Build Coastguard Worker         sp->ds_buffer[ci] = buf;
769*3ac0a46fSAndroid Build Coastguard Worker     }
770*3ac0a46fSAndroid Build Coastguard Worker     sp->samplesperclump = samples_per_clump;
771*3ac0a46fSAndroid Build Coastguard Worker     return (1);
772*3ac0a46fSAndroid Build Coastguard Worker }
773*3ac0a46fSAndroid Build Coastguard Worker 
774*3ac0a46fSAndroid Build Coastguard Worker /*
775*3ac0a46fSAndroid Build Coastguard Worker  * JPEG Decoding.
776*3ac0a46fSAndroid Build Coastguard Worker  */
777*3ac0a46fSAndroid Build Coastguard Worker 
778*3ac0a46fSAndroid Build Coastguard Worker #ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
779*3ac0a46fSAndroid Build Coastguard Worker 
780*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_MARKER_SOF0 0xC0
781*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_MARKER_SOF1 0xC1
782*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_MARKER_SOF2 0xC2
783*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_MARKER_SOF9 0xC9
784*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_MARKER_SOF10 0xCA
785*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_MARKER_DHT 0xC4
786*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_MARKER_SOI 0xD8
787*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_MARKER_SOS 0xDA
788*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_MARKER_DQT 0xDB
789*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_MARKER_DRI 0xDD
790*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_MARKER_APP0 0xE0
791*3ac0a46fSAndroid Build Coastguard Worker #define JPEG_MARKER_COM 0xFE
792*3ac0a46fSAndroid Build Coastguard Worker struct JPEGFixupTagsSubsamplingData
793*3ac0a46fSAndroid Build Coastguard Worker {
794*3ac0a46fSAndroid Build Coastguard Worker     TIFF *tif;
795*3ac0a46fSAndroid Build Coastguard Worker     void *buffer;
796*3ac0a46fSAndroid Build Coastguard Worker     uint32_t buffersize;
797*3ac0a46fSAndroid Build Coastguard Worker     uint8_t *buffercurrentbyte;
798*3ac0a46fSAndroid Build Coastguard Worker     uint32_t bufferbytesleft;
799*3ac0a46fSAndroid Build Coastguard Worker     uint64_t fileoffset;
800*3ac0a46fSAndroid Build Coastguard Worker     uint64_t filebytesleft;
801*3ac0a46fSAndroid Build Coastguard Worker     uint8_t filepositioned;
802*3ac0a46fSAndroid Build Coastguard Worker };
803*3ac0a46fSAndroid Build Coastguard Worker static void JPEGFixupTagsSubsampling(TIFF *tif);
804*3ac0a46fSAndroid Build Coastguard Worker static int
805*3ac0a46fSAndroid Build Coastguard Worker JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data);
806*3ac0a46fSAndroid Build Coastguard Worker static int
807*3ac0a46fSAndroid Build Coastguard Worker JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data,
808*3ac0a46fSAndroid Build Coastguard Worker                                  uint8_t *result);
809*3ac0a46fSAndroid Build Coastguard Worker static int
810*3ac0a46fSAndroid Build Coastguard Worker JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data,
811*3ac0a46fSAndroid Build Coastguard Worker                                  uint16_t *result);
812*3ac0a46fSAndroid Build Coastguard Worker static void
813*3ac0a46fSAndroid Build Coastguard Worker JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData *data,
814*3ac0a46fSAndroid Build Coastguard Worker                              uint16_t skiplength);
815*3ac0a46fSAndroid Build Coastguard Worker 
816*3ac0a46fSAndroid Build Coastguard Worker #endif
817*3ac0a46fSAndroid Build Coastguard Worker 
JPEGFixupTags(TIFF * tif)818*3ac0a46fSAndroid Build Coastguard Worker static int JPEGFixupTags(TIFF *tif)
819*3ac0a46fSAndroid Build Coastguard Worker {
820*3ac0a46fSAndroid Build Coastguard Worker #ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
821*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
822*3ac0a46fSAndroid Build Coastguard Worker     if ((tif->tif_dir.td_photometric == PHOTOMETRIC_YCBCR) &&
823*3ac0a46fSAndroid Build Coastguard Worker         (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG) &&
824*3ac0a46fSAndroid Build Coastguard Worker         (tif->tif_dir.td_samplesperpixel == 3) &&
825*3ac0a46fSAndroid Build Coastguard Worker         !sp->otherSettings.ycbcrsampling_fetched)
826*3ac0a46fSAndroid Build Coastguard Worker         JPEGFixupTagsSubsampling(tif);
827*3ac0a46fSAndroid Build Coastguard Worker #endif
828*3ac0a46fSAndroid Build Coastguard Worker 
829*3ac0a46fSAndroid Build Coastguard Worker     return (1);
830*3ac0a46fSAndroid Build Coastguard Worker }
831*3ac0a46fSAndroid Build Coastguard Worker 
832*3ac0a46fSAndroid Build Coastguard Worker #ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
833*3ac0a46fSAndroid Build Coastguard Worker 
JPEGFixupTagsSubsampling(TIFF * tif)834*3ac0a46fSAndroid Build Coastguard Worker static void JPEGFixupTagsSubsampling(TIFF *tif)
835*3ac0a46fSAndroid Build Coastguard Worker {
836*3ac0a46fSAndroid Build Coastguard Worker     /*
837*3ac0a46fSAndroid Build Coastguard Worker      * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in
838*3ac0a46fSAndroid Build Coastguard Worker      * the TIFF tags, but still use non-default (2,2) values within the jpeg
839*3ac0a46fSAndroid Build Coastguard Worker      * data stream itself.  In order for TIFF applications to work properly
840*3ac0a46fSAndroid Build Coastguard Worker      * - for instance to get the strip buffer size right - it is imperative
841*3ac0a46fSAndroid Build Coastguard Worker      * that the subsampling be available before we start reading the image
842*3ac0a46fSAndroid Build Coastguard Worker      * data normally.  This function will attempt to analyze the first strip in
843*3ac0a46fSAndroid Build Coastguard Worker      * order to get the sampling values from the jpeg data stream.
844*3ac0a46fSAndroid Build Coastguard Worker      *
845*3ac0a46fSAndroid Build Coastguard Worker      * Note that JPEGPreDeocode() will produce a fairly loud warning when the
846*3ac0a46fSAndroid Build Coastguard Worker      * discovered sampling does not match the default sampling (2,2) or whatever
847*3ac0a46fSAndroid Build Coastguard Worker      * was actually in the tiff tags.
848*3ac0a46fSAndroid Build Coastguard Worker      *
849*3ac0a46fSAndroid Build Coastguard Worker      * See the bug in bugzilla for details:
850*3ac0a46fSAndroid Build Coastguard Worker      *
851*3ac0a46fSAndroid Build Coastguard Worker      * http://bugzilla.remotesensing.org/show_bug.cgi?id=168
852*3ac0a46fSAndroid Build Coastguard Worker      *
853*3ac0a46fSAndroid Build Coastguard Worker      * Frank Warmerdam, July 2002
854*3ac0a46fSAndroid Build Coastguard Worker      * Joris Van Damme, May 2007
855*3ac0a46fSAndroid Build Coastguard Worker      */
856*3ac0a46fSAndroid Build Coastguard Worker     static const char module[] = "JPEGFixupTagsSubsampling";
857*3ac0a46fSAndroid Build Coastguard Worker     struct JPEGFixupTagsSubsamplingData m;
858*3ac0a46fSAndroid Build Coastguard Worker     uint64_t fileoffset = TIFFGetStrileOffset(tif, 0);
859*3ac0a46fSAndroid Build Coastguard Worker 
860*3ac0a46fSAndroid Build Coastguard Worker     if (fileoffset == 0)
861*3ac0a46fSAndroid Build Coastguard Worker     {
862*3ac0a46fSAndroid Build Coastguard Worker         /* Do not even try to check if the first strip/tile does not
863*3ac0a46fSAndroid Build Coastguard Worker            yet exist, as occurs when GDAL has created a new NULL file
864*3ac0a46fSAndroid Build Coastguard Worker            for instance. */
865*3ac0a46fSAndroid Build Coastguard Worker         return;
866*3ac0a46fSAndroid Build Coastguard Worker     }
867*3ac0a46fSAndroid Build Coastguard Worker 
868*3ac0a46fSAndroid Build Coastguard Worker     m.tif = tif;
869*3ac0a46fSAndroid Build Coastguard Worker     m.buffersize = 2048;
870*3ac0a46fSAndroid Build Coastguard Worker     m.buffer = _TIFFmallocExt(tif, m.buffersize);
871*3ac0a46fSAndroid Build Coastguard Worker     if (m.buffer == NULL)
872*3ac0a46fSAndroid Build Coastguard Worker     {
873*3ac0a46fSAndroid Build Coastguard Worker         TIFFWarningExtR(tif, module,
874*3ac0a46fSAndroid Build Coastguard Worker                         "Unable to allocate memory for auto-correcting of "
875*3ac0a46fSAndroid Build Coastguard Worker                         "subsampling values; auto-correcting skipped");
876*3ac0a46fSAndroid Build Coastguard Worker         return;
877*3ac0a46fSAndroid Build Coastguard Worker     }
878*3ac0a46fSAndroid Build Coastguard Worker     m.buffercurrentbyte = NULL;
879*3ac0a46fSAndroid Build Coastguard Worker     m.bufferbytesleft = 0;
880*3ac0a46fSAndroid Build Coastguard Worker     m.fileoffset = fileoffset;
881*3ac0a46fSAndroid Build Coastguard Worker     m.filepositioned = 0;
882*3ac0a46fSAndroid Build Coastguard Worker     m.filebytesleft = TIFFGetStrileByteCount(tif, 0);
883*3ac0a46fSAndroid Build Coastguard Worker     if (!JPEGFixupTagsSubsamplingSec(&m))
884*3ac0a46fSAndroid Build Coastguard Worker         TIFFWarningExtR(
885*3ac0a46fSAndroid Build Coastguard Worker             tif, module,
886*3ac0a46fSAndroid Build Coastguard Worker             "Unable to auto-correct subsampling values, likely corrupt JPEG "
887*3ac0a46fSAndroid Build Coastguard Worker             "compressed data in first strip/tile; auto-correcting skipped");
888*3ac0a46fSAndroid Build Coastguard Worker     _TIFFfreeExt(tif, m.buffer);
889*3ac0a46fSAndroid Build Coastguard Worker }
890*3ac0a46fSAndroid Build Coastguard Worker 
891*3ac0a46fSAndroid Build Coastguard Worker static int
JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData * data)892*3ac0a46fSAndroid Build Coastguard Worker JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData *data)
893*3ac0a46fSAndroid Build Coastguard Worker {
894*3ac0a46fSAndroid Build Coastguard Worker     static const char module[] = "JPEGFixupTagsSubsamplingSec";
895*3ac0a46fSAndroid Build Coastguard Worker     uint8_t m;
896*3ac0a46fSAndroid Build Coastguard Worker     while (1)
897*3ac0a46fSAndroid Build Coastguard Worker     {
898*3ac0a46fSAndroid Build Coastguard Worker         while (1)
899*3ac0a46fSAndroid Build Coastguard Worker         {
900*3ac0a46fSAndroid Build Coastguard Worker             if (!JPEGFixupTagsSubsamplingReadByte(data, &m))
901*3ac0a46fSAndroid Build Coastguard Worker                 return (0);
902*3ac0a46fSAndroid Build Coastguard Worker             if (m == 255)
903*3ac0a46fSAndroid Build Coastguard Worker                 break;
904*3ac0a46fSAndroid Build Coastguard Worker         }
905*3ac0a46fSAndroid Build Coastguard Worker         while (1)
906*3ac0a46fSAndroid Build Coastguard Worker         {
907*3ac0a46fSAndroid Build Coastguard Worker             if (!JPEGFixupTagsSubsamplingReadByte(data, &m))
908*3ac0a46fSAndroid Build Coastguard Worker                 return (0);
909*3ac0a46fSAndroid Build Coastguard Worker             if (m != 255)
910*3ac0a46fSAndroid Build Coastguard Worker                 break;
911*3ac0a46fSAndroid Build Coastguard Worker         }
912*3ac0a46fSAndroid Build Coastguard Worker         switch (m)
913*3ac0a46fSAndroid Build Coastguard Worker         {
914*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_SOI:
915*3ac0a46fSAndroid Build Coastguard Worker                 /* this type of marker has no data and should be skipped */
916*3ac0a46fSAndroid Build Coastguard Worker                 break;
917*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_COM:
918*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0:
919*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 1:
920*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 2:
921*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 3:
922*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 4:
923*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 5:
924*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 6:
925*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 7:
926*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 8:
927*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 9:
928*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 10:
929*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 11:
930*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 12:
931*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 13:
932*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 14:
933*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_APP0 + 15:
934*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_DQT:
935*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_SOS:
936*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_DHT:
937*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_DRI:
938*3ac0a46fSAndroid Build Coastguard Worker                 /* this type of marker has data, but it has no use to us and
939*3ac0a46fSAndroid Build Coastguard Worker                  * should be skipped */
940*3ac0a46fSAndroid Build Coastguard Worker                 {
941*3ac0a46fSAndroid Build Coastguard Worker                     uint16_t n;
942*3ac0a46fSAndroid Build Coastguard Worker                     if (!JPEGFixupTagsSubsamplingReadWord(data, &n))
943*3ac0a46fSAndroid Build Coastguard Worker                         return (0);
944*3ac0a46fSAndroid Build Coastguard Worker                     if (n < 2)
945*3ac0a46fSAndroid Build Coastguard Worker                         return (0);
946*3ac0a46fSAndroid Build Coastguard Worker                     n -= 2;
947*3ac0a46fSAndroid Build Coastguard Worker                     if (n > 0)
948*3ac0a46fSAndroid Build Coastguard Worker                         JPEGFixupTagsSubsamplingSkip(data, n);
949*3ac0a46fSAndroid Build Coastguard Worker                 }
950*3ac0a46fSAndroid Build Coastguard Worker                 break;
951*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_SOF0:  /* Baseline sequential Huffman */
952*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_SOF1:  /* Extended sequential Huffman */
953*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_SOF2:  /* Progressive Huffman: normally not allowed
954*3ac0a46fSAndroid Build Coastguard Worker                                        by  TechNote, but that doesn't hurt
955*3ac0a46fSAndroid Build Coastguard Worker                                        supporting it */
956*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_SOF9:  /* Extended sequential arithmetic */
957*3ac0a46fSAndroid Build Coastguard Worker             case JPEG_MARKER_SOF10: /* Progressive arithmetic: normally not
958*3ac0a46fSAndroid Build Coastguard Worker                                        allowed by TechNote, but that doesn't
959*3ac0a46fSAndroid Build Coastguard Worker                                        hurt supporting it */
960*3ac0a46fSAndroid Build Coastguard Worker                 /* this marker contains the subsampling factors we're scanning
961*3ac0a46fSAndroid Build Coastguard Worker                  * for */
962*3ac0a46fSAndroid Build Coastguard Worker                 {
963*3ac0a46fSAndroid Build Coastguard Worker                     uint16_t n;
964*3ac0a46fSAndroid Build Coastguard Worker                     uint16_t o;
965*3ac0a46fSAndroid Build Coastguard Worker                     uint8_t p;
966*3ac0a46fSAndroid Build Coastguard Worker                     uint8_t ph, pv;
967*3ac0a46fSAndroid Build Coastguard Worker                     if (!JPEGFixupTagsSubsamplingReadWord(data, &n))
968*3ac0a46fSAndroid Build Coastguard Worker                         return (0);
969*3ac0a46fSAndroid Build Coastguard Worker                     if (n != 8 + data->tif->tif_dir.td_samplesperpixel * 3)
970*3ac0a46fSAndroid Build Coastguard Worker                         return (0);
971*3ac0a46fSAndroid Build Coastguard Worker                     JPEGFixupTagsSubsamplingSkip(data, 7);
972*3ac0a46fSAndroid Build Coastguard Worker                     if (!JPEGFixupTagsSubsamplingReadByte(data, &p))
973*3ac0a46fSAndroid Build Coastguard Worker                         return (0);
974*3ac0a46fSAndroid Build Coastguard Worker                     ph = (p >> 4);
975*3ac0a46fSAndroid Build Coastguard Worker                     pv = (p & 15);
976*3ac0a46fSAndroid Build Coastguard Worker                     JPEGFixupTagsSubsamplingSkip(data, 1);
977*3ac0a46fSAndroid Build Coastguard Worker                     for (o = 1; o < data->tif->tif_dir.td_samplesperpixel; o++)
978*3ac0a46fSAndroid Build Coastguard Worker                     {
979*3ac0a46fSAndroid Build Coastguard Worker                         JPEGFixupTagsSubsamplingSkip(data, 1);
980*3ac0a46fSAndroid Build Coastguard Worker                         if (!JPEGFixupTagsSubsamplingReadByte(data, &p))
981*3ac0a46fSAndroid Build Coastguard Worker                             return (0);
982*3ac0a46fSAndroid Build Coastguard Worker                         if (p != 0x11)
983*3ac0a46fSAndroid Build Coastguard Worker                         {
984*3ac0a46fSAndroid Build Coastguard Worker                             TIFFWarningExtR(data->tif, module,
985*3ac0a46fSAndroid Build Coastguard Worker                                             "Subsampling values inside JPEG "
986*3ac0a46fSAndroid Build Coastguard Worker                                             "compressed data "
987*3ac0a46fSAndroid Build Coastguard Worker                                             "have no TIFF equivalent, "
988*3ac0a46fSAndroid Build Coastguard Worker                                             "auto-correction of TIFF "
989*3ac0a46fSAndroid Build Coastguard Worker                                             "subsampling values failed");
990*3ac0a46fSAndroid Build Coastguard Worker                             return (1);
991*3ac0a46fSAndroid Build Coastguard Worker                         }
992*3ac0a46fSAndroid Build Coastguard Worker                         JPEGFixupTagsSubsamplingSkip(data, 1);
993*3ac0a46fSAndroid Build Coastguard Worker                     }
994*3ac0a46fSAndroid Build Coastguard Worker                     if (((ph != 1) && (ph != 2) && (ph != 4)) ||
995*3ac0a46fSAndroid Build Coastguard Worker                         ((pv != 1) && (pv != 2) && (pv != 4)))
996*3ac0a46fSAndroid Build Coastguard Worker                     {
997*3ac0a46fSAndroid Build Coastguard Worker                         TIFFWarningExtR(data->tif, module,
998*3ac0a46fSAndroid Build Coastguard Worker                                         "Subsampling values inside JPEG "
999*3ac0a46fSAndroid Build Coastguard Worker                                         "compressed data have no TIFF "
1000*3ac0a46fSAndroid Build Coastguard Worker                                         "equivalent, auto-correction of TIFF "
1001*3ac0a46fSAndroid Build Coastguard Worker                                         "subsampling values failed");
1002*3ac0a46fSAndroid Build Coastguard Worker                         return (1);
1003*3ac0a46fSAndroid Build Coastguard Worker                     }
1004*3ac0a46fSAndroid Build Coastguard Worker                     if ((ph != data->tif->tif_dir.td_ycbcrsubsampling[0]) ||
1005*3ac0a46fSAndroid Build Coastguard Worker                         (pv != data->tif->tif_dir.td_ycbcrsubsampling[1]))
1006*3ac0a46fSAndroid Build Coastguard Worker                     {
1007*3ac0a46fSAndroid Build Coastguard Worker                         TIFFWarningExtR(
1008*3ac0a46fSAndroid Build Coastguard Worker                             data->tif, module,
1009*3ac0a46fSAndroid Build Coastguard Worker                             "Auto-corrected former TIFF subsampling values "
1010*3ac0a46fSAndroid Build Coastguard Worker                             "[%" PRIu16 ",%" PRIu16
1011*3ac0a46fSAndroid Build Coastguard Worker                             "] to match subsampling values inside JPEG "
1012*3ac0a46fSAndroid Build Coastguard Worker                             "compressed data [%" PRIu8 ",%" PRIu8 "]",
1013*3ac0a46fSAndroid Build Coastguard Worker                             data->tif->tif_dir.td_ycbcrsubsampling[0],
1014*3ac0a46fSAndroid Build Coastguard Worker                             data->tif->tif_dir.td_ycbcrsubsampling[1], ph, pv);
1015*3ac0a46fSAndroid Build Coastguard Worker                         data->tif->tif_dir.td_ycbcrsubsampling[0] = ph;
1016*3ac0a46fSAndroid Build Coastguard Worker                         data->tif->tif_dir.td_ycbcrsubsampling[1] = pv;
1017*3ac0a46fSAndroid Build Coastguard Worker                     }
1018*3ac0a46fSAndroid Build Coastguard Worker                 }
1019*3ac0a46fSAndroid Build Coastguard Worker                 return (1);
1020*3ac0a46fSAndroid Build Coastguard Worker             default:
1021*3ac0a46fSAndroid Build Coastguard Worker                 return (0);
1022*3ac0a46fSAndroid Build Coastguard Worker         }
1023*3ac0a46fSAndroid Build Coastguard Worker     }
1024*3ac0a46fSAndroid Build Coastguard Worker }
1025*3ac0a46fSAndroid Build Coastguard Worker 
1026*3ac0a46fSAndroid Build Coastguard Worker static int
JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData * data,uint8_t * result)1027*3ac0a46fSAndroid Build Coastguard Worker JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData *data,
1028*3ac0a46fSAndroid Build Coastguard Worker                                  uint8_t *result)
1029*3ac0a46fSAndroid Build Coastguard Worker {
1030*3ac0a46fSAndroid Build Coastguard Worker     if (data->bufferbytesleft == 0)
1031*3ac0a46fSAndroid Build Coastguard Worker     {
1032*3ac0a46fSAndroid Build Coastguard Worker         uint32_t m;
1033*3ac0a46fSAndroid Build Coastguard Worker         if (data->filebytesleft == 0)
1034*3ac0a46fSAndroid Build Coastguard Worker             return (0);
1035*3ac0a46fSAndroid Build Coastguard Worker         if (!data->filepositioned)
1036*3ac0a46fSAndroid Build Coastguard Worker         {
1037*3ac0a46fSAndroid Build Coastguard Worker             if (TIFFSeekFile(data->tif, data->fileoffset, SEEK_SET) ==
1038*3ac0a46fSAndroid Build Coastguard Worker                 (toff_t)-1)
1039*3ac0a46fSAndroid Build Coastguard Worker             {
1040*3ac0a46fSAndroid Build Coastguard Worker                 return 0;
1041*3ac0a46fSAndroid Build Coastguard Worker             }
1042*3ac0a46fSAndroid Build Coastguard Worker             data->filepositioned = 1;
1043*3ac0a46fSAndroid Build Coastguard Worker         }
1044*3ac0a46fSAndroid Build Coastguard Worker         m = data->buffersize;
1045*3ac0a46fSAndroid Build Coastguard Worker         if ((uint64_t)m > data->filebytesleft)
1046*3ac0a46fSAndroid Build Coastguard Worker             m = (uint32_t)data->filebytesleft;
1047*3ac0a46fSAndroid Build Coastguard Worker         assert(m < 0x80000000UL);
1048*3ac0a46fSAndroid Build Coastguard Worker         if (TIFFReadFile(data->tif, data->buffer, (tmsize_t)m) != (tmsize_t)m)
1049*3ac0a46fSAndroid Build Coastguard Worker             return (0);
1050*3ac0a46fSAndroid Build Coastguard Worker         data->buffercurrentbyte = data->buffer;
1051*3ac0a46fSAndroid Build Coastguard Worker         data->bufferbytesleft = m;
1052*3ac0a46fSAndroid Build Coastguard Worker         data->fileoffset += m;
1053*3ac0a46fSAndroid Build Coastguard Worker         data->filebytesleft -= m;
1054*3ac0a46fSAndroid Build Coastguard Worker     }
1055*3ac0a46fSAndroid Build Coastguard Worker     *result = *data->buffercurrentbyte;
1056*3ac0a46fSAndroid Build Coastguard Worker     data->buffercurrentbyte++;
1057*3ac0a46fSAndroid Build Coastguard Worker     data->bufferbytesleft--;
1058*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1059*3ac0a46fSAndroid Build Coastguard Worker }
1060*3ac0a46fSAndroid Build Coastguard Worker 
1061*3ac0a46fSAndroid Build Coastguard Worker static int
JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData * data,uint16_t * result)1062*3ac0a46fSAndroid Build Coastguard Worker JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData *data,
1063*3ac0a46fSAndroid Build Coastguard Worker                                  uint16_t *result)
1064*3ac0a46fSAndroid Build Coastguard Worker {
1065*3ac0a46fSAndroid Build Coastguard Worker     uint8_t ma;
1066*3ac0a46fSAndroid Build Coastguard Worker     uint8_t mb;
1067*3ac0a46fSAndroid Build Coastguard Worker     if (!JPEGFixupTagsSubsamplingReadByte(data, &ma))
1068*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1069*3ac0a46fSAndroid Build Coastguard Worker     if (!JPEGFixupTagsSubsamplingReadByte(data, &mb))
1070*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1071*3ac0a46fSAndroid Build Coastguard Worker     *result = (ma << 8) | mb;
1072*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1073*3ac0a46fSAndroid Build Coastguard Worker }
1074*3ac0a46fSAndroid Build Coastguard Worker 
1075*3ac0a46fSAndroid Build Coastguard Worker static void
JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData * data,uint16_t skiplength)1076*3ac0a46fSAndroid Build Coastguard Worker JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData *data,
1077*3ac0a46fSAndroid Build Coastguard Worker                              uint16_t skiplength)
1078*3ac0a46fSAndroid Build Coastguard Worker {
1079*3ac0a46fSAndroid Build Coastguard Worker     if ((uint32_t)skiplength <= data->bufferbytesleft)
1080*3ac0a46fSAndroid Build Coastguard Worker     {
1081*3ac0a46fSAndroid Build Coastguard Worker         data->buffercurrentbyte += skiplength;
1082*3ac0a46fSAndroid Build Coastguard Worker         data->bufferbytesleft -= skiplength;
1083*3ac0a46fSAndroid Build Coastguard Worker     }
1084*3ac0a46fSAndroid Build Coastguard Worker     else
1085*3ac0a46fSAndroid Build Coastguard Worker     {
1086*3ac0a46fSAndroid Build Coastguard Worker         uint16_t m;
1087*3ac0a46fSAndroid Build Coastguard Worker         m = (uint16_t)(skiplength - data->bufferbytesleft);
1088*3ac0a46fSAndroid Build Coastguard Worker         if (m <= data->filebytesleft)
1089*3ac0a46fSAndroid Build Coastguard Worker         {
1090*3ac0a46fSAndroid Build Coastguard Worker             data->bufferbytesleft = 0;
1091*3ac0a46fSAndroid Build Coastguard Worker             data->fileoffset += m;
1092*3ac0a46fSAndroid Build Coastguard Worker             data->filebytesleft -= m;
1093*3ac0a46fSAndroid Build Coastguard Worker             data->filepositioned = 0;
1094*3ac0a46fSAndroid Build Coastguard Worker         }
1095*3ac0a46fSAndroid Build Coastguard Worker         else
1096*3ac0a46fSAndroid Build Coastguard Worker         {
1097*3ac0a46fSAndroid Build Coastguard Worker             data->bufferbytesleft = 0;
1098*3ac0a46fSAndroid Build Coastguard Worker             data->filebytesleft = 0;
1099*3ac0a46fSAndroid Build Coastguard Worker         }
1100*3ac0a46fSAndroid Build Coastguard Worker     }
1101*3ac0a46fSAndroid Build Coastguard Worker }
1102*3ac0a46fSAndroid Build Coastguard Worker 
1103*3ac0a46fSAndroid Build Coastguard Worker #endif
1104*3ac0a46fSAndroid Build Coastguard Worker 
JPEGSetupDecode(TIFF * tif)1105*3ac0a46fSAndroid Build Coastguard Worker static int JPEGSetupDecode(TIFF *tif)
1106*3ac0a46fSAndroid Build Coastguard Worker {
1107*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
1108*3ac0a46fSAndroid Build Coastguard Worker     TIFFDirectory *td = &tif->tif_dir;
1109*3ac0a46fSAndroid Build Coastguard Worker 
1110*3ac0a46fSAndroid Build Coastguard Worker #if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12)
1111*3ac0a46fSAndroid Build Coastguard Worker     if (tif->tif_dir.td_bitspersample == 12)
1112*3ac0a46fSAndroid Build Coastguard Worker     {
1113*3ac0a46fSAndroid Build Coastguard Worker         /* We pass a pointer to a copy of otherSettings, since */
1114*3ac0a46fSAndroid Build Coastguard Worker         /* TIFFReInitJPEG_12() will clear sp */
1115*3ac0a46fSAndroid Build Coastguard Worker         JPEGOtherSettings savedOtherSettings = sp->otherSettings;
1116*3ac0a46fSAndroid Build Coastguard Worker         return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 0);
1117*3ac0a46fSAndroid Build Coastguard Worker     }
1118*3ac0a46fSAndroid Build Coastguard Worker #endif
1119*3ac0a46fSAndroid Build Coastguard Worker 
1120*3ac0a46fSAndroid Build Coastguard Worker     JPEGInitializeLibJPEG(tif, TRUE);
1121*3ac0a46fSAndroid Build Coastguard Worker 
1122*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != NULL);
1123*3ac0a46fSAndroid Build Coastguard Worker     assert(sp->cinfo.comm.is_decompressor);
1124*3ac0a46fSAndroid Build Coastguard Worker 
1125*3ac0a46fSAndroid Build Coastguard Worker     /* Read JPEGTables if it is present */
1126*3ac0a46fSAndroid Build Coastguard Worker     if (TIFFFieldSet(tif, FIELD_JPEGTABLES))
1127*3ac0a46fSAndroid Build Coastguard Worker     {
1128*3ac0a46fSAndroid Build Coastguard Worker         TIFFjpeg_tables_src(sp);
1129*3ac0a46fSAndroid Build Coastguard Worker         if (TIFFjpeg_read_header(sp, FALSE) != JPEG_HEADER_TABLES_ONLY)
1130*3ac0a46fSAndroid Build Coastguard Worker         {
1131*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, "JPEGSetupDecode", "Bogus JPEGTables field");
1132*3ac0a46fSAndroid Build Coastguard Worker             return (0);
1133*3ac0a46fSAndroid Build Coastguard Worker         }
1134*3ac0a46fSAndroid Build Coastguard Worker     }
1135*3ac0a46fSAndroid Build Coastguard Worker 
1136*3ac0a46fSAndroid Build Coastguard Worker     /* Grab parameters that are same for all strips/tiles */
1137*3ac0a46fSAndroid Build Coastguard Worker     sp->photometric = td->td_photometric;
1138*3ac0a46fSAndroid Build Coastguard Worker     switch (sp->photometric)
1139*3ac0a46fSAndroid Build Coastguard Worker     {
1140*3ac0a46fSAndroid Build Coastguard Worker         case PHOTOMETRIC_YCBCR:
1141*3ac0a46fSAndroid Build Coastguard Worker             sp->h_sampling = td->td_ycbcrsubsampling[0];
1142*3ac0a46fSAndroid Build Coastguard Worker             sp->v_sampling = td->td_ycbcrsubsampling[1];
1143*3ac0a46fSAndroid Build Coastguard Worker             break;
1144*3ac0a46fSAndroid Build Coastguard Worker         default:
1145*3ac0a46fSAndroid Build Coastguard Worker             /* TIFF 6.0 forbids subsampling of all other color spaces */
1146*3ac0a46fSAndroid Build Coastguard Worker             sp->h_sampling = 1;
1147*3ac0a46fSAndroid Build Coastguard Worker             sp->v_sampling = 1;
1148*3ac0a46fSAndroid Build Coastguard Worker             break;
1149*3ac0a46fSAndroid Build Coastguard Worker     }
1150*3ac0a46fSAndroid Build Coastguard Worker 
1151*3ac0a46fSAndroid Build Coastguard Worker     /* Set up for reading normal data */
1152*3ac0a46fSAndroid Build Coastguard Worker     TIFFjpeg_data_src(sp);
1153*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */
1154*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1155*3ac0a46fSAndroid Build Coastguard Worker }
1156*3ac0a46fSAndroid Build Coastguard Worker 
1157*3ac0a46fSAndroid Build Coastguard Worker /* Returns 1 if the full strip should be read, even when doing scanline per */
1158*3ac0a46fSAndroid Build Coastguard Worker /* scanline decoding. This happens when the JPEG stream uses multiple scans. */
1159*3ac0a46fSAndroid Build Coastguard Worker /* Currently only called in CHUNKY_STRIP_READ_SUPPORT mode through */
1160*3ac0a46fSAndroid Build Coastguard Worker /* scanline interface. */
1161*3ac0a46fSAndroid Build Coastguard Worker /* Only reads tif->tif_dir.td_bitspersample, tif->tif_rawdata and */
1162*3ac0a46fSAndroid Build Coastguard Worker /* tif->tif_rawcc members. */
1163*3ac0a46fSAndroid Build Coastguard Worker /* Can be called independently of the usual setup/predecode/decode states */
TIFFJPEGIsFullStripRequired(TIFF * tif)1164*3ac0a46fSAndroid Build Coastguard Worker int TIFFJPEGIsFullStripRequired(TIFF *tif)
1165*3ac0a46fSAndroid Build Coastguard Worker {
1166*3ac0a46fSAndroid Build Coastguard Worker     int ret;
1167*3ac0a46fSAndroid Build Coastguard Worker     JPEGState state;
1168*3ac0a46fSAndroid Build Coastguard Worker 
1169*3ac0a46fSAndroid Build Coastguard Worker #if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12)
1170*3ac0a46fSAndroid Build Coastguard Worker     if (tif->tif_dir.td_bitspersample == 12)
1171*3ac0a46fSAndroid Build Coastguard Worker         return TIFFJPEGIsFullStripRequired_12(tif);
1172*3ac0a46fSAndroid Build Coastguard Worker #endif
1173*3ac0a46fSAndroid Build Coastguard Worker 
1174*3ac0a46fSAndroid Build Coastguard Worker     memset(&state, 0, sizeof(JPEGState));
1175*3ac0a46fSAndroid Build Coastguard Worker     state.tif = tif;
1176*3ac0a46fSAndroid Build Coastguard Worker 
1177*3ac0a46fSAndroid Build Coastguard Worker     TIFFjpeg_create_decompress(&state);
1178*3ac0a46fSAndroid Build Coastguard Worker 
1179*3ac0a46fSAndroid Build Coastguard Worker     TIFFjpeg_data_src(&state);
1180*3ac0a46fSAndroid Build Coastguard Worker 
1181*3ac0a46fSAndroid Build Coastguard Worker     if (TIFFjpeg_read_header(&state, TRUE) != JPEG_HEADER_OK)
1182*3ac0a46fSAndroid Build Coastguard Worker     {
1183*3ac0a46fSAndroid Build Coastguard Worker         TIFFjpeg_destroy(&state);
1184*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1185*3ac0a46fSAndroid Build Coastguard Worker     }
1186*3ac0a46fSAndroid Build Coastguard Worker     ret = TIFFjpeg_has_multiple_scans(&state);
1187*3ac0a46fSAndroid Build Coastguard Worker 
1188*3ac0a46fSAndroid Build Coastguard Worker     TIFFjpeg_destroy(&state);
1189*3ac0a46fSAndroid Build Coastguard Worker 
1190*3ac0a46fSAndroid Build Coastguard Worker     return ret;
1191*3ac0a46fSAndroid Build Coastguard Worker }
1192*3ac0a46fSAndroid Build Coastguard Worker 
1193*3ac0a46fSAndroid Build Coastguard Worker /*
1194*3ac0a46fSAndroid Build Coastguard Worker  * Set up for decoding a strip or tile.
1195*3ac0a46fSAndroid Build Coastguard Worker  */
JPEGPreDecode(TIFF * tif,uint16_t s)1196*3ac0a46fSAndroid Build Coastguard Worker /*ARGSUSED*/ static int JPEGPreDecode(TIFF *tif, uint16_t s)
1197*3ac0a46fSAndroid Build Coastguard Worker {
1198*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
1199*3ac0a46fSAndroid Build Coastguard Worker     TIFFDirectory *td = &tif->tif_dir;
1200*3ac0a46fSAndroid Build Coastguard Worker     static const char module[] = "JPEGPreDecode";
1201*3ac0a46fSAndroid Build Coastguard Worker     uint32_t segment_width, segment_height;
1202*3ac0a46fSAndroid Build Coastguard Worker     int downsampled_output;
1203*3ac0a46fSAndroid Build Coastguard Worker     int ci;
1204*3ac0a46fSAndroid Build Coastguard Worker 
1205*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != NULL);
1206*3ac0a46fSAndroid Build Coastguard Worker 
1207*3ac0a46fSAndroid Build Coastguard Worker     if (sp->cinfo.comm.is_decompressor == 0)
1208*3ac0a46fSAndroid Build Coastguard Worker     {
1209*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_setupdecode(tif);
1210*3ac0a46fSAndroid Build Coastguard Worker     }
1211*3ac0a46fSAndroid Build Coastguard Worker 
1212*3ac0a46fSAndroid Build Coastguard Worker     assert(sp->cinfo.comm.is_decompressor);
1213*3ac0a46fSAndroid Build Coastguard Worker     /*
1214*3ac0a46fSAndroid Build Coastguard Worker      * Reset decoder state from any previous strip/tile,
1215*3ac0a46fSAndroid Build Coastguard Worker      * in case application didn't read the whole strip.
1216*3ac0a46fSAndroid Build Coastguard Worker      */
1217*3ac0a46fSAndroid Build Coastguard Worker     if (!TIFFjpeg_abort(sp))
1218*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1219*3ac0a46fSAndroid Build Coastguard Worker     /*
1220*3ac0a46fSAndroid Build Coastguard Worker      * Read the header for this strip/tile.
1221*3ac0a46fSAndroid Build Coastguard Worker      */
1222*3ac0a46fSAndroid Build Coastguard Worker 
1223*3ac0a46fSAndroid Build Coastguard Worker     if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK)
1224*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1225*3ac0a46fSAndroid Build Coastguard Worker 
1226*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte;
1227*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_rawcc = sp->src.bytes_in_buffer;
1228*3ac0a46fSAndroid Build Coastguard Worker 
1229*3ac0a46fSAndroid Build Coastguard Worker     /*
1230*3ac0a46fSAndroid Build Coastguard Worker      * Check image parameters and set decompression parameters.
1231*3ac0a46fSAndroid Build Coastguard Worker      */
1232*3ac0a46fSAndroid Build Coastguard Worker     if (isTiled(tif))
1233*3ac0a46fSAndroid Build Coastguard Worker     {
1234*3ac0a46fSAndroid Build Coastguard Worker         segment_width = td->td_tilewidth;
1235*3ac0a46fSAndroid Build Coastguard Worker         segment_height = td->td_tilelength;
1236*3ac0a46fSAndroid Build Coastguard Worker         sp->bytesperline = TIFFTileRowSize(tif);
1237*3ac0a46fSAndroid Build Coastguard Worker     }
1238*3ac0a46fSAndroid Build Coastguard Worker     else
1239*3ac0a46fSAndroid Build Coastguard Worker     {
1240*3ac0a46fSAndroid Build Coastguard Worker         segment_width = td->td_imagewidth;
1241*3ac0a46fSAndroid Build Coastguard Worker         segment_height = td->td_imagelength - tif->tif_row;
1242*3ac0a46fSAndroid Build Coastguard Worker         if (segment_height > td->td_rowsperstrip)
1243*3ac0a46fSAndroid Build Coastguard Worker             segment_height = td->td_rowsperstrip;
1244*3ac0a46fSAndroid Build Coastguard Worker         sp->bytesperline = TIFFScanlineSize(tif);
1245*3ac0a46fSAndroid Build Coastguard Worker     }
1246*3ac0a46fSAndroid Build Coastguard Worker     if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0)
1247*3ac0a46fSAndroid Build Coastguard Worker     {
1248*3ac0a46fSAndroid Build Coastguard Worker         /*
1249*3ac0a46fSAndroid Build Coastguard Worker          * For PC 2, scale down the expected strip/tile size
1250*3ac0a46fSAndroid Build Coastguard Worker          * to match a downsampled component
1251*3ac0a46fSAndroid Build Coastguard Worker          */
1252*3ac0a46fSAndroid Build Coastguard Worker         segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
1253*3ac0a46fSAndroid Build Coastguard Worker         segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
1254*3ac0a46fSAndroid Build Coastguard Worker     }
1255*3ac0a46fSAndroid Build Coastguard Worker     if (sp->cinfo.d.image_width < segment_width ||
1256*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.d.image_height < segment_height)
1257*3ac0a46fSAndroid Build Coastguard Worker     {
1258*3ac0a46fSAndroid Build Coastguard Worker         TIFFWarningExtR(tif, module,
1259*3ac0a46fSAndroid Build Coastguard Worker                         "Improper JPEG strip/tile size, "
1260*3ac0a46fSAndroid Build Coastguard Worker                         "expected %" PRIu32 "x%" PRIu32 ", got %ux%u",
1261*3ac0a46fSAndroid Build Coastguard Worker                         segment_width, segment_height, sp->cinfo.d.image_width,
1262*3ac0a46fSAndroid Build Coastguard Worker                         sp->cinfo.d.image_height);
1263*3ac0a46fSAndroid Build Coastguard Worker     }
1264*3ac0a46fSAndroid Build Coastguard Worker     if (sp->cinfo.d.image_width == segment_width &&
1265*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.d.image_height > segment_height &&
1266*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_row + segment_height == td->td_imagelength && !isTiled(tif))
1267*3ac0a46fSAndroid Build Coastguard Worker     {
1268*3ac0a46fSAndroid Build Coastguard Worker         /* Some files have a last strip, that should be truncated, */
1269*3ac0a46fSAndroid Build Coastguard Worker         /* but their JPEG codestream has still the maximum strip */
1270*3ac0a46fSAndroid Build Coastguard Worker         /* height. Warn about this as this is non compliant, but */
1271*3ac0a46fSAndroid Build Coastguard Worker         /* we can safely recover from that. */
1272*3ac0a46fSAndroid Build Coastguard Worker         TIFFWarningExtR(tif, module,
1273*3ac0a46fSAndroid Build Coastguard Worker                         "JPEG strip size exceeds expected dimensions,"
1274*3ac0a46fSAndroid Build Coastguard Worker                         " expected %" PRIu32 "x%" PRIu32 ", got %ux%u",
1275*3ac0a46fSAndroid Build Coastguard Worker                         segment_width, segment_height, sp->cinfo.d.image_width,
1276*3ac0a46fSAndroid Build Coastguard Worker                         sp->cinfo.d.image_height);
1277*3ac0a46fSAndroid Build Coastguard Worker     }
1278*3ac0a46fSAndroid Build Coastguard Worker     else if (sp->cinfo.d.image_width > segment_width ||
1279*3ac0a46fSAndroid Build Coastguard Worker              sp->cinfo.d.image_height > segment_height)
1280*3ac0a46fSAndroid Build Coastguard Worker     {
1281*3ac0a46fSAndroid Build Coastguard Worker         /*
1282*3ac0a46fSAndroid Build Coastguard Worker          * This case could be dangerous, if the strip or tile size has
1283*3ac0a46fSAndroid Build Coastguard Worker          * been reported as less than the amount of data jpeg will
1284*3ac0a46fSAndroid Build Coastguard Worker          * return, some potential security issues arise. Catch this
1285*3ac0a46fSAndroid Build Coastguard Worker          * case and error out.
1286*3ac0a46fSAndroid Build Coastguard Worker          */
1287*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module,
1288*3ac0a46fSAndroid Build Coastguard Worker                       "JPEG strip/tile size exceeds expected dimensions,"
1289*3ac0a46fSAndroid Build Coastguard Worker                       " expected %" PRIu32 "x%" PRIu32 ", got %ux%u",
1290*3ac0a46fSAndroid Build Coastguard Worker                       segment_width, segment_height, sp->cinfo.d.image_width,
1291*3ac0a46fSAndroid Build Coastguard Worker                       sp->cinfo.d.image_height);
1292*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1293*3ac0a46fSAndroid Build Coastguard Worker     }
1294*3ac0a46fSAndroid Build Coastguard Worker     if (sp->cinfo.d.num_components !=
1295*3ac0a46fSAndroid Build Coastguard Worker         (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel
1296*3ac0a46fSAndroid Build Coastguard Worker                                                     : 1))
1297*3ac0a46fSAndroid Build Coastguard Worker     {
1298*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module, "Improper JPEG component count");
1299*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1300*3ac0a46fSAndroid Build Coastguard Worker     }
1301*3ac0a46fSAndroid Build Coastguard Worker #ifdef JPEG_LIB_MK1
1302*3ac0a46fSAndroid Build Coastguard Worker     if (12 != td->td_bitspersample && 8 != td->td_bitspersample)
1303*3ac0a46fSAndroid Build Coastguard Worker     {
1304*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module, "Improper JPEG data precision");
1305*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1306*3ac0a46fSAndroid Build Coastguard Worker     }
1307*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.d.data_precision = td->td_bitspersample;
1308*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.d.bits_in_jsample = td->td_bitspersample;
1309*3ac0a46fSAndroid Build Coastguard Worker #else
1310*3ac0a46fSAndroid Build Coastguard Worker     if (sp->cinfo.d.data_precision != td->td_bitspersample)
1311*3ac0a46fSAndroid Build Coastguard Worker     {
1312*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module, "Improper JPEG data precision");
1313*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1314*3ac0a46fSAndroid Build Coastguard Worker     }
1315*3ac0a46fSAndroid Build Coastguard Worker #endif
1316*3ac0a46fSAndroid Build Coastguard Worker 
1317*3ac0a46fSAndroid Build Coastguard Worker     if (sp->cinfo.d.progressive_mode &&
1318*3ac0a46fSAndroid Build Coastguard Worker         !sp->otherSettings.has_warned_about_progressive_mode)
1319*3ac0a46fSAndroid Build Coastguard Worker     {
1320*3ac0a46fSAndroid Build Coastguard Worker         TIFFWarningExtR(tif, module,
1321*3ac0a46fSAndroid Build Coastguard Worker                         "The JPEG strip/tile is encoded with progressive mode, "
1322*3ac0a46fSAndroid Build Coastguard Worker                         "which is normally not legal for JPEG-in-TIFF.\n"
1323*3ac0a46fSAndroid Build Coastguard Worker                         "libtiff should be able to decode it, but it might "
1324*3ac0a46fSAndroid Build Coastguard Worker                         "cause compatibility issues with other readers");
1325*3ac0a46fSAndroid Build Coastguard Worker         sp->otherSettings.has_warned_about_progressive_mode = TRUE;
1326*3ac0a46fSAndroid Build Coastguard Worker     }
1327*3ac0a46fSAndroid Build Coastguard Worker 
1328*3ac0a46fSAndroid Build Coastguard Worker     /* In some cases, libjpeg needs to allocate a lot of memory */
1329*3ac0a46fSAndroid Build Coastguard Worker     /* http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf
1330*3ac0a46fSAndroid Build Coastguard Worker      */
1331*3ac0a46fSAndroid Build Coastguard Worker     if (TIFFjpeg_has_multiple_scans(sp))
1332*3ac0a46fSAndroid Build Coastguard Worker     {
1333*3ac0a46fSAndroid Build Coastguard Worker         /* In this case libjpeg will need to allocate memory or backing */
1334*3ac0a46fSAndroid Build Coastguard Worker         /* store for all coefficients */
1335*3ac0a46fSAndroid Build Coastguard Worker         /* See call to jinit_d_coef_controller() from master_selection() */
1336*3ac0a46fSAndroid Build Coastguard Worker         /* in libjpeg */
1337*3ac0a46fSAndroid Build Coastguard Worker 
1338*3ac0a46fSAndroid Build Coastguard Worker         /* 1 MB for regular libjpeg usage */
1339*3ac0a46fSAndroid Build Coastguard Worker         toff_t nRequiredMemory = 1024 * 1024;
1340*3ac0a46fSAndroid Build Coastguard Worker 
1341*3ac0a46fSAndroid Build Coastguard Worker         for (ci = 0; ci < sp->cinfo.d.num_components; ci++)
1342*3ac0a46fSAndroid Build Coastguard Worker         {
1343*3ac0a46fSAndroid Build Coastguard Worker             const jpeg_component_info *compptr = &(sp->cinfo.d.comp_info[ci]);
1344*3ac0a46fSAndroid Build Coastguard Worker             if (compptr->h_samp_factor > 0 && compptr->v_samp_factor > 0)
1345*3ac0a46fSAndroid Build Coastguard Worker             {
1346*3ac0a46fSAndroid Build Coastguard Worker                 nRequiredMemory +=
1347*3ac0a46fSAndroid Build Coastguard Worker                     (toff_t)(((compptr->width_in_blocks +
1348*3ac0a46fSAndroid Build Coastguard Worker                                compptr->h_samp_factor - 1) /
1349*3ac0a46fSAndroid Build Coastguard Worker                               compptr->h_samp_factor)) *
1350*3ac0a46fSAndroid Build Coastguard Worker                     ((compptr->height_in_blocks + compptr->v_samp_factor - 1) /
1351*3ac0a46fSAndroid Build Coastguard Worker                      compptr->v_samp_factor) *
1352*3ac0a46fSAndroid Build Coastguard Worker                     sizeof(JBLOCK);
1353*3ac0a46fSAndroid Build Coastguard Worker             }
1354*3ac0a46fSAndroid Build Coastguard Worker         }
1355*3ac0a46fSAndroid Build Coastguard Worker 
1356*3ac0a46fSAndroid Build Coastguard Worker         if (sp->cinfo.d.mem->max_memory_to_use > 0 &&
1357*3ac0a46fSAndroid Build Coastguard Worker             nRequiredMemory > (toff_t)(sp->cinfo.d.mem->max_memory_to_use) &&
1358*3ac0a46fSAndroid Build Coastguard Worker             getenv("LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC") == NULL)
1359*3ac0a46fSAndroid Build Coastguard Worker         {
1360*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(
1361*3ac0a46fSAndroid Build Coastguard Worker                 tif, module,
1362*3ac0a46fSAndroid Build Coastguard Worker                 "Reading this image would require libjpeg to allocate "
1363*3ac0a46fSAndroid Build Coastguard Worker                 "at least %" PRIu64 " bytes. "
1364*3ac0a46fSAndroid Build Coastguard Worker                 "This is disabled since above the %ld threshold. "
1365*3ac0a46fSAndroid Build Coastguard Worker                 "You may override this restriction by defining the "
1366*3ac0a46fSAndroid Build Coastguard Worker                 "LIBTIFF_ALLOW_LARGE_LIBJPEG_MEM_ALLOC environment variable, "
1367*3ac0a46fSAndroid Build Coastguard Worker                 "or setting the JPEGMEM environment variable to a value "
1368*3ac0a46fSAndroid Build Coastguard Worker                 "greater "
1369*3ac0a46fSAndroid Build Coastguard Worker                 "or equal to '%" PRIu64 "M'",
1370*3ac0a46fSAndroid Build Coastguard Worker                 nRequiredMemory, sp->cinfo.d.mem->max_memory_to_use,
1371*3ac0a46fSAndroid Build Coastguard Worker                 (nRequiredMemory + 1000000u - 1u) / 1000000u);
1372*3ac0a46fSAndroid Build Coastguard Worker             return 0;
1373*3ac0a46fSAndroid Build Coastguard Worker         }
1374*3ac0a46fSAndroid Build Coastguard Worker     }
1375*3ac0a46fSAndroid Build Coastguard Worker 
1376*3ac0a46fSAndroid Build Coastguard Worker     if (td->td_planarconfig == PLANARCONFIG_CONTIG)
1377*3ac0a46fSAndroid Build Coastguard Worker     {
1378*3ac0a46fSAndroid Build Coastguard Worker         /* Component 0 should have expected sampling factors */
1379*3ac0a46fSAndroid Build Coastguard Worker         if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling ||
1380*3ac0a46fSAndroid Build Coastguard Worker             sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling)
1381*3ac0a46fSAndroid Build Coastguard Worker         {
1382*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, module,
1383*3ac0a46fSAndroid Build Coastguard Worker                           "Improper JPEG sampling factors %d,%d\n"
1384*3ac0a46fSAndroid Build Coastguard Worker                           "Apparently should be %" PRIu16 ",%" PRIu16 ".",
1385*3ac0a46fSAndroid Build Coastguard Worker                           sp->cinfo.d.comp_info[0].h_samp_factor,
1386*3ac0a46fSAndroid Build Coastguard Worker                           sp->cinfo.d.comp_info[0].v_samp_factor,
1387*3ac0a46fSAndroid Build Coastguard Worker                           sp->h_sampling, sp->v_sampling);
1388*3ac0a46fSAndroid Build Coastguard Worker             return (0);
1389*3ac0a46fSAndroid Build Coastguard Worker         }
1390*3ac0a46fSAndroid Build Coastguard Worker         /* Rest should have sampling factors 1,1 */
1391*3ac0a46fSAndroid Build Coastguard Worker         for (ci = 1; ci < sp->cinfo.d.num_components; ci++)
1392*3ac0a46fSAndroid Build Coastguard Worker         {
1393*3ac0a46fSAndroid Build Coastguard Worker             if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 ||
1394*3ac0a46fSAndroid Build Coastguard Worker                 sp->cinfo.d.comp_info[ci].v_samp_factor != 1)
1395*3ac0a46fSAndroid Build Coastguard Worker             {
1396*3ac0a46fSAndroid Build Coastguard Worker                 TIFFErrorExtR(tif, module, "Improper JPEG sampling factors");
1397*3ac0a46fSAndroid Build Coastguard Worker                 return (0);
1398*3ac0a46fSAndroid Build Coastguard Worker             }
1399*3ac0a46fSAndroid Build Coastguard Worker         }
1400*3ac0a46fSAndroid Build Coastguard Worker     }
1401*3ac0a46fSAndroid Build Coastguard Worker     else
1402*3ac0a46fSAndroid Build Coastguard Worker     {
1403*3ac0a46fSAndroid Build Coastguard Worker         /* PC 2's single component should have sampling factors 1,1 */
1404*3ac0a46fSAndroid Build Coastguard Worker         if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 ||
1405*3ac0a46fSAndroid Build Coastguard Worker             sp->cinfo.d.comp_info[0].v_samp_factor != 1)
1406*3ac0a46fSAndroid Build Coastguard Worker         {
1407*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, module, "Improper JPEG sampling factors");
1408*3ac0a46fSAndroid Build Coastguard Worker             return (0);
1409*3ac0a46fSAndroid Build Coastguard Worker         }
1410*3ac0a46fSAndroid Build Coastguard Worker     }
1411*3ac0a46fSAndroid Build Coastguard Worker     downsampled_output = FALSE;
1412*3ac0a46fSAndroid Build Coastguard Worker     if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
1413*3ac0a46fSAndroid Build Coastguard Worker         sp->photometric == PHOTOMETRIC_YCBCR &&
1414*3ac0a46fSAndroid Build Coastguard Worker         sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB)
1415*3ac0a46fSAndroid Build Coastguard Worker     {
1416*3ac0a46fSAndroid Build Coastguard Worker         /* Convert YCbCr to RGB */
1417*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.d.jpeg_color_space = JCS_YCbCr;
1418*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.d.out_color_space = JCS_RGB;
1419*3ac0a46fSAndroid Build Coastguard Worker     }
1420*3ac0a46fSAndroid Build Coastguard Worker     else
1421*3ac0a46fSAndroid Build Coastguard Worker     {
1422*3ac0a46fSAndroid Build Coastguard Worker         /* Suppress colorspace handling */
1423*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN;
1424*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.d.out_color_space = JCS_UNKNOWN;
1425*3ac0a46fSAndroid Build Coastguard Worker         if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
1426*3ac0a46fSAndroid Build Coastguard Worker             (sp->h_sampling != 1 || sp->v_sampling != 1))
1427*3ac0a46fSAndroid Build Coastguard Worker             downsampled_output = TRUE;
1428*3ac0a46fSAndroid Build Coastguard Worker         /* XXX what about up-sampling? */
1429*3ac0a46fSAndroid Build Coastguard Worker     }
1430*3ac0a46fSAndroid Build Coastguard Worker     if (downsampled_output)
1431*3ac0a46fSAndroid Build Coastguard Worker     {
1432*3ac0a46fSAndroid Build Coastguard Worker         /* Need to use raw-data interface to libjpeg */
1433*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.d.raw_data_out = TRUE;
1434*3ac0a46fSAndroid Build Coastguard Worker #if JPEG_LIB_VERSION >= 70
1435*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.d.do_fancy_upsampling = FALSE;
1436*3ac0a46fSAndroid Build Coastguard Worker #endif /* JPEG_LIB_VERSION >= 70 */
1437*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decoderow = DecodeRowError;
1438*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decodestrip = JPEGDecodeRaw;
1439*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decodetile = JPEGDecodeRaw;
1440*3ac0a46fSAndroid Build Coastguard Worker     }
1441*3ac0a46fSAndroid Build Coastguard Worker     else
1442*3ac0a46fSAndroid Build Coastguard Worker     {
1443*3ac0a46fSAndroid Build Coastguard Worker         /* Use normal interface to libjpeg */
1444*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.d.raw_data_out = FALSE;
1445*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decoderow = JPEGDecode;
1446*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decodestrip = JPEGDecode;
1447*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decodetile = JPEGDecode;
1448*3ac0a46fSAndroid Build Coastguard Worker     }
1449*3ac0a46fSAndroid Build Coastguard Worker     /* Start JPEG decompressor */
1450*3ac0a46fSAndroid Build Coastguard Worker     if (!TIFFjpeg_start_decompress(sp))
1451*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1452*3ac0a46fSAndroid Build Coastguard Worker     /* Allocate downsampled-data buffers if needed */
1453*3ac0a46fSAndroid Build Coastguard Worker     if (downsampled_output)
1454*3ac0a46fSAndroid Build Coastguard Worker     {
1455*3ac0a46fSAndroid Build Coastguard Worker         if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info,
1456*3ac0a46fSAndroid Build Coastguard Worker                                        sp->cinfo.d.num_components))
1457*3ac0a46fSAndroid Build Coastguard Worker             return (0);
1458*3ac0a46fSAndroid Build Coastguard Worker         sp->scancount = DCTSIZE; /* mark buffer empty */
1459*3ac0a46fSAndroid Build Coastguard Worker     }
1460*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1461*3ac0a46fSAndroid Build Coastguard Worker }
1462*3ac0a46fSAndroid Build Coastguard Worker 
1463*3ac0a46fSAndroid Build Coastguard Worker /*
1464*3ac0a46fSAndroid Build Coastguard Worker  * Decode a chunk of pixels.
1465*3ac0a46fSAndroid Build Coastguard Worker  * "Standard" case: returned data is not downsampled.
1466*3ac0a46fSAndroid Build Coastguard Worker  */
1467*3ac0a46fSAndroid Build Coastguard Worker #if !JPEG_LIB_MK1_OR_12BIT
JPEGDecode(TIFF * tif,uint8_t * buf,tmsize_t cc,uint16_t s)1468*3ac0a46fSAndroid Build Coastguard Worker static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
1469*3ac0a46fSAndroid Build Coastguard Worker {
1470*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
1471*3ac0a46fSAndroid Build Coastguard Worker     tmsize_t nrows;
1472*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
1473*3ac0a46fSAndroid Build Coastguard Worker 
1474*3ac0a46fSAndroid Build Coastguard Worker     /*
1475*3ac0a46fSAndroid Build Coastguard Worker     ** Update available information, buffer may have been refilled
1476*3ac0a46fSAndroid Build Coastguard Worker     ** between decode requests
1477*3ac0a46fSAndroid Build Coastguard Worker     */
1478*3ac0a46fSAndroid Build Coastguard Worker     sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp;
1479*3ac0a46fSAndroid Build Coastguard Worker     sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc;
1480*3ac0a46fSAndroid Build Coastguard Worker 
1481*3ac0a46fSAndroid Build Coastguard Worker     if (sp->bytesperline == 0)
1482*3ac0a46fSAndroid Build Coastguard Worker         return 0;
1483*3ac0a46fSAndroid Build Coastguard Worker 
1484*3ac0a46fSAndroid Build Coastguard Worker     nrows = cc / sp->bytesperline;
1485*3ac0a46fSAndroid Build Coastguard Worker     if (cc % sp->bytesperline)
1486*3ac0a46fSAndroid Build Coastguard Worker         TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read");
1487*3ac0a46fSAndroid Build Coastguard Worker 
1488*3ac0a46fSAndroid Build Coastguard Worker     if (nrows > (tmsize_t)sp->cinfo.d.image_height)
1489*3ac0a46fSAndroid Build Coastguard Worker         nrows = sp->cinfo.d.image_height;
1490*3ac0a46fSAndroid Build Coastguard Worker 
1491*3ac0a46fSAndroid Build Coastguard Worker     /* data is expected to be read in multiples of a scanline */
1492*3ac0a46fSAndroid Build Coastguard Worker     if (nrows)
1493*3ac0a46fSAndroid Build Coastguard Worker     {
1494*3ac0a46fSAndroid Build Coastguard Worker         do
1495*3ac0a46fSAndroid Build Coastguard Worker         {
1496*3ac0a46fSAndroid Build Coastguard Worker             /*
1497*3ac0a46fSAndroid Build Coastguard Worker              * In the libjpeg6b-9a 8bit case.  We read directly into
1498*3ac0a46fSAndroid Build Coastguard Worker              * the TIFF buffer.
1499*3ac0a46fSAndroid Build Coastguard Worker              */
1500*3ac0a46fSAndroid Build Coastguard Worker             JSAMPROW bufptr = (JSAMPROW)buf;
1501*3ac0a46fSAndroid Build Coastguard Worker 
1502*3ac0a46fSAndroid Build Coastguard Worker             if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
1503*3ac0a46fSAndroid Build Coastguard Worker                 return (0);
1504*3ac0a46fSAndroid Build Coastguard Worker 
1505*3ac0a46fSAndroid Build Coastguard Worker             ++tif->tif_row;
1506*3ac0a46fSAndroid Build Coastguard Worker             buf += sp->bytesperline;
1507*3ac0a46fSAndroid Build Coastguard Worker             cc -= sp->bytesperline;
1508*3ac0a46fSAndroid Build Coastguard Worker         } while (--nrows > 0);
1509*3ac0a46fSAndroid Build Coastguard Worker     }
1510*3ac0a46fSAndroid Build Coastguard Worker 
1511*3ac0a46fSAndroid Build Coastguard Worker     /* Update information on consumed data */
1512*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte;
1513*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_rawcc = sp->src.bytes_in_buffer;
1514*3ac0a46fSAndroid Build Coastguard Worker 
1515*3ac0a46fSAndroid Build Coastguard Worker     /* Close down the decompressor if we've finished the strip or tile. */
1516*3ac0a46fSAndroid Build Coastguard Worker     return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height ||
1517*3ac0a46fSAndroid Build Coastguard Worker            TIFFjpeg_finish_decompress(sp);
1518*3ac0a46fSAndroid Build Coastguard Worker }
1519*3ac0a46fSAndroid Build Coastguard Worker #endif /* !JPEG_LIB_MK1_OR_12BIT */
1520*3ac0a46fSAndroid Build Coastguard Worker 
1521*3ac0a46fSAndroid Build Coastguard Worker #if JPEG_LIB_MK1_OR_12BIT
JPEGDecode(TIFF * tif,uint8_t * buf,tmsize_t cc,uint16_t s)1522*3ac0a46fSAndroid Build Coastguard Worker /*ARGSUSED*/ static int JPEGDecode(TIFF *tif, uint8_t *buf, tmsize_t cc,
1523*3ac0a46fSAndroid Build Coastguard Worker                                    uint16_t s)
1524*3ac0a46fSAndroid Build Coastguard Worker {
1525*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
1526*3ac0a46fSAndroid Build Coastguard Worker     tmsize_t nrows;
1527*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
1528*3ac0a46fSAndroid Build Coastguard Worker 
1529*3ac0a46fSAndroid Build Coastguard Worker     /*
1530*3ac0a46fSAndroid Build Coastguard Worker     ** Update available information, buffer may have been refilled
1531*3ac0a46fSAndroid Build Coastguard Worker     ** between decode requests
1532*3ac0a46fSAndroid Build Coastguard Worker     */
1533*3ac0a46fSAndroid Build Coastguard Worker     sp->src.next_input_byte = (const JOCTET *)tif->tif_rawcp;
1534*3ac0a46fSAndroid Build Coastguard Worker     sp->src.bytes_in_buffer = (size_t)tif->tif_rawcc;
1535*3ac0a46fSAndroid Build Coastguard Worker 
1536*3ac0a46fSAndroid Build Coastguard Worker     if (sp->bytesperline == 0)
1537*3ac0a46fSAndroid Build Coastguard Worker         return 0;
1538*3ac0a46fSAndroid Build Coastguard Worker 
1539*3ac0a46fSAndroid Build Coastguard Worker     nrows = cc / sp->bytesperline;
1540*3ac0a46fSAndroid Build Coastguard Worker     if (cc % sp->bytesperline)
1541*3ac0a46fSAndroid Build Coastguard Worker         TIFFWarningExtR(tif, tif->tif_name, "fractional scanline not read");
1542*3ac0a46fSAndroid Build Coastguard Worker 
1543*3ac0a46fSAndroid Build Coastguard Worker     if (nrows > (tmsize_t)sp->cinfo.d.image_height)
1544*3ac0a46fSAndroid Build Coastguard Worker         nrows = sp->cinfo.d.image_height;
1545*3ac0a46fSAndroid Build Coastguard Worker 
1546*3ac0a46fSAndroid Build Coastguard Worker     /* data is expected to be read in multiples of a scanline */
1547*3ac0a46fSAndroid Build Coastguard Worker     if (nrows)
1548*3ac0a46fSAndroid Build Coastguard Worker     {
1549*3ac0a46fSAndroid Build Coastguard Worker         TIFF_JSAMPROW line_work_buf = NULL;
1550*3ac0a46fSAndroid Build Coastguard Worker 
1551*3ac0a46fSAndroid Build Coastguard Worker         /*
1552*3ac0a46fSAndroid Build Coastguard Worker          * For 6B, only use temporary buffer for 12 bit imagery.
1553*3ac0a46fSAndroid Build Coastguard Worker          * For Mk1 always use it.
1554*3ac0a46fSAndroid Build Coastguard Worker          */
1555*3ac0a46fSAndroid Build Coastguard Worker         if (sp->cinfo.d.data_precision == 12)
1556*3ac0a46fSAndroid Build Coastguard Worker         {
1557*3ac0a46fSAndroid Build Coastguard Worker             line_work_buf = (TIFF_JSAMPROW)_TIFFmallocExt(
1558*3ac0a46fSAndroid Build Coastguard Worker                 tif, sizeof(short) * sp->cinfo.d.output_width *
1559*3ac0a46fSAndroid Build Coastguard Worker                          sp->cinfo.d.num_components);
1560*3ac0a46fSAndroid Build Coastguard Worker         }
1561*3ac0a46fSAndroid Build Coastguard Worker 
1562*3ac0a46fSAndroid Build Coastguard Worker         do
1563*3ac0a46fSAndroid Build Coastguard Worker         {
1564*3ac0a46fSAndroid Build Coastguard Worker             if (line_work_buf != NULL)
1565*3ac0a46fSAndroid Build Coastguard Worker             {
1566*3ac0a46fSAndroid Build Coastguard Worker                 /*
1567*3ac0a46fSAndroid Build Coastguard Worker                  * In the MK1 case, we always read into a 16bit
1568*3ac0a46fSAndroid Build Coastguard Worker                  * buffer, and then pack down to 12bit or 8bit.
1569*3ac0a46fSAndroid Build Coastguard Worker                  * In 6B case we only read into 16 bit buffer
1570*3ac0a46fSAndroid Build Coastguard Worker                  * for 12bit data, which we need to repack.
1571*3ac0a46fSAndroid Build Coastguard Worker                  */
1572*3ac0a46fSAndroid Build Coastguard Worker                 if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1)
1573*3ac0a46fSAndroid Build Coastguard Worker                     return (0);
1574*3ac0a46fSAndroid Build Coastguard Worker 
1575*3ac0a46fSAndroid Build Coastguard Worker                 if (sp->cinfo.d.data_precision == 12)
1576*3ac0a46fSAndroid Build Coastguard Worker                 {
1577*3ac0a46fSAndroid Build Coastguard Worker                     int value_pairs = (sp->cinfo.d.output_width *
1578*3ac0a46fSAndroid Build Coastguard Worker                                        sp->cinfo.d.num_components) /
1579*3ac0a46fSAndroid Build Coastguard Worker                                       2;
1580*3ac0a46fSAndroid Build Coastguard Worker                     int iPair;
1581*3ac0a46fSAndroid Build Coastguard Worker 
1582*3ac0a46fSAndroid Build Coastguard Worker                     for (iPair = 0; iPair < value_pairs; iPair++)
1583*3ac0a46fSAndroid Build Coastguard Worker                     {
1584*3ac0a46fSAndroid Build Coastguard Worker                         unsigned char *out_ptr =
1585*3ac0a46fSAndroid Build Coastguard Worker                             ((unsigned char *)buf) + iPair * 3;
1586*3ac0a46fSAndroid Build Coastguard Worker                         TIFF_JSAMPLE *in_ptr = line_work_buf + iPair * 2;
1587*3ac0a46fSAndroid Build Coastguard Worker 
1588*3ac0a46fSAndroid Build Coastguard Worker                         out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4);
1589*3ac0a46fSAndroid Build Coastguard Worker                         out_ptr[1] =
1590*3ac0a46fSAndroid Build Coastguard Worker                             (unsigned char)(((in_ptr[0] & 0xf) << 4) |
1591*3ac0a46fSAndroid Build Coastguard Worker                                             ((in_ptr[1] & 0xf00) >> 8));
1592*3ac0a46fSAndroid Build Coastguard Worker                         out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0));
1593*3ac0a46fSAndroid Build Coastguard Worker                     }
1594*3ac0a46fSAndroid Build Coastguard Worker                 }
1595*3ac0a46fSAndroid Build Coastguard Worker                 else if (sp->cinfo.d.data_precision == 8)
1596*3ac0a46fSAndroid Build Coastguard Worker                 {
1597*3ac0a46fSAndroid Build Coastguard Worker                     int value_count =
1598*3ac0a46fSAndroid Build Coastguard Worker                         (sp->cinfo.d.output_width * sp->cinfo.d.num_components);
1599*3ac0a46fSAndroid Build Coastguard Worker                     int iValue;
1600*3ac0a46fSAndroid Build Coastguard Worker 
1601*3ac0a46fSAndroid Build Coastguard Worker                     for (iValue = 0; iValue < value_count; iValue++)
1602*3ac0a46fSAndroid Build Coastguard Worker                     {
1603*3ac0a46fSAndroid Build Coastguard Worker                         ((unsigned char *)buf)[iValue] =
1604*3ac0a46fSAndroid Build Coastguard Worker                             line_work_buf[iValue] & 0xff;
1605*3ac0a46fSAndroid Build Coastguard Worker                     }
1606*3ac0a46fSAndroid Build Coastguard Worker                 }
1607*3ac0a46fSAndroid Build Coastguard Worker             }
1608*3ac0a46fSAndroid Build Coastguard Worker 
1609*3ac0a46fSAndroid Build Coastguard Worker             ++tif->tif_row;
1610*3ac0a46fSAndroid Build Coastguard Worker             buf += sp->bytesperline;
1611*3ac0a46fSAndroid Build Coastguard Worker             cc -= sp->bytesperline;
1612*3ac0a46fSAndroid Build Coastguard Worker         } while (--nrows > 0);
1613*3ac0a46fSAndroid Build Coastguard Worker 
1614*3ac0a46fSAndroid Build Coastguard Worker         if (line_work_buf != NULL)
1615*3ac0a46fSAndroid Build Coastguard Worker             _TIFFfreeExt(tif, line_work_buf);
1616*3ac0a46fSAndroid Build Coastguard Worker     }
1617*3ac0a46fSAndroid Build Coastguard Worker 
1618*3ac0a46fSAndroid Build Coastguard Worker     /* Update information on consumed data */
1619*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_rawcp = (uint8_t *)sp->src.next_input_byte;
1620*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_rawcc = sp->src.bytes_in_buffer;
1621*3ac0a46fSAndroid Build Coastguard Worker 
1622*3ac0a46fSAndroid Build Coastguard Worker     /* Close down the decompressor if we've finished the strip or tile. */
1623*3ac0a46fSAndroid Build Coastguard Worker     return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height ||
1624*3ac0a46fSAndroid Build Coastguard Worker            TIFFjpeg_finish_decompress(sp);
1625*3ac0a46fSAndroid Build Coastguard Worker }
1626*3ac0a46fSAndroid Build Coastguard Worker #endif /* JPEG_LIB_MK1_OR_12BIT */
1627*3ac0a46fSAndroid Build Coastguard Worker 
DecodeRowError(TIFF * tif,uint8_t * buf,tmsize_t cc,uint16_t s)1628*3ac0a46fSAndroid Build Coastguard Worker /*ARGSUSED*/ static int DecodeRowError(TIFF *tif, uint8_t *buf, tmsize_t cc,
1629*3ac0a46fSAndroid Build Coastguard Worker                                        uint16_t s)
1630*3ac0a46fSAndroid Build Coastguard Worker 
1631*3ac0a46fSAndroid Build Coastguard Worker {
1632*3ac0a46fSAndroid Build Coastguard Worker     (void)buf;
1633*3ac0a46fSAndroid Build Coastguard Worker     (void)cc;
1634*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
1635*3ac0a46fSAndroid Build Coastguard Worker 
1636*3ac0a46fSAndroid Build Coastguard Worker     TIFFErrorExtR(
1637*3ac0a46fSAndroid Build Coastguard Worker         tif, "TIFFReadScanline",
1638*3ac0a46fSAndroid Build Coastguard Worker         "scanline oriented access is not supported for downsampled JPEG "
1639*3ac0a46fSAndroid Build Coastguard Worker         "compressed images, consider enabling TIFFTAG_JPEGCOLORMODE as "
1640*3ac0a46fSAndroid Build Coastguard Worker         "JPEGCOLORMODE_RGB.");
1641*3ac0a46fSAndroid Build Coastguard Worker     return 0;
1642*3ac0a46fSAndroid Build Coastguard Worker }
1643*3ac0a46fSAndroid Build Coastguard Worker 
1644*3ac0a46fSAndroid Build Coastguard Worker /*
1645*3ac0a46fSAndroid Build Coastguard Worker  * Decode a chunk of pixels.
1646*3ac0a46fSAndroid Build Coastguard Worker  * Returned data is downsampled per sampling factors.
1647*3ac0a46fSAndroid Build Coastguard Worker  */
JPEGDecodeRaw(TIFF * tif,uint8_t * buf,tmsize_t cc,uint16_t s)1648*3ac0a46fSAndroid Build Coastguard Worker /*ARGSUSED*/ static int JPEGDecodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc,
1649*3ac0a46fSAndroid Build Coastguard Worker                                       uint16_t s)
1650*3ac0a46fSAndroid Build Coastguard Worker {
1651*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
1652*3ac0a46fSAndroid Build Coastguard Worker     tmsize_t nrows;
1653*3ac0a46fSAndroid Build Coastguard Worker     TIFFDirectory *td = &tif->tif_dir;
1654*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
1655*3ac0a46fSAndroid Build Coastguard Worker 
1656*3ac0a46fSAndroid Build Coastguard Worker     nrows = sp->cinfo.d.image_height;
1657*3ac0a46fSAndroid Build Coastguard Worker     /* For last strip, limit number of rows to its truncated height */
1658*3ac0a46fSAndroid Build Coastguard Worker     /* even if the codestream height is larger (which is not compliant, */
1659*3ac0a46fSAndroid Build Coastguard Worker     /* but that we tolerate) */
1660*3ac0a46fSAndroid Build Coastguard Worker     if ((uint32_t)nrows > td->td_imagelength - tif->tif_row && !isTiled(tif))
1661*3ac0a46fSAndroid Build Coastguard Worker         nrows = td->td_imagelength - tif->tif_row;
1662*3ac0a46fSAndroid Build Coastguard Worker 
1663*3ac0a46fSAndroid Build Coastguard Worker #if defined(JPEG_LIB_MK1_OR_12BIT)
1664*3ac0a46fSAndroid Build Coastguard Worker     unsigned short *tmpbuf = NULL;
1665*3ac0a46fSAndroid Build Coastguard Worker #endif
1666*3ac0a46fSAndroid Build Coastguard Worker 
1667*3ac0a46fSAndroid Build Coastguard Worker     /* data is expected to be read in multiples of a scanline */
1668*3ac0a46fSAndroid Build Coastguard Worker     if (nrows != 0)
1669*3ac0a46fSAndroid Build Coastguard Worker     {
1670*3ac0a46fSAndroid Build Coastguard Worker 
1671*3ac0a46fSAndroid Build Coastguard Worker         /* Cb,Cr both have sampling factors 1, so this is correct */
1672*3ac0a46fSAndroid Build Coastguard Worker         JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;
1673*3ac0a46fSAndroid Build Coastguard Worker         int samples_per_clump = sp->samplesperclump;
1674*3ac0a46fSAndroid Build Coastguard Worker 
1675*3ac0a46fSAndroid Build Coastguard Worker #if defined(JPEG_LIB_MK1_OR_12BIT)
1676*3ac0a46fSAndroid Build Coastguard Worker         tmpbuf = _TIFFmallocExt(tif, sizeof(unsigned short) *
1677*3ac0a46fSAndroid Build Coastguard Worker                                          sp->cinfo.d.output_width *
1678*3ac0a46fSAndroid Build Coastguard Worker                                          sp->cinfo.d.num_components);
1679*3ac0a46fSAndroid Build Coastguard Worker         if (tmpbuf == NULL)
1680*3ac0a46fSAndroid Build Coastguard Worker         {
1681*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, "JPEGDecodeRaw", "Out of memory");
1682*3ac0a46fSAndroid Build Coastguard Worker             return 0;
1683*3ac0a46fSAndroid Build Coastguard Worker         }
1684*3ac0a46fSAndroid Build Coastguard Worker #endif
1685*3ac0a46fSAndroid Build Coastguard Worker 
1686*3ac0a46fSAndroid Build Coastguard Worker         do
1687*3ac0a46fSAndroid Build Coastguard Worker         {
1688*3ac0a46fSAndroid Build Coastguard Worker             jpeg_component_info *compptr;
1689*3ac0a46fSAndroid Build Coastguard Worker             int ci, clumpoffset;
1690*3ac0a46fSAndroid Build Coastguard Worker 
1691*3ac0a46fSAndroid Build Coastguard Worker             if (cc < sp->bytesperline)
1692*3ac0a46fSAndroid Build Coastguard Worker             {
1693*3ac0a46fSAndroid Build Coastguard Worker                 TIFFErrorExtR(
1694*3ac0a46fSAndroid Build Coastguard Worker                     tif, "JPEGDecodeRaw",
1695*3ac0a46fSAndroid Build Coastguard Worker                     "application buffer not large enough for all data.");
1696*3ac0a46fSAndroid Build Coastguard Worker                 goto error;
1697*3ac0a46fSAndroid Build Coastguard Worker             }
1698*3ac0a46fSAndroid Build Coastguard Worker 
1699*3ac0a46fSAndroid Build Coastguard Worker             /* Reload downsampled-data buffer if needed */
1700*3ac0a46fSAndroid Build Coastguard Worker             if (sp->scancount >= DCTSIZE)
1701*3ac0a46fSAndroid Build Coastguard Worker             {
1702*3ac0a46fSAndroid Build Coastguard Worker                 int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE;
1703*3ac0a46fSAndroid Build Coastguard Worker                 if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n)
1704*3ac0a46fSAndroid Build Coastguard Worker                     goto error;
1705*3ac0a46fSAndroid Build Coastguard Worker                 sp->scancount = 0;
1706*3ac0a46fSAndroid Build Coastguard Worker             }
1707*3ac0a46fSAndroid Build Coastguard Worker             /*
1708*3ac0a46fSAndroid Build Coastguard Worker              * Fastest way to unseparate data is to make one pass
1709*3ac0a46fSAndroid Build Coastguard Worker              * over the scanline for each row of each component.
1710*3ac0a46fSAndroid Build Coastguard Worker              */
1711*3ac0a46fSAndroid Build Coastguard Worker             clumpoffset = 0; /* first sample in clump */
1712*3ac0a46fSAndroid Build Coastguard Worker             for (ci = 0, compptr = sp->cinfo.d.comp_info;
1713*3ac0a46fSAndroid Build Coastguard Worker                  ci < sp->cinfo.d.num_components; ci++, compptr++)
1714*3ac0a46fSAndroid Build Coastguard Worker             {
1715*3ac0a46fSAndroid Build Coastguard Worker                 int hsamp = compptr->h_samp_factor;
1716*3ac0a46fSAndroid Build Coastguard Worker                 int vsamp = compptr->v_samp_factor;
1717*3ac0a46fSAndroid Build Coastguard Worker                 int ypos;
1718*3ac0a46fSAndroid Build Coastguard Worker 
1719*3ac0a46fSAndroid Build Coastguard Worker                 for (ypos = 0; ypos < vsamp; ypos++)
1720*3ac0a46fSAndroid Build Coastguard Worker                 {
1721*3ac0a46fSAndroid Build Coastguard Worker                     TIFF_JSAMPLE *inptr =
1722*3ac0a46fSAndroid Build Coastguard Worker                         sp->ds_buffer[ci][sp->scancount * vsamp + ypos];
1723*3ac0a46fSAndroid Build Coastguard Worker                     JDIMENSION nclump;
1724*3ac0a46fSAndroid Build Coastguard Worker #if defined(JPEG_LIB_MK1_OR_12BIT)
1725*3ac0a46fSAndroid Build Coastguard Worker                     TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)tmpbuf + clumpoffset;
1726*3ac0a46fSAndroid Build Coastguard Worker #else
1727*3ac0a46fSAndroid Build Coastguard Worker                     TIFF_JSAMPLE *outptr = (TIFF_JSAMPLE *)buf + clumpoffset;
1728*3ac0a46fSAndroid Build Coastguard Worker                     if (cc < (tmsize_t)(clumpoffset +
1729*3ac0a46fSAndroid Build Coastguard Worker                                         (tmsize_t)samples_per_clump *
1730*3ac0a46fSAndroid Build Coastguard Worker                                             (clumps_per_line - 1) +
1731*3ac0a46fSAndroid Build Coastguard Worker                                         hsamp))
1732*3ac0a46fSAndroid Build Coastguard Worker                     {
1733*3ac0a46fSAndroid Build Coastguard Worker                         TIFFErrorExtR(
1734*3ac0a46fSAndroid Build Coastguard Worker                             tif, "JPEGDecodeRaw",
1735*3ac0a46fSAndroid Build Coastguard Worker                             "application buffer not large enough for all data, "
1736*3ac0a46fSAndroid Build Coastguard Worker                             "possible subsampling issue");
1737*3ac0a46fSAndroid Build Coastguard Worker                         goto error;
1738*3ac0a46fSAndroid Build Coastguard Worker                     }
1739*3ac0a46fSAndroid Build Coastguard Worker #endif
1740*3ac0a46fSAndroid Build Coastguard Worker 
1741*3ac0a46fSAndroid Build Coastguard Worker                     if (hsamp == 1)
1742*3ac0a46fSAndroid Build Coastguard Worker                     {
1743*3ac0a46fSAndroid Build Coastguard Worker                         /* fast path for at least Cb and Cr */
1744*3ac0a46fSAndroid Build Coastguard Worker                         for (nclump = clumps_per_line; nclump-- > 0;)
1745*3ac0a46fSAndroid Build Coastguard Worker                         {
1746*3ac0a46fSAndroid Build Coastguard Worker                             outptr[0] = *inptr++;
1747*3ac0a46fSAndroid Build Coastguard Worker                             outptr += samples_per_clump;
1748*3ac0a46fSAndroid Build Coastguard Worker                         }
1749*3ac0a46fSAndroid Build Coastguard Worker                     }
1750*3ac0a46fSAndroid Build Coastguard Worker                     else
1751*3ac0a46fSAndroid Build Coastguard Worker                     {
1752*3ac0a46fSAndroid Build Coastguard Worker                         int xpos;
1753*3ac0a46fSAndroid Build Coastguard Worker 
1754*3ac0a46fSAndroid Build Coastguard Worker                         /* general case */
1755*3ac0a46fSAndroid Build Coastguard Worker                         for (nclump = clumps_per_line; nclump-- > 0;)
1756*3ac0a46fSAndroid Build Coastguard Worker                         {
1757*3ac0a46fSAndroid Build Coastguard Worker                             for (xpos = 0; xpos < hsamp; xpos++)
1758*3ac0a46fSAndroid Build Coastguard Worker                                 outptr[xpos] = *inptr++;
1759*3ac0a46fSAndroid Build Coastguard Worker                             outptr += samples_per_clump;
1760*3ac0a46fSAndroid Build Coastguard Worker                         }
1761*3ac0a46fSAndroid Build Coastguard Worker                     }
1762*3ac0a46fSAndroid Build Coastguard Worker                     clumpoffset += hsamp;
1763*3ac0a46fSAndroid Build Coastguard Worker                 }
1764*3ac0a46fSAndroid Build Coastguard Worker             }
1765*3ac0a46fSAndroid Build Coastguard Worker 
1766*3ac0a46fSAndroid Build Coastguard Worker #if defined(JPEG_LIB_MK1_OR_12BIT)
1767*3ac0a46fSAndroid Build Coastguard Worker             {
1768*3ac0a46fSAndroid Build Coastguard Worker                 if (sp->cinfo.d.data_precision == 8)
1769*3ac0a46fSAndroid Build Coastguard Worker                 {
1770*3ac0a46fSAndroid Build Coastguard Worker                     int i = 0;
1771*3ac0a46fSAndroid Build Coastguard Worker                     int len =
1772*3ac0a46fSAndroid Build Coastguard Worker                         sp->cinfo.d.output_width * sp->cinfo.d.num_components;
1773*3ac0a46fSAndroid Build Coastguard Worker                     for (i = 0; i < len; i++)
1774*3ac0a46fSAndroid Build Coastguard Worker                     {
1775*3ac0a46fSAndroid Build Coastguard Worker                         ((unsigned char *)buf)[i] = tmpbuf[i] & 0xff;
1776*3ac0a46fSAndroid Build Coastguard Worker                     }
1777*3ac0a46fSAndroid Build Coastguard Worker                 }
1778*3ac0a46fSAndroid Build Coastguard Worker                 else
1779*3ac0a46fSAndroid Build Coastguard Worker                 { /* 12-bit */
1780*3ac0a46fSAndroid Build Coastguard Worker                     int value_pairs = (sp->cinfo.d.output_width *
1781*3ac0a46fSAndroid Build Coastguard Worker                                        sp->cinfo.d.num_components) /
1782*3ac0a46fSAndroid Build Coastguard Worker                                       2;
1783*3ac0a46fSAndroid Build Coastguard Worker                     int iPair;
1784*3ac0a46fSAndroid Build Coastguard Worker                     for (iPair = 0; iPair < value_pairs; iPair++)
1785*3ac0a46fSAndroid Build Coastguard Worker                     {
1786*3ac0a46fSAndroid Build Coastguard Worker                         unsigned char *out_ptr =
1787*3ac0a46fSAndroid Build Coastguard Worker                             ((unsigned char *)buf) + iPair * 3;
1788*3ac0a46fSAndroid Build Coastguard Worker                         JSAMPLE *in_ptr = (JSAMPLE *)(tmpbuf + iPair * 2);
1789*3ac0a46fSAndroid Build Coastguard Worker                         out_ptr[0] = (unsigned char)((in_ptr[0] & 0xff0) >> 4);
1790*3ac0a46fSAndroid Build Coastguard Worker                         out_ptr[1] =
1791*3ac0a46fSAndroid Build Coastguard Worker                             (unsigned char)(((in_ptr[0] & 0xf) << 4) |
1792*3ac0a46fSAndroid Build Coastguard Worker                                             ((in_ptr[1] & 0xf00) >> 8));
1793*3ac0a46fSAndroid Build Coastguard Worker                         out_ptr[2] = (unsigned char)(((in_ptr[1] & 0xff) >> 0));
1794*3ac0a46fSAndroid Build Coastguard Worker                     }
1795*3ac0a46fSAndroid Build Coastguard Worker                 }
1796*3ac0a46fSAndroid Build Coastguard Worker             }
1797*3ac0a46fSAndroid Build Coastguard Worker #endif
1798*3ac0a46fSAndroid Build Coastguard Worker 
1799*3ac0a46fSAndroid Build Coastguard Worker             sp->scancount++;
1800*3ac0a46fSAndroid Build Coastguard Worker             tif->tif_row += sp->v_sampling;
1801*3ac0a46fSAndroid Build Coastguard Worker 
1802*3ac0a46fSAndroid Build Coastguard Worker             buf += sp->bytesperline;
1803*3ac0a46fSAndroid Build Coastguard Worker             cc -= sp->bytesperline;
1804*3ac0a46fSAndroid Build Coastguard Worker 
1805*3ac0a46fSAndroid Build Coastguard Worker             nrows -= sp->v_sampling;
1806*3ac0a46fSAndroid Build Coastguard Worker         } while (nrows > 0);
1807*3ac0a46fSAndroid Build Coastguard Worker 
1808*3ac0a46fSAndroid Build Coastguard Worker #if defined(JPEG_LIB_MK1_OR_12BIT)
1809*3ac0a46fSAndroid Build Coastguard Worker         _TIFFfreeExt(tif, tmpbuf);
1810*3ac0a46fSAndroid Build Coastguard Worker #endif
1811*3ac0a46fSAndroid Build Coastguard Worker     }
1812*3ac0a46fSAndroid Build Coastguard Worker 
1813*3ac0a46fSAndroid Build Coastguard Worker     /* Close down the decompressor if done. */
1814*3ac0a46fSAndroid Build Coastguard Worker     return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height ||
1815*3ac0a46fSAndroid Build Coastguard Worker            TIFFjpeg_finish_decompress(sp);
1816*3ac0a46fSAndroid Build Coastguard Worker 
1817*3ac0a46fSAndroid Build Coastguard Worker error:
1818*3ac0a46fSAndroid Build Coastguard Worker #if defined(JPEG_LIB_MK1_OR_12BIT)
1819*3ac0a46fSAndroid Build Coastguard Worker     _TIFFfreeExt(tif, tmpbuf);
1820*3ac0a46fSAndroid Build Coastguard Worker #endif
1821*3ac0a46fSAndroid Build Coastguard Worker     return 0;
1822*3ac0a46fSAndroid Build Coastguard Worker }
1823*3ac0a46fSAndroid Build Coastguard Worker 
1824*3ac0a46fSAndroid Build Coastguard Worker /*
1825*3ac0a46fSAndroid Build Coastguard Worker  * JPEG Encoding.
1826*3ac0a46fSAndroid Build Coastguard Worker  */
1827*3ac0a46fSAndroid Build Coastguard Worker 
unsuppress_quant_table(JPEGState * sp,int tblno)1828*3ac0a46fSAndroid Build Coastguard Worker static void unsuppress_quant_table(JPEGState *sp, int tblno)
1829*3ac0a46fSAndroid Build Coastguard Worker {
1830*3ac0a46fSAndroid Build Coastguard Worker     JQUANT_TBL *qtbl;
1831*3ac0a46fSAndroid Build Coastguard Worker 
1832*3ac0a46fSAndroid Build Coastguard Worker     if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)
1833*3ac0a46fSAndroid Build Coastguard Worker         qtbl->sent_table = FALSE;
1834*3ac0a46fSAndroid Build Coastguard Worker }
1835*3ac0a46fSAndroid Build Coastguard Worker 
suppress_quant_table(JPEGState * sp,int tblno)1836*3ac0a46fSAndroid Build Coastguard Worker static void suppress_quant_table(JPEGState *sp, int tblno)
1837*3ac0a46fSAndroid Build Coastguard Worker {
1838*3ac0a46fSAndroid Build Coastguard Worker     JQUANT_TBL *qtbl;
1839*3ac0a46fSAndroid Build Coastguard Worker 
1840*3ac0a46fSAndroid Build Coastguard Worker     if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)
1841*3ac0a46fSAndroid Build Coastguard Worker         qtbl->sent_table = TRUE;
1842*3ac0a46fSAndroid Build Coastguard Worker }
1843*3ac0a46fSAndroid Build Coastguard Worker 
unsuppress_huff_table(JPEGState * sp,int tblno)1844*3ac0a46fSAndroid Build Coastguard Worker static void unsuppress_huff_table(JPEGState *sp, int tblno)
1845*3ac0a46fSAndroid Build Coastguard Worker {
1846*3ac0a46fSAndroid Build Coastguard Worker     JHUFF_TBL *htbl;
1847*3ac0a46fSAndroid Build Coastguard Worker 
1848*3ac0a46fSAndroid Build Coastguard Worker     if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)
1849*3ac0a46fSAndroid Build Coastguard Worker         htbl->sent_table = FALSE;
1850*3ac0a46fSAndroid Build Coastguard Worker     if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)
1851*3ac0a46fSAndroid Build Coastguard Worker         htbl->sent_table = FALSE;
1852*3ac0a46fSAndroid Build Coastguard Worker }
1853*3ac0a46fSAndroid Build Coastguard Worker 
suppress_huff_table(JPEGState * sp,int tblno)1854*3ac0a46fSAndroid Build Coastguard Worker static void suppress_huff_table(JPEGState *sp, int tblno)
1855*3ac0a46fSAndroid Build Coastguard Worker {
1856*3ac0a46fSAndroid Build Coastguard Worker     JHUFF_TBL *htbl;
1857*3ac0a46fSAndroid Build Coastguard Worker 
1858*3ac0a46fSAndroid Build Coastguard Worker     if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)
1859*3ac0a46fSAndroid Build Coastguard Worker         htbl->sent_table = TRUE;
1860*3ac0a46fSAndroid Build Coastguard Worker     if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)
1861*3ac0a46fSAndroid Build Coastguard Worker         htbl->sent_table = TRUE;
1862*3ac0a46fSAndroid Build Coastguard Worker }
1863*3ac0a46fSAndroid Build Coastguard Worker 
prepare_JPEGTables(TIFF * tif)1864*3ac0a46fSAndroid Build Coastguard Worker static int prepare_JPEGTables(TIFF *tif)
1865*3ac0a46fSAndroid Build Coastguard Worker {
1866*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
1867*3ac0a46fSAndroid Build Coastguard Worker 
1868*3ac0a46fSAndroid Build Coastguard Worker     /* Initialize quant tables for current quality setting */
1869*3ac0a46fSAndroid Build Coastguard Worker     if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE))
1870*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1871*3ac0a46fSAndroid Build Coastguard Worker     /* Mark only the tables we want for output */
1872*3ac0a46fSAndroid Build Coastguard Worker     /* NB: chrominance tables are currently used only with YCbCr */
1873*3ac0a46fSAndroid Build Coastguard Worker     if (!TIFFjpeg_suppress_tables(sp, TRUE))
1874*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1875*3ac0a46fSAndroid Build Coastguard Worker     if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT)
1876*3ac0a46fSAndroid Build Coastguard Worker     {
1877*3ac0a46fSAndroid Build Coastguard Worker         unsuppress_quant_table(sp, 0);
1878*3ac0a46fSAndroid Build Coastguard Worker         if (sp->photometric == PHOTOMETRIC_YCBCR)
1879*3ac0a46fSAndroid Build Coastguard Worker             unsuppress_quant_table(sp, 1);
1880*3ac0a46fSAndroid Build Coastguard Worker     }
1881*3ac0a46fSAndroid Build Coastguard Worker     if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF)
1882*3ac0a46fSAndroid Build Coastguard Worker     {
1883*3ac0a46fSAndroid Build Coastguard Worker         unsuppress_huff_table(sp, 0);
1884*3ac0a46fSAndroid Build Coastguard Worker         if (sp->photometric == PHOTOMETRIC_YCBCR)
1885*3ac0a46fSAndroid Build Coastguard Worker             unsuppress_huff_table(sp, 1);
1886*3ac0a46fSAndroid Build Coastguard Worker     }
1887*3ac0a46fSAndroid Build Coastguard Worker     /* Direct libjpeg output into otherSettings.jpegtables */
1888*3ac0a46fSAndroid Build Coastguard Worker     if (!TIFFjpeg_tables_dest(sp, tif))
1889*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1890*3ac0a46fSAndroid Build Coastguard Worker     /* Emit tables-only datastream */
1891*3ac0a46fSAndroid Build Coastguard Worker     if (!TIFFjpeg_write_tables(sp))
1892*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1893*3ac0a46fSAndroid Build Coastguard Worker 
1894*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1895*3ac0a46fSAndroid Build Coastguard Worker }
1896*3ac0a46fSAndroid Build Coastguard Worker 
1897*3ac0a46fSAndroid Build Coastguard Worker #if defined(JPEG_LIB_VERSION_MAJOR) &&                                         \
1898*3ac0a46fSAndroid Build Coastguard Worker     (JPEG_LIB_VERSION_MAJOR > 9 ||                                             \
1899*3ac0a46fSAndroid Build Coastguard Worker      (JPEG_LIB_VERSION_MAJOR == 9 && JPEG_LIB_VERSION_MINOR >= 4))
1900*3ac0a46fSAndroid Build Coastguard Worker /* This is a modified version of std_huff_tables() from jcparam.c
1901*3ac0a46fSAndroid Build Coastguard Worker  * in libjpeg-9d because it no longer initializes default Huffman
1902*3ac0a46fSAndroid Build Coastguard Worker  * tables in jpeg_set_defaults(). */
TIFF_std_huff_tables(j_compress_ptr cinfo)1903*3ac0a46fSAndroid Build Coastguard Worker static void TIFF_std_huff_tables(j_compress_ptr cinfo)
1904*3ac0a46fSAndroid Build Coastguard Worker {
1905*3ac0a46fSAndroid Build Coastguard Worker 
1906*3ac0a46fSAndroid Build Coastguard Worker     if (cinfo->dc_huff_tbl_ptrs[0] == NULL)
1907*3ac0a46fSAndroid Build Coastguard Worker     {
1908*3ac0a46fSAndroid Build Coastguard Worker         (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 0);
1909*3ac0a46fSAndroid Build Coastguard Worker     }
1910*3ac0a46fSAndroid Build Coastguard Worker     if (cinfo->ac_huff_tbl_ptrs[0] == NULL)
1911*3ac0a46fSAndroid Build Coastguard Worker     {
1912*3ac0a46fSAndroid Build Coastguard Worker         (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 0);
1913*3ac0a46fSAndroid Build Coastguard Worker     }
1914*3ac0a46fSAndroid Build Coastguard Worker     if (cinfo->dc_huff_tbl_ptrs[1] == NULL)
1915*3ac0a46fSAndroid Build Coastguard Worker     {
1916*3ac0a46fSAndroid Build Coastguard Worker         (void)jpeg_std_huff_table((j_common_ptr)cinfo, TRUE, 1);
1917*3ac0a46fSAndroid Build Coastguard Worker     }
1918*3ac0a46fSAndroid Build Coastguard Worker     if (cinfo->ac_huff_tbl_ptrs[1] == NULL)
1919*3ac0a46fSAndroid Build Coastguard Worker     {
1920*3ac0a46fSAndroid Build Coastguard Worker         (void)jpeg_std_huff_table((j_common_ptr)cinfo, FALSE, 1);
1921*3ac0a46fSAndroid Build Coastguard Worker     }
1922*3ac0a46fSAndroid Build Coastguard Worker }
1923*3ac0a46fSAndroid Build Coastguard Worker #endif
1924*3ac0a46fSAndroid Build Coastguard Worker 
JPEGSetupEncode(TIFF * tif)1925*3ac0a46fSAndroid Build Coastguard Worker static int JPEGSetupEncode(TIFF *tif)
1926*3ac0a46fSAndroid Build Coastguard Worker {
1927*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
1928*3ac0a46fSAndroid Build Coastguard Worker     TIFFDirectory *td = &tif->tif_dir;
1929*3ac0a46fSAndroid Build Coastguard Worker     static const char module[] = "JPEGSetupEncode";
1930*3ac0a46fSAndroid Build Coastguard Worker 
1931*3ac0a46fSAndroid Build Coastguard Worker #if defined(JPEG_DUAL_MODE_8_12) && !defined(FROM_TIF_JPEG_12)
1932*3ac0a46fSAndroid Build Coastguard Worker     if (tif->tif_dir.td_bitspersample == 12)
1933*3ac0a46fSAndroid Build Coastguard Worker     {
1934*3ac0a46fSAndroid Build Coastguard Worker         /* We pass a pointer to a copy of otherSettings, since */
1935*3ac0a46fSAndroid Build Coastguard Worker         /* TIFFReInitJPEG_12() will clear sp */
1936*3ac0a46fSAndroid Build Coastguard Worker         JPEGOtherSettings savedOtherSettings = sp->otherSettings;
1937*3ac0a46fSAndroid Build Coastguard Worker         return TIFFReInitJPEG_12(tif, &savedOtherSettings, COMPRESSION_JPEG, 1);
1938*3ac0a46fSAndroid Build Coastguard Worker     }
1939*3ac0a46fSAndroid Build Coastguard Worker #endif
1940*3ac0a46fSAndroid Build Coastguard Worker 
1941*3ac0a46fSAndroid Build Coastguard Worker     JPEGInitializeLibJPEG(tif, FALSE);
1942*3ac0a46fSAndroid Build Coastguard Worker 
1943*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != NULL);
1944*3ac0a46fSAndroid Build Coastguard Worker     assert(!sp->cinfo.comm.is_decompressor);
1945*3ac0a46fSAndroid Build Coastguard Worker 
1946*3ac0a46fSAndroid Build Coastguard Worker     sp->photometric = td->td_photometric;
1947*3ac0a46fSAndroid Build Coastguard Worker 
1948*3ac0a46fSAndroid Build Coastguard Worker     /*
1949*3ac0a46fSAndroid Build Coastguard Worker      * Initialize all JPEG parameters to default values.
1950*3ac0a46fSAndroid Build Coastguard Worker      * Note that jpeg_set_defaults needs legal values for
1951*3ac0a46fSAndroid Build Coastguard Worker      * in_color_space and input_components.
1952*3ac0a46fSAndroid Build Coastguard Worker      */
1953*3ac0a46fSAndroid Build Coastguard Worker     if (td->td_planarconfig == PLANARCONFIG_CONTIG)
1954*3ac0a46fSAndroid Build Coastguard Worker     {
1955*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.c.input_components = td->td_samplesperpixel;
1956*3ac0a46fSAndroid Build Coastguard Worker         if (sp->photometric == PHOTOMETRIC_YCBCR)
1957*3ac0a46fSAndroid Build Coastguard Worker         {
1958*3ac0a46fSAndroid Build Coastguard Worker             if (sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB)
1959*3ac0a46fSAndroid Build Coastguard Worker             {
1960*3ac0a46fSAndroid Build Coastguard Worker                 sp->cinfo.c.in_color_space = JCS_RGB;
1961*3ac0a46fSAndroid Build Coastguard Worker             }
1962*3ac0a46fSAndroid Build Coastguard Worker             else
1963*3ac0a46fSAndroid Build Coastguard Worker             {
1964*3ac0a46fSAndroid Build Coastguard Worker                 sp->cinfo.c.in_color_space = JCS_YCbCr;
1965*3ac0a46fSAndroid Build Coastguard Worker             }
1966*3ac0a46fSAndroid Build Coastguard Worker         }
1967*3ac0a46fSAndroid Build Coastguard Worker         else
1968*3ac0a46fSAndroid Build Coastguard Worker         {
1969*3ac0a46fSAndroid Build Coastguard Worker             if ((td->td_photometric == PHOTOMETRIC_MINISWHITE ||
1970*3ac0a46fSAndroid Build Coastguard Worker                  td->td_photometric == PHOTOMETRIC_MINISBLACK) &&
1971*3ac0a46fSAndroid Build Coastguard Worker                 td->td_samplesperpixel == 1)
1972*3ac0a46fSAndroid Build Coastguard Worker                 sp->cinfo.c.in_color_space = JCS_GRAYSCALE;
1973*3ac0a46fSAndroid Build Coastguard Worker             else if (td->td_photometric == PHOTOMETRIC_RGB &&
1974*3ac0a46fSAndroid Build Coastguard Worker                      td->td_samplesperpixel == 3)
1975*3ac0a46fSAndroid Build Coastguard Worker                 sp->cinfo.c.in_color_space = JCS_RGB;
1976*3ac0a46fSAndroid Build Coastguard Worker             else if (td->td_photometric == PHOTOMETRIC_SEPARATED &&
1977*3ac0a46fSAndroid Build Coastguard Worker                      td->td_samplesperpixel == 4)
1978*3ac0a46fSAndroid Build Coastguard Worker                 sp->cinfo.c.in_color_space = JCS_CMYK;
1979*3ac0a46fSAndroid Build Coastguard Worker             else
1980*3ac0a46fSAndroid Build Coastguard Worker                 sp->cinfo.c.in_color_space = JCS_UNKNOWN;
1981*3ac0a46fSAndroid Build Coastguard Worker         }
1982*3ac0a46fSAndroid Build Coastguard Worker     }
1983*3ac0a46fSAndroid Build Coastguard Worker     else
1984*3ac0a46fSAndroid Build Coastguard Worker     {
1985*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.c.input_components = 1;
1986*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.c.in_color_space = JCS_UNKNOWN;
1987*3ac0a46fSAndroid Build Coastguard Worker     }
1988*3ac0a46fSAndroid Build Coastguard Worker     if (!TIFFjpeg_set_defaults(sp))
1989*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1990*3ac0a46fSAndroid Build Coastguard Worker 
1991*3ac0a46fSAndroid Build Coastguard Worker     /* mozjpeg by default enables progressive JPEG, which is illegal in
1992*3ac0a46fSAndroid Build Coastguard Worker      * JPEG-in-TIFF */
1993*3ac0a46fSAndroid Build Coastguard Worker     /* So explicitly disable it. */
1994*3ac0a46fSAndroid Build Coastguard Worker     if (sp->cinfo.c.num_scans != 0 &&
1995*3ac0a46fSAndroid Build Coastguard Worker         (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0)
1996*3ac0a46fSAndroid Build Coastguard Worker     {
1997*3ac0a46fSAndroid Build Coastguard Worker         /* it has been found that mozjpeg could create corrupt strips/tiles */
1998*3ac0a46fSAndroid Build Coastguard Worker         /* in non optimize_coding mode. */
1999*3ac0a46fSAndroid Build Coastguard Worker         TIFFWarningExtR(
2000*3ac0a46fSAndroid Build Coastguard Worker             tif, module,
2001*3ac0a46fSAndroid Build Coastguard Worker             "mozjpeg library likely detected. Disable emission of "
2002*3ac0a46fSAndroid Build Coastguard Worker             "Huffman tables in JpegTables tag, and use optimize_coding "
2003*3ac0a46fSAndroid Build Coastguard Worker             "to avoid potential issues");
2004*3ac0a46fSAndroid Build Coastguard Worker         sp->otherSettings.jpegtablesmode &= ~JPEGTABLESMODE_HUFF;
2005*3ac0a46fSAndroid Build Coastguard Worker     }
2006*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.c.num_scans = 0;
2007*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.c.scan_info = NULL;
2008*3ac0a46fSAndroid Build Coastguard Worker 
2009*3ac0a46fSAndroid Build Coastguard Worker     /* Set per-file parameters */
2010*3ac0a46fSAndroid Build Coastguard Worker     switch (sp->photometric)
2011*3ac0a46fSAndroid Build Coastguard Worker     {
2012*3ac0a46fSAndroid Build Coastguard Worker         case PHOTOMETRIC_YCBCR:
2013*3ac0a46fSAndroid Build Coastguard Worker             sp->h_sampling = td->td_ycbcrsubsampling[0];
2014*3ac0a46fSAndroid Build Coastguard Worker             sp->v_sampling = td->td_ycbcrsubsampling[1];
2015*3ac0a46fSAndroid Build Coastguard Worker             if (sp->h_sampling == 0 || sp->v_sampling == 0)
2016*3ac0a46fSAndroid Build Coastguard Worker             {
2017*3ac0a46fSAndroid Build Coastguard Worker                 TIFFErrorExtR(tif, module,
2018*3ac0a46fSAndroid Build Coastguard Worker                               "Invalig horizontal/vertical sampling value");
2019*3ac0a46fSAndroid Build Coastguard Worker                 return (0);
2020*3ac0a46fSAndroid Build Coastguard Worker             }
2021*3ac0a46fSAndroid Build Coastguard Worker             if (td->td_bitspersample > 16)
2022*3ac0a46fSAndroid Build Coastguard Worker             {
2023*3ac0a46fSAndroid Build Coastguard Worker                 TIFFErrorExtR(tif, module,
2024*3ac0a46fSAndroid Build Coastguard Worker                               "BitsPerSample %" PRIu16 " not allowed for JPEG",
2025*3ac0a46fSAndroid Build Coastguard Worker                               td->td_bitspersample);
2026*3ac0a46fSAndroid Build Coastguard Worker                 return (0);
2027*3ac0a46fSAndroid Build Coastguard Worker             }
2028*3ac0a46fSAndroid Build Coastguard Worker 
2029*3ac0a46fSAndroid Build Coastguard Worker             /*
2030*3ac0a46fSAndroid Build Coastguard Worker              * A ReferenceBlackWhite field *must* be present since the
2031*3ac0a46fSAndroid Build Coastguard Worker              * default value is inappropriate for YCbCr.  Fill in the
2032*3ac0a46fSAndroid Build Coastguard Worker              * proper value if application didn't set it.
2033*3ac0a46fSAndroid Build Coastguard Worker              */
2034*3ac0a46fSAndroid Build Coastguard Worker             {
2035*3ac0a46fSAndroid Build Coastguard Worker                 float *ref;
2036*3ac0a46fSAndroid Build Coastguard Worker                 if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE, &ref))
2037*3ac0a46fSAndroid Build Coastguard Worker                 {
2038*3ac0a46fSAndroid Build Coastguard Worker                     float refbw[6];
2039*3ac0a46fSAndroid Build Coastguard Worker                     long top = 1L << td->td_bitspersample;
2040*3ac0a46fSAndroid Build Coastguard Worker                     refbw[0] = 0;
2041*3ac0a46fSAndroid Build Coastguard Worker                     refbw[1] = (float)(top - 1L);
2042*3ac0a46fSAndroid Build Coastguard Worker                     refbw[2] = (float)(top >> 1);
2043*3ac0a46fSAndroid Build Coastguard Worker                     refbw[3] = refbw[1];
2044*3ac0a46fSAndroid Build Coastguard Worker                     refbw[4] = refbw[2];
2045*3ac0a46fSAndroid Build Coastguard Worker                     refbw[5] = refbw[1];
2046*3ac0a46fSAndroid Build Coastguard Worker                     TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refbw);
2047*3ac0a46fSAndroid Build Coastguard Worker                 }
2048*3ac0a46fSAndroid Build Coastguard Worker             }
2049*3ac0a46fSAndroid Build Coastguard Worker             break;
2050*3ac0a46fSAndroid Build Coastguard Worker         case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */
2051*3ac0a46fSAndroid Build Coastguard Worker         case PHOTOMETRIC_MASK:
2052*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, module,
2053*3ac0a46fSAndroid Build Coastguard Worker                           "PhotometricInterpretation %" PRIu16
2054*3ac0a46fSAndroid Build Coastguard Worker                           " not allowed for JPEG",
2055*3ac0a46fSAndroid Build Coastguard Worker                           sp->photometric);
2056*3ac0a46fSAndroid Build Coastguard Worker             return (0);
2057*3ac0a46fSAndroid Build Coastguard Worker         default:
2058*3ac0a46fSAndroid Build Coastguard Worker             /* TIFF 6.0 forbids subsampling of all other color spaces */
2059*3ac0a46fSAndroid Build Coastguard Worker             sp->h_sampling = 1;
2060*3ac0a46fSAndroid Build Coastguard Worker             sp->v_sampling = 1;
2061*3ac0a46fSAndroid Build Coastguard Worker             break;
2062*3ac0a46fSAndroid Build Coastguard Worker     }
2063*3ac0a46fSAndroid Build Coastguard Worker 
2064*3ac0a46fSAndroid Build Coastguard Worker         /* Verify miscellaneous parameters */
2065*3ac0a46fSAndroid Build Coastguard Worker 
2066*3ac0a46fSAndroid Build Coastguard Worker         /*
2067*3ac0a46fSAndroid Build Coastguard Worker          * This would need work if libtiff ever supports different
2068*3ac0a46fSAndroid Build Coastguard Worker          * depths for different components, or if libjpeg ever supports
2069*3ac0a46fSAndroid Build Coastguard Worker          * run-time selection of depth.  Neither is imminent.
2070*3ac0a46fSAndroid Build Coastguard Worker          */
2071*3ac0a46fSAndroid Build Coastguard Worker #ifdef JPEG_LIB_MK1
2072*3ac0a46fSAndroid Build Coastguard Worker     /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */
2073*3ac0a46fSAndroid Build Coastguard Worker     if (td->td_bitspersample != 8 && td->td_bitspersample != 12)
2074*3ac0a46fSAndroid Build Coastguard Worker #else
2075*3ac0a46fSAndroid Build Coastguard Worker     if (td->td_bitspersample != BITS_IN_JSAMPLE)
2076*3ac0a46fSAndroid Build Coastguard Worker #endif
2077*3ac0a46fSAndroid Build Coastguard Worker     {
2078*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module,
2079*3ac0a46fSAndroid Build Coastguard Worker                       "BitsPerSample %" PRIu16 " not allowed for JPEG",
2080*3ac0a46fSAndroid Build Coastguard Worker                       td->td_bitspersample);
2081*3ac0a46fSAndroid Build Coastguard Worker         return (0);
2082*3ac0a46fSAndroid Build Coastguard Worker     }
2083*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.c.data_precision = td->td_bitspersample;
2084*3ac0a46fSAndroid Build Coastguard Worker #ifdef JPEG_LIB_MK1
2085*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.c.bits_in_jsample = td->td_bitspersample;
2086*3ac0a46fSAndroid Build Coastguard Worker #endif
2087*3ac0a46fSAndroid Build Coastguard Worker     if (isTiled(tif))
2088*3ac0a46fSAndroid Build Coastguard Worker     {
2089*3ac0a46fSAndroid Build Coastguard Worker         if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0)
2090*3ac0a46fSAndroid Build Coastguard Worker         {
2091*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, module,
2092*3ac0a46fSAndroid Build Coastguard Worker                           "JPEG tile height must be multiple of %" PRIu32,
2093*3ac0a46fSAndroid Build Coastguard Worker                           (uint32_t)(sp->v_sampling * DCTSIZE));
2094*3ac0a46fSAndroid Build Coastguard Worker             return (0);
2095*3ac0a46fSAndroid Build Coastguard Worker         }
2096*3ac0a46fSAndroid Build Coastguard Worker         if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0)
2097*3ac0a46fSAndroid Build Coastguard Worker         {
2098*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, module,
2099*3ac0a46fSAndroid Build Coastguard Worker                           "JPEG tile width must be multiple of %" PRIu32,
2100*3ac0a46fSAndroid Build Coastguard Worker                           (uint32_t)(sp->h_sampling * DCTSIZE));
2101*3ac0a46fSAndroid Build Coastguard Worker             return (0);
2102*3ac0a46fSAndroid Build Coastguard Worker         }
2103*3ac0a46fSAndroid Build Coastguard Worker     }
2104*3ac0a46fSAndroid Build Coastguard Worker     else
2105*3ac0a46fSAndroid Build Coastguard Worker     {
2106*3ac0a46fSAndroid Build Coastguard Worker         if (td->td_rowsperstrip < td->td_imagelength &&
2107*3ac0a46fSAndroid Build Coastguard Worker             (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0)
2108*3ac0a46fSAndroid Build Coastguard Worker         {
2109*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, module,
2110*3ac0a46fSAndroid Build Coastguard Worker                           "RowsPerStrip must be multiple of %" PRIu32
2111*3ac0a46fSAndroid Build Coastguard Worker                           " for JPEG",
2112*3ac0a46fSAndroid Build Coastguard Worker                           (uint32_t)(sp->v_sampling * DCTSIZE));
2113*3ac0a46fSAndroid Build Coastguard Worker             return (0);
2114*3ac0a46fSAndroid Build Coastguard Worker         }
2115*3ac0a46fSAndroid Build Coastguard Worker     }
2116*3ac0a46fSAndroid Build Coastguard Worker 
2117*3ac0a46fSAndroid Build Coastguard Worker     /* Create a JPEGTables field if appropriate */
2118*3ac0a46fSAndroid Build Coastguard Worker     if (sp->otherSettings.jpegtablesmode &
2119*3ac0a46fSAndroid Build Coastguard Worker         (JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF))
2120*3ac0a46fSAndroid Build Coastguard Worker     {
2121*3ac0a46fSAndroid Build Coastguard Worker         if (sp->otherSettings.jpegtables == NULL ||
2122*3ac0a46fSAndroid Build Coastguard Worker             memcmp(sp->otherSettings.jpegtables, "\0\0\0\0\0\0\0\0\0", 8) == 0)
2123*3ac0a46fSAndroid Build Coastguard Worker         {
2124*3ac0a46fSAndroid Build Coastguard Worker #if defined(JPEG_LIB_VERSION_MAJOR) &&                                         \
2125*3ac0a46fSAndroid Build Coastguard Worker     (JPEG_LIB_VERSION_MAJOR > 9 ||                                             \
2126*3ac0a46fSAndroid Build Coastguard Worker      (JPEG_LIB_VERSION_MAJOR == 9 && JPEG_LIB_VERSION_MINOR >= 4))
2127*3ac0a46fSAndroid Build Coastguard Worker             if ((sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF) != 0 &&
2128*3ac0a46fSAndroid Build Coastguard Worker                 (sp->cinfo.c.dc_huff_tbl_ptrs[0] == NULL ||
2129*3ac0a46fSAndroid Build Coastguard Worker                  sp->cinfo.c.dc_huff_tbl_ptrs[1] == NULL ||
2130*3ac0a46fSAndroid Build Coastguard Worker                  sp->cinfo.c.ac_huff_tbl_ptrs[0] == NULL ||
2131*3ac0a46fSAndroid Build Coastguard Worker                  sp->cinfo.c.ac_huff_tbl_ptrs[1] == NULL))
2132*3ac0a46fSAndroid Build Coastguard Worker             {
2133*3ac0a46fSAndroid Build Coastguard Worker                 /* libjpeg-9d no longer initializes default Huffman tables in */
2134*3ac0a46fSAndroid Build Coastguard Worker                 /* jpeg_set_defaults() */
2135*3ac0a46fSAndroid Build Coastguard Worker                 TIFF_std_huff_tables(&sp->cinfo.c);
2136*3ac0a46fSAndroid Build Coastguard Worker             }
2137*3ac0a46fSAndroid Build Coastguard Worker #endif
2138*3ac0a46fSAndroid Build Coastguard Worker 
2139*3ac0a46fSAndroid Build Coastguard Worker             if (!prepare_JPEGTables(tif))
2140*3ac0a46fSAndroid Build Coastguard Worker                 return (0);
2141*3ac0a46fSAndroid Build Coastguard Worker             /* Mark the field present */
2142*3ac0a46fSAndroid Build Coastguard Worker             /* Can't use TIFFSetField since BEENWRITING is already set! */
2143*3ac0a46fSAndroid Build Coastguard Worker             tif->tif_flags |= TIFF_DIRTYDIRECT;
2144*3ac0a46fSAndroid Build Coastguard Worker             TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
2145*3ac0a46fSAndroid Build Coastguard Worker         }
2146*3ac0a46fSAndroid Build Coastguard Worker     }
2147*3ac0a46fSAndroid Build Coastguard Worker     else
2148*3ac0a46fSAndroid Build Coastguard Worker     {
2149*3ac0a46fSAndroid Build Coastguard Worker         /* We do not support application-supplied JPEGTables, */
2150*3ac0a46fSAndroid Build Coastguard Worker         /* so mark the field not present */
2151*3ac0a46fSAndroid Build Coastguard Worker         TIFFClrFieldBit(tif, FIELD_JPEGTABLES);
2152*3ac0a46fSAndroid Build Coastguard Worker     }
2153*3ac0a46fSAndroid Build Coastguard Worker 
2154*3ac0a46fSAndroid Build Coastguard Worker     /* Direct libjpeg output to libtiff's output buffer */
2155*3ac0a46fSAndroid Build Coastguard Worker     TIFFjpeg_data_dest(sp, tif);
2156*3ac0a46fSAndroid Build Coastguard Worker 
2157*3ac0a46fSAndroid Build Coastguard Worker     return (1);
2158*3ac0a46fSAndroid Build Coastguard Worker }
2159*3ac0a46fSAndroid Build Coastguard Worker 
2160*3ac0a46fSAndroid Build Coastguard Worker /*
2161*3ac0a46fSAndroid Build Coastguard Worker  * Set encoding state at the start of a strip or tile.
2162*3ac0a46fSAndroid Build Coastguard Worker  */
JPEGPreEncode(TIFF * tif,uint16_t s)2163*3ac0a46fSAndroid Build Coastguard Worker static int JPEGPreEncode(TIFF *tif, uint16_t s)
2164*3ac0a46fSAndroid Build Coastguard Worker {
2165*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
2166*3ac0a46fSAndroid Build Coastguard Worker     TIFFDirectory *td = &tif->tif_dir;
2167*3ac0a46fSAndroid Build Coastguard Worker     static const char module[] = "JPEGPreEncode";
2168*3ac0a46fSAndroid Build Coastguard Worker     uint32_t segment_width, segment_height;
2169*3ac0a46fSAndroid Build Coastguard Worker     int downsampled_input;
2170*3ac0a46fSAndroid Build Coastguard Worker 
2171*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != NULL);
2172*3ac0a46fSAndroid Build Coastguard Worker 
2173*3ac0a46fSAndroid Build Coastguard Worker     if (sp->cinfo.comm.is_decompressor == 1)
2174*3ac0a46fSAndroid Build Coastguard Worker     {
2175*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_setupencode(tif);
2176*3ac0a46fSAndroid Build Coastguard Worker     }
2177*3ac0a46fSAndroid Build Coastguard Worker 
2178*3ac0a46fSAndroid Build Coastguard Worker     assert(!sp->cinfo.comm.is_decompressor);
2179*3ac0a46fSAndroid Build Coastguard Worker     /*
2180*3ac0a46fSAndroid Build Coastguard Worker      * Set encoding parameters for this strip/tile.
2181*3ac0a46fSAndroid Build Coastguard Worker      */
2182*3ac0a46fSAndroid Build Coastguard Worker     if (isTiled(tif))
2183*3ac0a46fSAndroid Build Coastguard Worker     {
2184*3ac0a46fSAndroid Build Coastguard Worker         segment_width = td->td_tilewidth;
2185*3ac0a46fSAndroid Build Coastguard Worker         segment_height = td->td_tilelength;
2186*3ac0a46fSAndroid Build Coastguard Worker         sp->bytesperline = TIFFTileRowSize(tif);
2187*3ac0a46fSAndroid Build Coastguard Worker     }
2188*3ac0a46fSAndroid Build Coastguard Worker     else
2189*3ac0a46fSAndroid Build Coastguard Worker     {
2190*3ac0a46fSAndroid Build Coastguard Worker         segment_width = td->td_imagewidth;
2191*3ac0a46fSAndroid Build Coastguard Worker         segment_height = td->td_imagelength - tif->tif_row;
2192*3ac0a46fSAndroid Build Coastguard Worker         if (segment_height > td->td_rowsperstrip)
2193*3ac0a46fSAndroid Build Coastguard Worker             segment_height = td->td_rowsperstrip;
2194*3ac0a46fSAndroid Build Coastguard Worker         sp->bytesperline = TIFFScanlineSize(tif);
2195*3ac0a46fSAndroid Build Coastguard Worker     }
2196*3ac0a46fSAndroid Build Coastguard Worker     if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0)
2197*3ac0a46fSAndroid Build Coastguard Worker     {
2198*3ac0a46fSAndroid Build Coastguard Worker         /* for PC 2, scale down the strip/tile size
2199*3ac0a46fSAndroid Build Coastguard Worker          * to match a downsampled component
2200*3ac0a46fSAndroid Build Coastguard Worker          */
2201*3ac0a46fSAndroid Build Coastguard Worker         segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
2202*3ac0a46fSAndroid Build Coastguard Worker         segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
2203*3ac0a46fSAndroid Build Coastguard Worker     }
2204*3ac0a46fSAndroid Build Coastguard Worker     if (segment_width > 65535 || segment_height > 65535)
2205*3ac0a46fSAndroid Build Coastguard Worker     {
2206*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module, "Strip/tile too large for JPEG");
2207*3ac0a46fSAndroid Build Coastguard Worker         return (0);
2208*3ac0a46fSAndroid Build Coastguard Worker     }
2209*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.c.image_width = segment_width;
2210*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.c.image_height = segment_height;
2211*3ac0a46fSAndroid Build Coastguard Worker     downsampled_input = FALSE;
2212*3ac0a46fSAndroid Build Coastguard Worker     if (td->td_planarconfig == PLANARCONFIG_CONTIG)
2213*3ac0a46fSAndroid Build Coastguard Worker     {
2214*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.c.input_components = td->td_samplesperpixel;
2215*3ac0a46fSAndroid Build Coastguard Worker         if (sp->photometric == PHOTOMETRIC_YCBCR)
2216*3ac0a46fSAndroid Build Coastguard Worker         {
2217*3ac0a46fSAndroid Build Coastguard Worker             if (sp->otherSettings.jpegcolormode != JPEGCOLORMODE_RGB)
2218*3ac0a46fSAndroid Build Coastguard Worker             {
2219*3ac0a46fSAndroid Build Coastguard Worker                 if (sp->h_sampling != 1 || sp->v_sampling != 1)
2220*3ac0a46fSAndroid Build Coastguard Worker                     downsampled_input = TRUE;
2221*3ac0a46fSAndroid Build Coastguard Worker             }
2222*3ac0a46fSAndroid Build Coastguard Worker             if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr))
2223*3ac0a46fSAndroid Build Coastguard Worker                 return (0);
2224*3ac0a46fSAndroid Build Coastguard Worker             /*
2225*3ac0a46fSAndroid Build Coastguard Worker              * Set Y sampling factors;
2226*3ac0a46fSAndroid Build Coastguard Worker              * we assume jpeg_set_colorspace() set the rest to 1
2227*3ac0a46fSAndroid Build Coastguard Worker              */
2228*3ac0a46fSAndroid Build Coastguard Worker             sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling;
2229*3ac0a46fSAndroid Build Coastguard Worker             sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling;
2230*3ac0a46fSAndroid Build Coastguard Worker         }
2231*3ac0a46fSAndroid Build Coastguard Worker         else
2232*3ac0a46fSAndroid Build Coastguard Worker         {
2233*3ac0a46fSAndroid Build Coastguard Worker             if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space))
2234*3ac0a46fSAndroid Build Coastguard Worker                 return (0);
2235*3ac0a46fSAndroid Build Coastguard Worker             /* jpeg_set_colorspace set all sampling factors to 1 */
2236*3ac0a46fSAndroid Build Coastguard Worker         }
2237*3ac0a46fSAndroid Build Coastguard Worker     }
2238*3ac0a46fSAndroid Build Coastguard Worker     else
2239*3ac0a46fSAndroid Build Coastguard Worker     {
2240*3ac0a46fSAndroid Build Coastguard Worker         if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN))
2241*3ac0a46fSAndroid Build Coastguard Worker             return (0);
2242*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.c.comp_info[0].component_id = s;
2243*3ac0a46fSAndroid Build Coastguard Worker         /* jpeg_set_colorspace() set sampling factors to 1 */
2244*3ac0a46fSAndroid Build Coastguard Worker         if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0)
2245*3ac0a46fSAndroid Build Coastguard Worker         {
2246*3ac0a46fSAndroid Build Coastguard Worker             sp->cinfo.c.comp_info[0].quant_tbl_no = 1;
2247*3ac0a46fSAndroid Build Coastguard Worker             sp->cinfo.c.comp_info[0].dc_tbl_no = 1;
2248*3ac0a46fSAndroid Build Coastguard Worker             sp->cinfo.c.comp_info[0].ac_tbl_no = 1;
2249*3ac0a46fSAndroid Build Coastguard Worker         }
2250*3ac0a46fSAndroid Build Coastguard Worker     }
2251*3ac0a46fSAndroid Build Coastguard Worker     /* ensure libjpeg won't write any extraneous markers */
2252*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.c.write_JFIF_header = FALSE;
2253*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo.c.write_Adobe_marker = FALSE;
2254*3ac0a46fSAndroid Build Coastguard Worker     /* set up table handling correctly */
2255*3ac0a46fSAndroid Build Coastguard Worker     /* calling TIFFjpeg_set_quality() causes quantization tables to be flagged
2256*3ac0a46fSAndroid Build Coastguard Worker      */
2257*3ac0a46fSAndroid Build Coastguard Worker     /* as being to be emitted, which we don't want in the JPEGTABLESMODE_QUANT
2258*3ac0a46fSAndroid Build Coastguard Worker      */
2259*3ac0a46fSAndroid Build Coastguard Worker     /* mode, so we must manually suppress them. However TIFFjpeg_set_quality()
2260*3ac0a46fSAndroid Build Coastguard Worker      */
2261*3ac0a46fSAndroid Build Coastguard Worker     /* should really be called when dealing with files with directories with */
2262*3ac0a46fSAndroid Build Coastguard Worker     /* mixed qualities. see http://trac.osgeo.org/gdal/ticket/3539 */
2263*3ac0a46fSAndroid Build Coastguard Worker     if (!TIFFjpeg_set_quality(sp, sp->otherSettings.jpegquality, FALSE))
2264*3ac0a46fSAndroid Build Coastguard Worker         return (0);
2265*3ac0a46fSAndroid Build Coastguard Worker     if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_QUANT)
2266*3ac0a46fSAndroid Build Coastguard Worker     {
2267*3ac0a46fSAndroid Build Coastguard Worker         suppress_quant_table(sp, 0);
2268*3ac0a46fSAndroid Build Coastguard Worker         suppress_quant_table(sp, 1);
2269*3ac0a46fSAndroid Build Coastguard Worker     }
2270*3ac0a46fSAndroid Build Coastguard Worker     else
2271*3ac0a46fSAndroid Build Coastguard Worker     {
2272*3ac0a46fSAndroid Build Coastguard Worker         unsuppress_quant_table(sp, 0);
2273*3ac0a46fSAndroid Build Coastguard Worker         unsuppress_quant_table(sp, 1);
2274*3ac0a46fSAndroid Build Coastguard Worker     }
2275*3ac0a46fSAndroid Build Coastguard Worker     if (sp->otherSettings.jpegtablesmode & JPEGTABLESMODE_HUFF)
2276*3ac0a46fSAndroid Build Coastguard Worker     {
2277*3ac0a46fSAndroid Build Coastguard Worker         /* Explicit suppression is only needed if we did not go through the */
2278*3ac0a46fSAndroid Build Coastguard Worker         /* prepare_JPEGTables() code path, which may be the case if updating */
2279*3ac0a46fSAndroid Build Coastguard Worker         /* an existing file */
2280*3ac0a46fSAndroid Build Coastguard Worker         suppress_huff_table(sp, 0);
2281*3ac0a46fSAndroid Build Coastguard Worker         suppress_huff_table(sp, 1);
2282*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.c.optimize_coding = FALSE;
2283*3ac0a46fSAndroid Build Coastguard Worker     }
2284*3ac0a46fSAndroid Build Coastguard Worker     else
2285*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.c.optimize_coding = TRUE;
2286*3ac0a46fSAndroid Build Coastguard Worker     if (downsampled_input)
2287*3ac0a46fSAndroid Build Coastguard Worker     {
2288*3ac0a46fSAndroid Build Coastguard Worker         /* Need to use raw-data interface to libjpeg */
2289*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.c.raw_data_in = TRUE;
2290*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_encoderow = JPEGEncodeRaw;
2291*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_encodestrip = JPEGEncodeRaw;
2292*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_encodetile = JPEGEncodeRaw;
2293*3ac0a46fSAndroid Build Coastguard Worker     }
2294*3ac0a46fSAndroid Build Coastguard Worker     else
2295*3ac0a46fSAndroid Build Coastguard Worker     {
2296*3ac0a46fSAndroid Build Coastguard Worker         /* Use normal interface to libjpeg */
2297*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo.c.raw_data_in = FALSE;
2298*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_encoderow = JPEGEncode;
2299*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_encodestrip = JPEGEncode;
2300*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_encodetile = JPEGEncode;
2301*3ac0a46fSAndroid Build Coastguard Worker     }
2302*3ac0a46fSAndroid Build Coastguard Worker     /* Start JPEG compressor */
2303*3ac0a46fSAndroid Build Coastguard Worker     if (!TIFFjpeg_start_compress(sp, FALSE))
2304*3ac0a46fSAndroid Build Coastguard Worker         return (0);
2305*3ac0a46fSAndroid Build Coastguard Worker     /* Allocate downsampled-data buffers if needed */
2306*3ac0a46fSAndroid Build Coastguard Worker     if (downsampled_input)
2307*3ac0a46fSAndroid Build Coastguard Worker     {
2308*3ac0a46fSAndroid Build Coastguard Worker         if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info,
2309*3ac0a46fSAndroid Build Coastguard Worker                                        sp->cinfo.c.num_components))
2310*3ac0a46fSAndroid Build Coastguard Worker             return (0);
2311*3ac0a46fSAndroid Build Coastguard Worker     }
2312*3ac0a46fSAndroid Build Coastguard Worker     sp->scancount = 0;
2313*3ac0a46fSAndroid Build Coastguard Worker 
2314*3ac0a46fSAndroid Build Coastguard Worker     return (1);
2315*3ac0a46fSAndroid Build Coastguard Worker }
2316*3ac0a46fSAndroid Build Coastguard Worker 
2317*3ac0a46fSAndroid Build Coastguard Worker /*
2318*3ac0a46fSAndroid Build Coastguard Worker  * Encode a chunk of pixels.
2319*3ac0a46fSAndroid Build Coastguard Worker  * "Standard" case: incoming data is not downsampled.
2320*3ac0a46fSAndroid Build Coastguard Worker  */
JPEGEncode(TIFF * tif,uint8_t * buf,tmsize_t cc,uint16_t s)2321*3ac0a46fSAndroid Build Coastguard Worker static int JPEGEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
2322*3ac0a46fSAndroid Build Coastguard Worker {
2323*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
2324*3ac0a46fSAndroid Build Coastguard Worker     tmsize_t nrows;
2325*3ac0a46fSAndroid Build Coastguard Worker     TIFF_JSAMPROW bufptr[1];
2326*3ac0a46fSAndroid Build Coastguard Worker     short *line16 = NULL;
2327*3ac0a46fSAndroid Build Coastguard Worker     int line16_count = 0;
2328*3ac0a46fSAndroid Build Coastguard Worker 
2329*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
2330*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != NULL);
2331*3ac0a46fSAndroid Build Coastguard Worker     /* data is expected to be supplied in multiples of a scanline */
2332*3ac0a46fSAndroid Build Coastguard Worker     nrows = cc / sp->bytesperline;
2333*3ac0a46fSAndroid Build Coastguard Worker     if (cc % sp->bytesperline)
2334*3ac0a46fSAndroid Build Coastguard Worker         TIFFWarningExtR(tif, tif->tif_name, "fractional scanline discarded");
2335*3ac0a46fSAndroid Build Coastguard Worker 
2336*3ac0a46fSAndroid Build Coastguard Worker     /* The last strip will be limited to image size */
2337*3ac0a46fSAndroid Build Coastguard Worker     if (!isTiled(tif) && tif->tif_row + nrows > tif->tif_dir.td_imagelength)
2338*3ac0a46fSAndroid Build Coastguard Worker         nrows = tif->tif_dir.td_imagelength - tif->tif_row;
2339*3ac0a46fSAndroid Build Coastguard Worker 
2340*3ac0a46fSAndroid Build Coastguard Worker     if (sp->cinfo.c.data_precision == 12)
2341*3ac0a46fSAndroid Build Coastguard Worker     {
2342*3ac0a46fSAndroid Build Coastguard Worker         line16_count = (int)((sp->bytesperline * 2) / 3);
2343*3ac0a46fSAndroid Build Coastguard Worker         line16 = (short *)_TIFFmallocExt(tif, sizeof(short) * line16_count);
2344*3ac0a46fSAndroid Build Coastguard Worker         if (!line16)
2345*3ac0a46fSAndroid Build Coastguard Worker         {
2346*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, "JPEGEncode", "Failed to allocate memory");
2347*3ac0a46fSAndroid Build Coastguard Worker 
2348*3ac0a46fSAndroid Build Coastguard Worker             return 0;
2349*3ac0a46fSAndroid Build Coastguard Worker         }
2350*3ac0a46fSAndroid Build Coastguard Worker     }
2351*3ac0a46fSAndroid Build Coastguard Worker 
2352*3ac0a46fSAndroid Build Coastguard Worker     while (nrows-- > 0)
2353*3ac0a46fSAndroid Build Coastguard Worker     {
2354*3ac0a46fSAndroid Build Coastguard Worker 
2355*3ac0a46fSAndroid Build Coastguard Worker         if (sp->cinfo.c.data_precision == 12)
2356*3ac0a46fSAndroid Build Coastguard Worker         {
2357*3ac0a46fSAndroid Build Coastguard Worker 
2358*3ac0a46fSAndroid Build Coastguard Worker             int value_pairs = line16_count / 2;
2359*3ac0a46fSAndroid Build Coastguard Worker             int iPair;
2360*3ac0a46fSAndroid Build Coastguard Worker 
2361*3ac0a46fSAndroid Build Coastguard Worker             bufptr[0] = (TIFF_JSAMPROW)line16;
2362*3ac0a46fSAndroid Build Coastguard Worker 
2363*3ac0a46fSAndroid Build Coastguard Worker             for (iPair = 0; iPair < value_pairs; iPair++)
2364*3ac0a46fSAndroid Build Coastguard Worker             {
2365*3ac0a46fSAndroid Build Coastguard Worker                 unsigned char *in_ptr = ((unsigned char *)buf) + iPair * 3;
2366*3ac0a46fSAndroid Build Coastguard Worker                 TIFF_JSAMPLE *out_ptr = (TIFF_JSAMPLE *)(line16 + iPair * 2);
2367*3ac0a46fSAndroid Build Coastguard Worker 
2368*3ac0a46fSAndroid Build Coastguard Worker                 out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4);
2369*3ac0a46fSAndroid Build Coastguard Worker                 out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2];
2370*3ac0a46fSAndroid Build Coastguard Worker             }
2371*3ac0a46fSAndroid Build Coastguard Worker         }
2372*3ac0a46fSAndroid Build Coastguard Worker         else
2373*3ac0a46fSAndroid Build Coastguard Worker         {
2374*3ac0a46fSAndroid Build Coastguard Worker             bufptr[0] = (TIFF_JSAMPROW)buf;
2375*3ac0a46fSAndroid Build Coastguard Worker         }
2376*3ac0a46fSAndroid Build Coastguard Worker         if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1)
2377*3ac0a46fSAndroid Build Coastguard Worker             return (0);
2378*3ac0a46fSAndroid Build Coastguard Worker         if (nrows > 0)
2379*3ac0a46fSAndroid Build Coastguard Worker             tif->tif_row++;
2380*3ac0a46fSAndroid Build Coastguard Worker         buf += sp->bytesperline;
2381*3ac0a46fSAndroid Build Coastguard Worker     }
2382*3ac0a46fSAndroid Build Coastguard Worker 
2383*3ac0a46fSAndroid Build Coastguard Worker     if (sp->cinfo.c.data_precision == 12)
2384*3ac0a46fSAndroid Build Coastguard Worker     {
2385*3ac0a46fSAndroid Build Coastguard Worker         _TIFFfreeExt(tif, line16);
2386*3ac0a46fSAndroid Build Coastguard Worker     }
2387*3ac0a46fSAndroid Build Coastguard Worker 
2388*3ac0a46fSAndroid Build Coastguard Worker     return (1);
2389*3ac0a46fSAndroid Build Coastguard Worker }
2390*3ac0a46fSAndroid Build Coastguard Worker 
2391*3ac0a46fSAndroid Build Coastguard Worker /*
2392*3ac0a46fSAndroid Build Coastguard Worker  * Encode a chunk of pixels.
2393*3ac0a46fSAndroid Build Coastguard Worker  * Incoming data is expected to be downsampled per sampling factors.
2394*3ac0a46fSAndroid Build Coastguard Worker  */
JPEGEncodeRaw(TIFF * tif,uint8_t * buf,tmsize_t cc,uint16_t s)2395*3ac0a46fSAndroid Build Coastguard Worker static int JPEGEncodeRaw(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
2396*3ac0a46fSAndroid Build Coastguard Worker {
2397*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
2398*3ac0a46fSAndroid Build Coastguard Worker     TIFF_JSAMPLE *inptr;
2399*3ac0a46fSAndroid Build Coastguard Worker     TIFF_JSAMPLE *outptr;
2400*3ac0a46fSAndroid Build Coastguard Worker     tmsize_t nrows;
2401*3ac0a46fSAndroid Build Coastguard Worker     JDIMENSION clumps_per_line, nclump;
2402*3ac0a46fSAndroid Build Coastguard Worker     int clumpoffset, ci, xpos, ypos;
2403*3ac0a46fSAndroid Build Coastguard Worker     jpeg_component_info *compptr;
2404*3ac0a46fSAndroid Build Coastguard Worker     int samples_per_clump = sp->samplesperclump;
2405*3ac0a46fSAndroid Build Coastguard Worker     tmsize_t bytesperclumpline;
2406*3ac0a46fSAndroid Build Coastguard Worker 
2407*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
2408*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != NULL);
2409*3ac0a46fSAndroid Build Coastguard Worker     /* data is expected to be supplied in multiples of a clumpline */
2410*3ac0a46fSAndroid Build Coastguard Worker     /* a clumpline is equivalent to v_sampling desubsampled scanlines */
2411*3ac0a46fSAndroid Build Coastguard Worker     /* TODO: the following calculation of bytesperclumpline, should substitute
2412*3ac0a46fSAndroid Build Coastguard Worker      * calculation of sp->bytesperline, except that it is per v_sampling lines
2413*3ac0a46fSAndroid Build Coastguard Worker      */
2414*3ac0a46fSAndroid Build Coastguard Worker     bytesperclumpline =
2415*3ac0a46fSAndroid Build Coastguard Worker         ((((tmsize_t)sp->cinfo.c.image_width + sp->h_sampling - 1) /
2416*3ac0a46fSAndroid Build Coastguard Worker           sp->h_sampling) *
2417*3ac0a46fSAndroid Build Coastguard Worker              ((tmsize_t)sp->h_sampling * sp->v_sampling + 2) *
2418*3ac0a46fSAndroid Build Coastguard Worker              sp->cinfo.c.data_precision +
2419*3ac0a46fSAndroid Build Coastguard Worker          7) /
2420*3ac0a46fSAndroid Build Coastguard Worker         8;
2421*3ac0a46fSAndroid Build Coastguard Worker 
2422*3ac0a46fSAndroid Build Coastguard Worker     nrows = (cc / bytesperclumpline) * sp->v_sampling;
2423*3ac0a46fSAndroid Build Coastguard Worker     if (cc % bytesperclumpline)
2424*3ac0a46fSAndroid Build Coastguard Worker         TIFFWarningExtR(tif, tif->tif_name, "fractional scanline discarded");
2425*3ac0a46fSAndroid Build Coastguard Worker 
2426*3ac0a46fSAndroid Build Coastguard Worker     /* Cb,Cr both have sampling factors 1, so this is correct */
2427*3ac0a46fSAndroid Build Coastguard Worker     clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width;
2428*3ac0a46fSAndroid Build Coastguard Worker 
2429*3ac0a46fSAndroid Build Coastguard Worker     while (nrows > 0)
2430*3ac0a46fSAndroid Build Coastguard Worker     {
2431*3ac0a46fSAndroid Build Coastguard Worker         /*
2432*3ac0a46fSAndroid Build Coastguard Worker          * Fastest way to separate the data is to make one pass
2433*3ac0a46fSAndroid Build Coastguard Worker          * over the scanline for each row of each component.
2434*3ac0a46fSAndroid Build Coastguard Worker          */
2435*3ac0a46fSAndroid Build Coastguard Worker         clumpoffset = 0; /* first sample in clump */
2436*3ac0a46fSAndroid Build Coastguard Worker         for (ci = 0, compptr = sp->cinfo.c.comp_info;
2437*3ac0a46fSAndroid Build Coastguard Worker              ci < sp->cinfo.c.num_components; ci++, compptr++)
2438*3ac0a46fSAndroid Build Coastguard Worker         {
2439*3ac0a46fSAndroid Build Coastguard Worker             int hsamp = compptr->h_samp_factor;
2440*3ac0a46fSAndroid Build Coastguard Worker             int vsamp = compptr->v_samp_factor;
2441*3ac0a46fSAndroid Build Coastguard Worker             int padding = (int)(compptr->width_in_blocks * DCTSIZE -
2442*3ac0a46fSAndroid Build Coastguard Worker                                 clumps_per_line * hsamp);
2443*3ac0a46fSAndroid Build Coastguard Worker             for (ypos = 0; ypos < vsamp; ypos++)
2444*3ac0a46fSAndroid Build Coastguard Worker             {
2445*3ac0a46fSAndroid Build Coastguard Worker                 inptr = ((TIFF_JSAMPLE *)buf) + clumpoffset;
2446*3ac0a46fSAndroid Build Coastguard Worker                 outptr = sp->ds_buffer[ci][sp->scancount * vsamp + ypos];
2447*3ac0a46fSAndroid Build Coastguard Worker                 if (hsamp == 1)
2448*3ac0a46fSAndroid Build Coastguard Worker                 {
2449*3ac0a46fSAndroid Build Coastguard Worker                     /* fast path for at least Cb and Cr */
2450*3ac0a46fSAndroid Build Coastguard Worker                     for (nclump = clumps_per_line; nclump-- > 0;)
2451*3ac0a46fSAndroid Build Coastguard Worker                     {
2452*3ac0a46fSAndroid Build Coastguard Worker                         *outptr++ = inptr[0];
2453*3ac0a46fSAndroid Build Coastguard Worker                         inptr += samples_per_clump;
2454*3ac0a46fSAndroid Build Coastguard Worker                     }
2455*3ac0a46fSAndroid Build Coastguard Worker                 }
2456*3ac0a46fSAndroid Build Coastguard Worker                 else
2457*3ac0a46fSAndroid Build Coastguard Worker                 {
2458*3ac0a46fSAndroid Build Coastguard Worker                     /* general case */
2459*3ac0a46fSAndroid Build Coastguard Worker                     for (nclump = clumps_per_line; nclump-- > 0;)
2460*3ac0a46fSAndroid Build Coastguard Worker                     {
2461*3ac0a46fSAndroid Build Coastguard Worker                         for (xpos = 0; xpos < hsamp; xpos++)
2462*3ac0a46fSAndroid Build Coastguard Worker                             *outptr++ = inptr[xpos];
2463*3ac0a46fSAndroid Build Coastguard Worker                         inptr += samples_per_clump;
2464*3ac0a46fSAndroid Build Coastguard Worker                     }
2465*3ac0a46fSAndroid Build Coastguard Worker                 }
2466*3ac0a46fSAndroid Build Coastguard Worker                 /* pad each scanline as needed */
2467*3ac0a46fSAndroid Build Coastguard Worker                 for (xpos = 0; xpos < padding; xpos++)
2468*3ac0a46fSAndroid Build Coastguard Worker                 {
2469*3ac0a46fSAndroid Build Coastguard Worker                     *outptr = outptr[-1];
2470*3ac0a46fSAndroid Build Coastguard Worker                     outptr++;
2471*3ac0a46fSAndroid Build Coastguard Worker                 }
2472*3ac0a46fSAndroid Build Coastguard Worker                 clumpoffset += hsamp;
2473*3ac0a46fSAndroid Build Coastguard Worker             }
2474*3ac0a46fSAndroid Build Coastguard Worker         }
2475*3ac0a46fSAndroid Build Coastguard Worker         sp->scancount++;
2476*3ac0a46fSAndroid Build Coastguard Worker         if (sp->scancount >= DCTSIZE)
2477*3ac0a46fSAndroid Build Coastguard Worker         {
2478*3ac0a46fSAndroid Build Coastguard Worker             int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
2479*3ac0a46fSAndroid Build Coastguard Worker             if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
2480*3ac0a46fSAndroid Build Coastguard Worker                 return (0);
2481*3ac0a46fSAndroid Build Coastguard Worker             sp->scancount = 0;
2482*3ac0a46fSAndroid Build Coastguard Worker         }
2483*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_row += sp->v_sampling;
2484*3ac0a46fSAndroid Build Coastguard Worker         buf += bytesperclumpline;
2485*3ac0a46fSAndroid Build Coastguard Worker         nrows -= sp->v_sampling;
2486*3ac0a46fSAndroid Build Coastguard Worker     }
2487*3ac0a46fSAndroid Build Coastguard Worker     return (1);
2488*3ac0a46fSAndroid Build Coastguard Worker }
2489*3ac0a46fSAndroid Build Coastguard Worker 
2490*3ac0a46fSAndroid Build Coastguard Worker /*
2491*3ac0a46fSAndroid Build Coastguard Worker  * Finish up at the end of a strip or tile.
2492*3ac0a46fSAndroid Build Coastguard Worker  */
JPEGPostEncode(TIFF * tif)2493*3ac0a46fSAndroid Build Coastguard Worker static int JPEGPostEncode(TIFF *tif)
2494*3ac0a46fSAndroid Build Coastguard Worker {
2495*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
2496*3ac0a46fSAndroid Build Coastguard Worker 
2497*3ac0a46fSAndroid Build Coastguard Worker     if (sp->scancount > 0)
2498*3ac0a46fSAndroid Build Coastguard Worker     {
2499*3ac0a46fSAndroid Build Coastguard Worker         /*
2500*3ac0a46fSAndroid Build Coastguard Worker          * Need to emit a partial bufferload of downsampled data.
2501*3ac0a46fSAndroid Build Coastguard Worker          * Pad the data vertically.
2502*3ac0a46fSAndroid Build Coastguard Worker          */
2503*3ac0a46fSAndroid Build Coastguard Worker         int ci, ypos, n;
2504*3ac0a46fSAndroid Build Coastguard Worker         jpeg_component_info *compptr;
2505*3ac0a46fSAndroid Build Coastguard Worker 
2506*3ac0a46fSAndroid Build Coastguard Worker         for (ci = 0, compptr = sp->cinfo.c.comp_info;
2507*3ac0a46fSAndroid Build Coastguard Worker              ci < sp->cinfo.c.num_components; ci++, compptr++)
2508*3ac0a46fSAndroid Build Coastguard Worker         {
2509*3ac0a46fSAndroid Build Coastguard Worker             int vsamp = compptr->v_samp_factor;
2510*3ac0a46fSAndroid Build Coastguard Worker             tmsize_t row_width =
2511*3ac0a46fSAndroid Build Coastguard Worker                 compptr->width_in_blocks * DCTSIZE * sizeof(JSAMPLE);
2512*3ac0a46fSAndroid Build Coastguard Worker             for (ypos = sp->scancount * vsamp; ypos < DCTSIZE * vsamp; ypos++)
2513*3ac0a46fSAndroid Build Coastguard Worker             {
2514*3ac0a46fSAndroid Build Coastguard Worker                 _TIFFmemcpy((void *)sp->ds_buffer[ci][ypos],
2515*3ac0a46fSAndroid Build Coastguard Worker                             (void *)sp->ds_buffer[ci][ypos - 1], row_width);
2516*3ac0a46fSAndroid Build Coastguard Worker             }
2517*3ac0a46fSAndroid Build Coastguard Worker         }
2518*3ac0a46fSAndroid Build Coastguard Worker         n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
2519*3ac0a46fSAndroid Build Coastguard Worker         if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
2520*3ac0a46fSAndroid Build Coastguard Worker             return (0);
2521*3ac0a46fSAndroid Build Coastguard Worker     }
2522*3ac0a46fSAndroid Build Coastguard Worker 
2523*3ac0a46fSAndroid Build Coastguard Worker     return (TIFFjpeg_finish_compress(JState(tif)));
2524*3ac0a46fSAndroid Build Coastguard Worker }
2525*3ac0a46fSAndroid Build Coastguard Worker 
JPEGCleanup(TIFF * tif)2526*3ac0a46fSAndroid Build Coastguard Worker static void JPEGCleanup(TIFF *tif)
2527*3ac0a46fSAndroid Build Coastguard Worker {
2528*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
2529*3ac0a46fSAndroid Build Coastguard Worker 
2530*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != 0);
2531*3ac0a46fSAndroid Build Coastguard Worker 
2532*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_tagmethods.vgetfield = sp->otherSettings.vgetparent;
2533*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_tagmethods.vsetfield = sp->otherSettings.vsetparent;
2534*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_tagmethods.printdir = sp->otherSettings.printdir;
2535*3ac0a46fSAndroid Build Coastguard Worker     if (sp->cinfo_initialized)
2536*3ac0a46fSAndroid Build Coastguard Worker         TIFFjpeg_destroy(sp);         /* release libjpeg resources */
2537*3ac0a46fSAndroid Build Coastguard Worker     if (sp->otherSettings.jpegtables) /* tag value */
2538*3ac0a46fSAndroid Build Coastguard Worker         _TIFFfreeExt(tif, sp->otherSettings.jpegtables);
2539*3ac0a46fSAndroid Build Coastguard Worker     _TIFFfreeExt(tif, tif->tif_data); /* release local state */
2540*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_data = NULL;
2541*3ac0a46fSAndroid Build Coastguard Worker 
2542*3ac0a46fSAndroid Build Coastguard Worker     _TIFFSetDefaultCompressionState(tif);
2543*3ac0a46fSAndroid Build Coastguard Worker }
2544*3ac0a46fSAndroid Build Coastguard Worker 
JPEGResetUpsampled(TIFF * tif)2545*3ac0a46fSAndroid Build Coastguard Worker static void JPEGResetUpsampled(TIFF *tif)
2546*3ac0a46fSAndroid Build Coastguard Worker {
2547*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
2548*3ac0a46fSAndroid Build Coastguard Worker     TIFFDirectory *td = &tif->tif_dir;
2549*3ac0a46fSAndroid Build Coastguard Worker 
2550*3ac0a46fSAndroid Build Coastguard Worker     /*
2551*3ac0a46fSAndroid Build Coastguard Worker      * Mark whether returned data is up-sampled or not so TIFFStripSize
2552*3ac0a46fSAndroid Build Coastguard Worker      * and TIFFTileSize return values that reflect the true amount of
2553*3ac0a46fSAndroid Build Coastguard Worker      * data.
2554*3ac0a46fSAndroid Build Coastguard Worker      */
2555*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_flags &= ~TIFF_UPSAMPLED;
2556*3ac0a46fSAndroid Build Coastguard Worker     if (td->td_planarconfig == PLANARCONFIG_CONTIG)
2557*3ac0a46fSAndroid Build Coastguard Worker     {
2558*3ac0a46fSAndroid Build Coastguard Worker         if (td->td_photometric == PHOTOMETRIC_YCBCR &&
2559*3ac0a46fSAndroid Build Coastguard Worker             sp->otherSettings.jpegcolormode == JPEGCOLORMODE_RGB)
2560*3ac0a46fSAndroid Build Coastguard Worker         {
2561*3ac0a46fSAndroid Build Coastguard Worker             tif->tif_flags |= TIFF_UPSAMPLED;
2562*3ac0a46fSAndroid Build Coastguard Worker         }
2563*3ac0a46fSAndroid Build Coastguard Worker         else
2564*3ac0a46fSAndroid Build Coastguard Worker         {
2565*3ac0a46fSAndroid Build Coastguard Worker #ifdef notdef
2566*3ac0a46fSAndroid Build Coastguard Worker             if (td->td_ycbcrsubsampling[0] != 1 ||
2567*3ac0a46fSAndroid Build Coastguard Worker                 td->td_ycbcrsubsampling[1] != 1)
2568*3ac0a46fSAndroid Build Coastguard Worker                 ; /* XXX what about up-sampling? */
2569*3ac0a46fSAndroid Build Coastguard Worker #endif
2570*3ac0a46fSAndroid Build Coastguard Worker         }
2571*3ac0a46fSAndroid Build Coastguard Worker     }
2572*3ac0a46fSAndroid Build Coastguard Worker 
2573*3ac0a46fSAndroid Build Coastguard Worker     /*
2574*3ac0a46fSAndroid Build Coastguard Worker      * Must recalculate cached tile size in case sampling state changed.
2575*3ac0a46fSAndroid Build Coastguard Worker      * Should we really be doing this now if image size isn't set?
2576*3ac0a46fSAndroid Build Coastguard Worker      */
2577*3ac0a46fSAndroid Build Coastguard Worker     if (tif->tif_tilesize > 0)
2578*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
2579*3ac0a46fSAndroid Build Coastguard Worker     if (tif->tif_scanlinesize > 0)
2580*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_scanlinesize = TIFFScanlineSize(tif);
2581*3ac0a46fSAndroid Build Coastguard Worker }
2582*3ac0a46fSAndroid Build Coastguard Worker 
JPEGVSetField(TIFF * tif,uint32_t tag,va_list ap)2583*3ac0a46fSAndroid Build Coastguard Worker static int JPEGVSetField(TIFF *tif, uint32_t tag, va_list ap)
2584*3ac0a46fSAndroid Build Coastguard Worker {
2585*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
2586*3ac0a46fSAndroid Build Coastguard Worker     const TIFFField *fip;
2587*3ac0a46fSAndroid Build Coastguard Worker     uint32_t v32;
2588*3ac0a46fSAndroid Build Coastguard Worker 
2589*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != NULL);
2590*3ac0a46fSAndroid Build Coastguard Worker 
2591*3ac0a46fSAndroid Build Coastguard Worker     switch (tag)
2592*3ac0a46fSAndroid Build Coastguard Worker     {
2593*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_JPEGTABLES:
2594*3ac0a46fSAndroid Build Coastguard Worker             v32 = (uint32_t)va_arg(ap, uint32_t);
2595*3ac0a46fSAndroid Build Coastguard Worker             if (v32 == 0)
2596*3ac0a46fSAndroid Build Coastguard Worker             {
2597*3ac0a46fSAndroid Build Coastguard Worker                 /* XXX */
2598*3ac0a46fSAndroid Build Coastguard Worker                 return (0);
2599*3ac0a46fSAndroid Build Coastguard Worker             }
2600*3ac0a46fSAndroid Build Coastguard Worker             _TIFFsetByteArrayExt(tif, &sp->otherSettings.jpegtables,
2601*3ac0a46fSAndroid Build Coastguard Worker                                  va_arg(ap, void *), v32);
2602*3ac0a46fSAndroid Build Coastguard Worker             sp->otherSettings.jpegtables_length = v32;
2603*3ac0a46fSAndroid Build Coastguard Worker             TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
2604*3ac0a46fSAndroid Build Coastguard Worker             break;
2605*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_JPEGQUALITY:
2606*3ac0a46fSAndroid Build Coastguard Worker             sp->otherSettings.jpegquality = (int)va_arg(ap, int);
2607*3ac0a46fSAndroid Build Coastguard Worker             return (1); /* pseudo tag */
2608*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_JPEGCOLORMODE:
2609*3ac0a46fSAndroid Build Coastguard Worker             sp->otherSettings.jpegcolormode = (int)va_arg(ap, int);
2610*3ac0a46fSAndroid Build Coastguard Worker             JPEGResetUpsampled(tif);
2611*3ac0a46fSAndroid Build Coastguard Worker             return (1); /* pseudo tag */
2612*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_PHOTOMETRIC:
2613*3ac0a46fSAndroid Build Coastguard Worker         {
2614*3ac0a46fSAndroid Build Coastguard Worker             int ret_value = (*sp->otherSettings.vsetparent)(tif, tag, ap);
2615*3ac0a46fSAndroid Build Coastguard Worker             JPEGResetUpsampled(tif);
2616*3ac0a46fSAndroid Build Coastguard Worker             return ret_value;
2617*3ac0a46fSAndroid Build Coastguard Worker         }
2618*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_JPEGTABLESMODE:
2619*3ac0a46fSAndroid Build Coastguard Worker             sp->otherSettings.jpegtablesmode = (int)va_arg(ap, int);
2620*3ac0a46fSAndroid Build Coastguard Worker             return (1); /* pseudo tag */
2621*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_YCBCRSUBSAMPLING:
2622*3ac0a46fSAndroid Build Coastguard Worker             /* mark the fact that we have a real ycbcrsubsampling! */
2623*3ac0a46fSAndroid Build Coastguard Worker             sp->otherSettings.ycbcrsampling_fetched = 1;
2624*3ac0a46fSAndroid Build Coastguard Worker             /* should we be recomputing upsampling info here? */
2625*3ac0a46fSAndroid Build Coastguard Worker             return (*sp->otherSettings.vsetparent)(tif, tag, ap);
2626*3ac0a46fSAndroid Build Coastguard Worker         default:
2627*3ac0a46fSAndroid Build Coastguard Worker             return (*sp->otherSettings.vsetparent)(tif, tag, ap);
2628*3ac0a46fSAndroid Build Coastguard Worker     }
2629*3ac0a46fSAndroid Build Coastguard Worker 
2630*3ac0a46fSAndroid Build Coastguard Worker     if ((fip = TIFFFieldWithTag(tif, tag)) != NULL)
2631*3ac0a46fSAndroid Build Coastguard Worker     {
2632*3ac0a46fSAndroid Build Coastguard Worker         TIFFSetFieldBit(tif, fip->field_bit);
2633*3ac0a46fSAndroid Build Coastguard Worker     }
2634*3ac0a46fSAndroid Build Coastguard Worker     else
2635*3ac0a46fSAndroid Build Coastguard Worker     {
2636*3ac0a46fSAndroid Build Coastguard Worker         return (0);
2637*3ac0a46fSAndroid Build Coastguard Worker     }
2638*3ac0a46fSAndroid Build Coastguard Worker 
2639*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_flags |= TIFF_DIRTYDIRECT;
2640*3ac0a46fSAndroid Build Coastguard Worker     return (1);
2641*3ac0a46fSAndroid Build Coastguard Worker }
2642*3ac0a46fSAndroid Build Coastguard Worker 
JPEGVGetField(TIFF * tif,uint32_t tag,va_list ap)2643*3ac0a46fSAndroid Build Coastguard Worker static int JPEGVGetField(TIFF *tif, uint32_t tag, va_list ap)
2644*3ac0a46fSAndroid Build Coastguard Worker {
2645*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
2646*3ac0a46fSAndroid Build Coastguard Worker 
2647*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != NULL);
2648*3ac0a46fSAndroid Build Coastguard Worker 
2649*3ac0a46fSAndroid Build Coastguard Worker     switch (tag)
2650*3ac0a46fSAndroid Build Coastguard Worker     {
2651*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_JPEGTABLES:
2652*3ac0a46fSAndroid Build Coastguard Worker             *va_arg(ap, uint32_t *) = sp->otherSettings.jpegtables_length;
2653*3ac0a46fSAndroid Build Coastguard Worker             *va_arg(ap, const void **) = sp->otherSettings.jpegtables;
2654*3ac0a46fSAndroid Build Coastguard Worker             break;
2655*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_JPEGQUALITY:
2656*3ac0a46fSAndroid Build Coastguard Worker             *va_arg(ap, int *) = sp->otherSettings.jpegquality;
2657*3ac0a46fSAndroid Build Coastguard Worker             break;
2658*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_JPEGCOLORMODE:
2659*3ac0a46fSAndroid Build Coastguard Worker             *va_arg(ap, int *) = sp->otherSettings.jpegcolormode;
2660*3ac0a46fSAndroid Build Coastguard Worker             break;
2661*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_JPEGTABLESMODE:
2662*3ac0a46fSAndroid Build Coastguard Worker             *va_arg(ap, int *) = sp->otherSettings.jpegtablesmode;
2663*3ac0a46fSAndroid Build Coastguard Worker             break;
2664*3ac0a46fSAndroid Build Coastguard Worker         default:
2665*3ac0a46fSAndroid Build Coastguard Worker             return (*sp->otherSettings.vgetparent)(tif, tag, ap);
2666*3ac0a46fSAndroid Build Coastguard Worker     }
2667*3ac0a46fSAndroid Build Coastguard Worker     return (1);
2668*3ac0a46fSAndroid Build Coastguard Worker }
2669*3ac0a46fSAndroid Build Coastguard Worker 
JPEGPrintDir(TIFF * tif,FILE * fd,long flags)2670*3ac0a46fSAndroid Build Coastguard Worker static void JPEGPrintDir(TIFF *tif, FILE *fd, long flags)
2671*3ac0a46fSAndroid Build Coastguard Worker {
2672*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
2673*3ac0a46fSAndroid Build Coastguard Worker 
2674*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != NULL);
2675*3ac0a46fSAndroid Build Coastguard Worker     (void)flags;
2676*3ac0a46fSAndroid Build Coastguard Worker 
2677*3ac0a46fSAndroid Build Coastguard Worker     if (sp != NULL)
2678*3ac0a46fSAndroid Build Coastguard Worker     {
2679*3ac0a46fSAndroid Build Coastguard Worker         if (TIFFFieldSet(tif, FIELD_JPEGTABLES))
2680*3ac0a46fSAndroid Build Coastguard Worker             fprintf(fd, "  JPEG Tables: (%" PRIu32 " bytes)\n",
2681*3ac0a46fSAndroid Build Coastguard Worker                     sp->otherSettings.jpegtables_length);
2682*3ac0a46fSAndroid Build Coastguard Worker         if (sp->otherSettings.printdir)
2683*3ac0a46fSAndroid Build Coastguard Worker             (*sp->otherSettings.printdir)(tif, fd, flags);
2684*3ac0a46fSAndroid Build Coastguard Worker     }
2685*3ac0a46fSAndroid Build Coastguard Worker }
2686*3ac0a46fSAndroid Build Coastguard Worker 
JPEGDefaultStripSize(TIFF * tif,uint32_t s)2687*3ac0a46fSAndroid Build Coastguard Worker static uint32_t JPEGDefaultStripSize(TIFF *tif, uint32_t s)
2688*3ac0a46fSAndroid Build Coastguard Worker {
2689*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
2690*3ac0a46fSAndroid Build Coastguard Worker     TIFFDirectory *td = &tif->tif_dir;
2691*3ac0a46fSAndroid Build Coastguard Worker 
2692*3ac0a46fSAndroid Build Coastguard Worker     s = (*sp->otherSettings.defsparent)(tif, s);
2693*3ac0a46fSAndroid Build Coastguard Worker     if (s < td->td_imagelength)
2694*3ac0a46fSAndroid Build Coastguard Worker         s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE);
2695*3ac0a46fSAndroid Build Coastguard Worker     return (s);
2696*3ac0a46fSAndroid Build Coastguard Worker }
2697*3ac0a46fSAndroid Build Coastguard Worker 
JPEGDefaultTileSize(TIFF * tif,uint32_t * tw,uint32_t * th)2698*3ac0a46fSAndroid Build Coastguard Worker static void JPEGDefaultTileSize(TIFF *tif, uint32_t *tw, uint32_t *th)
2699*3ac0a46fSAndroid Build Coastguard Worker {
2700*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
2701*3ac0a46fSAndroid Build Coastguard Worker     TIFFDirectory *td = &tif->tif_dir;
2702*3ac0a46fSAndroid Build Coastguard Worker 
2703*3ac0a46fSAndroid Build Coastguard Worker     (*sp->otherSettings.deftparent)(tif, tw, th);
2704*3ac0a46fSAndroid Build Coastguard Worker     *tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE);
2705*3ac0a46fSAndroid Build Coastguard Worker     *th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE);
2706*3ac0a46fSAndroid Build Coastguard Worker }
2707*3ac0a46fSAndroid Build Coastguard Worker 
2708*3ac0a46fSAndroid Build Coastguard Worker /*
2709*3ac0a46fSAndroid Build Coastguard Worker  * The JPEG library initialized used to be done in TIFFInitJPEG(), but
2710*3ac0a46fSAndroid Build Coastguard Worker  * now that we allow a TIFF file to be opened in update mode it is necessary
2711*3ac0a46fSAndroid Build Coastguard Worker  * to have some way of deciding whether compression or decompression is
2712*3ac0a46fSAndroid Build Coastguard Worker  * desired other than looking at tif->tif_mode.  We accomplish this by
2713*3ac0a46fSAndroid Build Coastguard Worker  * examining {TILE/STRIP}BYTECOUNTS to see if there is a non-zero entry.
2714*3ac0a46fSAndroid Build Coastguard Worker  * If so, we assume decompression is desired.
2715*3ac0a46fSAndroid Build Coastguard Worker  *
2716*3ac0a46fSAndroid Build Coastguard Worker  * This is tricky, because TIFFInitJPEG() is called while the directory is
2717*3ac0a46fSAndroid Build Coastguard Worker  * being read, and generally speaking the BYTECOUNTS tag won't have been read
2718*3ac0a46fSAndroid Build Coastguard Worker  * at that point.  So we try to defer jpeg library initialization till we
2719*3ac0a46fSAndroid Build Coastguard Worker  * do have that tag ... basically any access that might require the compressor
2720*3ac0a46fSAndroid Build Coastguard Worker  * or decompressor that occurs after the reading of the directory.
2721*3ac0a46fSAndroid Build Coastguard Worker  *
2722*3ac0a46fSAndroid Build Coastguard Worker  * In an ideal world compressors or decompressors would be setup
2723*3ac0a46fSAndroid Build Coastguard Worker  * at the point where a single tile or strip was accessed (for read or write)
2724*3ac0a46fSAndroid Build Coastguard Worker  * so that stuff like update of missing tiles, or replacement of tiles could
2725*3ac0a46fSAndroid Build Coastguard Worker  * be done. However, we aren't trying to crack that nut just yet ...
2726*3ac0a46fSAndroid Build Coastguard Worker  *
2727*3ac0a46fSAndroid Build Coastguard Worker  * NFW, Feb 3rd, 2003.
2728*3ac0a46fSAndroid Build Coastguard Worker  */
2729*3ac0a46fSAndroid Build Coastguard Worker 
JPEGInitializeLibJPEG(TIFF * tif,int decompress)2730*3ac0a46fSAndroid Build Coastguard Worker static int JPEGInitializeLibJPEG(TIFF *tif, int decompress)
2731*3ac0a46fSAndroid Build Coastguard Worker {
2732*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp = JState(tif);
2733*3ac0a46fSAndroid Build Coastguard Worker 
2734*3ac0a46fSAndroid Build Coastguard Worker     if (sp->cinfo_initialized)
2735*3ac0a46fSAndroid Build Coastguard Worker     {
2736*3ac0a46fSAndroid Build Coastguard Worker         if (!decompress && sp->cinfo.comm.is_decompressor)
2737*3ac0a46fSAndroid Build Coastguard Worker             TIFFjpeg_destroy(sp);
2738*3ac0a46fSAndroid Build Coastguard Worker         else if (decompress && !sp->cinfo.comm.is_decompressor)
2739*3ac0a46fSAndroid Build Coastguard Worker             TIFFjpeg_destroy(sp);
2740*3ac0a46fSAndroid Build Coastguard Worker         else
2741*3ac0a46fSAndroid Build Coastguard Worker             return 1;
2742*3ac0a46fSAndroid Build Coastguard Worker 
2743*3ac0a46fSAndroid Build Coastguard Worker         sp->cinfo_initialized = 0;
2744*3ac0a46fSAndroid Build Coastguard Worker     }
2745*3ac0a46fSAndroid Build Coastguard Worker 
2746*3ac0a46fSAndroid Build Coastguard Worker     /*
2747*3ac0a46fSAndroid Build Coastguard Worker      * Initialize libjpeg.
2748*3ac0a46fSAndroid Build Coastguard Worker      */
2749*3ac0a46fSAndroid Build Coastguard Worker     if (decompress)
2750*3ac0a46fSAndroid Build Coastguard Worker     {
2751*3ac0a46fSAndroid Build Coastguard Worker         if (!TIFFjpeg_create_decompress(sp))
2752*3ac0a46fSAndroid Build Coastguard Worker             return (0);
2753*3ac0a46fSAndroid Build Coastguard Worker     }
2754*3ac0a46fSAndroid Build Coastguard Worker     else
2755*3ac0a46fSAndroid Build Coastguard Worker     {
2756*3ac0a46fSAndroid Build Coastguard Worker         if (!TIFFjpeg_create_compress(sp))
2757*3ac0a46fSAndroid Build Coastguard Worker             return (0);
2758*3ac0a46fSAndroid Build Coastguard Worker #ifndef TIFF_JPEG_MAX_MEMORY_TO_USE
2759*3ac0a46fSAndroid Build Coastguard Worker #define TIFF_JPEG_MAX_MEMORY_TO_USE (10 * 1024 * 1024)
2760*3ac0a46fSAndroid Build Coastguard Worker #endif
2761*3ac0a46fSAndroid Build Coastguard Worker         /* libjpeg turbo 1.5.2 honours max_memory_to_use, but has no backing */
2762*3ac0a46fSAndroid Build Coastguard Worker         /* store implementation, so better not set max_memory_to_use ourselves.
2763*3ac0a46fSAndroid Build Coastguard Worker          */
2764*3ac0a46fSAndroid Build Coastguard Worker         /* See https://github.com/libjpeg-turbo/libjpeg-turbo/issues/162 */
2765*3ac0a46fSAndroid Build Coastguard Worker         if (sp->cinfo.c.mem->max_memory_to_use > 0)
2766*3ac0a46fSAndroid Build Coastguard Worker         {
2767*3ac0a46fSAndroid Build Coastguard Worker             /* This is to address bug related in ticket GDAL #1795. */
2768*3ac0a46fSAndroid Build Coastguard Worker             if (getenv("JPEGMEM") == NULL)
2769*3ac0a46fSAndroid Build Coastguard Worker             {
2770*3ac0a46fSAndroid Build Coastguard Worker                 /* Increase the max memory usable. This helps when creating
2771*3ac0a46fSAndroid Build Coastguard Worker                  * files */
2772*3ac0a46fSAndroid Build Coastguard Worker                 /* with "big" tile, without using libjpeg temporary files. */
2773*3ac0a46fSAndroid Build Coastguard Worker                 /* For example a 512x512 tile with 3 bands */
2774*3ac0a46fSAndroid Build Coastguard Worker                 /* requires 1.5 MB which is above libjpeg 1MB default */
2775*3ac0a46fSAndroid Build Coastguard Worker                 if (sp->cinfo.c.mem->max_memory_to_use <
2776*3ac0a46fSAndroid Build Coastguard Worker                     TIFF_JPEG_MAX_MEMORY_TO_USE)
2777*3ac0a46fSAndroid Build Coastguard Worker                     sp->cinfo.c.mem->max_memory_to_use =
2778*3ac0a46fSAndroid Build Coastguard Worker                         TIFF_JPEG_MAX_MEMORY_TO_USE;
2779*3ac0a46fSAndroid Build Coastguard Worker             }
2780*3ac0a46fSAndroid Build Coastguard Worker         }
2781*3ac0a46fSAndroid Build Coastguard Worker     }
2782*3ac0a46fSAndroid Build Coastguard Worker 
2783*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo_initialized = TRUE;
2784*3ac0a46fSAndroid Build Coastguard Worker 
2785*3ac0a46fSAndroid Build Coastguard Worker     return 1;
2786*3ac0a46fSAndroid Build Coastguard Worker }
2787*3ac0a46fSAndroid Build Coastguard Worker 
2788*3ac0a46fSAndroid Build Coastguard Worker /* Common to tif_jpeg.c and tif_jpeg_12.c */
TIFFInitJPEGCommon(TIFF * tif)2789*3ac0a46fSAndroid Build Coastguard Worker static void TIFFInitJPEGCommon(TIFF *tif)
2790*3ac0a46fSAndroid Build Coastguard Worker {
2791*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp;
2792*3ac0a46fSAndroid Build Coastguard Worker 
2793*3ac0a46fSAndroid Build Coastguard Worker     sp = JState(tif);
2794*3ac0a46fSAndroid Build Coastguard Worker     sp->tif = tif; /* back link */
2795*3ac0a46fSAndroid Build Coastguard Worker 
2796*3ac0a46fSAndroid Build Coastguard Worker     /* Default values for codec-specific fields */
2797*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.jpegtables = NULL;
2798*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.jpegtables_length = 0;
2799*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.jpegquality = 75; /* Default IJG quality */
2800*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.jpegcolormode = JPEGCOLORMODE_RAW;
2801*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.jpegtablesmode =
2802*3ac0a46fSAndroid Build Coastguard Worker         JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF;
2803*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.ycbcrsampling_fetched = 0;
2804*3ac0a46fSAndroid Build Coastguard Worker 
2805*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */
2806*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */
2807*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_tagmethods.printdir = JPEGPrintDir;   /* hook for codec tags */
2808*3ac0a46fSAndroid Build Coastguard Worker 
2809*3ac0a46fSAndroid Build Coastguard Worker     /*
2810*3ac0a46fSAndroid Build Coastguard Worker      * Install codec methods.
2811*3ac0a46fSAndroid Build Coastguard Worker      */
2812*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_fixuptags = JPEGFixupTags;
2813*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_setupdecode = JPEGSetupDecode;
2814*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_predecode = JPEGPreDecode;
2815*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_decoderow = JPEGDecode;
2816*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_decodestrip = JPEGDecode;
2817*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_decodetile = JPEGDecode;
2818*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_setupencode = JPEGSetupEncode;
2819*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_preencode = JPEGPreEncode;
2820*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_postencode = JPEGPostEncode;
2821*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_encoderow = JPEGEncode;
2822*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_encodestrip = JPEGEncode;
2823*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_encodetile = JPEGEncode;
2824*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_cleanup = JPEGCleanup;
2825*3ac0a46fSAndroid Build Coastguard Worker 
2826*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_defstripsize = JPEGDefaultStripSize;
2827*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_deftilesize = JPEGDefaultTileSize;
2828*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */
2829*3ac0a46fSAndroid Build Coastguard Worker     sp->cinfo_initialized = FALSE;
2830*3ac0a46fSAndroid Build Coastguard Worker }
2831*3ac0a46fSAndroid Build Coastguard Worker 
TIFFInitJPEG(TIFF * tif,int scheme)2832*3ac0a46fSAndroid Build Coastguard Worker int TIFFInitJPEG(TIFF *tif, int scheme)
2833*3ac0a46fSAndroid Build Coastguard Worker {
2834*3ac0a46fSAndroid Build Coastguard Worker     JPEGState *sp;
2835*3ac0a46fSAndroid Build Coastguard Worker 
2836*3ac0a46fSAndroid Build Coastguard Worker     (void)scheme;
2837*3ac0a46fSAndroid Build Coastguard Worker     assert(scheme == COMPRESSION_JPEG);
2838*3ac0a46fSAndroid Build Coastguard Worker 
2839*3ac0a46fSAndroid Build Coastguard Worker     /*
2840*3ac0a46fSAndroid Build Coastguard Worker      * Merge codec-specific tag information.
2841*3ac0a46fSAndroid Build Coastguard Worker      */
2842*3ac0a46fSAndroid Build Coastguard Worker     if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields)))
2843*3ac0a46fSAndroid Build Coastguard Worker     {
2844*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, "TIFFInitJPEG",
2845*3ac0a46fSAndroid Build Coastguard Worker                       "Merging JPEG codec-specific tags failed");
2846*3ac0a46fSAndroid Build Coastguard Worker         return 0;
2847*3ac0a46fSAndroid Build Coastguard Worker     }
2848*3ac0a46fSAndroid Build Coastguard Worker 
2849*3ac0a46fSAndroid Build Coastguard Worker     /*
2850*3ac0a46fSAndroid Build Coastguard Worker      * Allocate state block so tag methods have storage to record values.
2851*3ac0a46fSAndroid Build Coastguard Worker      */
2852*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(JPEGState));
2853*3ac0a46fSAndroid Build Coastguard Worker 
2854*3ac0a46fSAndroid Build Coastguard Worker     if (tif->tif_data == NULL)
2855*3ac0a46fSAndroid Build Coastguard Worker     {
2856*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, "TIFFInitJPEG", "No space for JPEG state block");
2857*3ac0a46fSAndroid Build Coastguard Worker         return 0;
2858*3ac0a46fSAndroid Build Coastguard Worker     }
2859*3ac0a46fSAndroid Build Coastguard Worker     _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState));
2860*3ac0a46fSAndroid Build Coastguard Worker 
2861*3ac0a46fSAndroid Build Coastguard Worker     sp = JState(tif);
2862*3ac0a46fSAndroid Build Coastguard Worker     /*
2863*3ac0a46fSAndroid Build Coastguard Worker      * Override parent get/set field methods.
2864*3ac0a46fSAndroid Build Coastguard Worker      */
2865*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.vgetparent = tif->tif_tagmethods.vgetfield;
2866*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.vsetparent = tif->tif_tagmethods.vsetfield;
2867*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.printdir = tif->tif_tagmethods.printdir;
2868*3ac0a46fSAndroid Build Coastguard Worker 
2869*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.defsparent = tif->tif_defstripsize;
2870*3ac0a46fSAndroid Build Coastguard Worker     sp->otherSettings.deftparent = tif->tif_deftilesize;
2871*3ac0a46fSAndroid Build Coastguard Worker 
2872*3ac0a46fSAndroid Build Coastguard Worker     TIFFInitJPEGCommon(tif);
2873*3ac0a46fSAndroid Build Coastguard Worker 
2874*3ac0a46fSAndroid Build Coastguard Worker     /*
2875*3ac0a46fSAndroid Build Coastguard Worker     ** Create a JPEGTables field if no directory has yet been created.
2876*3ac0a46fSAndroid Build Coastguard Worker     ** We do this just to ensure that sufficient space is reserved for
2877*3ac0a46fSAndroid Build Coastguard Worker     ** the JPEGTables field.  It will be properly created the right
2878*3ac0a46fSAndroid Build Coastguard Worker     ** size later.
2879*3ac0a46fSAndroid Build Coastguard Worker     */
2880*3ac0a46fSAndroid Build Coastguard Worker     if (tif->tif_diroff == 0)
2881*3ac0a46fSAndroid Build Coastguard Worker     {
2882*3ac0a46fSAndroid Build Coastguard Worker #define SIZE_OF_JPEGTABLES 2000
2883*3ac0a46fSAndroid Build Coastguard Worker         /*
2884*3ac0a46fSAndroid Build Coastguard Worker         The following line assumes incorrectly that all JPEG-in-TIFF files will
2885*3ac0a46fSAndroid Build Coastguard Worker         have a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags
2886*3ac0a46fSAndroid Build Coastguard Worker         to be written when the JPEG data is placed with TIFFWriteRawStrip.  The
2887*3ac0a46fSAndroid Build Coastguard Worker         field bit should be set, anyway, later when actual JPEGTABLES header is
2888*3ac0a46fSAndroid Build Coastguard Worker         generated, so removing it here hopefully is harmless.
2889*3ac0a46fSAndroid Build Coastguard Worker         TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
2890*3ac0a46fSAndroid Build Coastguard Worker         */
2891*3ac0a46fSAndroid Build Coastguard Worker         sp->otherSettings.jpegtables_length = SIZE_OF_JPEGTABLES;
2892*3ac0a46fSAndroid Build Coastguard Worker         sp->otherSettings.jpegtables =
2893*3ac0a46fSAndroid Build Coastguard Worker             (void *)_TIFFmallocExt(tif, sp->otherSettings.jpegtables_length);
2894*3ac0a46fSAndroid Build Coastguard Worker         if (sp->otherSettings.jpegtables)
2895*3ac0a46fSAndroid Build Coastguard Worker         {
2896*3ac0a46fSAndroid Build Coastguard Worker             _TIFFmemset(sp->otherSettings.jpegtables, 0, SIZE_OF_JPEGTABLES);
2897*3ac0a46fSAndroid Build Coastguard Worker         }
2898*3ac0a46fSAndroid Build Coastguard Worker         else
2899*3ac0a46fSAndroid Build Coastguard Worker         {
2900*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, "TIFFInitJPEG",
2901*3ac0a46fSAndroid Build Coastguard Worker                           "Failed to allocate memory for JPEG tables");
2902*3ac0a46fSAndroid Build Coastguard Worker             return 0;
2903*3ac0a46fSAndroid Build Coastguard Worker         }
2904*3ac0a46fSAndroid Build Coastguard Worker #undef SIZE_OF_JPEGTABLES
2905*3ac0a46fSAndroid Build Coastguard Worker     }
2906*3ac0a46fSAndroid Build Coastguard Worker     return 1;
2907*3ac0a46fSAndroid Build Coastguard Worker }
2908*3ac0a46fSAndroid Build Coastguard Worker #endif /* JPEG_SUPPORT */
2909