1*3ac0a46fSAndroid Build Coastguard Worker /*
2*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 1991-1997 Sam Leffler
3*3ac0a46fSAndroid Build Coastguard Worker * Copyright (c) 1991-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 /*
26*3ac0a46fSAndroid Build Coastguard Worker * TIFF Library.
27*3ac0a46fSAndroid Build Coastguard Worker *
28*3ac0a46fSAndroid Build Coastguard Worker * Auxiliary Support Routines.
29*3ac0a46fSAndroid Build Coastguard Worker */
30*3ac0a46fSAndroid Build Coastguard Worker #include "tif_predict.h"
31*3ac0a46fSAndroid Build Coastguard Worker #include "tiffiop.h"
32*3ac0a46fSAndroid Build Coastguard Worker #include <float.h>
33*3ac0a46fSAndroid Build Coastguard Worker #include <math.h>
34*3ac0a46fSAndroid Build Coastguard Worker
_TIFFMultiply32(TIFF * tif,uint32_t first,uint32_t second,const char * where)35*3ac0a46fSAndroid Build Coastguard Worker uint32_t _TIFFMultiply32(TIFF *tif, uint32_t first, uint32_t second,
36*3ac0a46fSAndroid Build Coastguard Worker const char *where)
37*3ac0a46fSAndroid Build Coastguard Worker {
38*3ac0a46fSAndroid Build Coastguard Worker if (second && first > UINT32_MAX / second)
39*3ac0a46fSAndroid Build Coastguard Worker {
40*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
41*3ac0a46fSAndroid Build Coastguard Worker return 0;
42*3ac0a46fSAndroid Build Coastguard Worker }
43*3ac0a46fSAndroid Build Coastguard Worker
44*3ac0a46fSAndroid Build Coastguard Worker return first * second;
45*3ac0a46fSAndroid Build Coastguard Worker }
46*3ac0a46fSAndroid Build Coastguard Worker
_TIFFMultiply64(TIFF * tif,uint64_t first,uint64_t second,const char * where)47*3ac0a46fSAndroid Build Coastguard Worker uint64_t _TIFFMultiply64(TIFF *tif, uint64_t first, uint64_t second,
48*3ac0a46fSAndroid Build Coastguard Worker const char *where)
49*3ac0a46fSAndroid Build Coastguard Worker {
50*3ac0a46fSAndroid Build Coastguard Worker if (second && first > UINT64_MAX / second)
51*3ac0a46fSAndroid Build Coastguard Worker {
52*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
53*3ac0a46fSAndroid Build Coastguard Worker return 0;
54*3ac0a46fSAndroid Build Coastguard Worker }
55*3ac0a46fSAndroid Build Coastguard Worker
56*3ac0a46fSAndroid Build Coastguard Worker return first * second;
57*3ac0a46fSAndroid Build Coastguard Worker }
58*3ac0a46fSAndroid Build Coastguard Worker
_TIFFMultiplySSize(TIFF * tif,tmsize_t first,tmsize_t second,const char * where)59*3ac0a46fSAndroid Build Coastguard Worker tmsize_t _TIFFMultiplySSize(TIFF *tif, tmsize_t first, tmsize_t second,
60*3ac0a46fSAndroid Build Coastguard Worker const char *where)
61*3ac0a46fSAndroid Build Coastguard Worker {
62*3ac0a46fSAndroid Build Coastguard Worker if (first <= 0 || second <= 0)
63*3ac0a46fSAndroid Build Coastguard Worker {
64*3ac0a46fSAndroid Build Coastguard Worker if (tif != NULL && where != NULL)
65*3ac0a46fSAndroid Build Coastguard Worker {
66*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, where,
67*3ac0a46fSAndroid Build Coastguard Worker "Invalid argument to _TIFFMultiplySSize() in %s",
68*3ac0a46fSAndroid Build Coastguard Worker where);
69*3ac0a46fSAndroid Build Coastguard Worker }
70*3ac0a46fSAndroid Build Coastguard Worker return 0;
71*3ac0a46fSAndroid Build Coastguard Worker }
72*3ac0a46fSAndroid Build Coastguard Worker
73*3ac0a46fSAndroid Build Coastguard Worker if (first > TIFF_TMSIZE_T_MAX / second)
74*3ac0a46fSAndroid Build Coastguard Worker {
75*3ac0a46fSAndroid Build Coastguard Worker if (tif != NULL && where != NULL)
76*3ac0a46fSAndroid Build Coastguard Worker {
77*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, where, "Integer overflow in %s", where);
78*3ac0a46fSAndroid Build Coastguard Worker }
79*3ac0a46fSAndroid Build Coastguard Worker return 0;
80*3ac0a46fSAndroid Build Coastguard Worker }
81*3ac0a46fSAndroid Build Coastguard Worker return first * second;
82*3ac0a46fSAndroid Build Coastguard Worker }
83*3ac0a46fSAndroid Build Coastguard Worker
_TIFFCastUInt64ToSSize(TIFF * tif,uint64_t val,const char * module)84*3ac0a46fSAndroid Build Coastguard Worker tmsize_t _TIFFCastUInt64ToSSize(TIFF *tif, uint64_t val, const char *module)
85*3ac0a46fSAndroid Build Coastguard Worker {
86*3ac0a46fSAndroid Build Coastguard Worker if (val > (uint64_t)TIFF_TMSIZE_T_MAX)
87*3ac0a46fSAndroid Build Coastguard Worker {
88*3ac0a46fSAndroid Build Coastguard Worker if (tif != NULL && module != NULL)
89*3ac0a46fSAndroid Build Coastguard Worker {
90*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, module, "Integer overflow");
91*3ac0a46fSAndroid Build Coastguard Worker }
92*3ac0a46fSAndroid Build Coastguard Worker return 0;
93*3ac0a46fSAndroid Build Coastguard Worker }
94*3ac0a46fSAndroid Build Coastguard Worker return (tmsize_t)val;
95*3ac0a46fSAndroid Build Coastguard Worker }
96*3ac0a46fSAndroid Build Coastguard Worker
_TIFFCheckRealloc(TIFF * tif,void * buffer,tmsize_t nmemb,tmsize_t elem_size,const char * what)97*3ac0a46fSAndroid Build Coastguard Worker void *_TIFFCheckRealloc(TIFF *tif, void *buffer, tmsize_t nmemb,
98*3ac0a46fSAndroid Build Coastguard Worker tmsize_t elem_size, const char *what)
99*3ac0a46fSAndroid Build Coastguard Worker {
100*3ac0a46fSAndroid Build Coastguard Worker void *cp = NULL;
101*3ac0a46fSAndroid Build Coastguard Worker tmsize_t count = _TIFFMultiplySSize(tif, nmemb, elem_size, NULL);
102*3ac0a46fSAndroid Build Coastguard Worker /*
103*3ac0a46fSAndroid Build Coastguard Worker * Check for integer overflow.
104*3ac0a46fSAndroid Build Coastguard Worker */
105*3ac0a46fSAndroid Build Coastguard Worker if (count != 0)
106*3ac0a46fSAndroid Build Coastguard Worker {
107*3ac0a46fSAndroid Build Coastguard Worker cp = _TIFFreallocExt(tif, buffer, count);
108*3ac0a46fSAndroid Build Coastguard Worker }
109*3ac0a46fSAndroid Build Coastguard Worker
110*3ac0a46fSAndroid Build Coastguard Worker if (cp == NULL)
111*3ac0a46fSAndroid Build Coastguard Worker {
112*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, tif->tif_name,
113*3ac0a46fSAndroid Build Coastguard Worker "Failed to allocate memory for %s "
114*3ac0a46fSAndroid Build Coastguard Worker "(%" TIFF_SSIZE_FORMAT " elements of %" TIFF_SSIZE_FORMAT
115*3ac0a46fSAndroid Build Coastguard Worker " bytes each)",
116*3ac0a46fSAndroid Build Coastguard Worker what, nmemb, elem_size);
117*3ac0a46fSAndroid Build Coastguard Worker }
118*3ac0a46fSAndroid Build Coastguard Worker
119*3ac0a46fSAndroid Build Coastguard Worker return cp;
120*3ac0a46fSAndroid Build Coastguard Worker }
121*3ac0a46fSAndroid Build Coastguard Worker
_TIFFCheckMalloc(TIFF * tif,tmsize_t nmemb,tmsize_t elem_size,const char * what)122*3ac0a46fSAndroid Build Coastguard Worker void *_TIFFCheckMalloc(TIFF *tif, tmsize_t nmemb, tmsize_t elem_size,
123*3ac0a46fSAndroid Build Coastguard Worker const char *what)
124*3ac0a46fSAndroid Build Coastguard Worker {
125*3ac0a46fSAndroid Build Coastguard Worker return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what);
126*3ac0a46fSAndroid Build Coastguard Worker }
127*3ac0a46fSAndroid Build Coastguard Worker
TIFFDefaultTransferFunction(TIFF * tif,TIFFDirectory * td)128*3ac0a46fSAndroid Build Coastguard Worker static int TIFFDefaultTransferFunction(TIFF *tif, TIFFDirectory *td)
129*3ac0a46fSAndroid Build Coastguard Worker {
130*3ac0a46fSAndroid Build Coastguard Worker uint16_t **tf = td->td_transferfunction;
131*3ac0a46fSAndroid Build Coastguard Worker tmsize_t i, n, nbytes;
132*3ac0a46fSAndroid Build Coastguard Worker
133*3ac0a46fSAndroid Build Coastguard Worker tf[0] = tf[1] = tf[2] = 0;
134*3ac0a46fSAndroid Build Coastguard Worker if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2)
135*3ac0a46fSAndroid Build Coastguard Worker return 0;
136*3ac0a46fSAndroid Build Coastguard Worker
137*3ac0a46fSAndroid Build Coastguard Worker n = ((tmsize_t)1) << td->td_bitspersample;
138*3ac0a46fSAndroid Build Coastguard Worker nbytes = n * sizeof(uint16_t);
139*3ac0a46fSAndroid Build Coastguard Worker tf[0] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
140*3ac0a46fSAndroid Build Coastguard Worker if (tf[0] == NULL)
141*3ac0a46fSAndroid Build Coastguard Worker return 0;
142*3ac0a46fSAndroid Build Coastguard Worker tf[0][0] = 0;
143*3ac0a46fSAndroid Build Coastguard Worker for (i = 1; i < n; i++)
144*3ac0a46fSAndroid Build Coastguard Worker {
145*3ac0a46fSAndroid Build Coastguard Worker double t = (double)i / ((double)n - 1.);
146*3ac0a46fSAndroid Build Coastguard Worker tf[0][i] = (uint16_t)floor(65535. * pow(t, 2.2) + .5);
147*3ac0a46fSAndroid Build Coastguard Worker }
148*3ac0a46fSAndroid Build Coastguard Worker
149*3ac0a46fSAndroid Build Coastguard Worker if (td->td_samplesperpixel - td->td_extrasamples > 1)
150*3ac0a46fSAndroid Build Coastguard Worker {
151*3ac0a46fSAndroid Build Coastguard Worker tf[1] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
152*3ac0a46fSAndroid Build Coastguard Worker if (tf[1] == NULL)
153*3ac0a46fSAndroid Build Coastguard Worker goto bad;
154*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(tf[1], tf[0], nbytes);
155*3ac0a46fSAndroid Build Coastguard Worker tf[2] = (uint16_t *)_TIFFmallocExt(tif, nbytes);
156*3ac0a46fSAndroid Build Coastguard Worker if (tf[2] == NULL)
157*3ac0a46fSAndroid Build Coastguard Worker goto bad;
158*3ac0a46fSAndroid Build Coastguard Worker _TIFFmemcpy(tf[2], tf[0], nbytes);
159*3ac0a46fSAndroid Build Coastguard Worker }
160*3ac0a46fSAndroid Build Coastguard Worker return 1;
161*3ac0a46fSAndroid Build Coastguard Worker
162*3ac0a46fSAndroid Build Coastguard Worker bad:
163*3ac0a46fSAndroid Build Coastguard Worker if (tf[0])
164*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, tf[0]);
165*3ac0a46fSAndroid Build Coastguard Worker if (tf[1])
166*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, tf[1]);
167*3ac0a46fSAndroid Build Coastguard Worker if (tf[2])
168*3ac0a46fSAndroid Build Coastguard Worker _TIFFfreeExt(tif, tf[2]);
169*3ac0a46fSAndroid Build Coastguard Worker tf[0] = tf[1] = tf[2] = 0;
170*3ac0a46fSAndroid Build Coastguard Worker return 0;
171*3ac0a46fSAndroid Build Coastguard Worker }
172*3ac0a46fSAndroid Build Coastguard Worker
TIFFDefaultRefBlackWhite(TIFF * tif,TIFFDirectory * td)173*3ac0a46fSAndroid Build Coastguard Worker static int TIFFDefaultRefBlackWhite(TIFF *tif, TIFFDirectory *td)
174*3ac0a46fSAndroid Build Coastguard Worker {
175*3ac0a46fSAndroid Build Coastguard Worker int i;
176*3ac0a46fSAndroid Build Coastguard Worker
177*3ac0a46fSAndroid Build Coastguard Worker td->td_refblackwhite = (float *)_TIFFmallocExt(tif, 6 * sizeof(float));
178*3ac0a46fSAndroid Build Coastguard Worker if (td->td_refblackwhite == NULL)
179*3ac0a46fSAndroid Build Coastguard Worker return 0;
180*3ac0a46fSAndroid Build Coastguard Worker if (td->td_photometric == PHOTOMETRIC_YCBCR)
181*3ac0a46fSAndroid Build Coastguard Worker {
182*3ac0a46fSAndroid Build Coastguard Worker /*
183*3ac0a46fSAndroid Build Coastguard Worker * YCbCr (Class Y) images must have the ReferenceBlackWhite
184*3ac0a46fSAndroid Build Coastguard Worker * tag set. Fix the broken images, which lacks that tag.
185*3ac0a46fSAndroid Build Coastguard Worker */
186*3ac0a46fSAndroid Build Coastguard Worker td->td_refblackwhite[0] = 0.0F;
187*3ac0a46fSAndroid Build Coastguard Worker td->td_refblackwhite[1] = td->td_refblackwhite[3] =
188*3ac0a46fSAndroid Build Coastguard Worker td->td_refblackwhite[5] = 255.0F;
189*3ac0a46fSAndroid Build Coastguard Worker td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F;
190*3ac0a46fSAndroid Build Coastguard Worker }
191*3ac0a46fSAndroid Build Coastguard Worker else
192*3ac0a46fSAndroid Build Coastguard Worker {
193*3ac0a46fSAndroid Build Coastguard Worker /*
194*3ac0a46fSAndroid Build Coastguard Worker * Assume RGB (Class R)
195*3ac0a46fSAndroid Build Coastguard Worker */
196*3ac0a46fSAndroid Build Coastguard Worker for (i = 0; i < 3; i++)
197*3ac0a46fSAndroid Build Coastguard Worker {
198*3ac0a46fSAndroid Build Coastguard Worker td->td_refblackwhite[2 * i + 0] = 0;
199*3ac0a46fSAndroid Build Coastguard Worker td->td_refblackwhite[2 * i + 1] =
200*3ac0a46fSAndroid Build Coastguard Worker (float)((1L << td->td_bitspersample) - 1L);
201*3ac0a46fSAndroid Build Coastguard Worker }
202*3ac0a46fSAndroid Build Coastguard Worker }
203*3ac0a46fSAndroid Build Coastguard Worker return 1;
204*3ac0a46fSAndroid Build Coastguard Worker }
205*3ac0a46fSAndroid Build Coastguard Worker
206*3ac0a46fSAndroid Build Coastguard Worker /*
207*3ac0a46fSAndroid Build Coastguard Worker * Like TIFFGetField, but return any default
208*3ac0a46fSAndroid Build Coastguard Worker * value if the tag is not present in the directory.
209*3ac0a46fSAndroid Build Coastguard Worker *
210*3ac0a46fSAndroid Build Coastguard Worker * NB: We use the value in the directory, rather than
211*3ac0a46fSAndroid Build Coastguard Worker * explicit values so that defaults exist only one
212*3ac0a46fSAndroid Build Coastguard Worker * place in the library -- in TIFFDefaultDirectory.
213*3ac0a46fSAndroid Build Coastguard Worker */
TIFFVGetFieldDefaulted(TIFF * tif,uint32_t tag,va_list ap)214*3ac0a46fSAndroid Build Coastguard Worker int TIFFVGetFieldDefaulted(TIFF *tif, uint32_t tag, va_list ap)
215*3ac0a46fSAndroid Build Coastguard Worker {
216*3ac0a46fSAndroid Build Coastguard Worker TIFFDirectory *td = &tif->tif_dir;
217*3ac0a46fSAndroid Build Coastguard Worker
218*3ac0a46fSAndroid Build Coastguard Worker if (TIFFVGetField(tif, tag, ap))
219*3ac0a46fSAndroid Build Coastguard Worker return (1);
220*3ac0a46fSAndroid Build Coastguard Worker switch (tag)
221*3ac0a46fSAndroid Build Coastguard Worker {
222*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_SUBFILETYPE:
223*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint32_t *) = td->td_subfiletype;
224*3ac0a46fSAndroid Build Coastguard Worker return (1);
225*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_BITSPERSAMPLE:
226*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_bitspersample;
227*3ac0a46fSAndroid Build Coastguard Worker return (1);
228*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_THRESHHOLDING:
229*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_threshholding;
230*3ac0a46fSAndroid Build Coastguard Worker return (1);
231*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_FILLORDER:
232*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_fillorder;
233*3ac0a46fSAndroid Build Coastguard Worker return (1);
234*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_ORIENTATION:
235*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_orientation;
236*3ac0a46fSAndroid Build Coastguard Worker return (1);
237*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_SAMPLESPERPIXEL:
238*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_samplesperpixel;
239*3ac0a46fSAndroid Build Coastguard Worker return (1);
240*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_ROWSPERSTRIP:
241*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint32_t *) = td->td_rowsperstrip;
242*3ac0a46fSAndroid Build Coastguard Worker return (1);
243*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_MINSAMPLEVALUE:
244*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_minsamplevalue;
245*3ac0a46fSAndroid Build Coastguard Worker return (1);
246*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_MAXSAMPLEVALUE:
247*3ac0a46fSAndroid Build Coastguard Worker {
248*3ac0a46fSAndroid Build Coastguard Worker uint16_t maxsamplevalue;
249*3ac0a46fSAndroid Build Coastguard Worker /* td_bitspersample=1 is always set in TIFFDefaultDirectory().
250*3ac0a46fSAndroid Build Coastguard Worker * Therefore, td_maxsamplevalue has to be re-calculated in
251*3ac0a46fSAndroid Build Coastguard Worker * TIFFGetFieldDefaulted(). */
252*3ac0a46fSAndroid Build Coastguard Worker if (td->td_bitspersample > 0)
253*3ac0a46fSAndroid Build Coastguard Worker {
254*3ac0a46fSAndroid Build Coastguard Worker /* This shift operation into a uint16_t limits the value to
255*3ac0a46fSAndroid Build Coastguard Worker * 65535 even if td_bitspersamle is > 16 */
256*3ac0a46fSAndroid Build Coastguard Worker if (td->td_bitspersample <= 16)
257*3ac0a46fSAndroid Build Coastguard Worker {
258*3ac0a46fSAndroid Build Coastguard Worker maxsamplevalue = (1 << td->td_bitspersample) -
259*3ac0a46fSAndroid Build Coastguard Worker 1; /* 2**(BitsPerSample) - 1 */
260*3ac0a46fSAndroid Build Coastguard Worker }
261*3ac0a46fSAndroid Build Coastguard Worker else
262*3ac0a46fSAndroid Build Coastguard Worker {
263*3ac0a46fSAndroid Build Coastguard Worker maxsamplevalue = 65535;
264*3ac0a46fSAndroid Build Coastguard Worker }
265*3ac0a46fSAndroid Build Coastguard Worker }
266*3ac0a46fSAndroid Build Coastguard Worker else
267*3ac0a46fSAndroid Build Coastguard Worker {
268*3ac0a46fSAndroid Build Coastguard Worker maxsamplevalue = 0;
269*3ac0a46fSAndroid Build Coastguard Worker }
270*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = maxsamplevalue;
271*3ac0a46fSAndroid Build Coastguard Worker return (1);
272*3ac0a46fSAndroid Build Coastguard Worker }
273*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_PLANARCONFIG:
274*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_planarconfig;
275*3ac0a46fSAndroid Build Coastguard Worker return (1);
276*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_RESOLUTIONUNIT:
277*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_resolutionunit;
278*3ac0a46fSAndroid Build Coastguard Worker return (1);
279*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_PREDICTOR:
280*3ac0a46fSAndroid Build Coastguard Worker {
281*3ac0a46fSAndroid Build Coastguard Worker TIFFPredictorState *sp = (TIFFPredictorState *)tif->tif_data;
282*3ac0a46fSAndroid Build Coastguard Worker if (sp == NULL)
283*3ac0a46fSAndroid Build Coastguard Worker {
284*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(
285*3ac0a46fSAndroid Build Coastguard Worker tif, tif->tif_name,
286*3ac0a46fSAndroid Build Coastguard Worker "Cannot get \"Predictor\" tag as plugin is not configured");
287*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = 0;
288*3ac0a46fSAndroid Build Coastguard Worker return 0;
289*3ac0a46fSAndroid Build Coastguard Worker }
290*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = (uint16_t)sp->predictor;
291*3ac0a46fSAndroid Build Coastguard Worker return 1;
292*3ac0a46fSAndroid Build Coastguard Worker }
293*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_DOTRANGE:
294*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = 0;
295*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = (1 << td->td_bitspersample) - 1;
296*3ac0a46fSAndroid Build Coastguard Worker return (1);
297*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_INKSET:
298*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = INKSET_CMYK;
299*3ac0a46fSAndroid Build Coastguard Worker return 1;
300*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_NUMBEROFINKS:
301*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = 4;
302*3ac0a46fSAndroid Build Coastguard Worker return (1);
303*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_EXTRASAMPLES:
304*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_extrasamples;
305*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, const uint16_t **) = td->td_sampleinfo;
306*3ac0a46fSAndroid Build Coastguard Worker return (1);
307*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_MATTEING:
308*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) =
309*3ac0a46fSAndroid Build Coastguard Worker (td->td_extrasamples == 1 &&
310*3ac0a46fSAndroid Build Coastguard Worker td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
311*3ac0a46fSAndroid Build Coastguard Worker return (1);
312*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_TILEDEPTH:
313*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint32_t *) = td->td_tiledepth;
314*3ac0a46fSAndroid Build Coastguard Worker return (1);
315*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_DATATYPE:
316*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_sampleformat - 1;
317*3ac0a46fSAndroid Build Coastguard Worker return (1);
318*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_SAMPLEFORMAT:
319*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_sampleformat;
320*3ac0a46fSAndroid Build Coastguard Worker return (1);
321*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_IMAGEDEPTH:
322*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint32_t *) = td->td_imagedepth;
323*3ac0a46fSAndroid Build Coastguard Worker return (1);
324*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_YCBCRCOEFFICIENTS:
325*3ac0a46fSAndroid Build Coastguard Worker {
326*3ac0a46fSAndroid Build Coastguard Worker /* defaults are from CCIR Recommendation 601-1 */
327*3ac0a46fSAndroid Build Coastguard Worker static const float ycbcrcoeffs[] = {0.299f, 0.587f, 0.114f};
328*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, const float **) = ycbcrcoeffs;
329*3ac0a46fSAndroid Build Coastguard Worker return 1;
330*3ac0a46fSAndroid Build Coastguard Worker }
331*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_YCBCRSUBSAMPLING:
332*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0];
333*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1];
334*3ac0a46fSAndroid Build Coastguard Worker return (1);
335*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_YCBCRPOSITIONING:
336*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning;
337*3ac0a46fSAndroid Build Coastguard Worker return (1);
338*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_WHITEPOINT:
339*3ac0a46fSAndroid Build Coastguard Worker {
340*3ac0a46fSAndroid Build Coastguard Worker /* TIFF 6.0 specification tells that it is no default
341*3ac0a46fSAndroid Build Coastguard Worker value for the WhitePoint, but AdobePhotoshop TIFF
342*3ac0a46fSAndroid Build Coastguard Worker Technical Note tells that it should be CIE D50. */
343*3ac0a46fSAndroid Build Coastguard Worker static const float whitepoint[] = {
344*3ac0a46fSAndroid Build Coastguard Worker D50_X0 / (D50_X0 + D50_Y0 + D50_Z0),
345*3ac0a46fSAndroid Build Coastguard Worker D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0)};
346*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, const float **) = whitepoint;
347*3ac0a46fSAndroid Build Coastguard Worker return 1;
348*3ac0a46fSAndroid Build Coastguard Worker }
349*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_TRANSFERFUNCTION:
350*3ac0a46fSAndroid Build Coastguard Worker if (!td->td_transferfunction[0] &&
351*3ac0a46fSAndroid Build Coastguard Worker !TIFFDefaultTransferFunction(tif, td))
352*3ac0a46fSAndroid Build Coastguard Worker {
353*3ac0a46fSAndroid Build Coastguard Worker TIFFErrorExtR(tif, tif->tif_name,
354*3ac0a46fSAndroid Build Coastguard Worker "No space for \"TransferFunction\" tag");
355*3ac0a46fSAndroid Build Coastguard Worker return (0);
356*3ac0a46fSAndroid Build Coastguard Worker }
357*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, const uint16_t **) = td->td_transferfunction[0];
358*3ac0a46fSAndroid Build Coastguard Worker if (td->td_samplesperpixel - td->td_extrasamples > 1)
359*3ac0a46fSAndroid Build Coastguard Worker {
360*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, const uint16_t **) = td->td_transferfunction[1];
361*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, const uint16_t **) = td->td_transferfunction[2];
362*3ac0a46fSAndroid Build Coastguard Worker }
363*3ac0a46fSAndroid Build Coastguard Worker return (1);
364*3ac0a46fSAndroid Build Coastguard Worker case TIFFTAG_REFERENCEBLACKWHITE:
365*3ac0a46fSAndroid Build Coastguard Worker if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(tif, td))
366*3ac0a46fSAndroid Build Coastguard Worker return (0);
367*3ac0a46fSAndroid Build Coastguard Worker *va_arg(ap, const float **) = td->td_refblackwhite;
368*3ac0a46fSAndroid Build Coastguard Worker return (1);
369*3ac0a46fSAndroid Build Coastguard Worker }
370*3ac0a46fSAndroid Build Coastguard Worker return 0;
371*3ac0a46fSAndroid Build Coastguard Worker }
372*3ac0a46fSAndroid Build Coastguard Worker
373*3ac0a46fSAndroid Build Coastguard Worker /*
374*3ac0a46fSAndroid Build Coastguard Worker * Like TIFFGetField, but return any default
375*3ac0a46fSAndroid Build Coastguard Worker * value if the tag is not present in the directory.
376*3ac0a46fSAndroid Build Coastguard Worker */
TIFFGetFieldDefaulted(TIFF * tif,uint32_t tag,...)377*3ac0a46fSAndroid Build Coastguard Worker int TIFFGetFieldDefaulted(TIFF *tif, uint32_t tag, ...)
378*3ac0a46fSAndroid Build Coastguard Worker {
379*3ac0a46fSAndroid Build Coastguard Worker int ok;
380*3ac0a46fSAndroid Build Coastguard Worker va_list ap;
381*3ac0a46fSAndroid Build Coastguard Worker
382*3ac0a46fSAndroid Build Coastguard Worker va_start(ap, tag);
383*3ac0a46fSAndroid Build Coastguard Worker ok = TIFFVGetFieldDefaulted(tif, tag, ap);
384*3ac0a46fSAndroid Build Coastguard Worker va_end(ap);
385*3ac0a46fSAndroid Build Coastguard Worker return (ok);
386*3ac0a46fSAndroid Build Coastguard Worker }
387*3ac0a46fSAndroid Build Coastguard Worker
388*3ac0a46fSAndroid Build Coastguard Worker struct _Int64Parts
389*3ac0a46fSAndroid Build Coastguard Worker {
390*3ac0a46fSAndroid Build Coastguard Worker int32_t low, high;
391*3ac0a46fSAndroid Build Coastguard Worker };
392*3ac0a46fSAndroid Build Coastguard Worker
393*3ac0a46fSAndroid Build Coastguard Worker typedef union
394*3ac0a46fSAndroid Build Coastguard Worker {
395*3ac0a46fSAndroid Build Coastguard Worker struct _Int64Parts part;
396*3ac0a46fSAndroid Build Coastguard Worker int64_t value;
397*3ac0a46fSAndroid Build Coastguard Worker } _Int64;
398*3ac0a46fSAndroid Build Coastguard Worker
_TIFFUInt64ToFloat(uint64_t ui64)399*3ac0a46fSAndroid Build Coastguard Worker float _TIFFUInt64ToFloat(uint64_t ui64)
400*3ac0a46fSAndroid Build Coastguard Worker {
401*3ac0a46fSAndroid Build Coastguard Worker _Int64 i;
402*3ac0a46fSAndroid Build Coastguard Worker
403*3ac0a46fSAndroid Build Coastguard Worker i.value = ui64;
404*3ac0a46fSAndroid Build Coastguard Worker if (i.part.high >= 0)
405*3ac0a46fSAndroid Build Coastguard Worker {
406*3ac0a46fSAndroid Build Coastguard Worker return (float)i.value;
407*3ac0a46fSAndroid Build Coastguard Worker }
408*3ac0a46fSAndroid Build Coastguard Worker else
409*3ac0a46fSAndroid Build Coastguard Worker {
410*3ac0a46fSAndroid Build Coastguard Worker long double df;
411*3ac0a46fSAndroid Build Coastguard Worker df = (long double)i.value;
412*3ac0a46fSAndroid Build Coastguard Worker df += 18446744073709551616.0; /* adding 2**64 */
413*3ac0a46fSAndroid Build Coastguard Worker return (float)df;
414*3ac0a46fSAndroid Build Coastguard Worker }
415*3ac0a46fSAndroid Build Coastguard Worker }
416*3ac0a46fSAndroid Build Coastguard Worker
_TIFFUInt64ToDouble(uint64_t ui64)417*3ac0a46fSAndroid Build Coastguard Worker double _TIFFUInt64ToDouble(uint64_t ui64)
418*3ac0a46fSAndroid Build Coastguard Worker {
419*3ac0a46fSAndroid Build Coastguard Worker _Int64 i;
420*3ac0a46fSAndroid Build Coastguard Worker
421*3ac0a46fSAndroid Build Coastguard Worker i.value = ui64;
422*3ac0a46fSAndroid Build Coastguard Worker if (i.part.high >= 0)
423*3ac0a46fSAndroid Build Coastguard Worker {
424*3ac0a46fSAndroid Build Coastguard Worker return (double)i.value;
425*3ac0a46fSAndroid Build Coastguard Worker }
426*3ac0a46fSAndroid Build Coastguard Worker else
427*3ac0a46fSAndroid Build Coastguard Worker {
428*3ac0a46fSAndroid Build Coastguard Worker long double df;
429*3ac0a46fSAndroid Build Coastguard Worker df = (long double)i.value;
430*3ac0a46fSAndroid Build Coastguard Worker df += 18446744073709551616.0; /* adding 2**64 */
431*3ac0a46fSAndroid Build Coastguard Worker return (double)df;
432*3ac0a46fSAndroid Build Coastguard Worker }
433*3ac0a46fSAndroid Build Coastguard Worker }
434*3ac0a46fSAndroid Build Coastguard Worker
_TIFFClampDoubleToFloat(double val)435*3ac0a46fSAndroid Build Coastguard Worker float _TIFFClampDoubleToFloat(double val)
436*3ac0a46fSAndroid Build Coastguard Worker {
437*3ac0a46fSAndroid Build Coastguard Worker if (val > FLT_MAX)
438*3ac0a46fSAndroid Build Coastguard Worker return FLT_MAX;
439*3ac0a46fSAndroid Build Coastguard Worker if (val < -FLT_MAX)
440*3ac0a46fSAndroid Build Coastguard Worker return -FLT_MAX;
441*3ac0a46fSAndroid Build Coastguard Worker return (float)val;
442*3ac0a46fSAndroid Build Coastguard Worker }
443*3ac0a46fSAndroid Build Coastguard Worker
_TIFFClampDoubleToUInt32(double val)444*3ac0a46fSAndroid Build Coastguard Worker uint32_t _TIFFClampDoubleToUInt32(double val)
445*3ac0a46fSAndroid Build Coastguard Worker {
446*3ac0a46fSAndroid Build Coastguard Worker if (val < 0)
447*3ac0a46fSAndroid Build Coastguard Worker return 0;
448*3ac0a46fSAndroid Build Coastguard Worker if (val > 0xFFFFFFFFU || val != val)
449*3ac0a46fSAndroid Build Coastguard Worker return 0xFFFFFFFFU;
450*3ac0a46fSAndroid Build Coastguard Worker return (uint32_t)val;
451*3ac0a46fSAndroid Build Coastguard Worker }
452*3ac0a46fSAndroid Build Coastguard Worker
_TIFFSeekOK(TIFF * tif,toff_t off)453*3ac0a46fSAndroid Build Coastguard Worker int _TIFFSeekOK(TIFF *tif, toff_t off)
454*3ac0a46fSAndroid Build Coastguard Worker {
455*3ac0a46fSAndroid Build Coastguard Worker /* Huge offsets, especially -1 / UINT64_MAX, can cause issues */
456*3ac0a46fSAndroid Build Coastguard Worker /* See http://bugzilla.maptools.org/show_bug.cgi?id=2726 */
457*3ac0a46fSAndroid Build Coastguard Worker return off <= (~(uint64_t)0) / 2 && TIFFSeekFile(tif, off, SEEK_SET) == off;
458*3ac0a46fSAndroid Build Coastguard Worker }
459