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